前一篇文章《Android划矩形截屏并加入OCR识别》在安卓中我们做了划矩形截图进行OCR实识,其中只是简单的进行了二值化的处理然后就传入图片识别,本来计划把图片二值化后做一些透视变换的Demo可以增加识别的效果,然后就出来了今天的文章。
样版原图
我自己照了一张素材图片,本来要进行处理的,如上图九型人格的字,照完后其实可以看到,上图中由于拍照的角度问题,有至少三分之一的面积是书封皮的反光。
threshold效果
我自己常用的二值化函数,因为里面有THRESH_OTSU自动阈值 ,觉得挺方便,使用效果也不错,就直接在程序中用了,结果就出来了一面的效果。
从上面可以看出来,我们如果要进行OCR识别,这样的效果估计只能认出“格”这个字,而九型人三个字都已经无法识别了。
遇到这个情况时,就只能回去补初级知识,看到了自适应二值化adaptiveThreshold函数,最初开始学的时候只是了解了一下,因为里面的有些值需要自己设,觉得麻烦,所以就一直没有在意。所以今天我们就来重新认识下这个函数。
adaptiveThreshold
void adaptiveThreshold( InputArray src, OutputArray dst,
double maxValue, int adaptiveMethod,
int thresholdType, int blockSize, double C );
参数说明
参数1:InputArray类型的src,输入图像,填单通道,单8位浮点类型Mat即可。
参数2:函数运算后的结果存放在这。即为输出图像(与输入图像同样的尺寸和类型)。
参数3:预设满足条件的最大值。
参数4:指定自适应阈值算法。可选择ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C两种。
ADAPTIVE_THRESH_MEAN_C,为局部邻域块的平均值。该算法是先求出块中的均值,再减去常数C。
ADAPTIVE_THRESH_GAUSSIAN_C ,为局部邻域块的高斯加权和。该算法是在区域中(x,y)周围的像素根据高斯函数按照他们离中心点的距离进行加权计算, 再减去常数C。
参数5:指定阈值类型。可选择THRESH_BINARY或者THRESH_BINARY_INV两种。(即二进制阈值或反二进制阈值)。
参数6:表示邻域块大小,用来计算区域阈值,一般选择为3、5、7......等。
参数7:参数C表示与算法有关的参数,它是一个从均值或加权均值提取的常数,可以是负数。
代码演示
我们直接对源图进行普通二值化和自适应二值化的使用,做一个对比,前面加入了灰度,高斯模糊,二值化后的形态学操作,最后再输出显示图片。
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
try
{
Mat src = imread("D:/Business/DemoTEST/CPP/opencv-perspective/imgOCR/01.png");
if (src.empty())
{
printf("不能读取图片...\n");
getchar();
return -1;
}
resize(src, src, Size(), 0.5, 0.5, INTER_LINEAR);
Mat gray, dst, dst2;
imshow("src", src);
//灰度
cvtColor(src, gray, COLOR_BGR2GRAY);
//高斯模糊
GaussianBlur(gray, gray, Size(3, 3), 0.8,0.8);
imshow("GaussianBlur", gray);
//二值化
adaptiveThreshold(gray, dst, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 11, 2);
threshold(gray, dst2, 0, 255, THRESH_BINARY | THRESH_OTSU);
//形态学操作
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
morphologyEx(dst, dst, MORPH_CLOSE, kernel,Point(-1,-1),1);
morphologyEx(dst2, dst2, MORPH_CLOSE, kernel,Point(-1,-1),1);
imshow("dst", dst);
imshow("dst2", dst2);
}
catch (const std::exception& ex)
{
printf("error:%s", ex.what());
}
waitKey(0);
return 0;
}
接下来我们直接看看效果
threshold
V
S
adaptive
Threshold
上面为两种二值化的对比结果
从上面的图可以看出来,用自适应二值化后,九型人格四个字非常明显的可以看出来,不过相对的,燥点也是比较多的,后面我们在这个基础上再看看怎么样处理不必要的东西。
-END-
Vaccae的往期经典
OpenCV
《C++ OpenCV案例实战---卡号获取》
《C++ OpenCV案例实战---卡片截取(附代码)》
《C++ OpenCV透视变换---切换手机正面图片》
《C++ OpenCV实战---获取数量》
《C++ OpenCV实战---利用颜色分割获取数量》
《OpenCV4Android NDK方式进行Canny边缘检测》
《OpenCV4Android NDK方式TesserartOCR实时进行识别》
《OpenCV4Android NDK级联方式实时进行人脸检测》
《OpenCV4Android NDK稠密光流调用》
《OpenCV4Android NDK背景消除建模(新Demo附源码)》
《OpenCV4Android NDK利用SurfaceVeiw划矩形截屏存放到RecyclerView中》
Android
《Android利用SurfaceView结合科大讯飞修改语音实别UI》
《Android关于语音识别的功能实现分析(一)---结构化思维》
《Android关于语音识别的功能实现分析(二)---语义解析》
《Android根据类生成签名字符串》
《Android碎片化布局fragment的实战应用》
《Android中RecyclerView嵌套RecyclerView》
《Android里用AsyncTask后的接口回调》
.Net C#
《C#自定义特性(Attribute)讲解与实际应用》
《C#根据类生成签名字符串(附DEMO下载地址)》
《C++创建动态库C#调用》
《C#与三菱PLC(型号FX2N)串口通讯类》
《C#开源跨平台机器学习框架ML.NET----二元分类情绪分析》
《C#开源跨平台机器学习框架ML.NET----结合SqlSugar进行多类分类》
数据库及其它
《Oracel存储过程写报表实战》
《Delphi轮播视频和图片程序(用于双屏显示程序)》
《SQL随机增加销售数据的脚本编写(附脚本下载地址)》
《SQL Server中With As的介绍与应用(三)--递归的实战应用》
《Oracle通过ODBC连接SQL Server数据库》
《Oracle利用row_number()over()方式解决插入数据时重复键的问题》
请扫码
给个关注
微卡智享