/*M/////////////////////////////////////////////////////////////////////////////////////// // // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // // By downloading, copying, installing or using the software you agree to this license. // If you do not agree to this license, do not download, install, // copy or use the software. // // // Intel License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000, Intel Corporation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // * Redistribution's of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // * Redistribution's in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // * The name of Intel Corporation may not be used to endorse or promote products // derived from this software without specific prior written permission. // // This software is provided by the copyright holders and contributors "as is" and // any express or implied warranties, including, but not limited to, the implied // warranties of merchantability and fitness for a particular purpose are disclaimed. // In no event shall the Intel Corporation or contributors be liable for any direct, // indirect, incidental, special, exemplary, or consequential damages // (including, but not limited to, procurement of substitute goods or services; // loss of use, data, or profits; or business interruption) however caused // and on any theory of liability, whether in contract, strict liability, // or tort (including negligence or otherwise) arising in any way out of // the use of this software, even if advised of the possibility of such damage. // //M*/ #include "_cvaux.h" #ifdef WIN32 /* make sure it builds under Linux whenever it is included into Makefile.am or not. */ //void icvCutContour( CvSeq* current, IplImage* image ); CvSeq* icvCutContourRaster( CvSeq* current, CvMemStorage* storage, IplImage* image ); //create lists of segments of all contours from image CvSeq* cvExtractSingleEdges( IplImage* image, //bw image - it's content will be destroyed by cvFindContours CvMemStorage* storage ) { CvMemStorage* tmp_storage = cvCreateChildMemStorage( storage ); CvSeq* contours = 0; cvFindContours( image, tmp_storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE ); cvZero( image ); //iterate through contours //iterate through tree CvSeq* current = contours; int number = 0; int level = 1; CvSeq* output = 0; CvSeq* tail_seq = 0; //actually this loop can iterates through tree, //but still we use CV_RETR_LIST it is not useful while( current ) { number++; //get vertical list of segments for one contour CvSeq* new_seq = icvCutContourRaster( current, storage, image ); //add this vertical list to horisontal list if( new_seq ) { if( tail_seq ) { tail_seq->h_next = new_seq; new_seq->h_prev = tail_seq; tail_seq = new_seq; } else { output = tail_seq = new_seq; } } //iteration through tree if( current->v_next ) { //goto child current = current->v_next; level++; } else { //go parent while( !current->h_next ) { current = current->v_prev; level--; if( !level ) break; } if( current ) //go brother current = current->h_next; } } //free temporary memstorage with initial contours cvReleaseMemStorage( &tmp_storage ); return output; } //makes vertical list of segments for 1 contour CvSeq* icvCutContourRaster( CvSeq* current, CvMemStorage* storage, IplImage* image /*tmp image*/) { //iplSet(image, 0 ); // this can cause double edges if two contours have common edge // for example if object is circle with 1 pixel width // to remove such problem - remove this iplSet //approx contour by single edges CvSeqReader reader; CvSeqWriter writer; int writing = 0; cvStartReadSeq( current, &reader, 0 ); //below line just to avoid warning cvStartWriteSeq( current->flags, sizeof(CvContour), sizeof(CvPoint), storage, &writer ); CvSeq* output = 0; CvSeq* tail = 0; //first pass through contour - compute number of branches at every point int i; for( i = 0; i < current->total; i++ ) { CvPoint cur; CV_READ_SEQ_ELEM( cur, reader ); //mark point ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x]++; assert( ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x] != 255 ); } //second pass - create separate edges for( i = 0; i < current->total; i++ ) { CvPoint cur; CV_READ_SEQ_ELEM( cur, reader ); //get pixel at this point uchar flag = image->imageData[image->widthStep * cur.y + cur.x]; if( flag != 255 && flag < 3) // { if(!writing) { cvStartWriteSeq( current->flags, sizeof(CvContour), sizeof(CvPoint), storage, &writer ); writing = 1 ; } //mark point if( flag < 3 ) ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x] = 255; //add it to another seq CV_WRITE_SEQ_ELEM( cur, writer ); } else { //exclude this point from contour if( writing ) { CvSeq* newseq = cvEndWriteSeq( &writer ); writing = 0; if( tail ) { tail->v_next = newseq; newseq->v_prev = tail; tail = newseq; } else { output = tail = newseq; } } } } if( writing ) //if were not self intersections { CvSeq* newseq = cvEndWriteSeq( &writer ); writing = 0; if( tail ) { tail->v_next = newseq; newseq->v_prev = tail; tail = newseq; } else { output = tail = newseq; } } return output; } /*void icvCutContour( CvSeq* current, IplImage* image ) { //approx contour by single edges CvSeqReader reader; CvSeqReader rev_reader; cvStartReadSeq( current, &reader, 0 ); int64* cur_pt = (int64*)reader.ptr; int64* prev_pt = (int64*)reader.prev_elem; //search for point a in aba position for( int i = 0; i < current->total; i++ ) { CV_NEXT_SEQ_ELEM( sizeof(int64), reader ); //compare current reader pos element with old previous if( prev_pt[0] == ((int64*)reader.ptr)[0] ) { //return to prev pos CV_PREV_SEQ_ELEM( sizeof(int64), reader ); //this point is end of edge //start going both directions and collect edge cvStartReadSeq( current, &rev_reader, 1 ); int pos = cvGetSeqReaderPos( &reader ); cvSetSeqReaderPos( &rev_reader, pos ); //walk in both directions while(1); } int64* cur_pt = (int64*)reader.ptr; int64* prev_pt = (int64*)reader.prev_elem; } } */ #endif /* WIN32 */