<Python, openCV> How I can use cv2.ellipse?
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 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).
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)
Related videos on Youtube
user2743393
Updated on September 16, 2022Comments
-
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 almost 5 yearsNitpick: this is not called "multiple dispatch" but rather "function overloading".
-
Arnaud P almost 5 yearsYes 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 over 4 yearsMultiple 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 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 over 4 yearsI 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.