double CBlobGetHullArea::operator()(const CBlob &blob) const { if(blob.Edges() != NULL && blob.Edges()->total > 0) { CvSeq *hull = cvConvexHull2( blob.Edges(), 0, CV_CLOCKWISE, 1 ); return fabs(cvContourArea(hull)); } return blob.Perimeter(); }
/** - FUNCTION: CBlobGetHullPerimeter - FUNCTIONALITY: Calculates the convex hull perimeter of the blob - PARAMETERS: - RESULT: - returns the convex hull perimeter of the blob or the perimeter if the blob edges could not be retrieved - RESTRICTIONS: - AUTHOR: Ricard Borr� - CREATION DATE: 25-05-2005. - MODIFICATION: Date. Author. Description. */ double CBlobGetHullPerimeter::operator()(const CBlob &blob) const { if(blob.Edges() != NULL && blob.Edges()->total > 0) { CvSeq *hull = cvConvexHull2( blob.Edges(), 0, CV_CLOCKWISE, 1 ); return fabs(cvArcLength(hull,CV_WHOLE_SEQ,1)); } return blob.Perimeter(); }
/** - FUNCTION: BlobGetXYInside - FUNCTIONALITY: Calculates whether a point is inside the rectangular bounding box of a blob - PARAMETERS: - RESULT: - returns 1 if it is inside; o if not - RESTRICTIONS: - AUTHOR: Francesc Pinyol Margalef - CREATION DATE: 16-01-2006. - MODIFICATION: Date. Author. Description. */ double CBlobGetXYInside::operator()(const CBlob &blob) const { if( blob.Edges() == NULL || blob.Edges()->total == 0 ) return 0.0; // passem els punts del blob a un vector de punts de les STL CvSeqReader reader; CBlob::vectorPunts vectorEdges; CBlob::vectorPunts::iterator itEdges, itEdgesSeguent; CvPoint edgeactual; bool dinsBlob; // agafem tots els punts amb la mateixa y que l'actual cvStartReadSeq( blob.Edges(), &reader); for( int i=0; i< blob.Edges()->total; i++) { CV_READ_SEQ_ELEM( edgeactual ,reader ); if( edgeactual.y == m_p.y ) vectorEdges.push_back( edgeactual ); } if( vectorEdges.size() == 0 ) return 0.0; // ordenem el vector per les Y's i les X's d'esquerra a dreta std::sort( vectorEdges.begin(), vectorEdges.end(), CBlob::comparaCvPoint() ); // recorrem el punts del blob de la mateixa fila que el punt d'entrada // i mirem si la X del punt d'entrada est�entre dos coordenades "plenes" // del blob itEdges = vectorEdges.begin(); itEdgesSeguent = vectorEdges.begin() + 1; dinsBlob = true; while( itEdges != (vectorEdges.end() - 1) ) { if( (*itEdges).x <= m_p.x && (*itEdgesSeguent).x >= m_p.x && dinsBlob ) { vectorEdges.clear(); return 1.0; } itEdges++; itEdgesSeguent++; dinsBlob = !dinsBlob; } vectorEdges.clear(); return 0.0; }
/** - FUNCTION: CBlob - FUNCTIONALITY: Copy constructor - PARAMETERS: - RESULT: - RESTRICTIONS: - AUTHOR: Ricard Borr� - CREATION DATE: 25-05-2005. - MODIFICATION: Date. Author. Description. */ CBlob::CBlob( const CBlob &src ) { // copiem les propietats del blob origen a l'actual etiqueta = src.etiqueta; exterior = src.exterior; area = src.Area(); perimeter = src.Perimeter(); parent = src.parent; minx = src.minx; maxx = src.maxx; miny = src.miny; maxy = src.maxy; sumx = src.sumx; sumy = src.sumy; sumxx = src.sumxx; sumyy = src.sumyy; sumxy = src.sumxy; mean = src.mean; stddev = src.stddev; externPerimeter = src.externPerimeter; // copiem els edges del blob origen a l'actual CvSeqReader reader; CvSeqWriter writer; CvPoint edgeactual; // creem una sequencia buida per als edges m_storage = cvCreateMemStorage(0); edges = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvContour), sizeof(CvPoint),m_storage); cvStartReadSeq( src.Edges(), &reader); cvStartAppendToSeq( edges, &writer ); for( int i=0; i< src.Edges()->total; i++) { CV_READ_SEQ_ELEM( edgeactual ,reader); CV_WRITE_SEQ_ELEM( edgeactual , writer ); } cvEndWriteSeq( &writer ); }
/** - FUNCTION: CBlobGetMaxYatMinX - FUNCTIONALITY: Calculates the maximum Y on the minimum X - PARAMETERS: - RESULT: - RESTRICTIONS: - AUTHOR: Ricard Borr� - CREATION DATE: 25-05-2005. - MODIFICATION: Date. Author. Description. */ double CBlobGetMaxYatMinX::operator()(const CBlob &blob) const { double MaxY_at_MinX = LONG_MIN; CvSeqReader reader; CvPoint edgeactual; cvStartReadSeq(blob.Edges(),&reader); for(int j=0;j<blob.Edges()->total;j++) { CV_READ_SEQ_ELEM(edgeactual,reader); if( (edgeactual.x == blob.MinY()) && (edgeactual.y > MaxY_at_MinX) ) { MaxY_at_MinX = edgeactual.y; } } return MaxY_at_MinX; }
/** - FUNCTION: CBlobGetMaxXatMaxY - FUNCTIONALITY: Calculates the maximum X on the maximum Y - PARAMETERS: - RESULT: - RESTRICTIONS: - AUTHOR: Ricard Borr� - CREATION DATE: 25-05-2005. - MODIFICATION: Date. Author. Description. */ double CBlobGetMaxXatMaxY::operator()(const CBlob &blob) const { double MaxX_at_MaxY = LONG_MIN; CvSeqReader reader; CvPoint edgeactual; cvStartReadSeq(blob.Edges(),&reader); for(int j=0;j<blob.Edges()->total;j++) { CV_READ_SEQ_ELEM(edgeactual,reader); if( (edgeactual.y == blob.MaxY()) && (edgeactual.x > MaxX_at_MaxY) ) { MaxX_at_MaxY = edgeactual.x; } } return MaxX_at_MaxY; }
/** - FUNCTION: CopyEdges - FUNCTIONALITY: Adds the blob edges to destination - PARAMETERS: - destination: where to add the edges - RESULT: - RESTRICTIONS: - AUTHOR: Ricard Borr� - CREATION DATE: 25-05-2005. - MODIFICATION: Date. Author. Description. */ void CBlob::CopyEdges( CBlob &destination ) const { CvSeqReader reader; CvSeqWriter writer; CvPoint edgeactual; cvStartReadSeq( edges, &reader); cvStartAppendToSeq( destination.Edges(), &writer ); for( int i=0; i<edges->total; i++) { CV_READ_SEQ_ELEM( edgeactual ,reader); CV_WRITE_SEQ_ELEM( edgeactual , writer ); } cvEndWriteSeq( &writer ); }