Home | History | Annotate | Download | only in src
      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 );
     47 CvSeq* icvCutContourRaster( CvSeq* current, CvMemStorage* storage, IplImage* image );
     48 
     49 
     50 //create lists of segments of all contours from image
     51 CvSeq* 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
    121 CvSeq* 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