How to detect lines in noisy line images?

2024/9/16 23:52:35

I generate noisy images with certain lines in them, like this one:

Generated image

I'm trying to detect the lines using OpenCV, but something is going wrong.

Here's my code so far, including the code to generate the noisy images.

import cv2
import numpy as npdef draw_random_lines(img, w, n):for i in range(n):point1 = (np.random.randint(low = 0, high = w), np.random.randint(low = 0, high = w))point2 = (np.random.randint(low = 0, high = w), np.random.randint(low = 0, high = w))cv2.line(img,point1,point2,(255,0,0),5)x = y = 0while(y<w):while(x<w):if(np.any(img[x, y] != 0)):if(np.random.randint(low=0, high=100) < 60):img[x, y] = [255, 255, 255] else:img[x, y] = [0, 0, 0]else:if(np.random.randint(low=0, high=100) < 95):img[x, y] = [255, 255, 255] else:img[x, y] = [0, 0, 0]x+=1x=0y+=1return imgw = 512
img = np.zeros((w,w,3), np.uint8)
img = draw_random_lines(img, w, 5)
cv2.imshow("Original", img)
cv2.imwrite("alo.png", img)
img = cv2.imread("alo.png")gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,150,apertureSize = 3)lines = cv2.HoughLines(edges,1,np.pi/180,200)
for line in lines:for rho,theta in line:a = np.cos(theta)b = np.sin(theta)x0 = a*rhoy0 = b*rhox1 = int(x0 + 1000*(-b))y1 = int(y0 + 1000*(a))x2 = int(x0 - 1000*(-b))y2 = int(y0 - 1000*(a))cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2)cv2.imshow("Detectada", img)cv2.waitKey(0)

And here are the results I'm getting (very wrong):

Wrong Results

So, how can I properly detect the lines in these noisy images?

Answer

Since OpenCV's Hough transform implementations look for white pixels on black background, the first important step for finding the lines is to invert your noisy images.

Slight median blurring will further help to get rid of the noise, thus improving the performance of the Hough transform.

For my suggested solution, I also used the HoughLinesP method instead of HoughLines. (From my experience, you'll get "better" results.)

So, here's my code snippet:

import cv2
import numpy as np# Read input
img = cv2.imread('images/K9YLm.png', cv2.IMREAD_GRAYSCALE)# Initialize output
out = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)# Median blurring to get rid of the noise; invert image
img = 255 - cv2.medianBlur(img, 3)# Detect and draw lines
lines = cv2.HoughLinesP(img, 1, np.pi/180, 10, minLineLength=50, maxLineGap=30)
for line in lines:for x1, y1, x2, y2 in line:cv2.line(out, (x1, y1), (x2, y2), (0, 0, 255), 2)cv2.imshow('out', out)
cv2.waitKey(0)
cv2.destroyAllWindows()

The output out looks like this:

Output

Due to the usage of HoughLinesP, you get a quite large set of (smaller) lines. One would need to setup a kind of "grouping" of similar lines. (Or, maybe one could just draw the red lines on a separate image, and re-run the line detection.)

Hope that helps!

https://en.xdnf.cn/q/73316.html

Related Q&A

How can I connect a StringVar to a Text widget in Python/Tkinter?

Basically, I want the body of a Text widget to change when a StringVar does.

python csv writer is adding quotes when not needed

I am having issues with writing json objects to a file using csv writer, the json objects seem to have multiple double quotes around them thus causing the json objects to become invalid, here is the re…

How to install google.cloud automl_v1beta1 for python using anaconda?

Google Cloud AutoML has python example code for detection, but I have error when importing these modulesfrom google.cloud import automl_v1beta1 from google.cloud.automl_v1beta1.proto import service_pb2…

Python3.8 - FastAPI and Serverless (AWS Lambda) - Unable to process files sent to api endpoint

Ive been using FastAPI with Serverless through AWS Lambda functions for a couple of months now and it works perfectly.Im creating a new api endpoint which requires one file to be sent.It works perfectl…

How to create a function for recursively generating iterating functions

I currently have a bit of Python code that looks like this:for set_k in data:for tup_j in set_k:for tup_l in tup_j:The problem is, Id like the number of nested for statements to differ based on user in…

How to get molecular weight of a compound in python?

User inputs a formula, for example: C12H2COOHWe have to calculate its molecular weight given that C = 12.01, H = 1.008 and O = 16. We were told to be careful of elements with double digits after it and…

How to install Numpy and Pandas for AWS Lambdas?

Problem: I wanted to use Numpy and Pandas in my AWS lambda function. I am working on Windows 10 with PyCharm. My function compiles and works fine on local machine, however, as soon as package it up and…

vim highlighting everything in red

I added a print line to a python script while the script was executing, and now all the text is highlighted in red when I open the file. Opening and closing the file doesnt get rid of it. Opening a sec…

Using python modules in node.js

Is it possible to create a glue that makes it possible for python modules (more specifically, library bindings) to be used in node.js? Some of the data structures can be directly mapped to V8 objects …

Using PHP to call Virtualenv’ed Python Script

Last night I spent 5.5 hours trying make PHP execute and receive the output of Virtualenv’ed Python script. Nothing worked; except for scripts that were not Virtualenv’ed.What I am trying to do:I am …