大家好,我是你的好朋友思创斯。今天说一说opencv 图像连通域分析,希望您对编程的造诣更进一步.
图像的连通域是指图像中具有相同像素值并且位置相邻的像素组成的区域,连通域分析是指在图像中寻找出彼此互相独立的连通域并将其标记出来。提取图像中不同的连通域是图像处理中较为常用的方法,例如在车牌识别、文字识别、目标检测等领域对感兴趣区域分割与识别。一般情况下,一个连通域内只包含一个像素值,因此为了防止像素值波动对提取不同连通域的影响,连通域分析常处理的是二值化后的图像。
int cv::connectedcomponents(
inputarray image,//待标记不同连通域的单通道图像,数据类型必须为cv_8u。
outputarray labels,//标记不同连通域后的输出图像,与输入图像具有相同的尺寸。
nt connectivity,//标记连通域时使用的邻域种类,4表示4-邻域,8表示8-邻域。
int ltype,//输出图像的数据类型,目前支持cv_32s和cv_16u两种数据类型。
int ccltype //标记连通域时使用的算法类型标志
)
是否还在为ide开发工具频繁失效而烦恼,来吧关注以下公众号获取最新激活方式。亲测可用!
【正版授权,激活自己账号】:
【官方授权 正版激活】:
#if 1// 连通域
int main()
{
//对图像进行距离变换
mat img = imread("c:\\users\473\\desktop\\opencv_images\8.png");
if (img.empty())
{
printf("could not load image....\n");
return -1;
}
mat rice, ricebw;
//将图像转成二值图像,用于统计连通域
cvtcolor(img, rice, color_bgr2gray);
threshold(rice, ricebw, 50, 255, thresh_binary);
//生成随机颜色,用于区分不同连通域
rng rng(12345);
mat out;
//统计图像中连通域的个数
int number = connectedcomponents(ricebw, out, 8, cv_16u);
vector colors;
for (int i = 0; i < number; i )
{
//使用均匀分布的随机数确定颜色
vec3b vec3 = vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
colors.push_back(vec3);
}
//以不同颜色标记出不同的连通域
mat result = mat::zeros(rice.size(), img.type());
int w = result.cols;
int h = result.rows;
for (int row = 0; row < h; row )
{
for (int col = 0; col < w; col )
{
int label = out.at(row, col);
if (label == 0) //背景的黑色不改变
{
continue;
}
result.at(row, col) = colors[label];
}
}
//显示结果
imshow("原图", img);
imshow("标记后的图像", result);
waitkey(0);
return 0;
}
#endif
int cv::connectedcomponentswithstats(
inputarray image,//必须为cv_8u
outputarray labels,//标记不同连通域后的输出图像,与输入图像具有相同的尺寸。
outputarray stats,//不同连通域的统计信息矩阵,矩阵的数据类型为cv_32s。矩阵中第i行是标签为i的连通域的统计特性,
outputarray centroids,//每个连通域的质心坐标,数据类型为cv_64f
int connectivity = 8,//标记连通域时使用的邻域种类,4表示4-邻域,8表示8-邻域,默认参数值为8
int ltype = cv_32s //输出图像的数据类型,目前只支持cv_32s和cv_16u这两种数据类型,默认参数值为cv_32s
)
#if 1 // 1.1连通域 connectedcomponentswithstats
int main()
{
//对图像进行距离变换
mat img = imread("c:\\users\473\\desktop\\opencv_images\8.png");
if (img.empty())
{
printf("could not load image....\n");
return -1;
}
imshow("原图", img);
mat rice, ricebw;
//将图像转成二值图像,用于统计连通域
cvtcolor(img, rice, color_bgr2gray);
threshold(rice, ricebw, 50, 255, thresh_binary);
//生成随机颜色,用于区分不同连通域
rng rng(10086);
mat out, stats, centroids;
//统计图像中连通域的个数
int number = connectedcomponentswithstats(ricebw, out, stats, centroids, 8, cv_16u);
vector colors;
for (int i = 0; i < number; i )
{
//使用均匀分布的随机数确定颜色
vec3b vec3 = vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
colors.push_back(vec3);
}
//以不同颜色标记出不同的连通域
mat result = mat::zeros(rice.size(), img.type());
int w = result.cols;
int h = result.rows;
for (int i = 1; i < number; i )
{
// 中心位置
int center_x = centroids.at(i, 0);
int center_y = centroids.at(i, 1);
//矩形边框
int x = stats.at(i, cc_stat_left);
int y = stats.at(i, cc_stat_top);
int w = stats.at(i, cc_stat_width);
int h = stats.at(i, cc_stat_height);
int area = stats.at(i, cc_stat_area);
// 中心位置绘制
circle(img, point(center_x, center_y), 2, scalar(0, 255, 0), 2, 8, 0);
// 外接矩形
rect rect(x, y, w, h);
rectangle(img, rect, colors[i], 1, 8, 0);
puttext(img, format("%d", i), point(center_x, center_y),
font_hershey_simplex, 0.5, scalar(0, 0, 255), 1);
cout << "number: " << i << ",area: " << area << endl;
}
//显示结果
imshow("标记后的图像", img);
waitkey(0);
return 0;
}
#endif
这文章的所属全归上面知乎的作者所有,我个人只是做个学习记录
文章由思创斯整理,转载请注明出处:https://ispacesoft.com/162948.html