1

I tried to make a circle with cv2.circle:

import cv2

cap = cv2.VideoCapture(0)
while(True):
    ret, frame = cap.read()
    a = cv2.circle(frame, frame[0]/2, frame[1]/2, 30, (0,255,255))
    #cv2.imshow("test", opening)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break
cap.release()
cv2.destroyAllWindows()

After I ran this code above, I got this:

 a = cv2.circle(frame, frame[0]/2, frame[1]/2, 30, (0,255,255))
cv2.error: OpenCV(4.5.2) :-1: error: (-5:Bad argument) in function 'circle'
> Overload resolution failed:
>  - Can't parse 'center'. Expected sequence length 2, got 1280
>  - Can't parse 'center'. Expected sequence length 2, got 1280

I thought it's about center coordinates, and changed frame[0]/2 as 300, and did the same to other. It worked. here's output.

So I used a virtual machine to test the same code with frame[0]/2 and frame[1]/2 and did the same things. I got this error message:

a = cv2.circle(frame, tuple(frame[0]/2), tuple(frame[1]/2), 10, (0,255,255))
TypeError: function takes exactly 2 arguments (1920 given)

My computer: MacBook pro m1 Visual Studio Code

Virtual Machine: Ubuntu 20.04.2 LTS PyCharm

Can anyone help me? I'm new at mac, StackOverflow and OpenCV so if I did a wrong thing please indicate it. Thank you all in advance.

kokomonci
  • 31
  • 1
  • 1
  • 3
  • 1
    The center `data type` needs to be an `integer tuple`, for example: `center = (150,150)`. Like this: `cv2.circle(frame, (150, 150), 30, (0,255,255), 1)`. [Here's](https://docs.opencv.org/master/dc/da5/tutorial_py_drawing_functions.html) the documentation. – stateMachine May 18 '21 at 22:13
  • first of all thank you for your interest. I used your info and rearranged the question. Thank you so much! – kokomonci May 18 '21 at 22:22

5 Answers5

6

By and large, I was having the same problem. As far as I know that probably this error stems from 4.5.2 version and I have solved this issue like this:

instead of

cv.circle(img,(pts1[1][0],pts1[1][1]),5,(0,0,255),cv.FILLED)

put this

cv.circle(img,(int(pts1[1][0]),int(pts1[1][1])),5,(0,0,255),cv.FILLED)

MWDE
  • 69
  • 2
  • there is no context to explain why your code references `pts1`. perhaps stick to what was established in the question. -- equivalent answers were already posted before you gave yours. I see no value added. – Christoph Rackwitz Apr 01 '22 at 08:28
3

Because opencv 4.5.2 has made a backwards-incompatible change without bumping their major version. This that would break with your existing code. Try opencv 4.1.1

tuanzi
  • 39
  • 1
  • 2
  • Horrible decision. Pythonic code should be type-flexible. This breaks a lot of code. Making this backwards-incompatible change on a minor release is ridiculous. – Ken Seehart Oct 02 '21 at 02:49
  • 1
    there is no "backwards-incompatible change". it has **always** been the case that these functions expected **tuples of python integers**. now there's simply a more verbose explanation of what went wrong in the type conversion. even newer versions now also accept numpy integers (instead of just python integers) and numpy arrays (instead of just tuples/lists) -- additionally, this question's main problem is that individual coordinates were passed as arguments, rather than a tuple representing the center point. this violates the function's signature on a basic level, unrelated to types. – Christoph Rackwitz Apr 01 '22 at 08:31
3

The problem is that opencv needs the center point to be a tuple of the X and Y coordinates and the coordinates individually have to be integers and not floats. I would suggest wrapping your center parenthesis and your individual coordinates with int(). Like this:

    a = cv2.circle(frame, (int(frame[0]/2), int(frame[1]/2), 30, (0,255,255))
2

You’re providing center as two parameters, when it should be a single parameter which is a tuple of those two values.

Instead of:

a = cv2.circle(frame, frame[0]/2, frame[1]/2, 30, (0,255,255))

Try:

a = cv2.circle(frame, (frame[0]/2, frame[1]/2), 30, (0,255,255))
  • First of all thank you for your interest. I tried it and got this: ` a = cv2.circle(frame, (frame[0]/2, frame[1]/2), 30, (0,255,255)) cv2.error: OpenCV(4.5.2) :-1: error: (-5:Bad argument) in function 'circle' > Overload resolution failed: > - Can't parse 'center'. Sequence item with index 0 has a wrong type > - Can't parse 'center'. Sequence item with index 0 has a wrong type ` – kokomonci May 18 '21 at 22:19
  • Pixel coordinates have to be integers - try with `(int(frame[0]/2), int(frame[1]/2))` – DisappointedByUnaccountableMod May 18 '21 at 22:28
  • @kokomonci You are slicing (or indexing) the first (`frame[0]`) and second (`frame[1]`) columns of `frame` and passing it directly to `cv2.circle`. You are passing the **whole** column. You probably want only the height and width of `frame`, so you use [shape](https://numpy.org/devdocs/reference/generated/numpy.shape.html) to get the dimensions of the numpy array: `(height, width) = frame.shape[:2]` . Be aware that you still need to cast `height` and `width` to integers. – stateMachine May 18 '21 at 22:37
  • @barny I tried in integer format, here's what I got: a = cv2.circle(frame, (int(frame[0]/2), int(frame[1]/2)), 30, (0,255,255)) TypeError: only size-1 arrays can be converted to Python scalar – kokomonci May 18 '21 at 22:41
  • @stateMachine now I can see the window as output, but I can't see any circles now. `(height, width) = frame.shape[:2] a = cv2.circle(frame, (height, width), 40, (0,255,255), 10) ` – kokomonci May 18 '21 at 22:46
  • @kokomonci Note that by setting the center at `(height, width)` you are drawing the circle center at the bottom right corner of the image, so its probably drawn outside the "canvas". Gotta be careful with that. If you want the center of the circle to be drawn at the center of the image use `0.5 * height` and `0.5 * width`, but cast the result to integers before passing them to `circle`. Also be sure to draw a circle **smaller** in size than your image, and to give it `thickness`! – stateMachine May 18 '21 at 22:52
  • @stateMachine I see the window and finally I can see the circle, but it's not in the middle. I set coordinate as half of width and height as I understand it and that is what I'm trying to do but circle is supposed to be in middle. Why circle is not in middle? – kokomonci May 18 '21 at 23:03
  • @kokomonci I don't know why the circle is not in the middle, as I don't have your code nor know what you are trying to do. Maybe you switched the coordinates you gave to `circle`. It first needs the `x` and then the `y` coordinate. Please, refer to the [documentation](https://docs.opencv.org/master/d6/d6e/group__imgproc__draw.html#gaf10604b069374903dbd0f0488cb43670) to se the function prototypes and examples. – stateMachine May 19 '21 at 00:01
  • Print the value (tuple) you’re using for the `center` parameter so you can confirm the location of the `center` you’re specifying. Just printing the values would also have speeded you up you through the problem of specifying the center. – DisappointedByUnaccountableMod May 19 '21 at 06:20
1

use integer value as x1,x2,y1,y2

_ = cv2.rectangle(img, (int(x1), int(y1)), (int(x2), int(y2)), (0,255,0),1)
Abhijith M
  • 743
  • 5
  • 5