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

13,272

Solution 1

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.

Solution 2

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

Solution 3

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 ints 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).

Solution 4

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)
Share:
13,272

Related videos on Youtube

user2743393
Author by

user2743393

Updated on September 16, 2022

Comments

  • user2743393
    user2743393 over 1 year

    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?

  • Keyur Padalia
    Keyur Padalia almost 5 years
    Nitpick: this is not called "multiple dispatch" but rather "function overloading".
  • Arnaud P
    Arnaud P almost 5 years
    Yes I've grown up with the 'method overloading' vocabulary too, in Java. It's only when writing this post that I learnt about the 'multiple dispatch' wording, which does seem to exist
  • alkasm
    alkasm over 4 years
    Multiple dispatch refers to something different than function overloading---multifunctions switch based on runtime types, as opposed to compiler-checked strictly typed functions, which would be function overloading. See for example this C++ report on multimethods: open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2216.pdf
  • Arnaud P
    Arnaud P over 4 years
    @alkasm, owing to the fact that python is dynamically typed, shall I assume that multiple dispatch is the correct term here then ?
  • alkasm
    alkasm over 4 years
    I believe so. GvR also similarly calls them multimethods, not function overloads, in his example from your prev link, here: artima.com/weblogs/viewpost.jsp?thread=101605, so I think your wording is fine. On the other hand, while Python doesn't have the functionality built-in, I'm not sure it's quite unpythonic. For example numpy arrays have different dtypes but the same functions can be called with any type arrays. Those types don't exist at the Python level (they're all just ndarrays) but they could be and it would be equally intuitive an interface.