Difetti di convessità C ++ OpenCv

Ti sarei grato se potessi aiutarmi con questo problema 🙂

In relazione a questa domanda cvConvexityDefects in OpenCV 2.X / C ++? , Ho lo stesso problema. Il wrapper OpenCV C ++ non ha la funzione cvConvexityDefects che appare nella versione C, quindi ho provato a scrivere la mia versione.

Parte del codice è (si noti che sia countour che hull sono vettoriali , calcolati separatamente:

CvSeq* contourPoints; CvSeq* hullPoints; CvSeq* defects; CvMemStorage* storage; CvMemStorage* strDefects; CvMemStorage* contourStr; CvMemStorage* hullStr; CvConvexityDefect *defectArray = 0; strDefects = cvCreateMemStorage(); defects = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvSeq),sizeof(CvPoint), strDefects ); //We start converting vector resulting from findContours contourStr = cvCreateMemStorage(); contourPoints = cvCreateSeq(CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), contourStr); printf("Metiendo valores\n"); for(int i=0; i<(int)contour.size(); i++) { CvPoint cp = {contour[i].x, contour[i].y}; cvSeqPush(contourPoints, &cp); } //Now, the hull points obtained from convexHull c++ hullStr = cvCreateMemStorage(0); hullPoints = cvCreateSeq(CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), hullStr); for(int i=0; i<(int)hull.size(); i++) { CvPoint cp = {hull[i].x, hull[i].y}; cvSeqPush(hullPoints, &cp); } //And we compute convexity defects storage = cvCreateMemStorage(0); defects = cvConvexityDefects(contourPoints, hullPoints, storage); 

L’output è Lo Convex hull must represented as a sequence of indices or sequence of pointers in function cvConvexityDefects . Davvero non so come fare la conversione nel modo giusto, ho cercato sul web e ho provato ad adattare / copiare / capire alcuni pezzi di codice, ma è sempre con la syntax C.

Spero di essere stato chiaro. Grazie in anticipo!

Ho sollevato questa domanda perché non ero in grado di trovare una soluzione (non è solo oggi che mi occupavo della questione hehe), ma in fin dei conti sono stato in grado di gestire il problema!

Ho dovuto cambiare il modo in cui ho calcolato lo scafo convesso, usando il modulo della matrice dell’indice. Quindi ora abbiamo un vettore invece un vettore .

Questo è il codice che ho usato (funziona, ho dipinto i punti su un’immagine):

 void HandDetection::findConvexityDefects(vector& contour, vector& hull, vector& convexDefects){ if(hull.size() > 0 && contour.size() > 0){ CvSeq* contourPoints; CvSeq* defects; CvMemStorage* storage; CvMemStorage* strDefects; CvMemStorage* contourStr; CvConvexityDefect *defectArray = 0; strDefects = cvCreateMemStorage(); defects = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvSeq),sizeof(CvPoint), strDefects ); //We transform our vector into a CvSeq* object of CvPoint. contourStr = cvCreateMemStorage(); contourPoints = cvCreateSeq(CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), contourStr); for(int i=0; i<(int)contour.size(); i++) { CvPoint cp = {contour[i].x, contour[i].y}; cvSeqPush(contourPoints, &cp); } //Now, we do the same thing with the hull index int count = (int)hull.size(); //int hullK[count]; int* hullK = (int*)malloc(count*sizeof(int)); for(int i=0; itotal); cvCvtSeqToArray(defects, defectArray, CV_WHOLE_SEQ); //printf("DefectArray %i %i\n",defectArray->end->x, defectArray->end->y); //We store defects points in the convexDefects parameter. for(int i = 0; itotal; i++){ CvPoint ptf; ptf.x = defectArray[i].depth_point->x; ptf.y = defectArray[i].depth_point->y; convexDefects.push_back(ptf); } //We release memory cvReleaseMemStorage(contourStr); cvReleaseMemStorage(strDefects); cvReleaseMemStorage(storage); } } 

Questo ha funzionato per me. Se vedi qualcosa di sbagliato o un altro modo per gestirlo, per favore dimmi!

trovato un approccio diretto usando cpp convexityDefects. Typehandling per convessoHull-function. Si riempie in base al tipo, int * restituisce gli indici, Punto * restituisce le coordinate.

 void WorkFrame( Mat img, double minArea ) { //assumption: // img already preprocessed, threshold, gray, smooth, morphology whatever.. //get some contours vector > contours; vector hierarchy; findContours( img, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); for( int i=0; i& c=contours[i]; double area = contourArea( c ); if( area ptHull1; //uncomment and compare to ptHull2 //convexHull( c, ptHull1 ); //convexHull is smart and fills direct coordinates std::vector ihull; convexHull( c, ihull ); //convexHull is smart and fills in contourIndices std::vector defects; convexityDefects( c, ihull, defects ); //expects indexed hull (internal assertion mat.channels()==1) std::vector< Point > ptHull2; std::vector::iterator ii=ihull.begin(); while( ii!=ihull.end() ) { int idx=(*ii); ptHull2.push_back( c[idx] ); ii++; } cv::polylines( mat, c, true, Scalar( 0xCC,0xCC,0xCC ), 1 ); cv::polylines( mat, ptHull2, true, Scalar( 0xFF, 0x20, 0x20 ), 1 ); std::vector::iterator d=defects.begin(); while( d!=defects.end() ) { Vec4i& v=(*d); d++; int startidx=v[0]; Point ptStart( c[startidx] ); int endidx=v[1]; Point ptEnd( c[endidx] ); int faridx=v[2]; Point ptFar( c[faridx] ); cv::circle( img, ptStart, 4, Scalar( 0x02,0x60,0xFF ), 2 ); cv::circle( img, ptEnd, 4, Scalar( 0xFF,0x60,0x02 ), 2 ); cv::circle( img, ptFar, 4, Scalar( 0x60,0xFF,0x02 ), 2 ); } } 

}