Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does result of 'list(contour)' denote?

I was just trying to understand what a contour means and what is the values stored when we create a contour using cv.FindContours function in OpenCV ( I am using OpenCV 2.3.1 and Python). I used following simple image for test:

enter image description here

After contour finding,i applied following commands in ipython:

In [8]: contour
Out[8]: <cv2.cv.cvseq at 0x90a31a0>

In [10]: list(contour)
Out[10]: 
 [(256, 190),
  (255, 191),
  (112, 191),
  (255, 191),
  (256, 190),
  (257, 191),
  (257, 190)]

First command says, contour is an cvSeq object.

I marked these points on the image, which give me following image(red marked circles are the points):

enter image description here

I don't understand what does it means.

So my question is what does the values in the result of second command (ie, list(contour)) denotes?


EDIT: Following is the code i used.

import cv
img = cv.LoadImage('simple.jpeg')
imgg = cv.LoadImage('simple.jpeg',cv.CV_LOAD_IMAGE_GRAYSCALE)
storage = cv.CreateMemStorage(0)
contours = cv.FindContours(imgg,storage,cv.CV_RETR_TREE,cv.CV_CHAIN_APPROX_SIMPLE,(0,0))
print list(contours)
for i in list(contours):
    cv.Circle(img,i,5,(0,0,255),1)
cv.ShowImage('img',img)
cv.WaitKey(0)
like image 416
Abid Rahman K Avatar asked Feb 22 '23 16:02

Abid Rahman K


1 Answers

Ok, I've had a look at your picture, and you are getting the vertices of each region. It took me a while to work out because I use the cv2 interface not the cv one.

A few things:

  • your input image simple.jpeg has multiple grayscale values in it besides 0 and 255, most likely due to the jpeg compression.
  • hence, you get multiple regions out of your FindContours, for the different grey levels.
  • cv.FindContours returns multiple linked sequences, and you have to iterate through them to get all the econtours.
  • The contour that you get out for your example is one of the border ones.

To demonstrate let's draw all the contours.

contours = cv.FindContours(imgg,storage,cv.CV_RETR_TREE,cv.CV_CHAIN_APPROX_SIMPLE,(0,0))
colours = [ (0,255,0,0),   # green
            (255,0,0,0),   # blue
            (255,255,0,0), # cyan
            (0,255,255,0), # yellow
            (255,0,255,0), # magenta
            (0,0,255,0)]   # red 
i=0
while contours:
    cv.DrawContours(img, contours, colours[i], colours[i], 0, thickness=-1)
    i = (i+1) % len(colours)
    contours = contours.h_next() # go to next contour
cv.ShowImage('img',img)
cv.WaitKey(0)

contours drawn

So we see that the first contour you had with list(contours) in your original question is that small green strip down the bottom of the square, and the points you got correspond to its vertices.

The reason there are all these weirdo tiny contours around th edges of the rectangle and in the corners are because (I'd guess) of compression artefacts introduced by saving your image as a JPEG, which is lossy. If you saved your square with a lossless format (say PNG or TIFF) you'd get just one contour being defined by the corners of the rectangle.

Lessons learned:

  • cv.FindContours does give the "vertices" of each contour
  • you need contours = contours.h_next() to iterate through each contour
  • if you save as JPEG expect artefacts! Use TIFF/PNG/something lossless instead!
like image 87
mathematical.coffee Avatar answered Mar 07 '23 13:03

mathematical.coffee