文字分割、使用Findcontours找文字区域。

文字分隔方法很多。最合适是聚类方法,本例在轮廓基础提取文字区域,速度在PC上最快。用Canny算子+findcontour函数可以提取目标的轮廓。轮廓提取后矩形框包围文字部分。最后对矩形进行筛选。

假设,对于下面二值化图像。

 

文字分割、使用Findcontours找文字区域。_第1张图片

过滤后的轮廓所在的矩形框基本能满足需求,直接上源码:

#include
#include
#include
using namespace cv;
using namespace std;
#define g_threshold 200;
int main(int argc, char* argv[])
{
    string input;
    Mat imageSource = imread("G:\\1.bmp", 0);
    imshow("原始图像", imageSource);
    Mat image;
    int p_threshold;
    //std::pair pair1 = cal_mean_std(imageSource.data,imageSource.rows, imageSource.cols);
    //p_threshold = (int)pair1.first;
    threshold(imageSource, image, 80,255,0);
    medianBlur(image, image, 7);
    imshow("二值化图像", image);
    int area=0;
    for (int i = 0; i < imageSource.rows; i++)
    {
        for (int j = 0; j < imageSource.cols; j++)
        {
            if (image.at(i, j) = 255) { area++; }

        }
    }
    if(area> imageSource.cols*imageSource.rows/2)
    {    bitwise_not(image, image);
    }
    //image.copyTo(imageSource);
    blur(imageSource, imageSource, cv::Size(3,3));
    Canny(imageSource, image, 80, 250,3);
    imshow("canny图像", image);
    vector> contours;
    vector hierarchy;
    findContours(image, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, Point());
    Mat imageContours = Mat::zeros(image.size(), CV_8UC1);
    Mat Contours = Mat::zeros(image.size(), CV_8UC1); //绘制
    Mat src = Mat::zeros(image.size(), CV_8UC3);
    //src.data[0] = image.data;
    int num = contours.size();
    vector boundRect(num);
    num = 0;
    for (int i = 0; i < contours.size(); i++)
    {
        //contours[i]代表的是第i个轮廓,contours[i].size()代表的是第i个轮廓上所有的像素点数
        for (int j = 0; j < contours[i].size(); j++)
        {
            //绘制出contours向量所有的像素点
            Point P = Point(contours[i][j].x, contours[i][j].y);
            Contours.at(P) = 255;
        }
        //输出hierarchy向量内容
        char ch[256];
        sprintf(ch, "%d", i);
        string str = ch;
        //cout << "向量hierarchy的第" << str << "个元素内容为:" << hierarchy[i] << endl << endl;
        //绘制轮廓
        int area = contourArea(contours[i], true);

        if (contourArea(contours[i], true) > 150 && contourArea(contours[i]) < 8000, true)
        {
            drawContours(imageContours, contours,
                i, Scalar(255), CV_FILLED, 8, hierarchy);
            Mat roi,roi2;
    

            cv::Rect rect = cv::boundingRect((cv::Mat)contours[i]);
            roi = image(rect);
            roi2 = imageContours(rect);
            boundRect[i].x = rect.x;
            boundRect[i].y = rect.y;
            boundRect[i].width = rect.width;
            boundRect[i].height = rect.height;
            if (rect.width > 20&& rect.height<200) {
                printf("%d,%d,%d,%d\t", rect.x, rect.y, rect.width, rect.height);
                num++;
                Mat roi3;
                roi.copyTo(roi3, roi2);
                ostringstream   of;
                of << "G:\\SVM-OCR\\Template\\" << i+222 << ".jpg";
                cv::resize(roi3, roi3, cv::Size(32, 32));
                cv::imwrite(of.str(), roi3);
                cv::rectangle(src, cv::Point(rect.x, rect.y), cv::Point(rect.width + rect.x, rect.height + rect.y), cv::Scalar(255), 3);
            }
        }

    }
    //cv::(src,src, imageContours);
    imshow("Contours Image rectang", src); //轮廓
    imshow("Point of Contours CV_CHAIN_APPROX_NONE", Contours); //向量contours内保存的所有轮廓点集
    waitKey(80000);
    //Mat roi = image(Contours[i]);

    return 0;
}

转载请注明:转载于CSDN windly_al

图像分割的效果如下:

文字分割、使用Findcontours找文字区域。_第2张图片

你可能感兴趣的:(文字分割、使用Findcontours找文字区域。)