I am detecting straight lines in an image using OpenCv. Below is the code:
import cv2
import numpy as np
img = cv2.imread('Image.jpg')
img = img[:, 10:img.shape[1]-10]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)
minLineLength = img.shape[1] - 300
lines = cv2.HoughLinesP(image=edges, rho=0.02, theta=np.pi / 500, threshold=10, lines=np.array([]), minLineLength=minLineLength, maxLineGap=2)
a, b, c = lines.shape
for i in range(a):
cv2.line(img, (lines[i][0][0], lines[i][0][1]), (lines[i][0][2], lines[i][0][3]), (0, 0, 255), 2, cv2.LINE_AA)
cv2.imwrite('result.png', img)
For the image( Screenshot of a PDF ) Image.jpg ( Below ) I am getting result.png ( Below ) as a result which is exactly the output I desire.
But when I give the below Image Test.jpg as an input, my algorithm is not working correctly. It is giving the following error:
a, b, c = lines.shape # 10th Line
AttributeError: 'NoneType' object has no attribute 'shape'
I think because in Test.jpg the horizontal lines are not that straight( because I clicked this by a phone's camera ) and also If I change the minLineLength value to let's say 100 it is not showing the above error but showing incomplete faded lines on each row. So can anyone please tell me what params should I change in my algorithm to make it work correctly?
You need to loosen up on your definition of "straight". The documentation is clear if you are already familiar with the terminology of the geometry. "rho" and "theta" are the variables for polar coordinates: length and direction, in this case. Since you're worried about a variation in direction, you need to loosen up on the theta value
theta=np.pi / 500
Is too restrictive (PI/500 radians, just over 1/3 of a degree). Decrease that 500
figure until you have a result you like. For instance, try starting with 90
(1 degree).
possibly add a condition to test if there is a line. remember you are looking for lines of a particular length. the second image has none. i tried your code and commented
minLineLength = img.shape[1] - 300
your code works with only particluar images. if you need to use any image comment out the lines
#img = img[:, 10:img.shape[1]-10]
minLineLength = 10 #img.shape[1] - 300
it works if this is the case the final code i executed is
import cv2
import numpy as np
img = cv2.imread('test.jpg')
#img = img[:, 10:img.shape[1]-10]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)
minLineLength = 20 #img.shape[1] - 300
lines = cv2.HoughLinesP(image=edges, rho=0.02, theta=np.pi / 500, threshold=10, lines=np.array([]), minLineLength=minLineLength, maxLineGap=2)
a, b, c = lines.shape
for i in range(a):
cv2.line(img, (lines[i][0][0], lines[i][0][1]), (lines[i][0][2], lines[i][0][3]), (0, 0, 255), 2, cv2.LINE_AA)
cv2.imwrite('result.png', img)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.