OpenCV 文字区域的提取
2017-10-27 10:03
609 查看
1. Detect
先来看main函数和Detect函数def detect(img):
# 1. 转化成灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 2. 形态学变换的预处理,得到可以查找矩形的图片
dilation = preprocess(gray)
# 3. 查找和筛选文字区域
region = findTextRegion(dilation)
# 4. 用绿线画出这些找到的轮廓
for box in region:
cv2.drawContours(img, [box], 0, (0, 255, 0), 2)
cv2.namedWindow("img", cv2.WINDOW_NORMAL)
cv2.imshow("img", img)
# 带轮廓的图片
cv2.imwrite("contours.png", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
2. Preprocess
利用数学形态学(Morphology)进行预处理。这个过程很重要,是文字区域检测效果好坏的核心代码,尤其是一下几个参数:
膨胀的核函数大小,这里用了
30 x 9,可以调节
腐蚀的核函数大小,这里用了
24 x 6,可以调节
def preprocess(gray): # 1. Sobel算子,x方向求梯度 sobel = cv2.Sobel(gray, cv2.CV_8U, 1, 0, ksize = 3) # 2. 二值化 ret, binary = cv2.threshold(sobel, 0, 255, cv2.THRESH_OTSU+cv2.THRESH_BINARY) # 3. 膨胀和腐蚀操作的核函数 element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 9)) element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (24, 6)) # 4. 膨胀一次,让轮廓突出 dilation = cv2.dilate(binary, element2, iterations = 1) # 5. 腐蚀一次,去掉细节,如表格线等。注意这里去掉的是竖直的线 erosion = cv2.erode(dilation, element1, iterations = 1) # 6. 再次膨胀,让轮廓明显一些 dilation2 = cv2.dilate(erosion, element2, iterations = 3) # 7. 存储中间图片 cv2.imwrite("binary.png", binary) cv2.imwrite("dilation.png", dilation) cv2.imwrite("erosion.png", erosion) cv2.imwrite("dilation2.png", dilation2) return dilation2
3. findTextRegion
def findTextRegion(img): region = [] # 1. 查找轮廓 contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 2. 筛选那些面积小的 for i in range(len(contours)): cnt = contours[i] # 计算该轮廓的面积 area = cv2.contourArea(cnt) # 面积小的都筛选掉 if(area < 1000): continue # 轮廓近似,作用很小 epsilon = 0.001 * cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, epsilon, True) # 找到最小的矩形,该矩形可能有方向 rect = cv2.minAreaRect(cnt) print ("rect is: ",rect) # box是四个点的坐标 box = cv2.boxPoints(rect) box = np.int0(box) # 计算高和宽 height = abs(box[0][1] - box[2][1]) width = abs(box[0][0] - box[2][0]) # 筛选那些太细的矩形,留下扁的 if(height > width * 1.2): continue region.append(box) return region
完整代码:
# coding:utf8
import cv2
import numpy as np
def preprocess(gray): # 1. Sobel算子,x方向求梯度 sobel = cv2.Sobel(gray, cv2.CV_8U, 1, 0, ksize = 3) # 2. 二值化 ret, binary = cv2.threshold(sobel, 0, 255, cv2.THRESH_OTSU+cv2.THRESH_BINARY) # 3. 膨胀和腐蚀操作的核函数 element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 9)) element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (24, 6)) # 4. 膨胀一次,让轮廓突出 dilation = cv2.dilate(binary, element2, iterations = 1) # 5. 腐蚀一次,去掉细节,如表格线等。注意这里去掉的是竖直的线 erosion = cv2.erode(dilation, element1, iterations = 1) # 6. 再次膨胀,让轮廓明显一些 dilation2 = cv2.dilate(erosion, element2, iterations = 3) # 7. 存储中间图片 cv2.imwrite("binary.png", binary) cv2.imwrite("dilation.png", dilation) cv2.imwrite("erosion.png", erosion) cv2.imwrite("dilation2.png", dilation2) return dilation2
def findTextRegion(img):
region = []
# 1. 查找轮廓
binary,contours,hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 2. 筛选那些面积小的
for i in range(len(contours)):
cnt = contours[i]
# 计算该轮廓的面积
area = cv2.contourArea(cnt)
# 面积小的都筛选掉
if(area < 1000):
continue
# 轮廓近似,作用很小
epsilon = 0.001 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
# 找到最小的矩形,该矩形可能有方向
rect = cv2.minAreaRect(cnt)
print ("rect is: ",rect)
# box是四个点的坐标
box = cv2.boxPoints(rect)
box = np.int0(box)
# 计算高和宽
height = abs(box[0][1] - box[2][1])
width = abs(box[0][0] - box[2][0])
# 筛选那些太细的矩形,留下扁的
if(height > width * 1.2):
continue
region.append(box)
return region
def detect(img):
# 1. 转化成灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 2. 形态学变换的预处理,得到可以查找矩形的图片
dilation = preprocess(gray)
# 3. 查找和筛选文字区域
region = findTextRegion(dilation)
# 4. 用绿线画出这些找到的轮廓
for box in region:
cv2.drawContours(img, [box], 0, (0, 255, 0), 2)
cv2.namedWindow("img", cv2.WINDOW_NORMAL)
cv2.imshow("img", img)
# 带轮廓的图片
cv2.imwrite("contours.png", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == '__main__':
# 读取文件
img = cv2.imread('/Users/yuki/Downloads/timg3.jpg')
detect(img)
相关文章推荐
- Opencv实战(二) 文字区域的提取 (VS2013 + C++)
- OpenCV入门笔记(七) 文字区域的提取
- OpenCV入门笔记(七) 文字区域的提取
- 【Python+OpenCV】图片局部区域像素值处理(改进版)-一种特征提取方法
- 【OpenCV学习笔记 010】提取直线、轮廓及连通区域
- OpenCV_提取图片中任意形状的区域
- 基于opencv+vs视频运动区域提取
- OPENCV学习笔记 提取连通区域的轮廓
- OpenCV+Tesseract进行OCR学习(一)文字提取
- 简单的图像显著性区域特征提取方法-----opencv实现LC,AC,FT
- 【Android】使用OpenCV提取人体肤色区域
- OpenCV 基于轮廓提取的二值图像分析与连通区域标记算法
- opencv提取截获图像,任意区域
- 【Python+OpenCV】视频流局部区域像素值处理-一种特征提取方法
- opencv2中MSER区域提取
- opencv mser算法框出图片文字区域
- opencv提取截获图像,任意区域
- 采用OPENCV,从一幅图像中提取部分区域,并保存为新图像
- opencv 提取感兴趣区域 (新版方法)
- matlab/python+opencv提取圆形鱼眼图片的有效区域