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:
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):
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)
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:
simple.jpeg
has multiple grayscale values in it besides 0 and 255, most likely due to the jpeg compression.FindContours
, for the different grey levels.cv.FindContours
returns multiple linked sequences, and you have to iterate through them to get all the econtours.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)
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 contourcontours = contours.h_next()
to iterate through each contourIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With