2016-11-22 9 views
1

私は中心にあるヒストグラムを作成しようとしています。つまり、中央にあるRGBイメージの値が重要です。私は以下のコードを書いたが、OpenCV自身のヒストグラム関数によれば非常に遅い。これを早くする方法はありますか?OpenCVセンターベースのヒストグラム

void calc_histogram(cv::Mat& image, cv::Mat& histogram) 
{ 
int bit = 8; 
int max_value = pow(2, bit); 

int n_blue_bin = 8; 
int n_green_bin = 8; 
int n_red_bin = 8; 

int blue_width = max_value/n_blue_bin; 
int green_width = max_value/n_green_bin; 
int red_width = max_value/n_red_bin; 

int mySizes[3]={n_blue_bin, n_green_bin, n_red_bin}; 
histogram = Mat::zeros(3,mySizes,CV_32F); 

int blue, green, red; 
int blue_bin, green_bin, red_bin; 

float k, length; 
float max_length = sqrt((image.rows/2)*(image.rows/2) + (image.cols/2)*(image.cols/2)); 

for(int i = 0 ; i < image.rows ; i++) 
{ 
    for(int j = 0 ; j < image.cols ; j++) 
    { 
     length = sqrt(abs(image.rows/2 - i)*abs(image.rows/2 - i) + abs(image.cols/2 - j)*abs(image.cols/2 - j))/max_length; 
     k = sqrt(1-length); 

     Vec3b intensity = image.at<Vec3b>(i, j); 
     blue = intensity.val[0]; 
     green = intensity.val[1]; 
     red = intensity.val[2]; 

     blue_bin = blue/blue_width; 
     green_bin = green/green_width; 
     red_bin = red/red_width; 
     histogram.at<float>(blue_bin, green_bin, red_bin) += k; 
    } 
} 
} 
+0

コードをプロファイリングしましたか?それは通常、良いスタートです。私はあなたの内部ループの 'sqrt()'への2回の呼び出しが、あなたが行うときに主な疑いがある可能性が高いと考えています。 –

+0

@TobySpeightおそらくそうですが、彼らは必要だと思います。 –

答えて

0

これはヒストグラム関数として私を正しく見なしません。結果は実際に8x8x8行列ですか?通常、ヒストグラムは3xNumBinsです。追加するには、ヒストグラムを行います[0] [赤] + = k;ヒストグラム[1] [緑] + = k;ヒストグラム[2] [青] + = k;通常k = 1ですが、あなたの場合はそれが重みです。多分私はopencvを間違って読んでいるかもしれません。

また、あなたは余分な仕事をたくさんしています:なぜ二乗する前にabsですか?相互に乗算できるときは決して分割しないでください。 yとxを繰り返します。 atを使用せず、代わりにポインタを取得します。

+0

はい、私は8x8x8の行列を求めていますが、値については問題ありません。はい、私はいつものヒストグラムとは違う何かをしています。そしてあなたはabs()について正しいです。私はそれを修正します。しかし、私はその逆もまた一部を得ていませんでした。 –

+0

@JennySimon相互:1/xをxで割るよりもずっと速くなります。それらを事前計算する。 at:の代わりに.ptr(行)を使用してください。ループを反転させて内側ループの列に移動します。次に、行ごとにptrを実行し、myptr [col]を索引付けします。また、sqrtの使用を再考してください。 2つの根の代わりに正方形の長さを使うことはできませんか? – starmole

関連する問題