作为图像识别的入门篇,主要是介绍opencv处理图像的常用功能,实现一个简单的功能:识别合同扫描件的文本行。
这个小功能来源一个实际的产品项目:
问题背景
以前很少接触合同,对合同没有多少了解,原来到了今时今日,合同的审核都还是需要花费大量人工去处理的,例如一份60页的合同,发出去给客户签名,客户签完名又发回来,这时问题来了,需要有人去审核发回来的合同是否有被修改过,特别是在金融证券等行业,据说因为这些而导致的纠纷还不少。
为了减少发生纠纷的可能性,于是企业可能常年需要招一批实习生来做合同审核,确保合同的一致性。对于大的金融证券公司,这种需要审核的合同或者类似合同的文档太多了,基本只能使用人工进行抽检,而且人天生就不擅长做这些机械重复的工作,总有老眼昏花的时候,结果就有点看天吃饭了。
机器视觉
很显然,像合同比对这种苦力,是很适合使用机器视觉进行解决的,因为它量大,且规则比较明确。所谓基于机器视觉来完成合同文档比对,其实就是计算扫描件和底稿的相似性。
这其中一个功能就是需要将文本行识别出来,这样我们就能计算每行的相似性,或者对行进行OCR。
图像二值化
例如一个合同文档的图像如下:
通过观察,我们也能知道,我们的合同文本都是一行一行的,行与行之间有间隙,我们就可以利用这个特征,进行文本行的检测。
为了效果更好,很自然我们希望特征能更加明显,这就需要对图像进行二值化,文本自身能加强,而非文本则减弱。
代码语言:javascript复制# 读入图像
img = cv2.imread('images/合同文本.png', cv2.IMREAD_GRAYSCALE)
print(img.shape)
# 反色处理
img = cv2.bitwise_not(img)
# 几种不同的二值化
ret, th_img = cv2.threshold(img, 40, 255, cv2.cv2.THRESH_BINARY)
ret, thtru_img = cv2.threshold(img, 200, 255, cv2.cv2.THRESH_TRUNC)
ret, otsu_img = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU)
ada_th_img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 0)
关于二值化更多可以看这里:https://ivanzz1001.github.io/records/post/python/2017/09/05/python-opencv-part2
这里二值化是需要进行选择的,经过比较,我们选择OTSU生成的二值化,展示效果如下:
看起来字有点模糊,不过这并不影响我们实现文本行的检测,因为我们要的效果就是黑白足够分明。当然,对于OCR这个效果可能并不好。
检测文本行
已经有了二值化图像了,我们只需要按行累加:
代码语言:javascript复制sum_img = otsu_img/255
print(otsu_img.shape)
sum_img = np.sum(sum_img, axis=1)
plt.barh(range(sum_img.size), sum_img)
plt.ylim(sum_img.size 1, 0)
plt.show()
就可以得到一个条形图,如下:
条形图中,比较大的空白其实就是行间隙之间的空白地带。将这个结果应用到原图中,就能将文本行检测出来:
代码语言:javascript复制img = cv2.imread('images/合同文本.png')
sum_img = otsu_img/255
h, w = otsu_img.shape
sum_img = np.sum(sum_img, axis=1)
out_img = img.copy()
is_started = False
for i, v in enumerate(sum_img):
if v == 0:
if is_started is False:
continue
max_v = max(sum_img[i:min(h, i 8)])
if max_v == 0:
cv2.line(out_img, (0, i), (w, i), (0, 0, 255), 1)
is_started = False
continue
if v > 0 and is_started is False:
is_started = True
cv2.line(out_img, (0, i-1), (w, i-1), (0, 0, 0), 1)
display_cv2(out_img)
这段代码其实就是在文本行的上方画一条黑线,下方画一条红线,效果如下:
可以看到,文本行的上下边界识别还是非常有效的。当然这是相对于场景下比较标准的合同文本来说的。
当然,文本行检测只是整体功能中非常小的一个功能,还有很多其他的功能,例如角度纠正,去噪,去水印,表格识别,OCR等等。
项目整体效果
产品上线之后,预计节省10 个实习生的工作量,节省企业成本,关键还是原来无法保证的合同篡改,现在能全量进行覆盖了。
特别适合金融证券,法院,律所,档案馆等这些领域,欢迎交流。
2020-01-06