14

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?

Community
  • 1
  • 1
user2743393
  • 153
  • 1
  • 1
  • 4
  • Please mention your Python and OpenCV version! At least I can confirm that the ellipse function is working fine with Python 2.6.1 and OpenCV 2.4.3 – Robert Caspary Sep 03 '13 at 14:59
  • I have the same error with python 2.7.5 and OpenCV 2.4.3. And I'm definitely passing tuples of length 2 for the "center" and "axes" arguments. – Mike Lawrence Nov 07 '13 at 00:44

5 Answers5

11

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.

Community
  • 1
  • 1
Arnaud P
  • 12,022
  • 7
  • 56
  • 67
  • Nitpick: this is not called "multiple dispatch" but rather "function overloading". – Thomas Apr 26 '19 at 10:19
  • 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](https://en.wikipedia.org/wiki/Multiple_dispatch#Python) – Arnaud P Apr 26 '19 at 15:29
  • 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: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2216.pdf – alkasm Jan 13 '20 at 23:35
  • @alkasm, owing to the fact that python is dynamically typed, shall I assume that *multiple dispatch* is the correct term here then ? – Arnaud P Jan 14 '20 at 09:20
  • I believe so. GvR also similarly calls them multimethods, not function overloads, in his example from your prev link, here: https://www.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. – alkasm Jan 14 '20 at 21:29
8

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

Pari
  • 81
  • 1
  • 2
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)
Todd Stellanova
  • 901
  • 1
  • 9
  • 13
2

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

rob3c
  • 1,936
  • 1
  • 21
  • 20
0

these parameters should be integer, or it will raise TypeError