我按照Extract horizontal and vertical lines by using morphological operations删除图片中的水平点。
此解决方案的主要思想是erode
图像(删除水平/垂直中的细线或细线)和dilate
。但这会降低图像中字符的质量。
所以我想问一下是否有更好的解决方案来删除点,并且不会丢失图像中的字符质量。
import util
import cv2
grayImage = cv2.imread("00.jpg", 0)
h = float(grayImage.shape[0])
maxVal = 255
blockSize = 15
C = 12.0*(90.0/h)
print("C:" + str(C))
showImages = []
bw = cv2.adaptiveThreshold(grayImage, maxVal, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, blockSize, C)
bw = ~bw
showImages.append(grayImage.copy())
showImages.append(bw.copy())
vertical = bw.copy()
# Specify size on vertical axis
# verticalsize = vertical.shape[0] / 20
verticalsize = 4
# Create structure element for extracting vertical lines through morphology operations
verticalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (1, verticalsize))
# Apply morphology operations
vertical = cv2.erode(vertical, verticalStructure, None, (-1,-1))
showImages.append(vertical.copy())
vertical = cv2.dilate(vertical, verticalStructure, None, (-1,-1))
showImages.append(vertical.copy())
util.showOpenCVImagesGrid(showImages, 2, 2, titles=["grayImage", "adaptiveThreshold", "after erode", "after dilate"])
util的:
import cv2
import matplotlib.pyplot as plt
def showOpenCVImagesGrid(images, x, y, titles=None, axis="on"):
fig = plt.figure()
i = 1
for item in images:
image = None
title = None
if type(images) is list:
image = item
if titles is not None:
title = titles[i - 1]
elif type(images) is dict:
image = images[item]
title = item
if image is None:
i += 1
continue
copy = image.copy()
channel = len(copy.shape)
cmap = None
if channel == 2:
cmap = "gray"
elif channel == 3:
copy = cv2.cvtColor(copy, cv2.COLOR_BGR2RGB)
elif channel == 4:
copy = cv2.cvtColor(copy, cv2.COLOR_BGRA2RGBA)
fig.add_subplot(x, y, i)
plt.title(title)
plt.axis(axis)
plt.imshow(copy, cmap=cmap)
i += 1
plt.show()
答案 0 :(得分:1)
如果线条穿过感兴趣的图形,则没有神奇的解决方案。
但在这种情况下,他们没有,只需使用合适的感兴趣区域来处理它们。
例如,您可以仅检测点(顶帽滤镜)并拟合直线。通过添加合适的边距,可以将图像分成两个区域,您可以应用任何处理。
例如,在下图中,下部已经用1x5垂直扩张进行清洁。你可以猜出分裂边缘的设置位置。
无论如何,有一个严肃的问题:你是否需要摆脱虚线?
答案 1 :(得分:0)
您可以使用cv2.bitwise
操作仅通过在行区域上进行遮罩来删除行。删除线条后,您可以使用cv2.inpaint
方法填充白色像素。您想看看documentation here