Defectos de convexidad C ++ OpenCv

Te agradecería si pudieras ayudarme con este problema 🙂

En relación con esta pregunta cvConvexityDefects en OpenCV 2.X / C ++? , Tengo el mismo problema. El contenedor OpenCV C ++ no tiene la función cvConvexityDefects que aparece en la versión C, así que traté de escribir mi propia versión.

Parte del código es (tenga en cuenta que tanto countour como el casco son vector , calculados por separado:

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); 

La salida es Convex hull must represented as a sequence of indices or sequence of pointers in function cvConvexityDefects . Realmente no sé cómo hacer las conversiones de la manera correcta. Busqué en la web e intenté adaptar / copiar / comprender algunos fragmentos de código, pero siempre con la syntax C.

Espero haber sido claro. ¡Gracias de antemano!

Planteé esta pregunta porque no fui capaz de encontrar una solución (no es solo hoy cuando estaba lidiando con el asunto jeje), ¡pero después de todo, pude manejar el problema!

Tuve que cambiar la forma en que calculé el casco convexo, usando la forma de matriz de índice. Entonces ahora tenemos un vector en lugar de un vector .

Este es el código que utilicé (funciona pintando los puntos sobre una imagen):

 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); } } 

Esto funcionó para mí. Si ve algo incorrecto u otra forma de gestionarlo, ¡dígamelo!

encontré un enfoque directo usando los cpp convexityDefects. Typehandling por convexHull-function. Rellena por tipo, int * devuelve indices, Point * devuelve coordenadas.

 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 ); } } 

}