BlobContour.cpp
Go to the documentation of this file.
00001 #include "hrl_cvblobslib/BlobContour.h"
00002 #include "cxcore.h"
00003 
00004 CBlobContour::CBlobContour()
00005 {
00006         m_startPoint.x = 0;
00007         m_startPoint.y = 0;
00008         m_area = -1;
00009         m_perimeter = -1;
00010         m_contourPoints = NULL;
00011         m_moments.m00 = -1;
00012         m_contour = NULL;
00013         m_parentStorage = NULL;
00014 }
00015 CBlobContour::CBlobContour(CvPoint startPoint, CvMemStorage *storage )
00016 {
00017         m_startPoint.x = startPoint.x;
00018         m_startPoint.y = startPoint.y;
00019         m_area = -1;
00020         m_perimeter = -1;
00021         m_moments.m00 = -1;
00022 
00023         m_parentStorage = storage;
00024 
00025         m_contourPoints = NULL;
00026 
00027         // contour sequence: must be compatible with opencv functions
00028         m_contour = cvCreateSeq( CV_SEQ_ELTYPE_CODE | CV_SEQ_KIND_CURVE | CV_SEQ_FLAG_CLOSED,
00029                                          sizeof(CvContour),
00030                                          sizeof(t_chainCode),m_parentStorage);
00031 
00032 }
00033 
00034 
00036 CBlobContour::CBlobContour( CBlobContour *source )
00037 {
00038         if (source != NULL )
00039         {
00040                 *this = *source;
00041         }
00042 }
00043 
00044 CBlobContour::~CBlobContour()
00045 {
00046         // let parent blob deallocate all contour and contour point memory
00047         m_contour = NULL;
00048         m_contourPoints = NULL;
00049 }
00050 
00051 
00053 CBlobContour& CBlobContour::operator=( const CBlobContour &source )
00054 {
00055         if( this != &source )
00056         {               
00057                 m_startPoint = source.m_startPoint;
00058 
00059                 m_parentStorage = source.m_parentStorage;
00060                 
00061                 if (m_contour)
00062                 {
00063                         cvClearSeq( m_contour );
00064                 }
00065 
00066                 if (source.m_contour)
00067                 {
00068                         m_contour =     cvCloneSeq( source.m_contour, m_parentStorage);
00069                 }
00070                 
00071                 if( source.m_contourPoints )
00072                 {
00073                         if( m_contourPoints )
00074                                 cvClearSeq( m_contourPoints );
00075                         m_contourPoints = cvCloneSeq( source.m_contourPoints, m_parentStorage);
00076                 }
00077 
00078                 m_area = source.m_area;
00079                 m_perimeter = source.m_area;
00080                 m_moments = source.m_moments;
00081         }
00082         return *this;
00083 }
00084 
00085 
00099 void CBlobContour::AddChainCode(t_chainCode chaincode)
00100 {
00101         cvSeqPush(m_contour, &chaincode);
00102 }
00103 
00105 void CBlobContour::ResetChainCode()
00106 {
00107         if( m_contour )
00108         {
00109                 cvClearSeq( m_contour );
00110                 m_contour = NULL;
00111         }
00112         if( m_contourPoints )
00113         {
00114                 cvClearSeq( m_contourPoints );
00115                 m_contourPoints = NULL;
00116         }
00117 }
00118 
00133 double CBlobContour::GetPerimeter()
00134 {
00135         // is calculated?
00136         if (m_perimeter != -1)
00137         {
00138                 return m_perimeter;
00139         }
00140 
00141         if( IsEmpty() )
00142                 return 0;
00143 
00144         m_perimeter = cvContourPerimeter( GetContourPoints() );
00145 
00146         return m_perimeter;
00147 }
00148 
00163 double CBlobContour::GetArea()
00164 {
00165         // is calculated?
00166         if (m_area != -1)
00167         {
00168                 return m_area;
00169         }
00170 
00171         if( IsEmpty() )
00172                 return 0;
00173 
00174         m_area = fabs( cvContourArea( GetContourPoints() ));
00175         
00176         return m_area;
00177 }
00178 
00180 double CBlobContour::GetMoment(int p, int q)
00181 {
00182         // is a valid moment?
00183         if ( p < 0 || q < 0 || p > MAX_MOMENTS_ORDER || q > MAX_MOMENTS_ORDER )
00184         {
00185                 return -1;
00186         }
00187 
00188         if( IsEmpty() )
00189                 return 0;
00190 
00191         // it is calculated?
00192         if( m_moments.m00 == -1)
00193         {
00194                 cvMoments( GetContourPoints(), &m_moments );
00195         }
00196                 
00197         return cvGetSpatialMoment( &m_moments, p, q );
00198 
00199         
00200 }
00201 
00203 t_PointList CBlobContour::GetContourPoints()
00204 {
00205         // it is calculated?
00206         if( m_contourPoints != NULL )
00207                 return m_contourPoints;
00208 
00209         if ( m_contour == NULL || m_contour->total <= 0 )
00210         {
00211                 return NULL;
00212         }
00213 
00214         CvSeq *tmpPoints;
00215         CvSeqReader reader;
00216         CvSeqWriter writer;
00217         CvPoint actualPoint;
00218         CvRect boundingBox;
00219 
00220         // if aproximation is different than simple extern perimeter will not work
00221         tmpPoints = cvApproxChains( m_contour, m_parentStorage, CV_CHAIN_APPROX_NONE);
00222 
00223 
00224         // apply an offset to contour points to recover real coordinates
00225         
00226         cvStartReadSeq( tmpPoints, &reader);
00227 
00228         m_contourPoints = cvCreateSeq( tmpPoints->flags, tmpPoints->header_size, tmpPoints->elem_size, m_parentStorage );
00229         cvStartAppendToSeq(m_contourPoints, &writer );
00230 
00231         // also calculate bounding box of the contour to allow cvPointPolygonTest
00232         // work correctly on the generated polygon
00233         boundingBox.x = boundingBox.y = 10000;
00234         boundingBox.width = boundingBox.height = 0;
00235         
00236         for( int i=0; i< tmpPoints->total; i++)
00237         {
00238                 CV_READ_SEQ_ELEM( actualPoint, reader);
00239 
00240                 actualPoint.x += m_startPoint.x;
00241                 actualPoint.y += m_startPoint.y;
00242 
00243                 boundingBox.x = MIN( boundingBox.x, actualPoint.x );
00244                 boundingBox.y = MIN( boundingBox.y, actualPoint.y );
00245                 boundingBox.width = MAX( boundingBox.width, actualPoint.x );
00246                 boundingBox.height = MAX( boundingBox.height, actualPoint.y );
00247                 
00248                 CV_WRITE_SEQ_ELEM( actualPoint, writer );
00249         }
00250         cvEndWriteSeq( &writer );
00251         cvClearSeq( tmpPoints );
00252 
00253         // assign calculated bounding box
00254         ((CvContour*)m_contourPoints)->rect = boundingBox;
00255 
00256 
00257         return m_contourPoints;
00258 }


hrl_cvblobslib
Author(s): kelsey
autogenerated on Wed Nov 27 2013 11:32:58