计算图像中圆棒的数量

时间:2017-07-01 16:16:44

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

我想用图像处理来计算图像中金属棒的数量。图像都与此类似:

image of rods

我想过使用霍夫圆形变换,但是杆不是精确的圆形,并且面上也有缺陷。另一个想法是使用分水岭算法。我采取了以下步骤:

  1. 灰度转换

  2. CLAHE增强

  3. 金字塔平均移位滤镜可消除纹理和不规则

  4. 应用高斯模糊。

  5. Otsu的Thresholding

  6. 结果:

    here

    上图是4之后,5之后

    显然,我无法将此图像用于Watershed。 然后我尝试使用一个简单的阈值处理,它可以提供更好的结果,但仍然不够准确。此外,我希望计数算法独立于所使用的图像,这意味着简单的阈值处理不会。

    我在网上搜索了检测圆形物体的算法,但它们似乎都依赖于分割或边缘检测。我不明白如何从这一点开始。我错过了一些基本的东西吗?

    编辑:基本的预处理代码:

    img = cv2.imread('testc.jpg')
    img = cv2.pyrMeanShiftFiltering(img, 21, 51)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(7,7))
    cl1 = clahe.apply(img)
    cl1 = cv2.GaussianBlur(cl1, (5,5), 1)
    ret3,thresh = cv2.threshold(cl1,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    

    流域:

    D = ndimage.distance_transform_edt(thresh)
    localMax = peak_local_max(D, indices=False, min_distance=35,
        labels=thresh)
    
    # perform a connected component analysis on the local peaks,
    # using 8-connectivity, then appy the Watershed algorithm
    markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]
    labels = watershed(-D, markers, mask=thresh)
    print("[INFO] {} unique segments found".format(len(np.unique(labels)) - 1))
    
    # loop over the unique labels returned by the Watershed
    # algorithm
    for label in np.unique(labels):
        # if the label is zero, we are examining the 'background'
        # so simply ignore it
        if label == 0:
            continue
    
        # otherwise, allocate memory for the label region and draw
        # it on the mask
        mask = np.zeros(gray.shape, dtype="uint8")
        mask[labels == label] = 255
    
        # detect contours in the mask and grab the largest one
        cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
            cv2.CHAIN_APPROX_SIMPLE)[-2]
        c = max(cnts, key=cv2.contourArea)
    
        # draw a circle enclosing the object
        ((x, y), r) = cv2.minEnclosingCircle(c)
        cv2.circle(img, (int(x), int(y)), int(r), (0, 255, 0), 2)
        cv2.putText(img, "#{}".format(label), (int(x) - 10, int(y)),
            cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
    

    Watershed算法代码我主要来自pyimagesearch我很抱歉没有给出链接,我当前只允许发布两个链接(和No Images)。

    这不是我尝试过的唯一一件事,但目前是最好的方法。

0 个答案:

没有答案