Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save CvSeq to an array

Tags:

opencv

I am a bit lost in OpenCV docs, I would like to save CvSeq returned by cvFindContours to an array, from what I understand it will return a seq of CvContour s but i couldn't find what it contains? which parts of it should I save to that later I can later I can iterate through it and say call cvBoundingRect etc.

like image 548
Hamza Yerlikaya Avatar asked Jan 18 '11 01:01

Hamza Yerlikaya


1 Answers

A CvContour is a struct with the same fields as a CvSeq, plus a few others, the most important of which is a CvRect rect (see include/opencv/cxtypes.h). So it really boils down to what a CvSeq is.

There is a file called opencv.pdf that comes with the OpenCV sources, and in p. 138 (for OpenCV 2.1) it says that CvSeq is defined as follows:

#define CV_SEQUENCE\_FIELDS()
    int flags; /* micsellaneous flags */ \
    int header_size; /* size of sequence header */ \
    struct CvSeq* h_prev; /* previous sequence */ \
    struct CvSeq* h_next; /* next sequence */ \
    struct CvSeq* v_prev; /* 2nd previous sequence */ \
    struct CvSeq* v_next; /* 2nd next sequence */ \
    int total; /* total number of elements */ \
    int elem_size;/* size of sequence element in bytes */ \
    char* block_max;/* maximal bound of the last block */ \
    char* ptr; /* current write pointer */ \
    int delta_elems; /* how many elements allocated when the sequence grows
    (sequence granularity) */ \
    CvMemStorage* storage; /* where the seq is stored */ \
    CvSeqBlock* free_blocks; /* free blocks list */ \
    CvSeqBlock* first; /* pointer to the first sequence block */

typedef struct CvSeq
{
    CV_SEQUENCE_FIELDS()
} CvSeq;

Let's say you call cvFindContours like this:

cvFindContours(img, storage, &contours, sizeof(CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

, where contours will be pointing to the first contour after calling cvFindContours. If you want to get its bounding rectangle, you simply pass it to cvBoundingRect. The next contour in the sequence can be accessed through contours->h_next. In the case of contour trees, that is, when a contour can be inside another contour in the image, you can access the first inner contour of the current contour through contours->v_next. The next inner contour, if it exists, would be contours->v_next->h_next, and so forth.

If you want to convert a sequence to an array you can use cvCvtSeqToArray.

You can also use the C++ interface starting from OpenCV 2.0 which seems to be nicer to use. For instance, the CvSeq** contours parameter to cvFindContours becomes vector<vector<Point> >& contours.

like image 164
carnieri Avatar answered Nov 26 '22 15:11

carnieri