图像处理案例06 OCR应用

news/2025/2/25 20:28:53

OCR应用

  • 1 OCR读取账单
    • 1.1 背景及思路
    • 1.2 代码

1 OCR读取账单

1.1 背景及思路

  1. 思路
    目标是读取图片中账单的信息。首先要截取图片上的账单,考虑到账单并非都是整齐摆放,为了保持算法的通用性,通过透视变换对扣取的账单摆正,然后调用工具识别账单上的信息。

  2. 步骤
    1) 读取图像,做二值化。
    2)开运算除噪声。
    3)找到图像的最大外部轮廓,根轮廓得到账单的最小外接矩形的坐标,根据坐标对账单做透视变换。
    4)识别账单上的信息。

在这里插入图片描述

1.2 代码

img_rgb = cv2.imread('OCR识别账单文字/note.jpg')
img_gray = cv2.imread('OCR识别账单文字/note.jpg', 0)
img = img_gray.copy()
_ ,benary = cv2.threshold(img_gray,0,240,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
plt.imshow(benary,"gray")
k=np.ones((10,10),np.uint8)
r1=cv2.morphologyEx(benary,cv2.MORPH_OPEN,k)  # 除掉了噪声
plt.imshow(r1,"gray")
ret, binary = cv2.threshold(r1,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# ret, binary = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) 
        
rect = cv2.minAreaRect(contours[0])
points = cv2.boxPoints(rect)
points = points.astype(np.int32)
image=cv2.drawContours(img_rgb.copy(),[points],0,(255,255,255),2)

# 透视变换
pts = np.zeros((4, 2), np.float32)
res = np.sum(points, axis=1)
pts[0] = points[np.argmin(res)]
pts[2] = points[np.argmax(res)]
res = np.diff(points, axis=1)
pts[1] = points[np.argmin(res)]
pts[3] = points[np.argmax(res)]
pts = np.array(pts, np.float32)

#计算边长
w1 = np.sqrt((pts[0][0] - pts[1][0]) ** 2 + (pts[0][1] - pts[1][1]) ** 2)
w2 = np.sqrt((pts[2][0] - pts[3][0]) ** 2 + (pts[2][1] - pts[3][1]) ** 2)
w = int(max(w1, w2))

h1 = np.sqrt((pts[1][0] - pts[2][0]) ** 2 + (pts[1][1] - pts[2][1]) ** 2)
h2 = np.sqrt((pts[0][0] - pts[3][0]) ** 2 + (pts[0][1] - pts[3][1]) ** 2)
h = int(max(h1, h2))

#计算目标图像的尺寸
dst = np.array([
    [0, 0],
    [w - 1, 0],
    [w - 1, h - 1],
    [0, h - 1]
], np.float32)

#透视变换
mat = cv2.getPerspectiveTransform(pts, dst)
img = img_gray.copy()
img = cv2.warpPerspective(img, mat, (w, h))
plt.imshow(img,"gray")

# 二值化
img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
text = pytesseract.image_to_string(img)
print(text)
'''
Berghotel
    
 
Srosse Scheidegg
SBI Geindehald
Fate Rotter
Rech te A572 2.07. 2007/18:29:17
bar Tech Y/0t
Qieatta Macehial 4450 OF 9.00
‘ubloxt a 500 oF s.09
nGcheotnscettzel & 22.00 OF 2200
worsespstzt) 850 OF HEBD
 
Jorat: oF 54,56
Incl, 1.8% St $850.08: 3.85
Fntsprteht tn Euro $6.33. EUR
Es bedtente Sta: Ursuta
  
Tht Hee: 430-234 |
Tel. 088 853.67 16
Fax, : 088 858 87 19
Ennai ls srassesche angeBbiuevie.ch
'''

在这里插入图片描述
上图中左图为原图,右图为二值化后的图像,观察发现,二值化后的图像有噪声,影响寻找账单的轮廓。

对二值化后的图像做开运算可以消除图像上的噪声,方便寻找图像的轮廓,右图为
根据图像最外轮廓得到的账单,并对账单做透视变换的结果,根据右图可以做检测。


http://www.niftyadmin.cn/n/5865921.html

相关文章

Unity汽车笔记

汽车的移动和转向 我们知道,汽车的前进后退是变速运动。按w,汽车开始加速,到最大速度后保持匀速,松开w,汽车受到阻力加速。如果按s减速,则以更大的加速度减速。后退反之。 按A/D时前轮偏转。只有前进后退…

基于 Vue.js 和 Element UI 实现九宫格按钮拖拽排序功能 | 详细教程与代码实现

在Vue.js项目中使用vue-element-template(基于Element UI)实现按钮的九宫格拖拽排序功能,可以通过以下步骤实现。我们将使用vuedraggable库来实现拖拽排序功能。 1. 安装依赖 首先,确保你已经安装了vuedraggable库: …

Python Seaborn库使用指南:从入门到精通

1. 引言 Seaborn 是基于 Matplotlib 的高级数据可视化库,专为统计图表设计。它提供了更简洁的 API 和更美观的默认样式,能够轻松生成复杂的统计图表。Seaborn 在数据分析、机器学习和科学计算领域中被广泛使用。 本文将详细介绍 Seaborn 的基本概念、常用功能以及高级用法,…

网络原理--UDP的特点

总的来说:1.无连接,2.面向数据报,3.全双工,4.有接受缓存,无发送缓存。5.不可靠传输。 一、UDP报文的格式 UDP报头中一共有四个字段,每个字段2个字节,一共8个字节。 因为每个字段2个字节&#…

git 命令 设置别名

在Git中,您可以通过以下命令查看所有的alias(别名): git config --get-regexp alias 这个命令会列出所有配置的alias,例如: alias.st.status alias.co.checkout alias.br.branch ... 如果您想查看某个特定a…

启动Redis报错记录

突然启动Redis就报了个错:‘Could not create server TCP listening socket 127.0.0.1:6379: bind: 操作成功完成。‘ 查了下解决方案,应该是6379端口已绑定,服务没有关闭。 需要输入命令redis-cli 再输入shutdown 但又出现了新的问题&…

JavaAPI(lambda表达式、流式编程)

Lambda表达式 本质上就是匿名内部类的简写方式(匿名内部类见:JAVA面向对象3(抽象类、接口、内部类、枚举)-CSDN博客) 该表达式只能作用于函数式接口,函数式接口就是只有一个抽象方法的接口。 可以使用注解…

2.1 第一个程序:从 Hello World 开始

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 同大多数编程语言教程一样,本书第一个代码也是输出:Hello world! 这似乎也是惯例。我们也先从这个简单的代码…