OpenCV二值化adaptiveThreshold与threshold的对比

前一篇文章《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 <opencv2/opencv.hpp>
#include <iostream>


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()方式解决插入数据时重复键的问题

 

请扫码

给个关注

微卡智享

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vaccae

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值