任务:
我有一组图像,每个图像看起来像这样:
我想从这张图片中提取所有水平线和所有垂直线。
所需结果:
当前方法:
import cv2
image = cv2.imread('img.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3, 3), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (20, 1))
horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=1)
结果如下:
问题:
很明显,当前内核太窄,无法绕过左侧的垂直粗线。这条线是41像素粗,因此内核(42,1)可以正常工作,但是我丢失了比41像素短的真实水平线:
有没有完美的技术可以解决这个问题?
答案 0 :(得分:0)
这个想法是通过骨架化将所有这些行调整为相同的“大小” 应用形态学过滤器并使用较小的过滤器
image = cv2.imread('Your_ImagePath' , cv2.IMREAD_COLOR)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
thresh = skeletonize(thresh)
cv2.imshow("Skelton",thresh)
cv2.waitKey()
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 1))
horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel,
iterations=1)
cv2.imshow("Horizontal Lines" , horizontal)
v2.waitKey()
输出图像:
注意:skeletonize.py的骨骼化代码
答案 1 :(得分:0)
我会考虑做一个“形态学开口” ,它具有一个高而细的结构元素(即一条垂直线,高15像素,宽1像素),以找到垂直条和水平线长15像素,高1像素以找到水平线。
您可以使用 OpenCV 进行相同的操作。但我只是在终端机中使用 ImageMagick 来完成此操作,因为我可以更快地这样做!这是垂直工作的命令-尝试改变15以获得不同的结果:
magick shapes.png -morphology open rectangle:1x15 result.png
这是一个动画,显示结果如何随着15(行的长度)的变化而变化:
这是将结构元素设为水平线时的外观:
magick shapes.png -morphology open rectangle:15x1 result.png
如果您不熟悉形态学,那么Anthony Thyssen here会提供出色的描述。请注意,可以用 ImageMagick 对其进行解释,但是这些原理同样适用于Python OpenCV -请参见here。