基于轮廓提取图像文字
内容:
使用你上一篇博客图像透视变换的结果,将A4纸上的线条单独识别出来。
输入图像:
输出图像:
Python使用opencv实现
实验环境:Window下使用Python的Opencv库
- 通过阈值进行前后景分割(将线条和A4纸分开)
先将输入图片转为灰度图,然后使用阈值分割函数实现二值化:
img = cv2.imread('input.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,190,255,cv2.THRESH_BINARY)
cv2.imwrite("thresh.jpg", thresh)
- 1
- 2
- 3
- 4
- 5
cv2.threshold第二个参数灰度值表示小于该值就将其变为0
- 形态学图像处理(膨胀腐蚀)
膨胀就是求局部最大值的操作,腐蚀就是求局部最小值,所以相当于做最大值最小值滤波。我们为了让轮廓更明显,所以需要做腐蚀处理。
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10))
eroded = cv2.erode(thresh, kernel)
cv2.imwrite("eroded.jpg", eroded)
- 1
- 2
- 3
用getStructuringElement函数定义一个10×10的十字结构元素,用作选取的周围点。
腐蚀后:
3. 轮廓检测
contours, hierarchy = cv2.findContours(eroded,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
- 1
findContours函数
参数
第一个参数是寻找轮廓的图像;
第二个参数表示轮廓的检索模式,有四种(本文介绍的都是新的cv2接口):
cv2.RETR_EXTERNAL表示只检测外轮廓
cv2.RETR_LIST检测的轮廓不建立等级关系
cv2.RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
cv2.RETR_TREE建立一个等级树结构的轮廓。
第三个参数method为轮廓的近似办法
cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1
cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
- 返回值
cv2.findContours()函数首先返回一个list值,list中每个元素都是图像中的一个轮廓也就我们要用到的contours。
选取边界矩形:
for c in contours:
x, y, w, h = cv2.boundingRect(c)
cv2.rectangle(img, (x, y), (x + w, y + h), color, 1)
- 1
- 2
- 3
4. 通过ROI将每张图片输出
通过矩形轮廓输出提取的笔划图像,这里直接用imwrite输出。
完整代码:
# -*- coding: utf-8 -*-
import cv2
img = cv2.imread('input.jpg')
result = img.copy()
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,190,255,cv2.THRESH_BINARY)
cv2.imwrite("thresh.jpg", thresh)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10))
eroded = cv2.erode(thresh, kernel)
cv2.imwrite("eroded.jpg", eroded)
binary, contours, hierarchy = cv2.findContours(eroded,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
color = (0, 255, 0)
for c in contours:
x, y, w, h = cv2.boundingRect(c)
cv2.rectangle(img, (x, y), (x + w, y + h), color, 1)
temp = result[y:(y + h), x:(x + w)]
cv2.imwrite("./result/" + str(x) + ".jpg", temp)
cv2.imwrite("result.jpg", img)