Stijn
Stijn

Reputation: 35

How can I find the angle between two contours in Python+Opencv

I'm trying to find the angle between the two contours in this image. However the center point of the contour far right is twitching all over the place. I'm using this code:

if len(contours) > 1:
    cnt1 = contours[0]
    cnt2 = contours[1]
    area = cv2.contourArea(cnt1)
    M1 = cv2.moments(cnt1)
    M2 = cv2.moments(cnt2)
    if area > 30:
        cv2.drawContours(frame, contours, -1, (0, 255, 255), 3)
        X1_px = int(M1['m10'] / M1['m00'])
        Y1_px = int(M1['m01'] / M1['m00'])
        X2_px = int(M2['m10'] / M1['m00'])
        Y2_px = int(M2['m01'] / M1['m00'])
        cv2.circle(frame, (X1_px, Y1_px), 3, (0, 0, 255), -1)
        cv2.circle(frame, (X2_px, Y2_px), 3, (0, 0, 255), -1)

        if (X2_px-X1_px) != 0:
            angle = math.atan((Y2_px-Y1_px)/(X2_px-X1_px))
            angle = int(angle * (180 / math.pi))
            print(angle)

I think the cnt1, cnt2 part of my code is causing the problem, I don't know how openCV orders the contours in this array.

Can anyone help me fix this code?

Upvotes: 1

Views: 4146

Answers (1)

ZdaR
ZdaR

Reputation: 22954

I am assuming that you have filtered the contours based on area etc and at last you have only 2 contours left:

enter image description here

Now for both the contours, simply get the centre point calculate the angle as:

import cv2
import math


def get_center(contour):
    M = cv2.moments(contour)
    cX = int(M["m10"] / M["m00"])
    cY = int(M["m01"] / M["m00"])

    return cX, cY


def get_angle(p1, p2):
    return math.atan2(p1[1] - p2[1], p1[0] - p2[0]) * 180/math.pi


img = cv2.imread("./binary_img.png", 0)
i, contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
if len(contours) == 2:
    center_1, center_2 = get_center(contours[0]), get_center(contours[1])
    print get_angle(center_1, center_2)

Upvotes: 2

Related Questions