连通组件扫描

介绍OpenCV里的寻找连通器的api——

connectedComponents(src,connectivity=8,ltype=cv.CV_32S)

他会返回连通的数量和连通的标签数组:

def connected_components_demo():
    src = cv.imread("D:/pythonTest/img/2.jpg")
    cv.imshow("input",src)
    src = cv.GaussianBlur(src,(3,3),0)
    grey = cv.cvtColor(src,cv.COLOR_BGR2GRAY)
    src = cv.adaptiveThreshold(grey, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 25, 5)
    cv.imshow("output",src)
    conn = cv.connectedComponents(src,connectivity=8,ltype=cv.CV_32S)
    num_labels = conn[0]
    labels = conn[1]
    color = []
    for i in range(num_labels):
        b = np.random.randint(0,256)
        g = np.random.randint(0, 256)
        r = np.random.randint(0, 256)
        color.append((b,g,r))
    color[0] = (0,0,0)

    h,w = src.shape
    image = np.zeros((h,w,3),dtype=np.uint8)
    for row in range (h):
        for col in range(w):
            image[row,col] = color[labels[row,col]]

    cv.imshow("colored label",image)

这里,我们先将一个彩色图片进行高斯模糊、转成灰度图、进行二值化。然后用连通组件对新图像进行上色。运行结果如下:

 

下面介绍一个能返回更多信息的api

connectedComponentsWithStats()

他需要输入一个二值图,然后会返回这个图中的连通器的标签数量、标签、中点、左上起点、宽高以及面积,代码如下:

#下面的这个api会返回的信息更多
    output_more = cv.connectedComponentsWithStats(src,connectivity=8,ltype=cv.CV_32S)
    num_labels = output_more[0]
    labels = output_more[1]
    states = output_more[2]
    centers = output_more[3]
    image_states = cv.cvtColor(src,cv.COLOR_GRAY2BGR)
    for i in range(num_labels):
        if i==0:
            continue
        cx,cy = centers[i]
        x,y,width,height,area = states[i]
        print(area)
        cv.rectangle(image_states,(x,y),(x+width,y+height),(0,0,255),2,8,0)
        cv.circle(image_states,(np.int(cx),np.int(cy)),2,(255,0,0),-1,8,0)
    cv.imshow("statistic",image_states)

 

于是我们就在图像上可以把每个连通器标出来:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C和OpenCV实现连通区域标记的二次扫描算法的示例代码: ``` #include <stdio.h> #include <stdlib.h> #include <opencv2/opencv.hpp> using namespace cv; using namespace std; int main(int argc, char** argv) { // Load the input image Mat image = imread("input_image.jpg", IMREAD_GRAYSCALE); // Check if the image is loaded successfully if (image.empty()) { printf("Could not open or find the image\n"); return -1; } // Threshold the image to create a binary image Mat binary_image; threshold(image, binary_image, 128, 255, THRESH_BINARY); // Create a label matrix to store the connected component labels Mat label_matrix(binary_image.size(), CV_32SC1); // Initialize the label matrix to -1 label_matrix.setTo(-1); // Define a label variable to assign to connected components int label = 0; // Perform the first pass of the algorithm to assign labels to connected components for (int i = 0; i < binary_image.rows; i++) { for (int j = 0; j < binary_image.cols; j++) { if (binary_image.at<uchar>(i, j) == 255) { // Check the neighboring pixels for labels int left_label = (j > 0) ? label_matrix.at<int>(i, j - 1) : -1; int top_label = (i > 0) ? label_matrix.at<int>(i - 1, j) : -1; if (left_label == -1 && top_label == -1) { // If there are no labels in the neighboring pixels, assign a new label label_matrix.at<int>(i, j) = label; label++; } else if (left_label != -1 && top_label == -1) { // If there is a label in the left pixel, assign it to the current pixel label_matrix.at<int>(i, j) = left_label; } else if (left_label == -1 && top_label != -1) { // If there is a label in the top pixel, assign it to the current pixel label_matrix.at<int>(i, j) = top_label; } else if (left_label != -1 && top_label != -1) { // If there are labels in both neighboring pixels, assign the minimum label to the current pixel int min_label = min(left_label, top_label); label_matrix.at<int>(i, j) = min_label; // Update the equivalence table if (left_label != top_label) { for (int k = 0; k < j; k++) { if (label_matrix.at<int>(i, k) == left_label) { label_matrix.at<int>(i, k) = top_label; } } } } } } } // Perform the second pass of the algorithm to update the labels based on the equivalence table for (int i = 0; i < binary_image.rows; i++) { for (int j = 0; j < binary_image.cols; j++) { if (label_matrix.at<int>(i, j) != -1) { label_matrix.at<int>(i, j) = label_matrix.at<int>(i, label_matrix.at<int>(i, j)); } } } // Draw the labeled regions on the original image Mat result_image = image.clone(); for (int i = 0; i < binary_image.rows; i++) { for (int j = 0; j < binary_image.cols; j++) { if (label_matrix.at<int>(i, j) != -1) { Scalar color = Scalar(rand() % 256, rand() % 256, rand() % 256); rectangle(result_image, Point(j, i), Point(j, i), color, 2); } } } // Display the result image imshow("Result Image", result_image); waitKey(0); return 0; } ``` 此代码使用OpenCV库加载输入图像,并将其阈值化为二进制图像。然后,它使用二次扫描算法将标签分配给连通组件,并更新标签以考虑等价性。最后,它在原始图像上绘制标记的区域,并显示结果图像。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值