有所更改,参数不求完备,但求实用。源码参考D:\source\opencv-3.4.9\samples\cpp\connected_components.cpp
【知识点】注意labels是只有0、1的矩阵(真正的二值图)。threshold的二值化其实是0和指定的数。
二值图中不同连通域显示不同的颜色,主要是connectedComponents()函数的使用。
int connectedComponents(InputArray image, OutputArray labels,int connectivity = 8, int ltype = CV_32S);
#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; Mat img; int threshval = 150; static void on_trackbar(int, void*) //滑动条回调函数 { Mat bw; threshold(img, bw, threshval, 255, THRESH_BINARY); //二值化 imshow("bw", bw);//bw是0、255的图,不是0、1的二值图。 Mat labelImage(img.size(), CV_8U);//元素全是205的与img等大单通道矩阵labelImage int nLabels = connectedComponents(bw, labelImage);//0、255的bw图变成0、1的labelImage std::vector<Vec3b> colors(nLabels); colors[0] = Vec3b(0, 0, 0);//background for (int label = 1; label < nLabels; ++label) { colors[label] = Vec3b((rand() & 255), (rand() & 255), (rand() & 255)); } Mat dst(img.size(), CV_8UC3); for (int r = 0; r < dst.rows; ++r) { for (int c = 0; c < dst.cols; ++c) { int label = labelImage.at<int>(r, c); Vec3b &pixel = dst.at<Vec3b>(r, c); pixel = colors[label]; } } imshow("Connected Components", dst); } int main(int argc, const char** argv) { img = imread("lena.jpg", IMREAD_GRAYSCALE); imshow("Image", img); namedWindow("Connected Components", WINDOW_AUTOSIZE);//先窗体,后滑动条 createTrackbar("Threshold", "Connected Components", &threshval, 255, on_trackbar); on_trackbar(threshval, 0);//先执行一次,出图。0无意义,装饰品 waitKey(0); return 0; }
【参考】