Line Detection in Python with OpenCV | Halfline method



We will see how the Hough transform works for line detection using the Hough transform method. To apply the Houghline method, it is desirable to first detect the edge of a specific image. For edge detection technique go to Edge detection

Basics of the Houghline method

The line can be represented as y = mx + c or in parametric form, as r = xcosθ + ysinθ, where r — the perpendicular distance from the origin to the line, and θ — the angle formed by this perpendicular line and the horizontal axis, measured in the meter. — clockwise (this direction depends on how you represent the coordinate system. This representation is used in OpenCV).

Thus, any line can be represented in these two terms (r, θ).

The Halfline method works:

  • It first creates a two-dimensional array or accumulator (to hold the values ​​of two parameters) and is initially set to zero.
  • Let the rows denote r and the columns — (θ) theta.
  • The size of the array depends on the required precision. Suppose you want 1 degree angle precision, you need 180 columns (the maximum degree for a straight line is 180).
  • For r, the maximum possible distance is — this is the diagonal length of the image. Thus, with an accuracy of one pixel, the number of lines can be the diagonal length of the image.

Example:
Consider a 100 × 100 image with a horizontal line in the middle … Take the first point of the line. You know its (x, y) values. Now in a linear equation put the values ​​θ (theta) = 0,1,2,…, 180 and check the r you get. For each pair (r, 0), the value is incremented by one in the accumulator in the corresponding cells (r, 0). So now in the battery cell (50.90) = 1 along with some other cells. 
Now take the second point on the line. Do the same as above. Increase the values ​​in the cells corresponding to (r, 0) you got. This time, cell (50.90) = 2. We`re actually voting for (r, 0) values. You continue this process for every point on the line. At each point, the cell (50.90) will be increased or scored, while other cells may or may not be voted on. Thus, at the end, cell (50.90) will receive the maximum number of votes. So if you search the accumulator for the maximum number of votes, you will get the value (50.90), which says there is a line in this image at a distance of 50 from the origin and at an angle of 90 degrees.

Everything explained above is encapsulated in an OpenCV function .HoughLines (). It just returns an array of (r, 0) values. r is measured in pixels, and 0 — in radians.

# Python HoughLine illustration program
# method for line detection

import cv2

import numpy as np

 
# Read the desired image in
# what operations should be performed.
# Make sure image in the same
# directory where this python program is located

img = cv2.imread ( `image.jpg` )

 
  # Convert img to grayscale

gray = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY)

 
# Apply method for determining the edge on the image

edges = cv2.Canny (gray, 50 , 150 , apertureSize = 3 )

 
# This returns an array of r and theta values ​​

lines = cv2.HoughLines (edges, 1 , np.pi / 180 , 200 )

 
# Below for loop works up to t and theta values ​​
# are in the 2d array

for r, theta in lines [ 0 ]:

  

  # Stores the cos (theta) value in

a = np.cos (theta)

 

# Stores the value of sin (theta) in b

  b = np.sin (theta)

 

# x0 stores the rcos (theta) value

x0 = a * r

 

# y0 stores the rsin value (theta)

y0 = b * r

 

# x1 stores the rounded value (rcos (theta) -1000sin (t heta))

x1 = int (x0 + 1000 * ( - b))

  

  # y1 stores the rounded value (rsin (theta) + 1000cos (theta))

y1 = int (y0 + 1000 * (a ))

 

# x2 stores the rounded value (rc os (theta) + 1000sin (theta))

x2 = int (x0 - 1000 * ( - b))

 

# y2 stores the rounded value (rsin (theta) -1000cos (theta))

  y2 = int (y0 - 1000 * (a))

 

# cv2.line pic takes a line in img from point (x1, y1) to (x2, y2).

# (0,0,255) denotes the line color that will be

# drawn. In this case, it`s red.

cv2.line (img, (x1, y1), (x2, y2), ( 0 , 0 , 255 ), 2 )

 
# All changes made to input image finally
# written on new image houghlines.jpg

cv2.imwrite ( ` linesDetected.jpg` , img)

Function development (cv2.HoughLines (edge, 1, np.pi / 180, 200)) :

  1. The first parameter, "Input Image", must be a binary image, so apply the threshold boundary definition before finding applying a rough transformation.
  2. The second and third parameters — they are precision r and θ (theta) respectively.
  3. The fourth argument — it is a threshold that means the minimum number of votes he must receive to be considered a line.
  4. Remember that the number of votes depends on the number of dots on the line. Thus, it represents the minimum line length to be detected. 

Summing up the process

  • In the context of image analysis, the coordinates of the point (s) of the edge segments (i.e., X, Y) in the image are known and therefore serve as constants in the parametric line equation, while R (rho) and Theta ( θ) are the unknown variables we are looking for.
  • If we plot the possible values ​​(r) defined by each (theta), points in Cartesian space are mapped to curves (i.e. sinusoids) in the space of Hough polar parameters. This point-to-curve transform is the Hough transform for straight lines.
  • The transform is implemented by quantizing the Hough parameter space into finite bins or battery cells. When the algorithm runs, each (X, Y) is converted to a sampled (r, 0) curve, and the accumulator cells (2D matrices) that lie along this curve are enlarged.
  • The resulting peaks in the accumulator array are compelling proof that the corresponding straight line exists in the image.

Applying the Hough transform:

  1. It is used to highlight elements of a certain shape in the image.
  2. Allows gaps in the description of object boundaries and is relatively independent of image noise.
  3. Widely used in scanning, validation and barcode recognition

This article is courtesy of Pratima Upadhyay . If you are as Python.Engineering and would like to contribute, you can also write an article using contribute.python.engineering or by posting an article contribute @ python.engineering. See my article appearing on the Python.Engineering homepage and help other geeks.

Please post comments if you find anything wrong or if you would like to share more information on the topic discussed above.