opencv对手写数字进行无黏连切割

//src:待分割的二值图,最大值为255
//segMat:分割好的每个图片
//算法:判断连通域,有几个连通域就会分割成几个子图片
//用途:手写数字识别中进行无黏连数字的分割
void getConnectedDomain(cv::Mat &src, vector<cv::Mat>& segMat)//segMat为最终结果,存放分割好的每个数字  
{
    int img_row = src.rows;
    int img_col = src.cols;
    cv::Mat flag = cv::Mat::zeros(cv::Size(img_col, img_row), CV_8UC1);//标志矩阵,为0则当前像素点未访问过

    for (int i = 0; i < img_row; i++)
    {
        for (int j = 0; j < img_col; j++)
        {
            if (src.ptr<uchar>(i)[j] == 255 && flag.ptr<uchar>(i)[j] == 0)
            {
                cv::Mat subMat = cv::Mat::zeros(cv::Size(img_col, img_row), CV_8UC1);//表明子图
                stack<cv::Point2f> cd;
                cd.push(cv::Point2f(j, i));
                flag.ptr<uchar>(i)[j] = 1;
                subMat.ptr<uchar>(i)[j] = 255;

                while (!cd.empty())
                {
                    cv::Point2f tmp = cd.top();

                    cd.pop();
                    cv::Point2f p[4];//邻域像素点,这里用的四邻域  
                    p[0] = cv::Point2f(tmp.x - 1 > 0 ? tmp.x - 1 : 0, tmp.y);
                    p[1] = cv::Point2f(tmp.x + 1 < img_col - 1 ? tmp.x + 1 : img_row - 1, tmp.y);
                    p[2] = cv::Point2f(tmp.x, tmp.y - 1 > 0 ? tmp.y - 1 : 0);
                    p[3] = cv::Point2f(tmp.x, tmp.y + 1 < img_row - 1 ? tmp.y + 1 : img_row - 1);
                    for (int m = 0; m < 4; m++)
                    {
                        int x = p[m].y;
                        int y = p[m].x;
                        if (src.ptr<uchar>(x)[y] == 255 && flag.ptr<uchar>(x)[y] == 0)//如果未访问,则入栈,并标记访问过该点  
                        {
                            cd.push(p[m]);
                            flag.ptr<uchar>(x)[y] = 1;
                            subMat.ptr<uchar>(x)[y] = 255;
                        }
                    }
                }
                segMat.push_back(subMat);
            }
        }
    }
}
原文地址:https://www.cnblogs.com/shixisheng/p/9184940.html