//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
相关资源:JAVA上百实例源码以及开源项目