I am implementing a program to detect lines in images from a camera. The problem is that when the photo is blurry, my line detection algorithm misses a few lines. Is there a way to increase the accuracy of the cv.HoughLines()
function without editing the parameters?
Example input image:
Desired image:
My current implementation:
def find_lines(img):
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edges = cv.dilate(gray,np.ones((3,3), np.uint8),iterations=5)
edges = cv.Canny(gray, 50, 150, apertureSize=3)
lines = cv.HoughLines(edges, 1, np.pi/180, 350)
The Hough Transform is a method that is used in image processing to detect any shape, if that shape can be represented in mathematical form. It can detect the shape even if it is broken or distorted a little bit.
With the help of the OpenCV library, we can easily process the images as well as videos to identify the objects, faces or even handwriting of a human present in the file. We will only focus to object detection from images using OpenCV in this tutorial.
Thus, the Hough Transform algorithm detects lines by finding the (ρ, θ) pairs that have a number of intersections larger than a certain threshold.
OpenCV is a pre-built, open-source CPU-only library (package) that is widely used for computer vision, machine learning, and image processing applications. It supports a good variety of programming languages including Python.
It would be a good idea to preprocess the image before giving it to cv2.HoughLines()
. Also I think cv2.HoughLinesP()
would be better. Here's a simple approach
Convert image to grayscale
Apply a sharpening kernel
Threshold image
Perform morphological operations to smooth/filter image
We apply a sharpening kernel using cv2.filter2D()
which gives us the general shape of the line and removes the blurred sections. Other filters can be found here.
Now we threshold the image to get solid lines
There are small imperfections so we can use morphological operations with a cv2.MORPH_ELLIPSE
kernel to get clean diamond shapes
Finally to get the desired result, we dilate using the same kernel. Depending on the number of iterations, we can obtain thinner or wider lines
Left (iterations=2
), Right (iterations=3
)
import cv2
import numpy as np
image = cv2.imread('1.png', 0)
sharpen_kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
sharpen = cv2.filter2D(image, -1, sharpen_kernel)
thresh = cv2.threshold(sharpen,220, 255,cv2.THRESH_BINARY)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=3)
result = cv2.dilate(opening, kernel, iterations=3)
cv2.imshow('thresh', thresh)
cv2.imshow('sharpen', sharpen)
cv2.imshow('opening', opening)
cv2.imshow('result', result)
cv2.waitKey()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With