Rune619
Rune619

Reputation: 11

How to Detect and Draw Hough Transform Lines at a certain range of angles

I am trying to detect edges at a certain range of angles using Probabilistic Hough Transform. I am able to detect the lines but my code is not showing the lines at the angle ranges I want. I just need some help in the implementation process in Python.

def gtob(image):
       cdst = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
       cdstP = np.copy(cdst)
       return cdstP
    

x = segmentation(img)
canny = canny_with_threshold(x)
z = gtob(canny)
theta = np.pi / 180
linesP = cv2.HoughLinesP(canny, 1, theta, 50, None, 150, 10)

if linesP is not None:
    for i in range(0, len(linesP)):
        l = linesP[i][0]
        #p_h = cv2.line(z, (l[0], l[1]), (l[2], l[3]), (0, 0, 255), 3, cv2.LINE_AA)
        x1 = (l[0])
        y1 = (l[1])
        x2 = (l[2])
        y2 = (l[3])
        slope = (y2 - y1) / (x2 - x1)
        angle = math.atan(slope)
        if (angle > 95 and angle < 165):
            m =cv2.line(z, (l[0], l[1]), (l[2], l[3]), (0, 0, 255), 3, cv2.LINE_AA)

cv2.imshow('ses',m)
cv2.waitKey()

Upvotes: 1

Views: 1284

Answers (1)

u1234x1234
u1234x1234

Reputation: 2510

You can find lines with cv2.HoughLinesP and then filter the results depending on angles.

  1. As beaker noted in the comment math.atan returns angles in radians not degrees.
  2. Also you may need to change your ranges to (-90, 90)

Example of an image:

enter image description here

Lines with depicted angles (blue lines is for angles within (-45, +45) range, red lines for other anlges):

enter image description here

Code:

import cv2
import numpy as np

image = cv2.imread("lines.jpg")
canny = cv2.Canny(image, 150, 200)

theta = np.pi / 180
linesP = cv2.HoughLinesP(canny, rho=1, theta=theta, threshold=100, minLineLength=100, maxLineGap=100)

used_angles = []
if linesP is not None:
    for line in linesP:
        x1, y1, x2, y2 = line[0]
        slope = (y2 - y1) / (x2 - x1)
        angle = np.math.atan(slope) * 180. / np.pi

        # Skip duplicated angles just for visualization
        similar = sum([np.abs(used_angle - angle) < 2 for used_angle in used_angles])
        if similar:
            continue
        used_angles.append(angle)

        if -45 < angle < 45:
            cv2.line(image, (x1, y1), (x2, y2), (255, 0, 0), 3, cv2.LINE_AA)
            cv2.putText(image, f'{angle:.2f}', (x1, y1), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)
        else:
            cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 3, cv2.LINE_AA)
            cv2.putText(image, f'{angle:.2f}', (x1, y1), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)


cv2.imshow("ses", image)
cv2.waitKey()

Upvotes: 2

Related Questions