4

我真的是opencv的新手,也是python的初学者。

我有这张图片:

原始 bmp 24 位图像

我想以某种方式应用适当的阈值来保留 6 位数字。

更大的图景是,我打算尝试分别对每个数字的图像执行手动 OCR,在每个数字级别上使用 k-最近邻算法 (kNearest.findNearest)

问题是我无法充分清理数字,尤其是带有蓝色水印的“7”数字。

到目前为止,我尝试的步骤如下:

我正在从磁盘读取图像

# IMREAD_UNCHANGED is -1
image = cv2.imread(sys.argv[1], cv2.IMREAD_UNCHANGED)

然后我只保留蓝色通道以消除数字“7”周围的蓝色水印,有效地将其转换为单通道图像

image = image[:,:,0] 
# openned with -1 which means as is, 
# so the blue channel is the first in BGR

单通道 - 仅红色 - 图像

然后我将它乘以一点以增加数字和背景之间的对比度:

image = cv2.multiply(image, 1.5)

将图像相乘以增加对比度

最后我执行 Binary+Otsu 阈值:

_,thressed1 = cv2.threshold(image,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

二值欧胡岛阈值图像

如您所见,最终结果非常好,除了数字“7”保留了很多噪音。

如何改善最终结果?请尽可能提供图像示例结果,它比单独的代码片段更好理解。

4

4 回答 4

6

你可以尝试用不同的内核(例如3、51)对灰度(blur)图像进行中值模糊,划分模糊的结果,并对其进行阈值处理。是这样的:</p>

在此处输入图像描述


#!/usr/bin/python3
# 2018/09/23 17:29 (CST) 
# (中秋节快乐)
# (Happy Mid-Autumn Festival)

import cv2 
import numpy as np 

fname = "color.png"
bgray = cv2.imread(fname)[...,0]

blured1 = cv2.medianBlur(bgray,3)
blured2 = cv2.medianBlur(bgray,51)
divided = np.ma.divide(blured1, blured2).data
normed = np.uint8(255*divided/divided.max())
th, threshed = cv2.threshold(normed, 100, 255, cv2.THRESH_OTSU)

dst = np.vstack((bgray, blured1, blured2, normed, threshed)) 
cv2.imwrite("dst.png", dst)

结果:</p>

在此处输入图像描述

于 2018-09-23T05:09:56.397 回答
1

完全去除烦人的印章似乎并不容易。

您可以做的是通过以下方式使背景强度变平

  • 计算低通图像(高斯滤波器,形态闭合);过滤器尺寸应该比字符尺寸大一点;

  • 将原始图像除以低通图像。

然后就可以使用大津了。

在此处输入图像描述

如您所见,结果并不完美。

于 2018-09-22T21:05:47.220 回答
1

为什么不只保留图像中高于某个阈值的值?

像这样:

import cv2
import numpy as np

img = cv2.imread("./a.png")[:,:,0]  # the last readable image

new_img = []
for line in img:
    new_img.append(np.array(list(map(lambda x: 0 if x < 100 else 255, line))))

new_img = np.array(list(map(lambda x: np.array(x), new_img)))

cv2.imwrite("./b.png", new_img) 

看起来很棒:

您可能会更多地使用阈值并获得更好的结果。

于 2018-09-22T20:14:13.017 回答
0

我在蓝色通道上尝试了一种与 Yves 略有不同的方法:蓝色通道

  • 应用中值滤波器(r=2):

过滤后的图像

  • 使用边缘检测(例如 Sobel 算子):

检测到的边缘

  • 自动阈值 (Otsu)

阈值图像

  • 关闭图像

关闭图像

这种方法似乎使输出的噪音更小。但是,必须解决数字中的漏洞。这可以通过检测完全被白色像素包围的黑色轮廓并简单地用白色填充它们来完成。

于 2018-09-22T22:41:53.063 回答