Neglecting image noise, does the IPAN algorithm return the same “dominant points
ID: 3592177 • Letter: N
Question
Neglecting image noise, does the IPAN algorithm return the same “dominant points” as we zoom in on an object? As we rotate the object?
a. Give the reasons for your answer.
b. Try it! Use PowerPoint or a similar program to draw an “interesting” white shape on a black background. Turn it into an image and save. Resize the object Figure 8-14. Pairwise geometric histogram: every two edge segments of the enclosing polygon have an angle and a minimum and maximum distance (panel a); these numbers are encoded into a two-dimensional histogram (panel b), which is rotation-invariant and can be matched against other objects 08-R4886-AT1.indd 262 9/15/08 4:22:32 PM Exercises | 263 several times, saving each time, and reposition it via several diff erent rotations. Read it in to OpenCV, turn it into grayscale, threshold, and fi nd the contour. Th en use cvFindDominantPoints() to fi nd the dominant points of the rotated and scaled versions of the object. Are the same points found or not?
dmax dmax dmin dminExplanation / Answer
Inserting and Removing Elements char* cvSeqInsert( CvSeq* seq, int before_index, void* element = NULL ); void cvSeqRemove( CvSeq* seq, int index ); Objects can be inserted into and removed from the middle of a sequence by using cvSeqInsert() and cvSeqRemove(), respectively, but remember that these are not very fast. On average, they take time proportional to the total size of the sequence. Sequence Block Size One function whose purpose may not be obvious at f rst glance is cvSetSeqBlockSize(). Th is routine takes as arguments a sequence and a new block size, which is the size of blocks that will be allocated out of the memory store when new elements are needed in the sequence. By making this size big you are less likely to fragment your sequence across disconnected memory blocks; by making it small you are less likely to waste memory. Th e default value is 1,000 bytes, but this can be changed at any time.* void cvSetSeqBlockSize( CvSeq* seq, Int delta_elems ); Sequence Readers and Sequence Writers When you are working with sequences and you want the highest performance, there are some special methods for accessing and modifying them that (although they require a bit of special care to use) will let you do what you want to do with a minimum of over- head. Th ese functions make use of special structures to keep track of the state of what they are doing; this allows many actions to be done in sequence and the necessary f nal bookkeeping to be done only aft er the last action. For writing, this control structure is called CvSeqWriter. Th e writer is initialized with the function cvStartWriteSeq() and is “closed” with cvEndWriteSeq(). While the sequence writing is “open”, new elements can be added to the sequence with the macro CV_WRITE_ SEQ(). Notice that the writing is done with a macro and not a function call, which saves even the overhead of entering and exiting that code. Using the writer is faster than us- ing cvSeqPush(); however, not all the sequence headers are updated immediately by this macro, so the added element will be essentially invisible until you are done writing. It will become visible when the structure is completely updated by cvEndWriteSeq(). * Eff ective with the beta 5 version of OpenCV, this size is automatically increased if the sequence becomes big; hence you’ll not need to worry about it under normal circumstances. Sequences | 231 9/15/08 4:22:24 PM 08-R4886-AT1.indd 231 08-R4886-AT1.indd 231 9/15/08 4:22:24 PM
If necessary, the structure can be brought up-to-date (without actually closing the writer) by calling cvFlushSeqWriter(). void cvStartWriteSeq( int seq_flags, int header_size, int elem_size, CvMemStorage* storage, CvSeqWriter* writer ); void cvStartAppendToSeq( CvSeq* seq, CvSeqWriter* writer ); CvSeq* cvEndWriteSeq( CvSeqWriter* writer ); void cvFlushSeqWriter( CvSeqWriter* writer ); CV_WRITE_SEQ_ELEM( elem, writer ) CV_WRITE_SEQ_ELEM_VAR( elem_ptr, writer ) Th e arguments to these functions are largely self-explanatory. Th e seq_flags, header_ size, and elem_size arguments to cvStartWriteSeq() are identical to the corresponding arguments to cvCreateSeq(). Th e function cvStartAppendToSeq() initializes the writer to begin adding new elements to the end of the existing sequence seq. Th e macro CV_WRITE_ SEQ_ELEM() requires the element to be written (e.g., a CvPoint) and a pointer to the writer; a new element is added to the sequence and the element elem is copied into that new element. Putting these all together into a simple example, we will create a writer and append a hundred random points drawn from a 320-by-240 rectangle to the new sequence. CvSeqWriter writer; cvStartWriteSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage, &writer ); for( i = 0; i < 100; i++ ) { CvPoint pt; pt.x = rand()%320; pt.y = rand()%240; CV_WRITE_SEQ_ELEM( pt, writer ); } CvSeq* seq = cvEndWriteSeq( &writer ); For reading, there is a similar set of functions and a few more associated macros. void cvStartReadSeq( const CvSeq* seq, CvSeqReader* reader, int reverse = 0 ); int cvGetSeqReaderPos( CvSeqReader* reader ); void cvSetSeqReaderPos( CvSeqReader* reader, 232 | Chapter 8: Contours 9/15/08 4:22:24 PM 08-R4886-AT1.indd 232 9/15/08 4:22:24 PM 08-R4886-AT1.indd 232
int index, int is_relative = 0 ); CV_NEXT_SEQ_ELEM( elem_size, reader ) CV_PREV_SEQ_ELEM( elem_size, reader ) CV_READ_SEQ_ELEM( elem, reader ) CV_REV_READ_SEQ_ELEM( elem, reader ) Th e structure CvSeqReader, which is analogous to CvSeqWriter, is initialized with the function cvStartReadSeq(). Th e argument reverse allows for the sequence to be read either in “normal” order (reverse=0) or backwards (reverse=1). Th e function cvGetSeqReaderPos() returns an integer indicating the current location of the reader in the sequence. Finally, cvSetSeqReaderPos() allows the reader to “seek” to an arbitrary location in the sequence. If the argument is_relative is nonzero, then the index will be interpreted as a relative off set to the current reader position. In this case, the index may be positive or negative. Th e two macros CV_NEXT_SEQ_ELEM() and CV_PREV_SEQ_ELEM() simply move the reader for- ward or backward one step in the sequence. Th ey do no error checking and thus cannot help you if you unintentionally step off the end of the sequence. Th e macros CV_READ_ SEQ_ELEM() and CV_REV_READ_SEQ_ELEM() are used to read from the sequence. Th ey will both copy the “current” element at which the reader is pointed onto the variable elem and then step the reader one step (forward or backward, respectively). Th ese latter two macros expect just the name of the variable to be copied to; the address of that variable will be computed inside of the macro. Sequences and Arrays You may oft en f nd yourself wanting to convert a sequence, usually full of points, into an array. void* cvCvtSeqToArray( const CvSeq* seq, void* elements, CvSlice slice = CV_WHOLE_SEQ ); CvSeq* cvMakeSeqHeaderForArray( int seq_type, int header_size, int elem_size, void* elements, int total, CvSeq* seq, CvSeqBlock* block );
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.