OpenCV探索之路(二十六):如何去除票据上的印章
最近在做票据识别的编码工作时遇到一些问题,就是票据上往往会有一些红色印章把一些重要信息区域给覆盖了,比如一些开发票人员盖印章时比较随意,容易吧一些关键区域给遮蔽了,这让接下来的票据识别很困难,因此,我们必须先对票据图像进行一定的预处理来移除印章干扰,再进行字符识别,这样子识别准确率才有保证。
我们从简单例子说起,比如我们有以下一张票据,上面盖有红色印章,虽然该印章没有遮挡关键信息,但是我们还是打算将其移除,那该怎么办?首先想到的肯定移除红色像素点的方法,这种方法需要查到红色的颜色范围,然后遍历全图像素点,在范围内的像素点就将它设置为白色。这种方法用起来其实不太好,毕竟这个“红色范围”的设定还是蛮困难的一件事。那现在我说一下我的方法,用几行代码移除红色印章。
原图

灰度化

二值化

做票据识别一般都要将票据转化为二值图像,我们从上面的二值图像可以看出,票据上还是存在大块的印章痕迹,我们此刻的任务就是,将它从票据中移除!
其实实现的方法非常简单,关键就是分离颜色通道 + 阈值分割。步骤如下:
- 对彩色图分离通道,拿到红色通道图
- 进行阈值分割
先看一下用split函数分离出来的三通道图像
红色通道

绿色通道

蓝色通道

从上面各通道的图像看出,每个通道的图像是略有不同,不同的地方就在于对不同颜色的敏感度不同。看一下红色通道的图,我们发现原图中的红色基本不见了!总结一下就是,原图中颜色越接近红色的地方在红色通道越接近白色。在纯红的地方在红色通道会出现纯白。绿色、蓝色也是同样的道理。
但是仔细观察一下票据图像中还是有一些印章痕迹,这时再使用一下阈值分割技术就可以移除一些印章痕迹了。

上面就是阈值分割后的图,可以看出,该二值图像已经完全看不出有印章的痕迹了,这时我们可以说比较好地移除了印章干扰。
代码
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
int main()
{
Mat src = imread("100.bmp");
//resize(src, src, Size(700, 500));
Mat gray;
cvtColor(src, gray, CV_RGB2GRAY);
if (src.empty())
{
printf("fail to open image!\n");
return -1;
}
// 全局二值化
int th = 180; //阈值要根据实际情况调整
Mat binary;
threshold(gray, binary, th, 255, CV_THRESH_BINARY);
vector<Mat> channels;
split(src, channels);
Mat red = channels[2];
Mat blue = channels[0];
Mat green = channels[1];
Mat red_binary;
threshold(red, red_binary, th, 255, CV_THRESH_BINARY);
imshow("src", src);
imshow("gray", gray);
imshow("binary", binary);
imshow("red channel", red);
imshow("blue channel", blue);
imshow("green channel", green);
imshow("red+binary", red_binary);
waitKey();
return 0;
}
来多几张发票看看效果
移除前


移除后

移除前


移除后

下面这个情形比较经典,因为印章刚好把一些关键区域(金额)给遮挡住了,现在人的肉眼也很难辨别出它的具体数字了,那机器还能正确识别吗?如果不做任何处理,机器也是没办法识别的,但是预处理一下之后,机器就能准确识别出其数字了。
移除前


移除后

当然,这种分离通道+阈值分割的方法还可以用到其他场合,例如在红绿灯的检测上,也是可以借鉴这种方法的。我在网上找了张红绿灯的照片来测试,也看看效果吧~
检测红灯

检测绿灯

OpenCV探索之路(二十六):如何去除票据上的印章的更多相关文章
- OpenCV探索之路(十六):图像矫正技术深入探讨
刚进入实验室导师就交给我一个任务,就是让我设计算法给图像进行矫正.哎呀,我不太会图像这块啊,不过还是接下来了,硬着头皮开干吧! 那什么是图像的矫正呢?举个例子就好明白了. 我的好朋友小明给我拍了这几张 ...
- Bootstrap <基础二十六>进度条
Bootstrap 进度条.在本教程中,你将看到如何使用 Bootstrap 创建加载.重定向或动作状态的进度条. Bootstrap 进度条使用 CSS3 过渡和动画来获得该效果.Internet ...
- Web 前端开发人员和设计师必读精华文章【系列二十六】
<Web 前端开发精华文章推荐>2014年第5期(总第26期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- 二十六:Struts2 和 spring整合
二十六:Struts2 和 spring整合 将项目名称为day29_02_struts2Spring下的scr目录下的Struts.xml文件拷贝到新项目的scr目录下 在新项目的WebRoot-- ...
- 二十六、Jcreator使用初步
摘自http://blog.csdn.net/liujun13579/article/details/7751464 二十六.Jcreator使用初步 Jcreator是一个小巧灵活的Java开发工具 ...
- WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇]
原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇] 通过<实现篇>对WSDL元素和终结点三要素的之间的匹配关系的介绍,我们知道了WSDL的Binding ...
- WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]
原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇] 元数据的导出就是实现从ServiceEndpoint对象向MetadataSet对象转换的过程,在WCF元数据框 ...
- VMware vSphere 服务器虚拟化之二十六 桌面虚拟化之View Persona Management
VMware vSphere 服务器虚拟化之二十六 桌面虚拟化之View Persona Management 实验失败告终,启动VMware View Persona Management服务报10 ...
- 第一百二十六节,JavaScript,XPath操作xml节点
第一百二十六节,JavaScript,XPath操作xml节点 学习要点: 1.IE中的XPath 2.W3C中的XPath 3.XPath跨浏览器兼容 XPath是一种节点查找手段,对比之前使用标准 ...
随机推荐
- MIPI DSI转LVDS芯片方案TC358775XBG
型号:TC358775XBG功能:MIPI转LVDS通信方式:IIC/MIPI Command mode分辨率:1920*1080电源:3.3/1.8/1.2封装形式:BGA64深圳长期现货 ,提供技 ...
- [js高手之路]深入浅出webpack系列1-安装与基本打包用法和命令参数
webpack,我想大家应该都知道或者听过,Webpack是前端一个工具,可以让各个模块进行加载,预处理,再进行打包.现代的前端开发很多环境都依赖webpack构建,比如vue官方就推荐使用webpa ...
- 在centos6上实现编译安装lamp和wordpress,并编译xcache
author:JevonWei 版权声明:原创作品 软件环境: centos6.9 httpd-2.4.27.tar.bz2 apr-1.5.2.tar.bz2 apr-util-1.5.4.tar. ...
- node简单配置一台服务器
要想使用nodeJS来搭建服务器,首先需要一个必备的条件:node必须安装,建议为4.0版本及以上: 在node中,为我们封装了好多类,搭建服务器需要的一个类是"http"类. 用 ...
- IntelliJ IDEA使用(一)基本设置与类、方法模板设置
其实之前一直开发都是在使用的是Eclipse,但是最近在做Maven项目的时候要用IntelliJ IDEA,据说这个idea功能非常的强大,最近在使用的时候发现如果适应的真的是非常的强大.感觉是比E ...
- Java中死锁的简单例子及其避免
死锁:当一个线程永远地持有一个锁,并且其他线程都尝试获得这个锁时,那么它们将永远被阻塞.比如,线程1已经持有了A锁并想要获得B锁的同时,线程2持有B锁并尝试获取A锁,那么这两个线程将永远地等待下去. ...
- 【java】关于java类和对象,你想知道的在这里!
java类的基本组成 java作为一门面向对象的语言, 类和对象是最重要的概念之一,下面,就让我们来看看java中类的基本结构是怎样的: 一个简单的java类主要可由以下几个部分(要素)组成: 1.实 ...
- 201521123001《Java程序设计》第1周学习总结
1. 本周学习总结 java和我们以前学的C语言的区别大致有: C语言可以直接操作内存,java不能直接操作: C语言的代码不能跨平台,java的代码可以跨平台: C语言有指针,java没有指针: C ...
- Log4J:Log4J三大组件:Logger+Appender+Layout 格式化编程详解
快速了解Log4J Log4J的三个组件: Logger:日志记录器,负责收集处理日志记录 (如何处理日志) Appender:日志输出目的地,负责日志的输出 (输出到什么 地方) Layo ...
- 银河麒麟操作系统打开VMware报vmmon无法编译
使用银河麒麟操作系统打开VMware可能会报vmmon无法编译 这个时候... 将/usr/src/linux-headers-xxx/include/miscdevice.h第71行void改为in ...