OpenCV联通域检测 connectedComponentsWithStats

    技术2022-07-11  85

    文章目录

    函数介绍C++ 代码示例Python 代码示例


    函数介绍

    输入必须是单通道图像,最好是二值图

    int cv::connectedComponents ( cv::InputArrayn image, // input 8-bit single-channel 二值图 cv::OutputArray labels, // output label map int connectivity = 8, // 4- or 8-connected components int ltype = CV_32S // Output label type (CV_32S or CV_16U) ); int cv::connectedComponentsWithStats ( cv::InputArrayn image, // input 8-bit single-channel 二值图 cv::OutputArray labels, // output label map cv::OutputArray stats, // N x 5 matrix (CV_32S) of statistics: [x1, y1, width, height, area] 分别是连通域外接矩形和区域面积 cv::OutputArray centroids, // Nx2 CV_64F matrix of centroids: [cx0, cy0] 质心坐标 int connectivity = 8, // 4- or 8-connected components int ltype = CV_32S // Output label type (CV_32S or CV_16U) );

    C++ 代码示例

    参数类型: num int labels = Mat w × h CV_32S stats = Mat num × 5 CV_32S centroids = Mat num × 2 CV64F 获取随机色 vector<cv::Vec3b> getColors(int num) { int step = 256 / num; vector<int> px; for (int i = 0; i < 256; i += step) px.push_back(i); vector<cv::Vec3b> colors(num); for (int j = 0; j < 3; j++) { random_shuffle(px.begin(), px.end()); for (int i = 0; i < num; i++) { colors[i][j] = px[i]; } } return colors; } 给各个连通域上色: 只需要用到标签矩阵 labels cv::Mat labels, stats, centroids; //labels CV_32S; stats CV_32S; centroids CV64F; num = cv::connectedComponentsWithStats(img, labels, stats, centroids); auto colors = getColors(num); cv:: Mat drawing= cv::Mat(img.size(), CV_8UC3, cv::Scalar(255, 255, 255)); for (int i = 0; i < img.size().height; i++) { for (int j = 0; j < img.size().width; j++) { index = labels.at<int>(i, j); drawing.at<cv::Vec3b>(i, j) = colors[index]; } } 过滤连通域,获取目标区域的标签: 只需要用到状态矩阵 stats (和质心坐标矩阵 centroids) cv::Mat labels, stats, centroids; //labels CV_32S; stats CV_32S; centroids CV64F; num = cv::connectedComponentsWithStats(img, labels, stats, centroids); int x0, y0, x1, y1, w, h; std::cout << "符合规则的区域label: "<< std::endl; for(int k = 0; k < num; k++){ x0 = centroids.at<double>(k, 0); y0 = centroids.at<double>(k, 1); x1 = stats.at<int>(k, 0); y1= stats.at<int>(k, 1); w = stats.at<int>(k, 2); h = stats.at<int>(k, 3); printf("Comp -: (=×=) from (=,=) 质心(=,=)\n", k, w, h, x1, y1, x0, y0); if(条件1 or 条件2 or ...) continue; std::cout << k << ", "; } std::cout << std::endl;

    Python 代码示例

    获取随机色 def getColors(n): colors = np.zeros((n, 3)) colors[:, 0] = np.random.permutation(np.linspace(0, 256, n)) colors[:, 1] = np.random.permutation(colors[:, 0]) colors[:, 2] = np.random.permutation(colors[:, 1]) return colors 给各个连通域上色: 只需要用到标签矩阵 labels ccNum, labels, stats, centroids = cv.connectedComponentsWithStats(img) colors = getColors(ccNum) dst = np.ones((img.shape[0], img.shape[1], 3), dtype=np.uint8) * 255 for i in range(ccNum): dst[labels == i] = colors[i] 过滤连通域,获取目标区域的标签: 只需要用到状态矩阵 stats (和质心坐标矩阵 centroids) ccNum, labels, stats, centroids = cv.connectedComponentsWithStats(img) colors = getColors(ccNum) print("符合规则的区域label: ") for i in range(ccNum): x1, y1, width, height, count = stats[i] x0, y0 = centroids[i] # 质心坐标 if 条件1 or 条件2 or ...: continue print("符合规则的区域label: ") dst[labels == i] = colors[i]; // 可以随手上色

    参考文章: jsxyhelu: OpenCV中的新函数connectedComponentsWithStats使用

    Processed: 0.011, SQL: 9