0

I am using the openCV library in python. I want to open an image, click three distinct points, and from these generate a circle segment.

The first point clicked is the center of the circle. The next point clicked defines the beginning of the segment and the last point clicked defines the end of the segment.

I am a little bit lost as on how to do this, since the cv2.ellipse function requires angle information, which I am not sure how to acquire from my mouse clicks.

Here is my initial idea:

def draw_circleSegment(event, x, y, flags, param):

global center_pt, upper_pt, center_clicked, upper_clicked

#right mouse click
if event == cv2.EVENT_RBUTTONDOWN:
    #reset
    if center_clicked and upper_clicked:
        center_clicked = False
        upper_clicked = False
        center_pt = (0,0)
        upper_clicked = (0,0)
    #get coordinates of circle center
    if not center_clicked:
        center_pt = tuple(int(el) for el in (x,y))
        center_clicked = True
    #get coordinates of upper point of the circle segment
    if not upper_clicked:
        upper_pt = tuple(int(el) for el in(x,y))
        upper_clicked = True

#initial values of the circle segment
center_pt = (0,0)
upper_pt = (0,0)
center_clicked = False
upper_clicked = False

#capture video
cap = cv2.VideoCapture(r'Path')
cv2.namedWindow(winname='Window Name')
cv2.setMouseCallback('Window Name', draw_circleSegment)

while True: 
    ret_frame, frame = cap.read()

    #draw a circle segment whose points are defined by right mouse click   
    if center_clicked and upper_clicked: 
        cv2.line(frame, center_pt, upper_pt, (255,0,0), 2)
        SegmentAngle=math.degrees(math.atan2(upper_pt[1]-center_pt[1], upper_pt[0]-center_pt[0]))
        radius = int(math.sqrt((upper_pt[0]-center_pt[0])**2 + (upper_pt[1]-center_pt[1])**2))
        cv2.ellipse(frame, center_pt, axes=(radius, radius), angle=SegmentAngle, startAngle=SegmentAngle, endAngle=SegmentAngle+180, thickness=2)
        lower_pt = (upper_pt[0], upper_pt[1]-radius)
            cv2.line(frame, center_pt, lower_ppt, (255,0,0), 2)
        break

So when running this code, I get the error message "TypeError: ellipse() takes at most 5 arguments (7 given)" ... and I think this means at least one of the arguments of ellipse has a wrong type. That's why I performed these weird casts to integer values for both center_pt and upper_pt and radius. But it didn't help.

Can anyone help?

Luk
  • 1,009
  • 2
  • 15
  • 33
  • see doc for [cv2.eclipse](https://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html#ellipse) - you can use 0 and 360 to create full circle. Try with different values to see how it works. – furas May 19 '19 at 10:11
  • if you have two points then you can create rectangular triangle and calculate tangens or cotangens of angle using `x2-x1 / y2-y1`. And then you can use module `math` to convert tangens/cotangens to angle. – furas May 19 '19 at 10:17
  • `angle = math.degrees(math.atan2(y2-y1, x2-x1))` – furas May 19 '19 at 11:12
  • @furas: thx very much! I have tried to implement your suggested solution. However, as you can see in my edited question, it did not completely work out. – Luk May 19 '19 at 18:38
  • So, the issue is most likely that some parameter of ellipse is a floating point value now. At least this is what I understand from [this related question](https://stackoverflow.com/questions/18595099/python-opencv-how-i-can-use-cv2-ellipse/27202073) – Luk May 19 '19 at 19:33
  • so convert values to integer using `int(value)` or `round(value)` . You have also `math.ceil(value)`, `math.floor(value)`, `math.trunc(value)` – furas May 19 '19 at 20:57

0 Answers0