Reputation: 143
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.
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()
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:
Upvotes: 6
Views: 21060
Reputation: 1235
Using cv2.CC_STAT_AREA
for readability:
# Connected components with stats.
nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(image, connectivity=4)
# Find the largest non background component.
# Note: range() starts from 1 since 0 is the background label.
max_label, max_size = max([(i, stats[i, cv2.CC_STAT_AREA]) for i in range(1, nb_components)], key=lambda x: x[1])
More here: https://stackoverflow.com/a/35854198/650885
Upvotes: 2
Reputation: 4542
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.
Upvotes: 8