Convexity欠陥C ++ opencv
-
25-10-2019 - |
質問
あなたがこの問題で私を助けてくれたら、私はあなたに感謝します:)
この質問に関連しています opencv 2.x / c ++のcvconvexitydefects?, 、 私も同じ問題を抱えてる。 OpenCV C ++ラッパーには、Cバージョンに表示される関数cvconvexitydefectsがないため、独自のバージョンを作成しようとしました。
コードの一部はです(CountourとHullの両方がVector <point>であり、別々に計算されていることに注意してください。
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<Point> 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);
出力はです Convex hull must represented as a sequence of indices or sequence of pointers in function cvConvexityDefects
. 。私は本当に正しい方法で変換を行う方法がわかりません。私はウェブ上で検索して、いくつかのコードを適応/コピー/理解しようとしましたが、それは常にC構文を使用しています。
私は明確だったことを願っています。前もって感謝します!
解決
解決策を理解できなかったので、この質問を提起しました(今日だけでなく、問題を扱っていたのは今日だけではありません)が、結局、問題を管理することができました!
インデックスアレイフォームを使用して、凸式船体を計算した方法を変更する必要がありました。そのため、代わりにベクトル<int>がvector <point>になりました。
これは私が使用したコードです(画像の上にポイントをペイントしたのは機能します):
void HandDetection::findConvexityDefects(vector<Point>& contour, vector<int>& hull, vector<Point>& 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<Point> 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; i<count; i++){hullK[i] = hull.at(i);}
CvMat hullMat = cvMat(1, count, CV_32SC1, hullK);
//We calculate convexity defects
storage = cvCreateMemStorage(0);
defects = cvConvexityDefects(contourPoints, &hullMat, storage);
defectArray = (CvConvexityDefect*)malloc(sizeof(CvConvexityDefect)*defects->total);
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; i<defects->total; 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);
}
}
これは私のために働いた。何か間違ったことやそれを管理する別の方法がある場合は、教えてください!
他のヒント
CPP ConvexityDefectsを使用して、いくつかの直接的なアプローチが見つかりました。 convexhull機能によるタイプハンドリング。タイプごとに記入し、int* returns indizes、point* return soordinates。
void WorkFrame( Mat img, double minArea )
{
//assumption:
// img already preprocessed, threshold, gray, smooth, morphology whatever..
//get some contours
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours( img, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE );
for( int i=0; i<contours.size(); i++ )
{
vector<Point>& c=contours[i];
double area = contourArea( c );
if( area<minArea ){ continue; } //filter remaining noise
//convexHull works typedependent.
//std::vector<Point> ptHull1; //uncomment and compare to ptHull2
//convexHull( c, ptHull1 ); //convexHull is smart and fills direct coordinates
std::vector<int> ihull;
convexHull( c, ihull ); //convexHull is smart and fills in contourIndices
std::vector<Vec4i> defects;
convexityDefects( c, ihull, defects ); //expects indexed hull (internal assertion mat.channels()==1)
std::vector< Point > ptHull2;
std::vector<int>::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<Vec4i>::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 );
}
}
}