Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extract the largest connected component using OpenCV and Python?

I am using OpenCV in Python to be able to identify only the Leaf presented on the image. I already be able to segment my image, and now I am currently stuck at "how to crop the largest component after I have detected all of them. Below is the codes, please have a look.

  1. Using scipy.ndimage, I was unable to advance after find the components:

    def undesired_objects ( image ):
        components, n = ndimage.label( image )
        components = skimage.morphology.remove_small_objects( components, min_size = 50 )
        components, n = ndimage.label( components )
        plot.imshow( components )
        plot.show()
    
  2. Using OpenCV connectedComponentsWithStats:

    def undesired_objects ( image ):
        image = image.astype( 'uint8' )
        nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(image, connectivity=4)
        sizes = stats[1:, -1]; nb_components = nb_components - 1
        min_size = 150
        img2 = np.zeros(( output.shape ))
        for i in range(0, nb_components):
            if sizes[i] >= min_size:
                img2[output == i + 1] = 255
                plot.imshow( img2 )
                plot.show()
    

However, in both approaches, I'm still getting more than one component as result. Below, you will find the binary image:

Binary Image

like image 463
Tarcisiofl Avatar asked Nov 01 '17 13:11

Tarcisiofl


People also ask

What is cv2 ConnectedComponentsWithStats?

ConnectedComponentsWithStats Method (InputArray, OutputArray, OutputArray, OutputArray, PixelConnectivity, MatType) computes the connected components labeled image of boolean image. image with 4 or 8 way connectivity - returns N, the total number of labels [0, N-1] where 0 represents the background label.

What is connected Component image processing?

Connected components labeling scans an image and groups its pixels into components based on pixel connectivity, i.e. all pixels in a connected component share similar pixel intensity values and are in some way connected with each other.


1 Answers

I would replace your code with something like this:

def undesired_objects (image):
    image = image.astype('uint8')
    nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(image, connectivity=4)
    sizes = stats[:, -1]

    max_label = 1
    max_size = sizes[1]
    for i in range(2, nb_components):
        if sizes[i] > max_size:
            max_label = i
            max_size = sizes[i]

    img2 = np.zeros(output.shape)
    img2[output == max_label] = 255
    cv2.imshow("Biggest component", img2)
    cv2.waitKey()

The loop on components now finds the component with the biggest area and displays it at the end of the loop.

Tell me if this works for you as I haven't tested it myself.

like image 150
Sunreef Avatar answered Sep 20 '22 01:09

Sunreef