int main( int argc, char** argv ) { if(argc < 2) { printf("Veuillez specifier l'image binaire...\n"); return; } char* filename = argv[1]; IplImage* frame = cvLoadImage(filename, 0); if(frame == NULL) { fprintf(stderr, "Erreur de lecture de l'image %s\n", filename); } Blob* blobs; int blobCount = extractBlobs(frame, NULL, &blobs); printf("%d blobs trouves\n", blobCount); int b; for(b = 0; b < blobCount; b++) { printf("Label = %d\n", blobs[b].label); printf("x = %d\n", blobs[b].box.x); } // Dessine les boites englobantes drawBoundingRects(frame, blobs, blobCount); cvSaveImage("bbox-output.pgm", frame); releaseBlobs(blobs); }
//extract blobs, get there 3D position, check which point they correspond to in HashTable void GH::getModelPointsFromImage(const cv::Mat& img, std::vector<DetectionGH> &matches) const { //get blobs vector<KeyPoint> blobs; extractBlobs(img, blobs); //plot them //for(int p=0;p<blobs.size();p++) // cv::circle(img, blobs[p].pt, (blobs[p].size - 1) / 2 + 1, cv::Scalar(255, 0, 0), -1); //get list of points from blob (will have to be removed later as just a copy of blobs) vector<Point2f> mPoints; for(unsigned int p=0;p<blobs.size();p++)mPoints.push_back(toMeters(cameraCalibration.cameraMatrix,blobs[p].pt)); //empty output vectors matches.clear(); //loop through all points for(unsigned int p=0;p<mPoints.size();p++) { //for each point need to accumulate votes from HT float votesId[nbIds]; //init all votes to 0 for(int id=0;id<nbIds;id++) votesId[id]=0; //for each point have to find the nbPtBasis closest points vector<unsigned int> idNeigbors; getClosestNeigbors(p, mPoints, idNeigbors); //for each positively oriented possible triangle in closest neigbors //define basis and project all points on it to fill HT for(unsigned int tp2=0;tp2<idNeigbors.size();tp2++) { //get index of point 2 in mVerticesDes unsigned int p2=idNeigbors[tp2]; //define first basis vector Point2f basis1= mPoints[p2]-mPoints[p]; for(unsigned int tp3=0;tp3<idNeigbors.size();tp3++) if(p2!=idNeigbors[tp3]) { unsigned int p3=idNeigbors[tp3]; //define second basis Point2f basis2= mPoints[p3]-mPoints[p]; //check direction of triangle if(testDirectionBasis(basis1,basis2)) { //put basis in a 2x2 matrix to inverse it and express all other points i this basis Matx22f tBasis(basis1.x,basis2.x,basis1.y,basis2.y); Matx22f tBasisInv=tBasis.inv(); //good basis => project all points and fill HT for(unsigned int i=0;i<mPoints.size();i++) if(i!=p && i!=p2 && i!=p3) { //project in current basis Point2f relCoord=tBasisInv*(mPoints[i]-mPoints[p]); //get bin Point2i bin=toCell(relCoord); //read HT with vote for p if(bin.x>=0 && bin.x<nbBinPerDim.x && bin.y>=0 && bin.y<nbBinPerDim.y) for(int id=0;id<nbIds;id++) votesId[id]+=HashTable[bin.x*(nbBinPerDim.y*nbIds) + bin.y*nbIds + id]; } } } } //if had votes, then find the id with max value int idPointEstim=-1; int nbVotesForId=0; for(int id=0;id<nbIds;id++) if(votesId[id]>nbVotesForId) { idPointEstim=id; nbVotesForId=votesId[id]; } //find second best id to compute discriminative power int idPointSecondBest=-1; (void)idPointSecondBest; int nbVotesForSecondBest=0; for(int id=0;id<nbIds;id++) if(id!=idPointEstim && votesId[id]>nbVotesForSecondBest) { idPointSecondBest=id; nbVotesForSecondBest=votesId[id]; } //add the point&id pair to output if id not already in list; if it is then need to check which one has most votes if(nbVotesForId>0) { std::vector<DetectionGH>::iterator it; it = find_if (matches.begin(), matches.end(), findIdInDetections(idPointEstim)); if (it != matches.end())//point exist, check which one is the best { int posInList=it-matches.begin(); if(matches[posInList].nbVotes<nbVotesForId)//if new one better than existing one, then replace it { matches[posInList].position=blobs[p].pt; matches[posInList].id=idPointEstim; matches[posInList].nbVotes=nbVotesForId; matches[posInList].discriminativePower=nbVotesForId-nbVotesForSecondBest; } } else { DetectionGH newMatch(blobs[p].pt,idPointEstim,nbVotesForId,nbVotesForId-nbVotesForSecondBest); matches.push_back(newMatch); } } } }
void playLoop(IplImage* frameBuffer[], int frameCount) { Blob* pBlobs = NULL; int pBlobCount = 0; CvMemStorage* storage = cvCreateMemStorage(0); /////////////////////////////////////////// // Etape 1: construction du modele de fond MedianModel medianModel; // Apprentissage du modele learnMedianModel(&medianModel, "../View_008", "%s/frame_%04d.jpg", frameCount, 0.95); char filename[255]; int i, pb, b; IplImage* frame = NULL, *segFrame = NULL; for(i = 0; i < frameCount; i++) { frame = frameBuffer[i]; //////////////////////////////////////////// // Etape 2: segmentation utilisant un modele segFrame = segmentMedianStdDev(frame, 2.0, &medianModel); opening(segFrame, segFrame, 3); closing(segFrame, segFrame, 3); /////////////////////////////////////////////////////////// // Etape 3: extraction des blobs et de leur caracteristiques Blob* blobs; DistMetrics m; // Extraction des blobs int blobCount = extractBlobs(segFrame, frame, &blobs, storage); if(pBlobs != NULL) { // Matrice des combinaisons de recouvrements spatiaux m.mSpatial = cvCreateMat(blobCount, pBlobCount, CV_32FC1); // Matrices des differences d'histogramme m.mHist5 = cvCreateMat(blobCount, pBlobCount, CV_32FC3); m.mHist10 = cvCreateMat(blobCount, pBlobCount, CV_32FC3); m.mHist15 = cvCreateMat(blobCount, pBlobCount, CV_32FC3); float coverage, absDiff; Blob *b1, *b2; int step = m.mSpatial->step, hstep = m.mHist5->step; for(b = 0; b < blobCount; b++) { for(pb = 0; pb < pBlobCount; pb++) { b1 = &blobs[b]; b2 = &pBlobs[pb]; coverage = percentOverlap(b1, b2); ((float*)(m.mSpatial->data.ptr + b*step))[pb] = coverage; absDiff = absDiffHistograms(&b1->h5, &b2->h5, 0); ((float*)(m.mHist5->data.ptr + b*hstep))[pb*3] = absDiff; absDiff = absDiffHistograms(&b1->h10, &b2->h10, 0); ((float*)(m.mHist10->data.ptr + b*hstep))[pb*3] = absDiff; absDiff = absDiffHistograms(&b1->h15, &b2->h15, 0); ((float*)(m.mHist15->data.ptr + b*hstep))[pb*3] = absDiff; // TODO: Faire les autres canaux } } ////////////////////////////////////////////////////////// // Etape 4: association temporelle avec le frame precedent int assocMatrix[blobCount]; association(blobs, pBlobs, &m, assocMatrix); // Transfer des identites (etiquettes) aux nouveaux blobs for(b = 0; b < blobCount; b++) { int index = assocMatrix[b]; if(index != -1) blobs[b].label = pBlobs[index].label; else blobs[b].label = generateLabel(); } } else { // Attribution d'une premiere etiquette a chaque blob for(b = 0; b < blobCount; b++) blobs[b].label = generateLabel(); } // Images binaires drawBoundingRects(segFrame, blobs, blobCount); drawLabels(segFrame, blobs, blobCount); sprintf(filename, "bbox_%04d.jpg", i); cvSaveImage(filename, segFrame); // Image originales drawBoundingRects(frame, blobs, blobCount); drawLabels(frame, blobs, blobCount); sprintf(filename, "suivi_%04d.jpg", i); cvSaveImage(filename, frame); pBlobCount = blobCount; pBlobs = blobs; } cvReleaseMemStorage(&storage); }