获取垂直线numpy

时间:2018-12-18 10:37:55

标签: python-3.x numpy opencv

我在这张照片中检测到水平线和垂直线:

enter image description here

enter image description here

enter image description here

使用此代码:

import numpy as np
import cv2 as cv

src = cv.imread("filename.png", cv.IMREAD_COLOR)

if len(src.shape) != 2:
    gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
else:
    gray = src

gray = cv.bitwise_not(gray)
bw = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 15, -2)

horizontal = np.copy(bw)
vertical = np.copy(bw)

cols = horizontal.shape[1]
horizontal_size = int(cols / 30)

horizontalStructure = cv.getStructuringElement(cv.MORPH_RECT, (horizontal_size, 1))
horizontal = cv.erode(horizontal, horizontalStructure)
horizontal = cv.dilate(horizontal, horizontalStructure)

#np.set_printoptions(threshold=np.inf)
cv.imwrite("img_horizontal8.png", horizontal)

h_transpose = np.transpose(np.nonzero(horizontal))
print("h_transpose")
print(h_transpose[:100])
#prints [ 56  35] ... [ 56  134]
#and that makes sense, there is an horizontal line more or less in the height 56 like that on the image img_horizontal8.png



rows = vertical.shape[0]
verticalsize = int(rows / 30)
verticalStructure = cv.getStructuringElement(cv.MORPH_RECT, (1, verticalsize))
vertical = cv.erode(vertical, verticalStructure)
vertical = cv.dilate(vertical, verticalStructure)

cv.imwrite("img_vertical8.png", vertical)

v_transpose = np.transpose(np.nonzero(vertical))

print("v_transpose")
print(v_transpose[:100])

prints:

 [  68  489]
 [  68  490]
 [  69  489]
 [  69  490]
 [  69  721]
 [  70  489]
 [  70  490]
 [  70  721]
 [  71  489]
 [  71  490]
 [  71  721]
 [  71  950]
 [  72  489]
 [  72  490]
 [  72  721]
 [  72  950]
 [  73  489]
 [  73  490]
 [  73  721]
 [  73  950]
 [  74  489]
 [  74  490]
 [  74  721]
 [  74  950]
 [  75  489]
 [  75  490]
 [  75  721]
 [  75  950]
 [  75 1179]
 [  75 1410]
 [  76  489]
 [  76  490]
 [  76  721]
 [  76  950]
 [  76 1178]
 [  76 1179]
 [  76 1410]
 [  77  489]
 [  77  490]
 [  77  721]
 [  77  950]
 [  77 1178]
 [  77 1179]
 [  77 1410]
 [  78  489]
 [  78  490]
 [  78  721]
 [  78  950]
 [  78 1178]
 [  78 1179]
 [  78 1410]

我是否误解了获取垂直线的坐标?打印结果似乎表明我们有一条线从68,489到68,490(长度为1的线),然后是一堆其他非常短的线,直到x = 78。但是在图像img_vertical8.png上,没有可见的非常短的线,所以我不知道发生了什么。这些垂直线的数组是否由于某些原因而出错?有什么想法吗?

1 个答案:

答案 0 :(得分:1)

问题

您要打印的是所产生的大多数为黑白色条纹图像的像素坐标。它们没有与之关联的任何连通性信息,因此您不应该假定生成的列表中相邻的两个像素之间实际上有一条线。

我认为,让您感到困惑的是np.nonzero在有效地整理您要打印的数据。 “排序”是指它的返回值将始终首先包含第0行中非零值的索引,然后是第1行中非零值的索引,依此类推。

考虑一下它,就像旧的CRT显示器(如果您足够大,可以知道那是什么):nonzero在图像上进行水平扫描,连续从彼此平行的行中捕获像素,未连接。

解决方案

您可以进一步处理垂直线和水平线的图像,以获得所需的实际线。按照我发现的here的说明,我通过找到然后将线段拉回到原始报纸图像上来制作了以下图像:

enter image description here

这是我使用的代码(从代码停止的地方开始):

img = src.copy()

# edges = cv.Canny(vertical,50,150,apertureSize = 3)
minLineLength = 100
maxLineGap = 200
lines = cv.HoughLinesP(vertical,1,np.pi/180,100,minLineLength,maxLineGap)
for line in lines:
    for x1,y1,x2,y2 in line:
        cv.line(img,(x1,y1),(x2,y2),(0,255,0),2)

cv.imwrite('houghlinesP_vert.jpg', img)