答案 0 :(得分:1)
如果行的长度“足够”变化,则以下方法可能有用:
cv2.threshold
逆二值化图像。cv2.dilate
使用水平线内核将图像放大以强调线条。np.sum
将所有像素按行求和,并使用np.diff
计算行之间的绝对差。np.where
查找正确的索引。np.insert
在找到的索引之前在原始图像中插入白线。在下面的示例中,索引是手动选择的。必须进行适当的自动化工作:将“步骤”排除为“背景”,在多行之间找到“步骤”。下面是一个代码段:
import cv2
from matplotlib import pyplot as plt
import numpy as np
from skimage import io # Only needed for web grabbing images, use cv2.imread for local images
# Read and binarize image
image = cv2.cvtColor(io.imread('https://i.stack.imgur.com/56g7s.jpg'), cv2.COLOR_RGB2GRAY)
_, image_bin = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY_INV)
# Dilate rows by using horizontal line as kernel
kernel = np.ones((1, 51), np.uint8)
image_dil = cv2.dilate(image_bin, kernel)
# Sum pixels row-wise, and calculate absolute differences between the rows
row_sum = np.sum(image_dil / 255, 1, dtype=np.int32)
row_sum_diff = np.abs(np.diff(row_sum))
# Just for visualization: Summed row-wise pixels
plt.plot(row_sum)
plt.show()
# Find "steps" in the differences between the rows
step_thr = 100
step_idx = np.where(row_sum_diff > step_thr)[0]
# Insert n lines before desired index; simple hard-coding here, more work needs to be done for multiple lines
n_lines = 5
image_mod = np.insert(image, step_idx[1] + 1, 255 * np.ones((n_lines, image.shape[1]), np.uint8), axis=0)
# Result visualization
cv2.imshow('image', image)
cv2.imshow('image_dil', image_dil)
cv2.imshow('image_mod', image_mod)
cv2.waitKey(0)
cv2.destroyAllWindows()
膨胀的逆二值化图像:
“步骤”的可视化:
最终的输出为n = 5
,其中插入了白线:
如您所见,结果并不完美,但这是由于原始图像。在相应的行中,您具有第一行和第二行的部分。因此,不可能在这两者之间进行适当的区分。可能会在输出中添加很小的形态封闭,以消除这些伪像。
希望有帮助!