1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
42 #include "precomp.hpp"
45 //#ifdef WIN32 /* make sure it builds under Linux whenever it is included into Makefile.am or not. */
47 //void icvCutContour( CvSeq* current, IplImage* image );
48 CvSeq* icvCutContourRaster( CvSeq* current, CvMemStorage* storage, IplImage* image );
51 //create lists of segments of all contours from image
52 CvSeq* cvExtractSingleEdges( IplImage* image, //bw image - it's content will be destroyed by cvFindContours
53 CvMemStorage* storage )
55 CvMemStorage* tmp_storage = cvCreateChildMemStorage( storage );
57 cvFindContours( image, tmp_storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE );
60 //iterate through contours
61 //iterate through tree
62 CvSeq* current = contours;
69 //actually this loop can iterates through tree,
70 //but still we use CV_RETR_LIST it is not useful
75 //get vertical list of segments for one contour
76 CvSeq* new_seq = icvCutContourRaster( current, storage, image );
78 //add this vertical list to horisontal list
83 tail_seq->h_next = new_seq;
84 new_seq->h_prev = tail_seq;
89 output = tail_seq = new_seq;
93 //iteration through tree
97 current = current->v_next;
103 while( !current->h_next )
105 current = current->v_prev;
110 if( current ) //go brother
111 current = current->h_next;
115 //free temporary memstorage with initial contours
116 cvReleaseMemStorage( &tmp_storage );
121 //makes vertical list of segments for 1 contour
122 CvSeq* icvCutContourRaster( CvSeq* current, CvMemStorage* storage, IplImage* image /*tmp image*/)
124 //iplSet(image, 0 ); // this can cause double edges if two contours have common edge
125 // for example if object is circle with 1 pixel width
126 // to remove such problem - remove this iplSet
128 //approx contour by single edges
133 cvStartReadSeq( current, &reader, 0 );
134 //below line just to avoid warning
135 cvStartWriteSeq( current->flags, sizeof(CvContour), sizeof(CvPoint), storage, &writer );
140 //first pass through contour - compute number of branches at every point
142 for( i = 0; i < current->total; i++ )
146 CV_READ_SEQ_ELEM( cur, reader );
149 ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x]++;
150 assert( ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x] != 255 );
154 //second pass - create separate edges
155 for( i = 0; i < current->total; i++ )
159 CV_READ_SEQ_ELEM( cur, reader );
161 //get pixel at this point
162 uchar flag = image->imageData[image->widthStep * cur.y + cur.x];
163 if( flag != 255 && flag < 3) //
167 cvStartWriteSeq( current->flags, sizeof(CvContour), sizeof(CvPoint), storage, &writer );
172 if( flag < 3 ) ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x] = 255;
173 //add it to another seq
174 CV_WRITE_SEQ_ELEM( cur, writer );
179 //exclude this point from contour
182 CvSeq* newseq = cvEndWriteSeq( &writer );
187 tail->v_next = newseq;
188 newseq->v_prev = tail;
193 output = tail = newseq;
200 if( writing ) //if were not self intersections
202 CvSeq* newseq = cvEndWriteSeq( &writer );
207 tail->v_next = newseq;
208 newseq->v_prev = tail;
213 output = tail = newseq;
223 /*void icvCutContour( CvSeq* current, IplImage* image )
225 //approx contour by single edges
227 CvSeqReader rev_reader;
229 cvStartReadSeq( current, &reader, 0 );
231 int64* cur_pt = (int64*)reader.ptr;
232 int64* prev_pt = (int64*)reader.prev_elem;
234 //search for point a in aba position
235 for( int i = 0; i < current->total; i++ )
237 CV_NEXT_SEQ_ELEM( sizeof(int64), reader );
239 //compare current reader pos element with old previous
240 if( prev_pt[0] == ((int64*)reader.ptr)[0] )
243 CV_PREV_SEQ_ELEM( sizeof(int64), reader );
246 //this point is end of edge
247 //start going both directions and collect edge
248 cvStartReadSeq( current, &rev_reader, 1 );
250 int pos = cvGetSeqReaderPos( &reader );
251 cvSetSeqReaderPos( &rev_reader, pos );
253 //walk in both directions
258 int64* cur_pt = (int64*)reader.ptr;
259 int64* prev_pt = (int64*)reader.prev_elem;