1/*M/////////////////////////////////////////////////////////////////////////////////////// 2// 3// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4// 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. 8// 9// 10// Intel License Agreement 11// For Open Source Computer Vision Library 12// 13// Copyright (C) 2000, Intel Corporation, all rights reserved. 14// Third party copyrights are property of their respective owners. 15// 16// Redistribution and use in source and binary forms, with or without modification, 17// are permitted provided that the following conditions are met: 18// 19// * Redistribution's of source code must retain the above copyright notice, 20// this list of conditions and the following disclaimer. 21// 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. 25// 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. 28// 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. 39// 40//M*/ 41 42#include "_cvaux.h" 43 44#ifdef WIN32 /* make sure it builds under Linux whenever it is included into Makefile.am or not. */ 45 46//void icvCutContour( CvSeq* current, IplImage* image ); 47CvSeq* icvCutContourRaster( CvSeq* current, CvMemStorage* storage, IplImage* image ); 48 49 50//create lists of segments of all contours from image 51CvSeq* cvExtractSingleEdges( IplImage* image, //bw image - it's content will be destroyed by cvFindContours 52 CvMemStorage* storage ) 53{ 54 CvMemStorage* tmp_storage = cvCreateChildMemStorage( storage ); 55 CvSeq* contours = 0; 56 cvFindContours( image, tmp_storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE ); 57 cvZero( image ); 58 59 //iterate through contours 60 //iterate through tree 61 CvSeq* current = contours; 62 int number = 0; 63 int level = 1; 64 65 CvSeq* output = 0; 66 CvSeq* tail_seq = 0; 67 68 //actually this loop can iterates through tree, 69 //but still we use CV_RETR_LIST it is not useful 70 while( current ) 71 { 72 number++; 73 74 //get vertical list of segments for one contour 75 CvSeq* new_seq = icvCutContourRaster( current, storage, image ); 76 77 //add this vertical list to horisontal list 78 if( new_seq ) 79 { 80 if( tail_seq ) 81 { 82 tail_seq->h_next = new_seq; 83 new_seq->h_prev = tail_seq; 84 tail_seq = new_seq; 85 } 86 else 87 { 88 output = tail_seq = new_seq; 89 } 90 } 91 92 //iteration through tree 93 if( current->v_next ) 94 { 95 //goto child 96 current = current->v_next; 97 level++; 98 } 99 else 100 { 101 //go parent 102 while( !current->h_next ) 103 { 104 current = current->v_prev; 105 level--; 106 if( !level ) break; 107 } 108 109 if( current ) //go brother 110 current = current->h_next; 111 } 112 } 113 114 //free temporary memstorage with initial contours 115 cvReleaseMemStorage( &tmp_storage ); 116 117 return output; 118} 119 120//makes vertical list of segments for 1 contour 121CvSeq* icvCutContourRaster( CvSeq* current, CvMemStorage* storage, IplImage* image /*tmp image*/) 122{ 123 //iplSet(image, 0 ); // this can cause double edges if two contours have common edge 124 // for example if object is circle with 1 pixel width 125 // to remove such problem - remove this iplSet 126 127 //approx contour by single edges 128 CvSeqReader reader; 129 CvSeqWriter writer; 130 131 int writing = 0; 132 cvStartReadSeq( current, &reader, 0 ); 133 //below line just to avoid warning 134 cvStartWriteSeq( current->flags, sizeof(CvContour), sizeof(CvPoint), storage, &writer ); 135 136 CvSeq* output = 0; 137 CvSeq* tail = 0; 138 139 //first pass through contour - compute number of branches at every point 140 int i; 141 for( i = 0; i < current->total; i++ ) 142 { 143 CvPoint cur; 144 145 CV_READ_SEQ_ELEM( cur, reader ); 146 147 //mark point 148 ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x]++; 149 assert( ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x] != 255 ); 150 151 } 152 153 //second pass - create separate edges 154 for( i = 0; i < current->total; i++ ) 155 { 156 CvPoint cur; 157 158 CV_READ_SEQ_ELEM( cur, reader ); 159 160 //get pixel at this point 161 uchar flag = image->imageData[image->widthStep * cur.y + cur.x]; 162 if( flag != 255 && flag < 3) // 163 { 164 if(!writing) 165 { 166 cvStartWriteSeq( current->flags, sizeof(CvContour), sizeof(CvPoint), storage, &writer ); 167 writing = 1 ; 168 } 169 170 //mark point 171 if( flag < 3 ) ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x] = 255; 172 //add it to another seq 173 CV_WRITE_SEQ_ELEM( cur, writer ); 174 175 } 176 else 177 { 178 //exclude this point from contour 179 if( writing ) 180 { 181 CvSeq* newseq = cvEndWriteSeq( &writer ); 182 writing = 0; 183 184 if( tail ) 185 { 186 tail->v_next = newseq; 187 newseq->v_prev = tail; 188 tail = newseq; 189 } 190 else 191 { 192 output = tail = newseq; 193 } 194 } 195 } 196 } 197 198 199 if( writing ) //if were not self intersections 200 { 201 CvSeq* newseq = cvEndWriteSeq( &writer ); 202 writing = 0; 203 204 if( tail ) 205 { 206 tail->v_next = newseq; 207 newseq->v_prev = tail; 208 tail = newseq; 209 } 210 else 211 { 212 output = tail = newseq; 213 } 214 } 215 216 217 return output; 218 219} 220 221 222/*void icvCutContour( CvSeq* current, IplImage* image ) 223{ 224 //approx contour by single edges 225 CvSeqReader reader; 226 CvSeqReader rev_reader; 227 228 cvStartReadSeq( current, &reader, 0 ); 229 230 int64* cur_pt = (int64*)reader.ptr; 231 int64* prev_pt = (int64*)reader.prev_elem; 232 233 //search for point a in aba position 234 for( int i = 0; i < current->total; i++ ) 235 { 236 CV_NEXT_SEQ_ELEM( sizeof(int64), reader ); 237 238 //compare current reader pos element with old previous 239 if( prev_pt[0] == ((int64*)reader.ptr)[0] ) 240 { 241 //return to prev pos 242 CV_PREV_SEQ_ELEM( sizeof(int64), reader ); 243 244 245 //this point is end of edge 246 //start going both directions and collect edge 247 cvStartReadSeq( current, &rev_reader, 1 ); 248 249 int pos = cvGetSeqReaderPos( &reader ); 250 cvSetSeqReaderPos( &rev_reader, pos ); 251 252 //walk in both directions 253 while(1); 254 255 256 } 257 int64* cur_pt = (int64*)reader.ptr; 258 int64* prev_pt = (int64*)reader.prev_elem; 259 260 } 261} 262 263*/ 264#endif /* WIN32 */ 265 266 267 268 269