OpenCV二值化adaptiveThreshold与threshold的对比

2019-10-28 17:33:46 浏览数 (1)

前一篇文章《Android划矩形截屏并加入OCR识别》在安卓中我们做了划矩形截图进行OCR实识,其中只是简单的进行了二值化的处理然后就传入图片识别,本来计划把图片二值化后做一些透视变换的Demo可以增加识别的效果,然后就出来了今天的文章。

样版原图

我自己照了一张素材图片,本来要进行处理的,如上图九型人格的字,照完后其实可以看到,上图中由于拍照的角度问题,有至少三分之一的面积是书封皮的反光。

threshold效果

我自己常用的二值化函数,因为里面有THRESH_OTSU自动阈值 ,觉得挺方便,使用效果也不错,就直接在程序中用了,结果就出来了一面的效果。

从上面可以看出来,我们如果要进行OCR识别,这样的效果估计只能认出“格”这个字,而九型人三个字都已经无法识别了。

遇到这个情况时,就只能回去补初级知识,看到了自适应二值化adaptiveThreshold函数,最初开始学的时候只是了解了一下,因为里面的有些值需要自己设,觉得麻烦,所以就一直没有在意。所以今天我们就来重新认识下这个函数。

adaptiveThreshold

代码语言:javascript复制
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表示与算法有关的参数,它是一个从均值或加权均值提取的常数,可以是负数。

代码演示

我们直接对源图进行普通二值化和自适应二值化的使用,做一个对比,前面加入了灰度,高斯模糊,二值化后的形态学操作,最后再输出显示图片。

代码语言:javascript复制
#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-

0 人点赞