Reputation: 21
I want to count paper, so I am thinking about using line detection. I have tried some methods like Canny
, HoughLines
, and FLD
. But I only get the processed photo. I have no idea how to count it. There are some small line segments that are the lines we want. I have used len(lines
) or len(contours
). However, the result is far from what I expected. The result is a hundred or thousand. So, does anyone have any suggestions?
The original photo:
Processd by Canny:
Processed by LSD:
Processed by HoughLinesP
:
#Canny
samplename = "sam04.jpg"
img = cv2.imread('D:\\Users\\Administrator\\PycharmProjects\\EdgeDetect\\venv\\sample\\{}'.format(samplename),0)
edges = cv2.Canny(img,100,200)
cv2.imwrite('.\\detected\\{}'.format("p03_"+samplename),edges)
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()
#LSD
samplename = "sam09.jpg"
img0 = cv2.imread('D:\\Users\\Administrator\\PycharmProjects\\EdgeDetect\\venv\\sample\\{}'.format(samplename))
img = cv2.cvtColor(img0,cv2.COLOR_BGR2GRAY)
fld = cv2.ximgproc.createFastLineDetector()
dlines = fld.detect(img)
# drawn_img = fld.drawSegments(img0,dlines, )
for dline in dlines:
x0 = int(round(dline[0][0]))
y0 = int(round(dline[0][1]))
x1 = int(round(dline[0][2]))
y1 = int(round(dline[0][3]))
cv2.line(img0, (x0, y0), (x1,y1), (0,255,0), 1, cv2.LINE_AA)
cv2.imwrite('.\\detected\\{}'.format("p12_"+samplename), img0)
cv2.imshow("LSD", img0)
cv2.waitKey(0)
cv2.destroyAllWindows()
#HoughLine
import cv2
import numpy as np
samplename = "sam09.jpg"
#First, get the gray image and process GaussianBlur.
img = cv2.imread('D:\\Users\\Administrator\\PycharmProjects\\EdgeDetect\\venv\\sample\\{}'.format(samplename))
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
kernel_size = 5
blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size),0)
#Second, process edge detection use Canny.
low_threshold = 50
high_threshold = 150
edges = cv2.Canny(blur_gray, low_threshold, high_threshold)
cv2.imshow('photo2',edges)
cv2.waitKey(0)
#Then, use HoughLinesP to get the lines. You can adjust the parameters for better performance.
rho = 1 # distance resolution in pixels of the Hough grid
theta = np.pi / 180 # angular resolution in radians of the Hough grid
threshold = 15 # minimum number of votes (intersections in Hough grid cell)
min_line_length = 50 # minimum number of pixels making up a line
max_line_gap = 20 # maximum gap in pixels between connectable line segments
line_image = np.copy(img) * 0 # creating a blank to draw lines on
# Run Hough on edge detected image
# Output "lines" is an array containing endpoints of detected line segments
lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]),
min_line_length, max_line_gap)
print(lines)
print(len(lines))
for line in lines:
for x1,y1,x2,y2 in line:
cv2.line(line_image,(x1,y1),(x2,y2 ),(255,0,0),5)
#Finally, draw the lines on your srcImage.
# Draw the lines on the image
lines_edges = cv2.addWeighted(img, 0.8, line_image, 1, 0)
cv2.imshow('photo',lines_edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('.\\detected\\{}'.format("p14_"+samplename),lines_edges)
Upvotes: 2
Views: 3858
Reputation: 41
I think you could count the number of lines (papers) based on how many straight lines do you have. My idea is that
np.linalg.norm(point1 - point2)
for more details.min_line_length
in HoughLinesP.This is the code that I used for your image:
# After you apply Hough on edge detected image
lines = cv.HoughLinesP(img, rho, theta, threshold, np.array([]),
min_line_length, max_line_gap)
# calculate the distances between points (x1,y1), (x2,y2) :
distance = []
for line in lines:
distance.append(np.linalg.norm(line[:,:2] - line[:,2:]))
print('max distance:',max(distance),'\nmin distance:',min(distance))
# Adjusting the best distance
bestDistance=1110
numberOfLines=[]
count=0
for x in distance:
if x>bestDistance:
numberOfLines.append(x)
count=count+1
print('Number of lines:',count)
Output:
max distance: 1352.8166912039487
min distance: 50.0
Number of lines: 17
Upvotes: 2