pythonopencvobject-detectioncontourcanny-operator

I am getting fractional artifacts (pieces of metal) instead of whole ones. It seems that the edges are not continuous but they are


My goal is to detect objects placed on a white surface. From there, count how many there are and calculate the area of each one.

It seems that this algorithm is detecting its edge but counting it as multiple objects.

original picture

picture after edge detection

part of the picture with problems

results

In short, I am using "canny" and "connected components" and I am getting fractional objects instead just a whole object.


Solution

  • Following code should do the job, you might need to tweak minItemArea and maxItemArea to filter objects.

    import numpy as np
    import cv2
    import matplotlib.pyplot as plt
    
    rgb = cv2.imread('/path/to/your/image/items_0001.png')
    gray = cv2.cvtColor(rgb, cv2.COLOR_BGR2GRAY)
    
    imh, imw = gray.shape
    
    th = cv2.adaptiveThreshold(gray,255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY_INV,21,5)
    
    contours, hier = cv2.findContours(th.copy(),cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
    
    out_img = rgb.copy()
    minItemArea = 50
    maxItemArea = 4000
    
    for i in range(len(contours)):
        if hier[0][i][3] != -1:
            continue
            
        x,y,w,h = cv2.boundingRect(contours[i])
        if minItemArea < w*h < maxItemArea:
            cv2.drawContours(out_img, [contours[i]], -1, 255, 1)
    
    plt.imshow(out_img)
    

    Contours of Items