文字分割、得到物體的連通區域

對於下面二值化圖像,目標將其中的文字部分提取出來。輪廓提取後矩形框包圍文字部分。

用Canny算子+findcontour函數可以提取目標的輪廓。然後對矩形進行篩選。

 

輪廓所在的矩形框基本能滿足需求,直接上源碼:

#include <opencv2//opencv.hpp>
#include <iostream>
#include <string>
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<float, float> 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<uchar>(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<vector<Point>> contours;
    vector<Vec4i> 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<cv::Rect> 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<uchar>(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

圖像分割的效果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章