aa2488f832ab4a3f2142302d2cf31d701d87b5e5
[platform/upstream/opencv.git] / modules / legacy / src / extendededges.cpp
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 "precomp.hpp"
43
44 #if 0
45 //#ifdef WIN32 /* make sure it builds under Linux whenever it is included into Makefile.am or not. */
46
47 //void icvCutContour( CvSeq* current, IplImage* image );
48 CvSeq* icvCutContourRaster( CvSeq* current, CvMemStorage* storage, IplImage* image );
49
50
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 )
54 {
55     CvMemStorage* tmp_storage = cvCreateChildMemStorage( storage );
56     CvSeq* contours = 0;
57     cvFindContours( image, tmp_storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE );
58     cvZero( image );
59
60     //iterate through contours
61       //iterate through tree
62     CvSeq* current = contours;
63     int number = 0;
64     int level = 1;
65
66     CvSeq* output = 0;
67     CvSeq* tail_seq = 0;
68
69     //actually this loop can iterates through tree,
70     //but still we use CV_RETR_LIST it is not useful
71     while( current )
72     {
73         number++;
74
75         //get vertical list of segments for one contour
76         CvSeq* new_seq = icvCutContourRaster( current, storage,  image );
77
78         //add this vertical list to horisontal list
79         if( new_seq )
80         {
81             if( tail_seq )
82             {
83                 tail_seq->h_next = new_seq;
84                 new_seq->h_prev = tail_seq;
85                 tail_seq = new_seq;
86             }
87             else
88             {
89                 output = tail_seq = new_seq;
90             }
91         }
92
93         //iteration through tree
94         if( current->v_next )
95         {
96             //goto child
97             current = current->v_next;
98             level++;
99         }
100         else
101         {
102             //go parent
103             while( !current->h_next )
104             {
105                 current = current->v_prev;
106                 level--;
107                 if( !level ) break;
108             }
109
110             if( current ) //go brother
111                 current = current->h_next;
112         }
113     }
114
115     //free temporary memstorage with initial contours
116     cvReleaseMemStorage( &tmp_storage );
117
118     return output;
119 }
120
121 //makes vertical list of segments for 1 contour
122 CvSeq* icvCutContourRaster( CvSeq* current, CvMemStorage* storage, IplImage* image /*tmp image*/)
123 {
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
127
128     //approx contour by single edges
129     CvSeqReader reader;
130     CvSeqWriter writer;
131
132     int writing = 0;
133     cvStartReadSeq( current, &reader, 0 );
134     //below line just to avoid warning
135     cvStartWriteSeq( current->flags, sizeof(CvContour), sizeof(CvPoint), storage, &writer );
136
137     CvSeq* output = 0;
138     CvSeq* tail = 0;
139
140     //first pass through contour - compute number of branches at every point
141     int i;
142     for( i = 0; i < current->total; i++ )
143     {
144         CvPoint cur;
145
146         CV_READ_SEQ_ELEM( cur, reader );
147
148         //mark point
149         ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x]++;
150         assert( ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x] != 255 );
151
152     }
153
154     //second pass - create separate edges
155     for( i = 0; i < current->total; i++ )
156     {
157         CvPoint cur;
158
159         CV_READ_SEQ_ELEM( cur, reader );
160
161         //get pixel at this point
162         uchar flag = image->imageData[image->widthStep * cur.y + cur.x];
163         if( flag != 255 && flag < 3) //
164         {
165             if(!writing)
166             {
167                 cvStartWriteSeq( current->flags, sizeof(CvContour), sizeof(CvPoint), storage, &writer );
168                 writing = 1 ;
169             }
170
171             //mark point
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 );
175
176         }
177         else
178         {
179             //exclude this point from contour
180            if( writing )
181            {
182                CvSeq* newseq = cvEndWriteSeq( &writer );
183                writing = 0;
184
185                if( tail )
186                {
187                    tail->v_next = newseq;
188                    newseq->v_prev = tail;
189                    tail = newseq;
190                }
191                else
192                {
193                    output = tail = newseq;
194                }
195            }
196         }
197     }
198
199
200    if( writing ) //if were not self intersections
201    {
202        CvSeq* newseq = cvEndWriteSeq( &writer );
203        writing = 0;
204
205        if( tail )
206        {
207            tail->v_next = newseq;
208            newseq->v_prev = tail;
209            tail = newseq;
210        }
211        else
212        {
213            output = tail = newseq;
214        }
215    }
216
217
218     return output;
219
220 }
221
222
223 /*void icvCutContour( CvSeq* current, IplImage* image )
224 {
225     //approx contour by single edges
226     CvSeqReader reader;
227     CvSeqReader rev_reader;
228
229     cvStartReadSeq( current, &reader, 0 );
230
231     int64* cur_pt = (int64*)reader.ptr;
232     int64* prev_pt = (int64*)reader.prev_elem;
233
234     //search for point a in aba position
235     for( int i = 0; i < current->total; i++ )
236     {
237         CV_NEXT_SEQ_ELEM( sizeof(int64), reader );
238
239         //compare current reader pos element with old previous
240         if( prev_pt[0] == ((int64*)reader.ptr)[0] )
241         {
242             //return to prev pos
243             CV_PREV_SEQ_ELEM( sizeof(int64), reader );
244
245
246             //this point is end of edge
247             //start going both directions and collect edge
248             cvStartReadSeq( current, &rev_reader, 1 );
249
250             int pos = cvGetSeqReaderPos( &reader );
251             cvSetSeqReaderPos( &rev_reader, pos );
252
253             //walk in both directions
254             while(1);
255
256
257         }
258         int64* cur_pt = (int64*)reader.ptr;
259         int64* prev_pt = (int64*)reader.prev_elem;
260
261     }
262 }
263
264 */
265 #endif /* WIN32 */