/** - FUNCTION: CBlobGetMaxYatMinX - FUNCTIONALITY: Calculates the maximum Y on the minimum X - PARAMETERS: - RESULT: - RESTRICTIONS: - AUTHOR: Ricard Borràs - CREATION DATE: 25-05-2005. - MODIFICATION: Date. Author. Description. */ double CBlobGetMaxYatMinX::operator()(CBlob &blob) { double result = LONG_MIN; //CvSeqReader reader; //CvPoint actualPoint; t_PointList externContour; externContour = blob.GetExternalContour()->GetContourPoints(); if( externContour.size()==0 ) return result; t_PointList::iterator it=externContour.begin(),en=externContour.end(); for( it;it!=en;it++) { Point &actualPoint = *it; if( (actualPoint.x == blob.MinX()) && (actualPoint.y > result) ) { result = actualPoint.y; } } return result; }
/** - 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()(CBlob &blob) { const t_PointList &contourPoints = blob.GetExternalContour()->GetContourPoints(); if( contourPoints.size()==0 ) { return pointPolygonTest(contourPoints,m_p,false) >=0; } return 0; }
/** - FUNCTION: CBlobGetMinXatMinY - FUNCTIONALITY: Calculates the minimum X on the minimum Y - PARAMETERS: - RESULT: - RESTRICTIONS: - AUTHOR: Ricard Borràs - CREATION DATE: 25-05-2005. - MODIFICATION: Date. Author. Description. */ double CBlobGetMinXatMinY::operator()(CBlob &blob) { double result = LONG_MAX; CvSeqReader reader; CvPoint actualPoint; t_PointList externContour; externContour = blob.GetExternalContour()->GetContourPoints(); if( !externContour ) return result; cvStartReadSeq( externContour, &reader); for( int i=0; i< externContour->total; i++) { CV_READ_SEQ_ELEM( actualPoint, reader); if( (actualPoint.y == blob.MinY()) && (actualPoint.x < result) ) { result = actualPoint.x; } } return result; }
/** - FUNCIÓ: ComponentLabeling - FUNCIONALITAT: Calcula els components binaris (blobs) d'una imatge amb connectivitat a 8 - PARÀMETRES: - inputImage: image to segment (pixel values different than blobColor are treated as background) - maskImage: if not NULL, all the pixels equal to 0 in mask are skipped in input image - backgroundColor: color of background (ignored pixels) - blobs: blob vector destination - RESULTAT: - - RESTRICCIONS: - - AUTOR: rborras - DATA DE CREACIÓ: 2008/04/21 - MODIFICACIÓ: Data. Autor. Descripció. - NOTA: Algorithm based on "A linear-time component labeling algorithm using contour tracing technique", F.Chang et al */ bool ComponentLabeling( IplImage* inputImage, IplImage* maskImage, unsigned char backgroundColor, Blob_vector &blobs ) { int i,j; // row major vector with visited points bool *visitedPoints, *pVisitedPoints, internalContour, externalContour; unsigned char *pInputImage, *pMask, *pAboveInputImage, *pBelowInputImage, *pAboveMask, *pBelowMask; int imageWidth, imageHeight, currentLabel, contourLabel; // row major vector with labelled image t_labelType *labelledImage, *pLabels; //! current blob pointer CBlob *currentBlob; CvSize imageSizes; CvPoint currentPoint; // verify input image if( !CV_IS_IMAGE( inputImage ) ) return false; // verify that input image and mask image has same size if( maskImage ) { if( !CV_IS_IMAGE(maskImage) || maskImage->width != inputImage->width || maskImage->height != inputImage->height ) return false; } else { pMask = NULL; pAboveMask = NULL; pBelowMask = NULL; } imageSizes = cvSize(inputImage->width,inputImage->height); imageWidth = inputImage->width; imageHeight = inputImage->height; // create auxiliary buffers labelledImage = (t_labelType*) malloc( inputImage->width * inputImage->height * sizeof(t_labelType) ); visitedPoints = (bool*) malloc( inputImage->width * inputImage->height * sizeof(bool) ); // initialize it to 0 memset(labelledImage, 0, inputImage->width * inputImage->height * sizeof(t_labelType) ) ; memset(visitedPoints, false, inputImage->width * inputImage->height * sizeof(bool) ) ; // initialize pointers and label counter pLabels = labelledImage; pVisitedPoints = visitedPoints; currentLabel = 1; for (j = 0; j < imageHeight; j++ ) { // don't verify if we area on first or last row, it will verified on pointer access pAboveInputImage = (unsigned char*) inputImage->imageData + (j-1) * inputImage->widthStep; pBelowInputImage = (unsigned char*) inputImage->imageData + (j+1) * inputImage->widthStep; pInputImage = (unsigned char*) inputImage->imageData + j * inputImage->widthStep; if( maskImage ) { pMask = (unsigned char*) maskImage->imageData + j * maskImage->widthStep; // don't verify if we area on first or last row, it will verified on pointer access pAboveMask = (unsigned char*) maskImage->imageData + (j-1) * maskImage->widthStep; pBelowMask = (unsigned char*) maskImage->imageData + (j+1) * maskImage->widthStep; } for (i = 0; i < imageWidth; i++, pInputImage++, pMask++, pAboveInputImage++, pBelowInputImage++, pAboveMask++, pBelowMask++ ) { // ignore background pixels or 0 pixels in mask if ( (*pInputImage == backgroundColor) || (maskImage && *pMask == 0 )) { pLabels++; pVisitedPoints++; continue; } // new external contour: current label == 0 and above pixel is background if( j > 0 ) { externalContour = ((*pAboveInputImage == backgroundColor) || (maskImage && *pAboveMask == 0)) && (*pLabels == 0); } else externalContour = (*pLabels == 0); // new internal contour: below pixel is background and not visited if( !externalContour && j < imageHeight - 1 ) { internalContour = *pBelowInputImage == backgroundColor && !GET_BELOW_VISITEDPIXEL( pVisitedPoints, imageWidth); } else { internalContour = false; } if( externalContour ) { currentPoint = cvPoint(i,j); // assign label to labelled image *pLabels = currentLabel; // create new blob currentBlob = new CBlob(currentLabel, currentPoint, imageSizes ); // contour tracing with currentLabel contourTracing( inputImage, maskImage, currentPoint, labelledImage, visitedPoints, currentLabel, false, backgroundColor, currentBlob->GetExternalContour() ); // add new created blob blobs.push_back(currentBlob); currentLabel++; } else { if( internalContour ) { currentPoint = cvPoint(i,j); if( *pLabels == 0 ) { // take left neightbour value as current if( i > 0 ) contourLabel = *(pLabels - 1); } else { contourLabel = *pLabels; } if(contourLabel>0) { currentBlob = blobs[contourLabel-1]; CBlobContour newContour(currentPoint, currentBlob->GetStorage()); // contour tracing with contourLabel contourTracing( inputImage, maskImage, currentPoint, labelledImage, visitedPoints, contourLabel, true, backgroundColor, &newContour ); currentBlob->AddInternalContour( newContour ); } } // neither internal nor external contour else { // take left neightbour value as current if it is not labelled if( i > 0 && *pLabels == 0 ) *pLabels = *(pLabels - 1); } } pLabels++; pVisitedPoints++; } } // free auxiliary buffers free( labelledImage ); free( visitedPoints ); return true; }