python - 在不应用高斯模糊的情况下检测 Python OpenCV 中的线条
问题描述
我正在检测无噪音、以编程方式生成的 png 文件中的线条。我通常会使用霍夫线,这需要我首先从精明检测中提供边缘,但精明检测的第一步是应用高斯模糊来消除噪声。有没有一种方法可以在我的原始图像上进行边缘检测而不会故意模糊它?我怀疑这会比先去毛刺产生更好的结果,因为线条已经非常干净且对比度很高。
这是一个使用精明检测和图像的简单示例。每组中的线从 5 像素宽开始,然后下一行是 4,然后是 3、2 和 1。如您所见,canny 检测不能完美工作(2 像素线看起来小于 1 像素那些):
原图:
边缘(canny 检测的结果):
示例代码:
import cv2
import numpy as np
import matplotlib.pylab as plot
# img = cv2.imread("8px_and_2px_lines.png")
img = cv2.imread("5-1px_lines.png")
crop_size = 520
img = img[100:crop_size, 100:crop_size]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imwrite("5-1px_lines_cropped.png", img)
cv2.imshow("start", img)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)
cv2.imshow("canny", edges)
cv2.imwrite("5-1px_lines_cropped_canny.png", edges)
# plot.imshow(edges, cmap="gray")
# plot.show()
lines = cv2.HoughLines(edges, 1, np.pi / 180, 200)
line_length = 3000
for line in lines:
rho, theta = line[0]
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + line_length * (-b))
y1 = int(y0 + line_length * (a))
x2 = int(x0 - line_length * (-b))
y2 = int(y0 - line_length * (a))
cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
cv2.imshow("lines", img)
cv2.waitKey()
关于如何对这些图像进行更好的线检测有什么想法吗?我认为精明检测器内置的高斯模糊使线条更难检测。
解决方案
一种简单的方法是简单地设置阈值,将线条反转为白色,然后进行骨架化。这是 Python/OpenCV/Skimage 的代码
输入:
import cv2
import numpy as np
import skimage.morphology
img = cv2.imread("lines_horizontal.png")
ht, wd = img.shape[:2]
# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# create a binary thresholded image
thresh = cv2.threshold(gray, 0, 1, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
# invert so lines are white
thresh = 1 - thresh
# apply skeletonization
skeleton = skimage.morphology.skeletonize(thresh)
skeleton = (255*skeleton).clip(0,255).astype(np.uint8)
# save result
cv2.imwrite("lines_horizontal_skeleton.png", skeleton)
# show results
cv2.imshow("skeleton", skeleton)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果:
请注意,端点处的骨架化在末端会出现一些失真。
另请注意,OpenCV opencv-contrib-python 具有类似于骨架化的细化方法。
推荐阅读
- javascript - 如何根据 Jquery 中的值向子 div 动态添加和删除类
- c# - 如果不存在,如何检查和创建文件夹?以及如何使按 K 键时每次截取一张屏幕截图?
- python - 查找列表中的对数
- arrays - 如何在 C 语言中使用 for 循环验证结构值是否存在
- html - css float 选项不起作用的原因是什么?
- css - ag-grid 角度中的自定义工具提示部分可见
- bash - 删除同一行中的重复单词?
- python - 制作一个在指定聊天 discord.py 中每 10 秒发送一次消息的 cog
- python - 协助 while 循环
- c++ - C++ 奇怪问题:在类中找不到函数成员