目的:得到每个连通域中心位置或者在图像中标记处连通域所在的矩形区域。
connectedComponentsWithStats(riceBW, out, stats, centroid,8, CV_16U);
一、输入图像 二、输出图像
三、不同连通域的统计信息矩阵,矩阵中第i行是标签为i的连通域的统计特性。
四、每个连通域质心的坐标 五、统计连通域时使用的邻域种类 4/8
六、输出图像的数据类型 CV_32S/CV_16U
步骤:
- 将图像转换成灰度图,再将灰度图二值化
- 利用connectedComponentsWithStats()函数对图像进行连通域的统计
- 根据统计结果,用不同颜色的矩形框将连通域围起来,并标记每个连通域的质心,标出连通域的标签数字,以区分不同的连通域
- 输出每个连通域的面积
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> #include<math.h> #include <opencv2/imgproc.hpp> #include<vector> using namespace cv; using namespace std; int main(int argc, char** argv) { //QuickDemo qd; //qd.myFilter_demo(src); system("color F0"); Mat img = imread("D:/images/hua.jpeg"); if (img.empty()) { cout << "请确认图像文件名称正确!" << endl; return -1; } Mat rice,riceBW; //把图像转成二值图像,同时把黑白区域互换 cvtColor(img, rice, COLOR_BGR2GRAY); //彩色-->灰度 threshold(rice, riceBW, 50, 255, THRESH_BINARY); //二值化 //生成随机颜色,用于区分不同连通域 RNG rng(10086); Mat out,stats,centroid; int number = connectedComponentsWithStats(riceBW, out, stats, centroid,8, CV_16U); //统计图像中连通域的个数 vector<Vec3b> 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 = centroid.at<double>(i, 0); int center_y = centroid.at<double>(i, 1); //矩形边框 int x = stats.at<int>(i, CC_STAT_LEFT); int y = stats.at<int>(i, CC_STAT_TOP); int w = stats.at<int>(i, CC_STAT_WIDTH); int h = stats.at<int>(i, CC_STAT_HEIGHT); int area = stats.at<int>(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", img); waitKey(0);//此时图片显示时间为一直停留。(x)为x毫秒 //destroyAllWindows(); return 0; }