2012-06-08 14 views
5

OpenCV C++のcv :: Momentsを使って重心を見つけようとしています。私がそれに提出する議論が何であれ、私が受け取るのはゼロです。明らかに私は何か非常に単純に間違っています。コードの出力:OpenCV C++のcv :: Momentsの使用

23 of 500 elements in unit 3 
point values 2.976444 18.248287 
matrix size 23 
moments 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 
moments 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 

とコード:

printf("%d of %d elements in unit %d\n",k,number_of_features,i); 
cv::Mat x(k, 1, cv::DataType<cv::Point2f>::type); 
k=0; 
for(int j=0;j <number_of_features;j++) { 
    if(i == labels.at<int>(j)) { 
     x.at<cv::Point2f>(k++) = samples.at<cv::Point2f>(i); 
    } 
} 
printf("point values %f %f\n", x.at<cv::Point2f>(0).x,x.at<cv::Point2f>(0).y); 
cv::Size s=x.size(); 
printf("matrix size %d\n",s.height); 
cv::Moments m=cv::moments(x); 
printf("moments %f %f %f %f %f %f %f %f\n",m.m00,m.m01,m.m20,m.m11,m.m02,m.m30,m.m21,m.m03); 
double h[7]; 
cv::HuMoments(m,h); 
printf("moments %f %f %f %f %f %f %f\n",h[0],h[1],h[2],h[3],h[4],h[5],h[6]); 

は不思議私はGoogleからの任意の同一のコードサンプルを見つけることができません。私が見ているのはCスタイルのアプローチです。

答えて

10

重心を見つけるためにモーメントを使用することは少し過剰です。 あなたはそれを行うには、次のアルゴリズムを使用することができます。

sumX = 0; sumY = 0; 
size = array_points.size; 
if(size > 0){ 

    foreach(point in array_points){ 
     sumX += point.x; 
     sumY += point.y; 
    } 

centroid.x = sumX/size; 
centroid.y = sumY/size; 
} 

かのOpenCVのboundingRectの助けを借りて:

//pseudo-code: 

Rect bRect = Imgproc.boundingRect(array_points); 

centroid.x = bRect.x + (bRect.width/2); 
centroid.y = bRect.y + (bRect.height/2); 
+0

ありがとう!まずメソッドが正常に動作していることを確認し、コードで作業していたためにバグが見つかりました。私は、 "i" が代わりに "J" を使用していました: x.at (K ++)= samples.at (J/* BUGはここにありました* /); –

3

瞬間に公式チュートリアルにアクセスすることをお勧めします。そのコードを最初に学び、実行してください。

http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/moments/moments.html#moments

それが成功したら、あなたが好きな実装しよう。

+0

まあ、それは輪郭の配列に動作しますが、私はそれがの1次元配列で作業する必要があります浮動小数点ポイント。これらの違いの何かがそれを制動します。少なくとも私はそう思う。 –

関連する問題