opencv练手项目:文档OCR识别

整体思路:利用边缘检测+轮廓检测+透射变换+百度文字识别API实现。
总体分为3步:
1.运用边缘检测与轮廓检测检测到文本最外侧的边缘。
2.根据边缘的四点确定文档的区域,再利用透射变换等操作将文档视角转换。
3.调用百度文字识别API进行文本识别。
原始图像:
在这里插入图片描述
透射变换等操作之后的图像:
在这里插入图片描述
文本识别的结果(部分):
在这里插入图片描述
具体步骤:
Step1:运用边缘检测与轮廓检测检测到文本最外侧的边缘
通过Canny边缘检测将测出轮廓,然后再进行轮廓检测。轮廓检测时会出现多个闭合图形,可以通过比较闭合图形的面积的大小确定,拥有面积最大值的闭合图形即为文档边缘。

#读取图像
img=cv.imread('receipt.jpg',cv.IMREAD_COLOR)
org=img.copy()
ratio=0.4	#由于原图过大,所以采用缩放一定比例,方便观察结果
img=cv.resize(img, dsize=None,fx=ratio,fy=ratio)

#边缘检测+轮廓检测检测到最外围的矩形
gray=cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edged=cv.Canny(gray,75, 200)
cnts,hierarchy=cv.findContours(edged.copy(), cv.RETR_LIST, 
cv.CHAIN_APPROX_SIMPLE) 
cnt = sorted(cnts, key = cv.contourArea, reverse = True)[0]

peri = cv.arcLength(cnt, True)	#计算图形的周长
approx=cv.approxPolyDP(cnt, 0.1*peri, True)	#轮廓检测中的近似操作

if(len(list(approx))==4):	#判断是否为4点(确定一个矩形)
    screenCnt=approx
else:
    print("未找到轮廓")
    exit()

效果:
在这里插入图片描述

Step2:根据边缘的四点确定文档的区域,再利用透射变换等操作将文档视角转换。

1.确定文档边缘四点。
在这里插入图片描述
作者采用如下方法确定:
当x+y为最小/大值时,分别对应A/C点。(sum求和函数)
当y-x为最小/大值时,分别对应B/D点。(diff做差函数)

def order_points(pts):
	# 一共4个坐标点
	rect = np.zeros((4, 2), dtype = "float32")

	# 按顺序找到对应坐标0123分别是 左上,右上,右下,左下
	# 计算左上,右下
	s = pts.sum(axis = 1)
	rect[0] = pts[np.argmin(s)]
	rect[2] = pts[np.argmax(s)]

	# 计算右上和左下
	diff = np.diff(pts, n=1,axis = 1)
	rect[1] = pts[np.argmin(diff)]
	rect[3] = pts[np.argmax(diff)]

	return rect

2.透射变换
以四个边长的长/宽的最大值分别作为透射变换后长/宽,然后做透射变换。

def four_point_transform(image, pts):   #image为原始图像,pts为4*2的坐标矩阵
    rect=order_points(pts)
    len=np.zeros((4,1))
    for (i,p) in enumerate(pts) : 
        if i!=3:   
            x=pts[i:(i+2),0]
            y=pts[i:(i+2),1]
        elif i==3:
            x=[pts[3,0],pts[0,0]]
            y=[pts[3,0],pts[0,1]]
        len[i]=np.sqrt(((x[0]-x[1])**2+(y[0]-y[1])**2))

    maxWidth=int(max(len[0],len[2]))
    maxHight=int(max(len[1],len[3]))

    dst=np.array([
        [0,0],
        [maxWidth-1,0],
        [maxWidth-1,maxHight-1],
        [0,maxHight-1]
    ],dtype = "float32")

    M=cv.getPerspectiveTransform(rect, dst)
    warped=cv.warpPerspective(image, M, (maxWidth,maxHight))
    return warped

实际调用:

warped=four_point_transform(org, screenCnt.reshape(4,2)/ratio)

再进行旋转变换与阈值处理即可获得纠正后的图像:

#旋转90°(针对特定需要旋转的对象)
rows,cols = dst.shape[:2]
M = cv.getRotationMatrix2D((cols/2,rows/2),90,1)
dst = cv.warpAffine(dst,M,(cols,rows))
#阈值处理
gray=cv.cvtColor(warped, cv.COLOR_BGR2GRAY)
ret,dst=cv.threshold(gray, 127, 255, cv.THRESH_BINARY)

在这里插入图片描述
Step3:调用百度文字识别API进行文本识别。
如何获取OCR模块参考:https://blog.csdn.net/jyd0124/article/details/105868562
然后调用API即可,详细深入的OCR处理不在这里展开。

#调用百度API实现OCR功能    
AppID = '*******'
API_Key = '********'
Secret_Key = '**************'

client = AipOcr(AppID, API_Key, Secret_Key)

image = get_file_content('图片的地址')
options = {}
options["language_type"] = "ENG"
options["detect_direction"] = "true"
options["detect_language"] = "true"
options["probability"] = "true"
res=client.basicGeneral(image,options)
print(res['words_result'])
for item in res['words_result']:
    print(item['words'])

OCR结果:
在这里插入图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值