python - 如何使用 python、openCV 计算图像中的行数

标签 python opencv canny-operator straight-line-detection houghlines

我想计算纸张数量,所以我正在考虑使用线条检测。我尝试过一些方法,例如 CannyHoughLinesFLD。但我只得到处理过的照片。我不知道如何计算。有一些小线段就是我们想要的线。我使用了 len(lines) 或 len(contours)。然而,结果与我的预期相去甚远。结果是一百或一千。那么,有人有什么建议吗?

原图:

the original photo

由 Canny 处理:

processd by Canny

由 LSD 处理:

processed by LSD

HoughLinesP处理:

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)

最佳答案

我认为你可以根据有多少条直线来计算行数(纸张)。我的想法是

  1. 您应该使用 np.linalg.norm(point1 - point2) for more details 计算从 HoughLinesP 获得的所有点的距离.
  2. 然后您可以调整用于识别线条的适当距离以忽略噪声(小)线条。我建议在 HoughLinesP 中使用 min_line_length
  3. 计算大于适当距离的距离(线)的数量。

这是我用于您的图像的代码:

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)

输出:

max distance: 1352.8166912039487 
min distance: 50.0
Number of lines: 17

关于python - 如何使用 python、openCV 计算图像中的行数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60586283/

相关文章:

python - 如何填充图像边缘内的白色背景以去除背景?

c++ - 如何只保留 opencv android 库的一个模块(Canny Edge Detection)?

python - 如何在Python中将一个列表中的字符串连接到第二个列表中的其他字符串?

python - 使用 numpys loadtxt 在具有不同名称的数组中循环加载许多文本文件

python - 在列表字典的每个索引处查找最小值和最大值

Python:排除模块 Pyinstaller

opencv - 简历透视变换: What am I supposed to provide?

opencv - 如何使用 javacv 开始网络摄像头捕获

Android - 访问预编译库中的 native 函数

c++ - 使用Opencv和霍夫变换圆检测圆(下标错误)