资讯专栏INFORMATION COLUMN

学习Opencv+Python之文档OCR

tangr206 / 380人阅读

摘要:类推,求坐标值的差,当差最小时为右上角,最大时为左下角对获取的四个点组成的四边形求边长,那么转换后的四个顶点为对于原始图像的高和宽,如果输入的高为,先求比例,而后即可获得原始高宽比下的宽。

学习Opencv+Python之文档OCR

思路:

  1. 图像预处理获取轮廓信息
  2. 获取照片中的角点构建变换矩阵
  3. 进行仿射变换矫正文档视角
  4. 二值化提取文字信息

代码:

# 导入工具包import numpy as npimport cv2# 获取角点函数def order_points(pts):	# 设置并初始化一个4行2列全为0的array,来存放四个角点	rect = np.zeros((4, 2), dtype = "float32")	# 对容器pts按行求和,即将坐标的x值和y值求和	s = pts.sum(axis = 1)	# 当x+y最小时,为左上角	rect[0] = pts[np.argmin(s)]	# 当x+y最大时,为右下角	rect[2] = pts[np.argmax(s)]	# 对容器pts按行求差,即将坐标的x值和y值求差	diff = np.diff(pts, axis = 1)	# 当差值最小时,即为右上角	rect[1] = pts[np.argmin(diff)]	# 当差值最小时,即为左下角	rect[3] = pts[np.argmax(diff)]	return rect# 投射变换函数def four_point_transform(image, pts):	# 获取输入坐标点	rect = order_points(pts)	(tl, tr, br, bl) = rect	# 计算距离	widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))	widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))	maxWidth = max(int(widthA), int(widthB))	heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))	heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))	maxHeight = max(int(heightA), int(heightB))	# 变换后对应坐标位置,dst[0]对应左上角,dst[1]对应右上角,dst[2]对应右下角,dst[3]对应左下角,注意图像的坐标原点是左上角	dst = np.array([		[0, 0],		[maxWidth - 1, 0],		[maxWidth - 1, maxHeight - 1],		[0, maxHeight - 1]], dtype = "float32")	# 计算变换矩阵	## 投射变换,函数cv2.getPerspectiveTransform需提供四个坐标点	M = cv2.getPerspectiveTransform(rect, dst)	warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))	# 返回变换后结果	return warped# 指定输出图像的大小,防止图像尺寸太大def resize(image, width=None, height=None):	dim = None	#获取图像的高、宽	(h, w) = image.shape[:2]	if width is None and height is None:		return image	if width is None:		r = height / float(h) #指定缩放比		dim = (int(w * r), height) #只要设定高即可获取宽	else:		r = width / float(w) #指定缩放比		dim = (width, int(h * r)) #只要设定宽即可获取高	resized = cv2.resize(image, dim, cv2.INTER_AREA)	return resized# 读取输入image = cv2.imread("1.jpg")# 坐标也会相同变化ratio = image.shape[0] / 500.0# 复制图像orig = image.copy()# 指定图像高,自动获取缩放比得到宽image = resize(orig, height = 500)# 第一步:预处理# 转换为灰度图像gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 高斯滤波,高斯核大小为(5, 5)gray = cv2.GaussianBlur(gray, (5, 5), 0)# 使用Canny算子获取边缘信息edged = cv2.Canny(gray, 75, 200)print("STEP 1: 边缘检测")cv2.imshow("Image", image)cv2.imshow("Edged", edged)# 轮廓检测cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[0]# 依据轮廓所围的面积进行排序,并选取前六个,进行顺时针标记cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5]# 第二步:遍历获取轮廓for c in cnts:	# 计算轮廓长度	peri = cv2.arcLength(c, True)	# 对轮廓进行多边形拟合近似,原曲线到拟合多边形的距离为d,若d小于(0.02*peri),则滤掉,否则保留	approx = cv2.approxPolyDP(c, 0.02 * peri, True)	# 当只需四边形即能拟合时取出	if len(approx) == 4:		screenCnt = approx		break# 展示结果print("STEP 2: 获取轮廓")cv2.drawContours(image, [screenCnt], -1, (0, 255, 0), 2)cv2.imshow("Outline", image)# 第三步:透视变换warped = four_point_transform(orig, screenCnt.reshape(4, 2) * ratio)# 二值处理warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)_, ref = cv2.threshold(warped, 180, 255, cv2.THRESH_BINARY)cv2.imwrite("scan.jpg", ref)# 展示结果print("STEP 3: 变换")cv2.imshow("Original", resize(orig, height = 650))cv2.imshow("Scanned", resize(ref, height = 650))cv2.waitKey(0)

结果:

注意:(代码中的几个自定义函数理解,大家可以用debug调试一下即可理解)

  1. order_points():对于坐标(x, y),求 s = x + y 的值,当 s 最小时说明是左上的那个角,当 s 的值最大时为左上角的对角。类推,求坐标值的差,当差最小时为右上角,最大时为左下角;
  2. four_point_transform():对order_points()获取的四个点组成的四边形求边长,那么转换后的四个顶点为:
  3. resize():对于原始图像的高和宽(h, w),如果输入的高为height,先求比例r = height / h, 而后即可获得原始高宽比下的宽width。类推,指定宽同样得到高。

注:此代码是对唐宇迪博士Opencv实战代码的复现

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/119256.html

相关文章

  • 首次公开,整理12年积累的博客收藏夹,零距离展示《收藏夹吃灰》系列博客

    摘要:时间永远都过得那么快,一晃从年注册,到现在已经过去了年那些被我藏在收藏夹吃灰的文章,已经太多了,是时候把他们整理一下了。那是因为收藏夹太乱,橡皮擦给设置私密了,不收拾不好看呀。 ...

    Harriet666 评论0 收藏0
  • 验证码破解技术四部曲环境搭建篇(一)

    摘要:最容易破解的验证码直接使用库识别。验证码使用卷积神经网络训练识别。说明项目源码可以帮我点个开发语言编写爬虫编写图像处理部分以及机器学习算法开发环境依赖库环境搭建安装安装安装安装的库安装的库下载项目源码 前言 转眼就变成大四狗了,大学期间做的比较深入的技术是爬虫,但是爬虫也有很多高级的技术没有涉及,比如说验证码的破解便是其中之一,再加上我对其非常感兴趣,于是乎,开始苦学图像处理、学习机器...

    Null 评论0 收藏0
  • [译]OpenCV OCR and text recognition with Tesseract

    摘要:纳入深度学习模型来进一步提升准确率只是时间问题,事实上,这个时间已经到来。最新版本支持基于深度学习的,准确率显著提高。该函数使用基于深度学习的文本检测器来检测不是识别图像中的文本区域。高效使用概率最高的文本区域,删除其他重叠区域。 By Adrian Rosebrock on September 17, 2018 in Deep Learning, Optical Character ...

    gnehc 评论0 收藏0
  • 使用 OpenCVPython 识别信用卡号

    摘要:使用和识别信用卡号在之前的博文中,我们学习了如何安装二进制文件并将其用于。应用识别信用卡上的十六位数字。识别信用卡类型即等。两个必需的命令行参数是要进行处理的图像的路径。使用纵横比,我们分析每个轮廓的形状。 ...

    Jensen 评论0 收藏0
  • opencv python 基于KNN的手写体识别

    摘要:我们的目标是构建一个可以读取手写数字的应用程序为此,我们需要一些和附带一个在文件夹中,它有个手写数字每个数字个每个数字是图像所以首先要将图片切割成个不同图片每个数字变成一个单行像素前面的个数字作为训练数据,后个作为测试数据输出进一步 OCR of Hand-written Data using kNN OCR of Hand-written Digits 我们的目标是构建一个可以读取...

    wing324 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<