opencv文字区域的提取(vs2019 & c++)

原理

我们是怎么做到检测到区域的呢?

首先,我们会注意到,文字区域和其他的图片背景很不一样。我们用膨胀处理图片,让文字变成一块块大区域,然后识别整块的轮廓,用矩形去框住这个轮廓。

这个程序分三个子函数,detect(检测),preprocess(图片预处理),findTextRegion(查找和筛选文字区域)。即main函数调用detect函数去实际完成文字区域检测。detect函数又分成preprocess和findTextRegion两个步骤来做。

#include
#include
#include
#include

using namespace cv;
using namespace std;

Mat preprocess(Mat gray)
{
    //1.Sobel算子,x方向求梯度
    Mat sobel;
    Sobel(gray, sobel, CV_8U, 1, 0, 3);

    //2.二值化
    Mat binary;
    threshold(sobel, binary, 0, 255, THRESH_OTSU + THRESH_BINARY);

    //3.膨胀和腐蚀操作核设定
    Mat element1 = getStructuringElement(MORPH_RECT, Size(30, 9));
    //控制高度设置可以控制上下行的膨胀程度,例如3比4的区分能力更强,但也会造成漏检
    Mat element2 = getStructuringElement(MORPH_RECT, Size(24, 4));

    //4.膨胀一次,让轮廓突出
    Mat dilate1;
    dilate(binary, dilate1, element2);

    //5.腐蚀一次,去掉细节,表格线等。这里去掉的是竖直的线
    Mat erode1;
    erode(dilate1, erode1, element1);

    //6.再次膨胀,让轮廓明显一些
    Mat dilate2;
    dilate(erode1, dilate2, element2);

    //7.显示中间图片
    //imshow("binary.jpg", binary);
    //imshow("dilate1.jpg", dilate1);
    //imshow("erode1.jpg", erode1);
    //imshow("dilate2.jpg", dilate2);

    return dilate2;
}


vector findTextRegion(Mat img)
{
    vector rects;
    //1.查找轮廓
    vector> contours;
    vector hierarchy;
    findContours(img, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE, Point(0, 0));

    //2.筛选那些面积小的
    for (int i = 0; i < contours.size(); i++)
    {
        //计算当前轮廓的面积
        double area = contourArea(contours[i]);

        //面积小于1000的全部筛选掉
        if (area < 1000)
            continue;

        //轮廓近似,作用较小,approxPolyDP函数有待研究
        double epsilon = 0.001 * arcLength(contours[i], true);
        Mat approx;
        approxPolyDP(contours[i], approx, epsilon, true);

        //找到最小矩形,该矩形可能有方向
        RotatedRect rect = minAreaRect(contours[i]);

        //计算高和宽
        int m_width = rect.boundingRect().width;
        int m_height = rect.boundingRect().height;

        //筛选那些太细的矩形,留下扁的
        if (m_height > m_width * 1.2)
            continue;

        //符合条件的rect添加到rects集合中
        rects.push_back(rect);

    }
    return rects;
}

void detect(Mat img)
{
    //1.转化成灰度图
    Mat gray;
    cvtColor(img, gray, CV_BGR2GRAY);

    //2.形态学变换的预处理,得到可以查找矩形的轮廓
    Mat dilation = preprocess(gray);

    //3.查找和筛选文字区域
    vector rects = findTextRegion(dilation);

    //4.用绿线画出这些找到的轮廓
    for(int i = 0; i

效果如下:

opencv文字区域的提取(vs2019 & c++)_第1张图片

opencv文字区域的提取(vs2019 & c++)_第2张图片

 

你可能感兴趣的:(opencv,opencv,图像处理)