一、定位和变换票据

定位照片中的不规范票据或矩形文本,并将其变换为正规矩形,以供OCR识别。

# -*- coding:utf-8 -*-
__author__ = 'Leo.Z' import cv2 as cv
import numpy as np def show_img(img, win_name):
cv.imshow(win_name, img)
cv.waitKey(0)
cv.destroyAllWindows() def image_process(img_path):
# 读入图像
img = cv.imread(img_path)
show_img(img, 'img') # 转换为灰度图
gray = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
# 高斯模糊,消除一些噪声
gray = cv.GaussianBlur(gray, (5, 5), 0)
show_img(gray, 'gray') # 寻找边缘
edged = cv.Canny(gray, 50, 120)
show_img(edged, 'edged') # 形态学变换,由于光照影响,有很多小的边缘需要进行腐蚀和膨胀处理
kernel = np.ones((5, 5), np.uint8)
morphed = cv.dilate(edged, kernel, iterations=3)
morphed = cv.erode(morphed, kernel, iterations=3)
show_img(morphed, 'morphed') # 找轮廓
morphed_copy = morphed.copy()
cnts, _ = cv.findContours(morphed_copy, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)
# 排序,并获取其中最大的轮廓
if len(cnts) is not 0:
cnts = sorted(cnts, key=cv.contourArea, reverse=True)[:1]
else:
print("Did not find contours\n")
return # 用周长的0.1倍作为阈值,对轮廓做近似处理,使其变成一个矩形
epsilon = 0.1 * cv.arcLength(cnts[0], True)
approx = cv.approxPolyDP(cnts[0], epsilon, True) # 在原图的拷贝上画出轮廓
ticket_copy = img.copy()
cv.drawContours(ticket_copy, [approx], -1, (255, 0, 0), 2)
show_img(ticket_copy, 'ticket_copy') # 获取透视变换的原坐标
if approx.shape[0] is not 4:
print("Found a non-rect\n")
return
src_coor = np.reshape(approx, (4, 2))
src_coor = np.float32(src_coor) # 右上,左上,左下,右下 坐标
(tr, tl, bl, br) = src_coor # 计算宽
w1 = np.sqrt((tr[0] - tl[0]) ** 2 + (tr[1] - tl[1]) ** 2)
w2 = np.sqrt((br[0] - bl[0]) ** 2 + (br[1] - bl[1]) ** 2)
# 求出比较大的w
max_w = max(int(w1), int(w2))
# 计算高
h1 = np.sqrt((bl[0] - tl[0]) ** 2 + (bl[1] - tl[1]) ** 2)
h2 = np.sqrt((br[0] - tr[0]) ** 2 + (br[1] - tr[1]) ** 2)
# 求出比较大的h
max_h = max(int(h1), int(h2)) # 透视变换的目标坐标
dst_coor = np.array([[max_w - 1, 0], [0, 0], [0, max_h - 1], [max_w - 1, max_h - 1]], dtype=np.float32) # 求转换矩阵
trans_mat = cv.getPerspectiveTransform(src_coor, dst_coor)
# 进行转换,将图中对应坐标的图片截取出来,并转换到dst_coor大小
warped = cv.warpPerspective(img, trans_mat, (max_w, max_h)) return warped if __name__ == '__main__':
wrap = image_process('zhengshu.png')
show_img(wrap, 'result')

效果如下:

注意:本例是一个相对简单的示例,对于背景复杂,或票据与背景灰度相近时,可能效果不好。本例只作为前面学习内容的一个综合案例。如果要用到实际环境中需要结合更多技术,使其具有更好的鲁棒性。

二、使用OCR库实现文本扫描

我们使用一个名叫Tesseract的OCR库来实现图片上的文本扫描。

1.下载一个版本的Tesseract :https://digi.bib.uni-mannheim.de/tesseract/

2.安装并将安装目录加到环境变量path中,假设为

D:/Dev_apps/Tesseract-OCR/tesseract.exe

3.在pycharm中安装pytesseract,并修改D:\......\Lib\site-packages\pytesseract\pytesseract.py中的

tesseract_cmd = 'D:/Dev_apps/Tesseract-OCR/tesseract.exe'

在python中使用该库:(可以将已经预处理完毕的图像,例如小票发票等使用该OCR库进行处理)

import pytesseract

img = cv.imread('piao6.png')
# 使用tesseract来处理图片,并获取文本
text = pytesseract.image_to_string(img)
print(text)

OpenCV笔记(5)(定位票据并规范化、调库扫描文本)的更多相关文章

  1. opencv笔记6:角点检测

    time:2015年10月09日 星期五 23时11分58秒 # opencv笔记6:角点检测 update:从角点检测,学习图像的特征,这是后续图像跟踪.图像匹配的基础. 角点检测是什么鬼?前面一篇 ...

  2. python+opencv实现车牌定位

    写在前面 HIT大三上学期视听觉信号处理课程中视觉部分的实验三,经过和学长们实验的对比发现每一级实验要求都不一样,因此这里标明了是2019年秋季学期的视觉实验三. 由于时间紧张,代码没有进行任何优化, ...

  3. OpenCV笔记大集锦(转载)

    整理了我所了解的有关OpenCV的学习笔记.原理分析.使用例程等相关的博文.排序不分先后,随机整理的.如果有好的资源,也欢迎介绍和分享. 1:OpenCV学习笔记 作者:CSDN数量:55篇博文网址: ...

  4. opencv笔记5:频域和空域的一点理解

    time:2015年10月06日 星期二 12时14分51秒 # opencv笔记5:频域和空域的一点理解 空间域和频率域 傅立叶变换是f(t)乘以正弦项的展开,正弦项的频率由u(其实是miu)的值决 ...

  5. opencv笔记4:模板运算和常见滤波操作

    time:2015年10月04日 星期日 00时00分27秒 # opencv笔记4:模板运算和常见滤波操作 这一篇主要是学习模板运算,了解各种模板运算的运算过程和分类,理论方面主要参考<图像工 ...

  6. opencv笔记3:trackbar简单使用

    time:2015年 10月 03日 星期六 13:54:17 CST # opencv笔记3:trackbar简单使用 当需要测试某变量的一系列取值取值会产生什么结果时,适合用trackbar.看起 ...

  7. opencv笔记2:图像ROI

    time:2015年 10月 03日 星期六 12:03:45 CST # opencv笔记2:图像ROI ROI ROI意思是Region Of Interests,感兴趣区域,是一个图中的一个子区 ...

  8. opencv笔记1:opencv的基本模块,以及环境搭建

    opencv笔记1:opencv的基本模块,以及环境搭建 安装系统 使用fedora22-workstation-x86_64 安装opencv sudo dnf install opencv-dev ...

  9. Windows phone 8 学习笔记(8) 定位地图导航

    原文:Windows phone 8 学习笔记(8) 定位地图导航 Windows phone 8 已经不使用自家的bing地图,新地图控件可以指定制图模式.视图等.bing地图的定位误差比较大,在模 ...

随机推荐

  1. 学习shell的第二天

    重定向和管道符: 1.重定向 程序 = 指令 + 数据            命令    变量  在程序中,数据如何输入?又如何输出?  数据输入:键盘  --  标准输入,但是并不是唯一输入方式:  ...

  2. [转帖]国产CPU性能最全盘点 宜良性竞争优胜劣汰

    国产CPU性能最全盘点 宜良性竞争优胜劣汰 电子工程专辑的网站内容 其实里面说的不尽全面 比如龙芯和申威就放到一块了 一个是 MIPS 一个是Alpha 明显不一样的东西 x86的应该都不行 而且. ...

  3. 设计模式:建造者模式(Builder)

    流水作业大家应该都清楚吧!在流水作业中,我们可以将一些复杂的东西给构建出来,例如汽车.我们都知道汽车内部构件比较复杂,由很多部件组成,例如车轮.车门.发动机.方向盘等等,对于我们用户来说我们并不需要知 ...

  4. 解决WordPress百度分享图标不显示问题

    最近在帮朋友维护博客时,发现他的百度分享居然不能使用了,首先很多人会认为,百度分享挂在那里就是一种摆设,又没有几个人去分享,有什么含义呢?其实挂百度分享的含义是非常重要的,网站增加一个百度分享是可以增 ...

  5. MySQL性能优化(一):优化方式

    原文:MySQL性能优化(一):优化方式 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/v ...

  6. 导出excel-NPOI

    前台调用: view: <a href='/Admin/NurseUser/Excel' target='_blank'>导出Excel</a>或js: window.loca ...

  7. sql server sum函数

    sum()函数 --SUM 函数返回数值列的总数 语法:SELECT SUM(column_name) FROM table_name

  8. SQL----Scalar 函数

    UCASE() 函数 UCASE 函数把字段的值转换为大写. SQL UCASE() 语法 SELECT UCASE(column_name) FROM table_name SQL UCASE() ...

  9. 【Activiti】为每一个流程绑定相应的业务对象的2种方法

    方式1: 在保存每一个流程实例时,设置多个流程变量,通过多个流程变量的组合来过滤筛选符合该组合条件的流程实例,以后在需要查询对应业务对象所对应的流程实例时,只需查询包含该流程变量的值的流程实例即可. ...

  10. Django框架——基础之路由系统(urls.py)11111111

    1.URL路由系统前言 URL是Web服务的入口,用户通过浏览器发送过来的任何请求,都是发送到一个指定的URL地址,然后被响应. 在Django项目中编写路由,就是向外暴露我们接收哪些URL的请求,除 ...