4

I am trying to draw an arc using Open CV, using cv2.ellipse function I tried reading the documentation for the same, but I m finding it very confusing. It is an arc in my case so axes_x and axes_y are same, i.e the radius. What should be my axis, In which direction should I calculate the Start and the End angle? And what is this angle of rotation? Given is the function - cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]])

import cv2
import numpy as np

def create_blank(height, width, color):

    blank_image = np.zeros((int(height), int(width), 3), np.uint8)
    blank_image[:, :] = color
    return blank_image

def draw_arc(image):
    height, width = image.shape[0:2]
    # Ellipse parameters
    radius = 100
    center = (width / 2, height/2)
    axes = (radius, radius)
    angle = 0
    startAngle = 135
    endAngle = 180
    cv2.line(image, (0, 150), (300, 150), (0, 0, 0), 2, cv2.CV_AA)
    cv2.line(image, (150, 0), (150, 300), (0, 0, 0), 2, cv2.CV_AA)
    cv2.ellipse(image, center, axes, angle, startAngle, endAngle, (0, 0, 0), 2, cv2.CV_AA)
    cv2.imshow("ellipse", image)


# Create new blank 300x150 white image
width, height = 300, 300
image = create_blank(width, height, color=WHITE)
draw_arc(image)

cv2.waitKey(0)
cv2.destroyAllWindows()

When my startAngle is 135 and endAngle is 180, the result looks like enter image description here

whereas when the startAngle is 0 and endAngle is 90, the result looks like enter image description here

So this makes it confusing, in which direction is the arc rotating.

Anuradha
  • 1,089
  • 4
  • 18
  • 29
  • Referring to the corresponding [doc page](https://docs.opencv.org/4.1.0/d6/d6e/group__imgproc__draw.html#ga28b2267d35786f5f890ca167236cbc69), which part(s) do you have difficulties with to understand? Maybe, provide an example ellipse you'd like to draw (e.g. drawn manually), and what you've tried so far to achieve that, i.e. provide the code. – HansHirse Jun 17 '19 at 11:37
  • The `startAngle` is NOT the rotation angle, which is the `angle` parameter in `cv2.ellipse`! Starting point of the drawing is the point `(x, 0)`, and drawing takes place clockwise from there. Let's say, your second example is something like `cv2.ellipse(img, (x, y), (rx, ry), angle=0, startAngle=0, endAngle=90, ...`, compare the output with `cv2.ellipse(img, (x, y), (rx, ry), angle=45, startAngle=0, endAngle=90, ...`, and you'll see the difference, and what the actual rotation angle `angle` is. – HansHirse Jun 17 '19 at 12:20
  • Is angle a function of start angle and end angle? or a totally independent entity? – Anuradha Jun 17 '19 at 12:25
  • Totally independent. The ellipse (or arc) is drawn from `startAngle` to `endAngle`. Then, the whole ellipse (or arc) is rotated by `angle`. – HansHirse Jun 17 '19 at 12:26
  • That makes sense, as I read it somewhere where angle = startAngle -endAngle, that made the whole confusion – Anuradha Jun 17 '19 at 12:28

1 Answers1

10

You can really easily view how the change of parameters affect the drawing of the ellipse. Here is a simple code for it:

import numpy as np
import cv2

center = (200, 200) # x,y
axes = (100, 75) # first, second
angle = 0. # clockwise, first axis, starts horizontal
for i in range(360):
  image = np.zeros((400, 400, 3)) # creates a black image
  image = cv2.ellipse(image, center, axes, angle, 0., 360, (0,0,255))
  image = cv2.ellipse(image, center, axes, angle, 0., i, (0,255,0))
  cv2.imshow("image", image)
  cv2.waitKey(5)

cv2.waitKey(0)
cv2.destroyAllWindows()

This will do something like:

enter image description here

Lets go through the parameters:

center -> x and y tuple where the center of the ellipse is.

axes -> first and second axes radius (half the total size). The first one is the horizontal one if angle 0 is applied, the second one will be the vertical one.

angle -> The angle of the whole ellipse, i.e. if you move clockwise the first axis

startAngle -> where you want to start drawing your arc, for example 0 will be like my example image (in the first axis), but if the angle has a value, then the 0 will rotate the same way.

endAngle -> where you want to stop drawing, you can see that I vary it in my example to draw an increasing ellipse.

If you want an arc of a circle of radius 50px, lets say from 60 degrees up to 120 degrees, but in counterclockwise (360 - start/endAngle) you can do:

image = cv2.ellipse(image, (100,100), (50,50), 0.0, 360-120, 360-60, (0,255,0))

If you have doubts with any of them, feel free to ask in a comment

api55
  • 11,070
  • 4
  • 41
  • 57
  • Say my start angle is 135 and end angle is 180, my arc is drawn in the second quadrant, which makes sense if i start from 135 and stop at 180. How does this make sense when my start angle is 0 and end angle is 90, according to the previous logic, it should lie in the 1st quadrant, but the actual result is in 4th Quad – Anuradha Jun 17 '19 at 11:55
  • @Anuradha clockwise vs counter clockwise. just put as starting angle 360-180 and as ending angle 360-135. This should draw it in the second quadrant. same with the other one 360 - 0 for ending and 360-90 for starting. So it is 360-angle and switch starting with the ending angle – api55 Jun 17 '19 at 11:57
  • I have a set of parameters, given for a shape, using them how can i figure out in which direction do i have to draw the arc, clockwise or anti clockwise? Example of such parameters are - Number 1. 'center': (100.0, 100.0, 0.0), 'start_angle': 315, 'end_angle': 0.0, 'radius': 3.0 Number 2. 'center': (200.0, 200.0, 0.0), 'start_angle': 135, 'end_angle': 180, 'radius': 8.0 – Anuradha Jun 17 '19 at 12:11
  • 1
    The ellipse function is always clockwise. The first one is clockwise since start angle is greater than the end angle, the second one is counter clockwise end angle is bigger this time and you need to revert it... the first one 0.0 could also be 360, which will be counter clockwise instead, so be careful with that. – api55 Jun 17 '19 at 12:25
  • And what about `shift`? What does it do? – sh37211 Sep 14 '21 at 01:26