这是我的一个简单算法,用于清理该特定图像。请随意使用它并进一步调整它以获得所需的结果。
NB:所示代码应适用于 OpenCV 的 2.4.x 和 3.x 分支。
Step 0
将输入图像加载为灰度图像。
img = cv2.imread('paper.jpg',0)
Step 1
放大图像,以消除文本。
此步骤在某种程度上有助于保留条形码。
dilated_img = cv2.dilate(img, np.ones((7,7), np.uint8))
Step 2
使用适当大小的内核对结果进行中值模糊,以进一步抑制任何文本。
这应该会给我们带来一个相当好的背景图像,其中包含所有阴影和/或变色。
bg_img = cv2.medianBlur(dilated_img, 21)
Step 3
计算原始图像和我们刚刚获得的背景之间的差异。相同的位将显示为黑色(接近 0 差异),文本将显示为白色(差异较大)。
因为我们想要白底黑字,所以我们反转结果。
diff_img = 255 - cv2.absdiff(img, bg_img)
Step 4
标准化图像,以便我们使用完整的动态范围。
norm_img = diff_img.copy() # Needed for 3.x compatibility
cv2.normalize(diff_img, norm_img, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)
Step 5
此时我们的纸张仍然有些灰色。我们可以将其截断,然后重新规范化图像。
_, thr_img = cv2.threshold(norm_img, 230, 0, cv2.THRESH_TRUNC)
cv2.normalize(thr_img, thr_img, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)
Done...
好吧,至少对我来说是这样;)您可能想要裁剪它,并进行您想要的任何其他后处理。
注意:在获得差异图像后,可能值得切换到更高的精度(16+ 位整数或浮点数),以便最大限度地减少重复归一化中累积的舍入误差。