2016-11-22 72 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()'的兩次調用可能會成爲你的主要嫌疑人... –

+0

@TobySpeight他們可能是,但我認爲他們是必要的。 –

回答

0

這對我來說不是一個直方圖函數:我的結果是否應該是一個8x8x8矩陣?通常直方圖是3xNumBins。要添加,請執行直方圖[0] [red] + = k;直方圖[1] [綠色] + = K;直方圖[2] [藍色] + = K;通常k = 1,但在你的情況下,它是一個重量。也許我正在閱讀opencv錯誤。

此外,您正在做很多多餘的工作:爲什麼在平方之前的abs?當你可以乘以倒數時,不要分裂。迭代y然後x。不要使用at,而是使用指針。

+0

是的,我得到一個8x8x8矩陣,沒有關於這個值的問題。是的,我正在做一些與通常直方圖不同的東西。你對abs()是正確的。我會修好它。但我沒有得到相互的和部分的。 –

+0

@JennySimon互惠:乘以1/x要快於除以x要快得多。預先計算這些。在:使用.ptr(行)而不是at。翻轉你的循環去內循環中的列。然後每行執行一次ptr並索引myptr [col]。還要重新考慮你對sqrt的使用。你不能只用方形而不是兩根? – starmole