【发布时间】:2017-07-16 14:49:44
【问题描述】:
我的图像是写在螺旋笔记本纸上的文字。纸上有水平线。我想从图像中删除水平线。
在谷歌搜索时,我发现了一个我认为可行的解决方案:Extract horizontal and vertical lines by using morphological operations 该解决方案使用 C++,因此我将其转换为 Python。它适用于该解决方案中提供的示例图像,但是,它似乎不适用于我的图像。
在我的图像上运行它时,我得到了以下结果:
下面是我从 C++ 翻译过来的 Python 代码
#cpp code converted from http://docs.opencv.org/3.2.0/d1/dee/tutorial_moprh_lines_detection.html
import cv2
import numpy as np
img = cv2.imread("original.jpg")
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img = cv2.bitwise_not(img)
th2 = cv2.adaptiveThreshold(img,255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,15,-2)
cv2.imshow("th2", th2)
cv2.imwrite("th2.jpg", th2)
cv2.waitKey(0)
cv2.destroyAllWindows()
horizontal = th2
vertical = th2
rows,cols = horizontal.shape
horizontalsize = cols / 30
horizontalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (horizontalsize,1))
horizontal = cv2.erode(horizontal, horizontalStructure, (-1, -1))
horizontal = cv2.dilate(horizontal, horizontalStructure, (-1, -1))
cv2.imshow("horizontal", horizontal)
cv2.imwrite("horizontal.jpg", horizontal)
cv2.waitKey(0)
cv2.destroyAllWindows()
verticalsize = rows / 30
verticalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (1, verticalsize))
vertical = cv2.erode(vertical, verticalStructure, (-1, -1))
vertical = cv2.dilate(vertical, verticalStructure, (-1, -1))
cv2.imshow("vertical", vertical)
cv2.imwrite("vertical.jpg", vertical)
cv2.waitKey(0)
cv2.destroyAllWindows()
vertical = cv2.bitwise_not(vertical)
cv2.imshow("vertical_bitwise_not", vertical)
cv2.imwrite("vertical_bitwise_not.jpg", vertical)
cv2.waitKey(0)
cv2.destroyAllWindows()
#step1
edges = cv2.adaptiveThreshold(vertical,255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,3,-2)
cv2.imshow("edges", edges)
cv2.imwrite("edges.jpg", edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
#step2
kernel = np.ones((2, 2), dtype = "uint8")
dilated = cv2.dilate(edges, kernel)
cv2.imshow("dilated", dilated)
cv2.imwrite("dilated.jpg", dilated)
cv2.waitKey(0)
cv2.destroyAllWindows()
# step3
smooth = vertical.copy()
#step 4
smooth = cv2.blur(smooth, (4,4))
cv2.imshow("smooth", smooth)
cv2.imwrite("smooth.jpg", smooth)
cv2.waitKey(0)
cv2.destroyAllWindows()
#step 5
(rows, cols) = np.where(img == 0)
vertical[rows, cols] = smooth[rows, cols]
cv2.imshow("vertical_final", vertical)
cv2.imwrite("vertical_final.jpg", vertical)
cv2.waitKey(0)
cv2.destroyAllWindows()
我也在我的原始图像上尝试了 ImageMagik,以消除线条。
我使用 ImageMagik 获得了更好的结果,但仍不完全准确。
convert original -morphology close:3 "1x5: 0,1,1,1,0" original_im.jpg
【问题讨论】:
-
你的线条似乎不直。我会从一侧到另一侧进行连续性检测。
-
关于如何实现这一点的任何指示?
-
我以前没有实现过类似的东西,但我可以为你写一个基本的伪代码。我敢打赌,还有很多更有效的方法。我假设您的输入数据总是相似的,对吧?
-
是的,主要是用线条写在纸上。有时线条是水平的,有时是垂直的。
-
我还会考虑查看概率霍夫变换并删除一定长度和特定方向的线。今晚晚些时候我会试着写一个答案。
标签: python opencv image-processing imagemagick