Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you delete a cvseq in OpenCV?

Tags:

c++

c

opencv

Bradski states that "When you want to delete a sequence, you can use cvClearSeq(), a routine that clears all elements of the sequence."

HOWEVER, this function does not return allocated blocks in the memory store to either the store or to the system.

He says that "If you want to retrieve that memory for some other purpose, you must clear the memory store via cvClearMemStore()".

This function does not appear to exist:

error C3861: 'cvClearMemStore': identifier not found

In the errata for the book, it states that: " 'cvClearMemStore' should be 'cvClearMemStorage' " but this function expects a pointer to CvMemStorage, not CvSeq.

error C2664: 'cvClearMemStorage' : cannot convert parameter 1 from 'CvSeq *' to 'CvMemStorage *' 

Any ideas?

like image 267
kylestephens Avatar asked May 10 '11 14:05

kylestephens


2 Answers

I'm convinced that he meant cvClearMemStorage():

Clears memory storage. This is the only way(!!!) (besides cvRestoreMemStoragePos) to reuse memory allocated for the storage - cvClearSeq,cvClearSet ... do not free any memory. A child storage returns all the blocks to the parent when it is cleared.

Text copied from the header: core/core_c.h

As you can tell from the error, you are passing the wrong data type to this function. Check the docs of these functions to know exactly how to call them.

I'll try to illustrate with the code below:

// Create variable to hold the memory allocated for calculations
CvMemStorage* storage = 0;

// Allocate the memory storage. Param 0 will set the block size to a default value - currently it is about 64K.
storage = cvCreateMemStorage(0);

IplImage* gray = NULL; 
// <insert code to load a gray image here>

/* Retrieves contours from the binary image and returns the number of retrieved contours.
 * cvFindContours will scan through the image and store connected contours in "storage".
 * "contours" will point to the first contour detected.
 */
CvSeq* contours = 0;
cvFindContours(gray, storage, &contours );

// Clear the memory storage which was used before
cvClearMemStorage(storage);

// Release memory
cvReleaseMemStorage(&storage);

There are a few tutorials out there that shows the use of cvSeq. I found this one quite interesting. There's a link to the source code at the bottom of the post.

like image 88
karlphillip Avatar answered Oct 06 '22 09:10

karlphillip


It looks like the CVMemStorage structure is used as a basic low-level structure to create space to store things.

It says about CvMemStorage:

Memory storage is a low-level structure used to store dynamicly growing data structures such as sequences, contours, graphs, subdivisions, etc.

Your struct cvSeq contains a pointer to a CVMemStorage to tell it where it is stored.

#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 */ \  //HERE!!! pointer to storage
    CvSeqBlock* free_blocks; /* free blocks list */ \
    CvSeqBlock* first; /* pointer to the first sequence block */

typedef struct CvSeq
{
    CV_SEQUENCE_FIELDS()
} CvSeq;

So you'd need to call CvClearMemStorage and pass the pointer to the CvMemStorage of your cvSeq object to it, which will clear the storage for your CvSeq object.

It is really nicely explained on this page.

like image 30
Tony The Lion Avatar answered Oct 06 '22 10:10

Tony The Lion