Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract external contour or silhouette of image in Python

I want to extract the silhouette of an image, and I'm trying to do it using the contour function of MatplotLib. This is my code:

from PIL import Image
from pylab import *

# read image to array
im = array(Image.open('HOJA.jpg').convert('L'))

# create a new figure
figure()

# show contours with origin upper left corner
contour(im, origin='image')
axis('equal')

show()

This is my original image:

Original

And this is my result:

Contour

But I just want to show the external contour, the silhouette. Just the read lines in this example.

How can I do it? I read the documentation of the contour function, but I can't get what I want.

If you know a better way to do this in Python, please tell me! (MatplotLib, OpenCV, etc.)

like image 714
Xithias Avatar asked Nov 27 '12 14:11

Xithias


People also ask

How to find contours in an image in Python?

To find contours in an image, follow these steps: 1 Read image as grey scale image. 2 Use cv2.threshold () function to obtain the threshold image. 3 Use cv2.findContours () and pass the threshold image and necessary parameters. 4 findContours () returns contours. You can draw it on the original image or a blank image. More ...

How to extract contours from a mask image in OpenCV?

There are multiple options available such as Canny and Sobel functions and each has its merits and demerits. We will use the OpenCV “findContours ()” function for edge detection to extract all contours in the mask image. The contour with the largest area is the one corresponding to the table itself.

How to extract contours from an image using edge detection?

Now is the correct time to apply Edge Detection techniques to identify and extract desired components from the image. There are multiple options available such as Canny and Sobel functions and each has its merits and demerits. We will use the OpenCV “findContours ()” function for edge detection to extract all contours in the mask image.

How do you find the value of a contour in skimage?

We use a marching squares method to find constant valued contours in an image. In skimage.measure.find_contours, array values are linearly interpolated to provide better precision of the output contours. Contours which intersect the image edge are open; all others are closed.


1 Answers

For those who want the OpenCV solution, here it is:

ret,thresh = cv2.threshold(image,245,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

tam = 0

for contorno in contours:
    if len(contorno) > tam:
        contornoGrande = contorno
        tam = len(contorno)

cv2.drawContours(image,contornoGrande.astype('int'),-1,(0,255,0),2)

cv2.imshow('My image',image)

cv2.waitKey()
cv2.destroyAllWindows()

In this example, I only draw the biggest contour. Remember that 'image' must be a single-channel array.

You should change the parameters of the threshold function, the findContours function and the drawContours function to get what you want.

  • threshold Documentation
  • findContours Documentation
  • drawContours Documentation

I do the conversion to 'int' in the drawContours function because there is a bug in the Open CV 2.4.3 version, and if you don't do this conversion, the program breaks. This is the bug.

like image 51
Xithias Avatar answered Nov 07 '22 15:11

Xithias