简体   繁体   中英

<Python, openCV> How I can use cv2.ellipse?

OpenCV2 for python have 2 function


[Function 1]

  • Python: cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]]) → None

[Function 2]

  • Python: cv2.ellipse(img, box, color[, thickness[, lineType]]) → None

I want to use [Function 1]

But when I use this Code

cv2.ellipse(ResultImage, Circle, Size, Angle, 0, 360, Color, 2, cv2.CV_AA, 0)

It raise

TypeError: ellipse() takes at most 5 arguments (10 given)


Could you help me?

The fact that Python doesn't support multiple dispatch by default doesn't help here: having two functions with the same name but different parameters is not pythonic. So the question is: how does cv2 guess the version we'd like to call ? I couldn't find any explicit doc on that.

Anyhow, after experiencing the same issue with opencv 3.0.0-beta and Python 3.4.2, I finally found out that in my case one of the circle's point was a float , and although I was running the official samples code with 8 parameters, for some reason cv2 defaulted to the 5-args function. Using int fixed the problem, so the error message was pretty misleading.

I believe going from Python 2 to 3 may bring that kind of confusion in existing code, since integer divisions return floats in Python 3.

Make sure all the ellipse parameters are int otherwise it raises "TypeError: ellipse() takes at most 5 arguments (10 given)". Had the same problem and casting the parameters to int, fixed it.

Please note that in Python, you should round the number first and then use int(), since int function will cut the number:

x = 2.7 , int(x) will be 2 not 3

I ran into this same error and it turned out that I was not passing the correct minimum number of parameters (7) to the startAngle/endAngle form of the method. In my case I was missing the "angle" parameter (the angle of rotation of the ellipse), which precedes the startAngle and endAngle parameter.

My guess is that your "Circle" or "Size" parameters are wrong...they should be tuples, (x,y) for center and (width,height) for axes

cv2.ellipse(ResultImage, (centerX,centerY), (width,height), 0, 0, 180, yellow, 2)

这些参数应该是整数,否则会引发TypeError

Other answers correctly point out that calling the [Function 1] version requires using int coordinates in some of the arguments ( center and axes , specifically). However, they don't mention that you can use the shift argument to maintain "fractional bit" accuracy in the coordinates for sub-integer resolution.

Here's an example wrapper function for cv2.ellipse that can accept float coordinates and cast them to int s after rewriting them for use with the shift argument:

def draw_ellipse(
        img, center, axes, angle,
        startAngle, endAngle, color,
        thickness=3, lineType=cv2.LINE_AA, shift=10):
    center = (
        int(round(center[0] * 2**shift)),
        int(round(center[1] * 2**shift))
    )
    axes = (
        int(round(axes[0] * 2**shift)),
        int(round(axes[1] * 2**shift))
    )
    cv2.ellipse(
        img, center, axes, angle,
        startAngle, endAngle, color,
        thickness, lineType, shift)

The shift parameter indicates the number of "fractional bits" in the center and axes coordinate values, so that's why the coordinates multiplied by powers of 2 (multiplying by 2 is the same as shifting the bits in their integer binary representations to the left by one.) This shift trick is handy with many other opencv functions, as well, but its usage isn't documented very well (especially in python).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM