【问题标题】:How to use watershed segmentation in opencv python如何在opencv python中使用分水岭分割
【发布时间】:2019-09-05 21:22:04
【问题描述】:

我有一个问题,即如何使用 python 中的分水岭分割单独分割该图像中的粒子。我的主要目标是通过应用过滤器中值模糊然后应用 Canny 边缘检测方法来去除噪声。

[![img = cv2.imread('sands.jpg')
img = cv2.medianBlur(img,7)
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
imo = cv2.Canny(img,140,255)][1]][1]

我想增强 Canny 边缘检测功能产生的轮廓,因为我使用这些图像检测图像中粒子的区域属性来估计面积。

【问题讨论】:

    标签: python opencv image-processing computer-vision watershed


    【解决方案1】:

    这是一种改编自blog post的方法

    • 将图像转换为灰度
    • Otsu 获取二值图像的阈值
    • 计算欧几里得距离变换
    • 执行连通分量分析
    • 应用分水岭
    • 遍历标签值并提取对象

    这是结果

    在遍历每个轮廓时,可以累积总面积

    1388903.5

    import cv2
    import numpy as np
    from skimage.feature import peak_local_max
    from skimage.morphology import watershed
    from scipy import ndimage
    
    # Load in image, convert to gray scale, and Otsu's threshold
    image = cv2.imread('1.jpg')
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
    
    # Compute Euclidean distance from every binary pixel
    # to the nearest zero pixel then find peaks
    distance_map = ndimage.distance_transform_edt(thresh)
    local_max = peak_local_max(distance_map, indices=False, min_distance=20, labels=thresh)
    
    # Perform connected component analysis then apply Watershed
    markers = ndimage.label(local_max, structure=np.ones((3, 3)))[0]
    labels = watershed(-distance_map, markers, mask=thresh)
    
    # Iterate through unique labels
    total_area = 0
    for label in np.unique(labels):
        if label == 0:
            continue
    
        # Create a mask
        mask = np.zeros(gray.shape, dtype="uint8")
        mask[labels == label] = 255
    
        # Find contours and determine contour area
        cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        cnts = cnts[0] if len(cnts) == 2 else cnts[1]
        c = max(cnts, key=cv2.contourArea)
        area = cv2.contourArea(c)
        total_area += area
        cv2.drawContours(image, [c], -1, (36,255,12), 4)
    
    print(total_area)
    cv2.imshow('image', image)
    cv2.waitKey()
    

    【讨论】:

    • 我在这一行出现错误 >>>>> 第 19 行,在 标签 = watershed(-distance_map, markers, mask=thresh)
    • 可能您没有安装scikit-image 或scipy。试试pip install scikit-image 和pip install scipy
    • 我检查并发现安装了这些包,也发现了这个错误 >>>> File "C:\Users\speedTECH\AppData\Local\Programs\Python\Python37-32\lib\site-packages \skimage\morphology\watershed.py",第 83 行,在 _validate_inputs 中标记 = np.asanyarray(markers) * 掩码 ValueError:操作数无法与形状一起广播 (2,) (2824,5092)
    • 我无法复制您的错误,它对我来说工作正常。我正在使用scipy v1.3.1、opencv-python v4.1.0.25 和 scikit-image v0.15.0
    • 可能是因为我在 Windows 10 上使用 python 32 位?
    猜你喜欢
    • 2012-07-11
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    • 2020-07-27
    • 2011-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多