Click here to Skip to main content
15,884,472 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
i have two lines that will be draw through mouse events and to find the angle between them like if i draw two parallel line the angle give me 0

What I have tried:

Python
import numpy as np
import cv2
import math

btn_down = False

def get_points(im):
    # Set up data to send to mouse handler
    data = {}
    data['im'] = im.copy()
    data['lines'] = []

    # Set the callback function for any mouse event
    cv2.imshow("Image", im)
    cv2.setMouseCallback("Image", mouse_handler,data)
    cv2.waitKey(0)

    # Convert array to np.array in shape n,2,2
    points = np.uint16(data['lines'])

    return points, data['im']

def mouse_handler(event, x, y, flags, data):
    global btn_down

    if event == cv2.EVENT_LBUTTONUP and btn_down:
        #if you release the button, finish the line
        btn_down = False
        data['lines'][0].append((x, y)) #append the seconf point
        cv2.circle(data['im'], (x, y), 3, (0, 0, 255),5)
        cv2.line(data['im'], data['lines'][0][0], data['lines'][0][1], (0,0,255), 2)
        cv2.imshow("Image", data['im'])

    elif event == cv2.EVENT_MOUSEMOVE and btn_down:
        #thi is just for a ine visualization
        image = data['im'].copy()
        cv2.line(image, data['lines'][0][0], (x, y), (0,0,0), 1)
        cv2.imshow("Image", image)

    elif event == cv2.EVENT_LBUTTONDOWN:
        btn_down = True
        data['lines'].insert(0,[(x, y)]) #prepend the point
        cv2.circle(data['im'], (x, y), 3, (0, 0, 255), 5, 16)
        cv2.imshow("Image", data['im'])

def gradient(pt1, pt2):
    return (pt2[1] - pt1[1]) / (pt2[0] - pt1[0])

def getangle(pt1,pt2,pt3,pt4):
    pt1,pt2,pt3,pt4 =    data['im'][-4:]
    #last_points = pts[-4:]
    #pt2 = pts[-1][0]
    #pt1 = pts[-2][0]
    #pt3 = pts[-2][1]
    print(f"point1: {pt1} \n point2: {pt2} \n point3 : {pt3}")
    m1 = gradient(pt1, pt2)
    m2 = gradient(pt1, pt3)
    angR = math.atan((m2 - m1) / (1 + (m2 * m1)))
    angD = math.degrees(angR)
    cv2.putText(final_image, str(angD), (pt1[0] - 20, pt1[1] - 20), cv2.FONT_HERSHEY_COMPLEX,1, (0, 0, 255), 2)
    print(f"angle: {angD} \n angleR: {angR}")


# Running the code
img = cv2.imread('2.jpg', 1)
pts, final_image = get_points(img)

while True:
    if len(pts) % 4 == 0 and len(pts) != 0:
        getangle( data['im'])
        cv2.imshow('Image', final_image)
        print(pts[-2:])
        # pts1 = pts[-1]
        # print(f"point 1 : {pts1[0]}")
        cv2.waitKey(0)
Posted
Updated 16-Dec-20 21:46pm
v2

1 solution

You can make use of use the Hough Transform as mentioned here: How to measure the angle between 2 lines in a same image using python opencv? - Stack Overflow[^]

Snippet from there:
Python
from skimage.transform import (hough_line, hough_line_peaks)
import numpy as np
import cv2

image = cv2.imread('2.png')

# Compute arithmetic mean
image = np.mean(image, axis=2)

# Perform Hough Transformation to detect lines
hspace, angles, distances = hough_line(image)

# Find angle
angle=[]
for _, a , distances in zip(*hough_line_peaks(hspace, angles, distances)):
    angle.append(a)

# Obtain angle for each line
angles = [a*180/np.pi for a in angle]

# Compute difference between the two lines
angle_difference = np.max(angles) - np.min(angles)
print(angle_difference)
 
Share this answer
 
Comments
Member 14649324 17-Dec-20 3:09am    
@Sandeep Mewara I tried this but its not working because when i draw the line with mouse events then angle is not finding
Sandeep Mewara 17-Dec-20 3:16am    
Once you raw the lines with mouse, you should be left with two lines at an angle. then you can apply above to get the angle. You trying something different?
Member 14649324 17-Dec-20 4:11am    
i try this but its not working can you edit the code for me plz and make the full code for me the one i provided about it will be a great help

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900