cv2.rectangle() 是不是有一个名为“rec”的参数?

Posted

技术标签:

【中文标题】cv2.rectangle() 是不是有一个名为“rec”的参数?【英文标题】:Does cv2.rectangle() have an argument named “rec”?cv2.rectangle() 是否有一个名为“rec”的参数? 【发布时间】:2020-10-15 09:25:45 【问题描述】:

我试图在图像中绘制一些矩形,但系统给了我这个错误:

这是我的代码:

cv2.rectangle(img=sample,
                      pt1=(box[0], box[1]),
                      pt2=(box[2], box[3]),
                      color=(220, 0, 0), thickness=2)

任何建议将不胜感激!

PS:我在 kaggle notebok 上尝试了这段代码,它运行成功,但是当我想应用 streamlit 部署 Web 应用程序(使用我的本地机器)时它崩溃了。不确定它是否有影响,仅供参考。

【问题讨论】:

这能回答你的问题吗? cv2.rectangle() calls overloaded method, although I give other parameter 【参考方案1】:

我发现了这个问题,它与版本有关。当我降级到 4.1.0.25 后,问题就解决了。

【讨论】:

【参考方案2】:

cv2.rectangle 有一个错误;如果你给它传递了无效值的参数,它会尝试调用错误的重载。

这是因为在c++中,矩形有两个重载,见documentation:

void cv::rectangle (InputOutputArray img, Point pt1, Point pt2, const Scalar &color, int thickness=1, int lineType=LINE_8, int shift=0)

void cv::rectangle (InputOutputArray img, Rect rec, const Scalar &color, int thickness=1, int lineType=LINE_8, int shift=0)

但是,python 包装器不会将其表示为两个函数,python 包装器将尝试根据提供给它的参数类型而不是参数的名称来调用正确的函数.

如果你阅读https://docs.opencv.org/master/da/d49/tutorial_py_bindings_basics.html,你会看到:

可以使用 CV_EXPORTS_AS 扩展重载函数。但是我们需要传递一个新名称,以便在 Python 中使用该名称调用每个函数。下面以积分函数为例。三个函数可用,因此每个函数在 Python 中都以后缀命名。同样 CV_WRAP_AS 可用于包装重载方法。

但是,如果您检查源代码,则不会这样做。

这在之前的here 和here 中作为opencv 的bug 提交,具体请看opencv 开发者的评论:https://github.com/opencv/opencv/issues/15465#issuecomment-758025129

问题的根本原因是生成的 Python 绑定中重载解决方案的当前实现。 在我看来,要解决不恰当/误导性消息的问题,应该执行以下步骤: ... 如果最后一个重载适合 - 使用它并忘记以前的错误。 否则,使用先前收集的消息引发 OverloadError 类型的自定义 OpenCV 异常。

这在https://github.com/opencv/opencv/pull/19312 中得到解决,它被合并到一些未来版本的opencv 中。

即。长话短说:这是一个错误。现在已经修复了,但可能不在你之前的 opencv 版本上。

原因很可能是 pt1 和 pt2 类型不是 'int',这导致 opencv 尝试调用错误的重载,但却引发了不正确的错误消息。

【讨论】:

【参考方案3】:

你的pt1pt2一定有有问题,因此cv2.rectangle在构造矩形时遇到了寻找pt1或pt2的问题。

我可以通过此代码重现您的错误:

fig, ax = plt.subplots(1, 1, figsize=(10, 10))
img = np.ones((128, 128))
x1, y1, x2, y2 = 20, 30, 70, 90
line_width = 2
color = (0, 255, 255)

img = cv2.rectangle(img=img,
                    pt2=(x1, y1),
                    color=color,
                    thickness=line_width)

ax.imshow(img)

但是,如果你给cv2.rectangle正确pt1和pt2,你就能得到正确的答案。

fig, ax = plt.subplots(1, 1, figsize=(10, 10))
img = np.ones((128, 128))
x1, y1, x2, y2 = 20, 30, 70, 90
line_width = 2
color = (0, 255, 255)
img = cv2.rectangle(img=img,
                    pt1=(x1, y1),
                    pt2=(x2, y2),
                    color=color,
                    thickness=line_width)

ax.imshow(img)

你可以试试上面这段代码进行调试。

【讨论】:

显然,如果您只提供 pt2,您将像第一种情况一样收到此错误。你的例子根本没有帮助。问题是专门询问为什么当您提供 p1 和 p2 时会发生这种情况。 他应用的代码一定有问题(与上面粘贴的代码相比)。错误明显指出,少了一个param 错误是错误的。自己试试;如果你这样做,你会得到这个错误:pt1=np.array((x1, y,1), dtype=np.float) 即使你通过了 pt2。这里的问题是(很可能)x1,y1,x2,y2 的类型不是“int”。 'box' 很可能是一个 ndarray,其 dtype 不是 'int'。这个答案是正确的“出了点问题”,但这没有帮助。 正确的答案是'box'的dtype不是int。 感谢您的评论。我想也许你是对的,即使我在没有pt2 的情况下使用这个 API 时遇到了同样的错误。

以上是关于cv2.rectangle() 是不是有一个名为“rec”的参数?的主要内容,如果未能解决你的问题,请参考以下文章

cv2.rectangle() 调用重载方法,虽然我给出了其他参数

OpenCV cv2.rectangle 输出二值图像

cv2.rectangle()、cv2.putText()和cv2.imwrite()用法

为啥 cv2.rectangle 有时会返回 np.ndarray,而有时会返回 cv2.UMat

cv2.rectangle:TypeError:由名称('厚度')和位置(4)给出的参数

Opencv的绘图