Does cv2.rectangle() have an argument named “rec”?

Viewed 929

I was trying to draw some rectangles within an image but the system gave me this error:enter image description here

Here is my code:

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

Any advice will be appreciated!

PS: I tried this piece of codes on kaggle notebok and it ran successfully but it crashed when I want to apply streamlit to deploy a web app (using my local machine). Not sure if it makes a difference, just FYI.

3 Answers

I figured out this issue, it is about the version. When I downgraded to 4.1.0.25, problem is solved.

cv2.rectangle has a bug; if you pass it arguments with invalid values, it will attempt to call the wrong overload.

This is because in c++, rectangle has two overloads, see the 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)

However, the python wrapper does not express this as two functions, the python wrapper will attempt to invoke the correct function based on the types of the arguments provided to it, not the names of the arguments.

If you read https://docs.opencv.org/master/da/d49/tutorial_py_bindings_basics.html, you will see:

Overloaded functions can be extended using CV_EXPORTS_AS. But we need to pass a new name so that each function will be called by that name in Python. Take the case of integral function below. Three functions are available, so each one is named with a suffix in Python. Similarly CV_WRAP_AS can be used to wrap overloaded methods.

However, if you inspect the source, this is not done.

This has been filed as a bug in opencv previous here and here, specifically see the comment from the opencv developers here: https://github.com/opencv/opencv/issues/15465#issuecomment-758025129

The root cause of the issue is current implementation of the overload resolution in the generated Python bindings. In my opinion, to solve the problem with inappropriate/misleading message the following steps should be done: ... If the last overload fits - use it and forget about previous errors. Otherwise raise custom OpenCV exception of OverloadError type with previously collected messages.

This is resolved in https://github.com/opencv/opencv/pull/19312, which is merged in some future version of opencv.

Ie. Long story short: This is a bug. It's fixed now, but probably not on the version of opencv you had before.

The cause is most likely that the pt1 and pt2 types are not 'int', which is causing opencv to try to invoke the wrong overload, but it is raising the incorrect error message.

There must be something wrong with your pt1 or pt2, thus cv2.rectangle encounters a problem looking for pt1 or pt2 when constructing a rectangle.

I'm able to reproduce your error by this code:

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)

However, if you give cv2.rectangle the right pt1 and pt2, you can get the right answer.

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)

You can try the above piece of code for debugging.

Related