2017-08-09 164 views
-1

索引和列的最大價值這是原來的MATLAB實現查找OpenCV的矩陣

function[m, p] = max2(im) 

[m1, k1] = max(im); 
[m, k2] = max(m1); 

x = k2; 
y = k1(k2); 

p = [y, x]; 

它被此功能

for r = 2.^linspace(log2(minR),log2(maxR),numSteps); 
    itestSeek = imresize(itestBase,minR/r);  
    icorr = normxcorr2(cc,itestSeek); 
    [m,p] = max2(icorr); //here 
    if (m>bestm) 
     bestp = p*r; 
     bests = ccSize*r; 
     bestm = m;   
    end; 
end; 

這裏內部使用的是我的OpenCV 3.0.0/C++實施

void Utilities::Max2(cv::Mat input_image, double& m, std::vector<int>& p) 
{ 
    std::vector<double> m1(input_image.cols); // the local maximum for each column 
    std::vector<int> k1(input_image.cols); // the index of the local maximum 
    for (int c = 0; c < input_image.cols; ++c) 
    { 
     float temp_max = input_image.at<float>(0, c); 
     int temp_index = 0; 
     for (int r = 0; r < input_image.rows; ++r) 
     { 
      if (temp_max < input_image.at<float>(r, c)) 
      { 
       temp_max = input_image.at<float>(r, c); 
       temp_index = r; 
      } 
     } 
     m1[c] = temp_max; 
     k1[c] = temp_index; 
    } 
    auto iter = std::max_element(m1.begin(), m1.end()); //max of all the local maximum; 
    m = *iter; 
    int k2 = std::distance(m1.begin(), iter); 

    double y = k1[k2]; 
    p.push_back(y); 
    p.push_back(k2); 
} 

C++函數的使用

std::vector<double> best_p; 
std::vector<double> best_s; 
for (double i = 0; i < linspace_vector.size(); i++) 
{ 
    cv::Mat i_test_seek; 
    cv::Mat i_corr; 
    double r = linspace_vector[i]; 
    double resize_factor = min_r/r; // minR/r in matlab 
    cv::resize(i_test_base, i_test_seek, cv::Size(), resize_factor, resize_factor, cv::INTER_CUBIC); 
    cv::matchTemplate(i_test_seek, cc_template, i_corr, CV_TM_CCORR_NORMED); 

    cv::imshow("i_corr", i_corr); 
    cv::waitKey(0); 
    double m; 
    std::vector<int> p; 

    Utilities::Max2(i_corr, m, p); 
    if (m> best_m) 
    { 
     best_p.clear(); 
     best_s.clear(); 
     for (int i = 0; i < p.size(); ++i) 
     { 
      best_p.push_back(p[i] * r); 
     } 
     best_s.push_back(cc_size_height * r); 
     best_s.push_back(cc_size_width * r); 
     best_m = m; 
    } 
} 

你能提出一個更有效的方法嗎? 我找到每列的局部最大值和該值的索引。

後來我找到了所有指數的全局最大值。

+3

更改標題,因爲「查找列索引」有點混亂imho – user463035818

+3

假設這是工作代碼,您的問題可能更適合https://codereview.stackexchange.com/ – user463035818

+3

如果圖像是列明智在內存中,切換內部和外部循環可以提高性能,因爲緩存未命中少。儘管編譯器可能會爲你做到這一點。 – OutOfBound

回答

1

你可以嘗試以下和基準,如果性能提高:

#include <limits> 


void Utilities::Max2(cv::Mat input_image, double& m, std::vector<int>& p) 
{ 
    m = std::numeric_limits<double>::min; 
    std::pair<int, int> temp_index = 0; 

    for (int r = 0; r < input_image.rows; ++r) 
    { 
     for (int c = 0; c < input_image.cols; ++c) 
     { 
      if (m < input_image.at<float>(r, c)) 
      { 
       m = input_image.at<float>(r, c); 
       temp_index = std::make_pair(c, r); 
      } 
     } 
    } 

    p[0] = temp_index.second; 
    p[1] = temp_index.first; 
} 
1

如果有一種方式來獲得的輸入作爲載體,可以使用獲得數山坳列,例如:

int cols = input_image.rows; 
std::vector<double> v; 
v.assign(input_image.datastart, input_image.dataend); 

然後你就可以計算在短短一氣呵成:

std::vector<double>::iterator iter = std::max_element(v.begin(), v.end()); 
double m = *iter; 
int k = std::distance(v.begin(), iter); 
int y = (int)k/cols; 
int x = k % cols; 

但是,我不知道如果將數據作爲矢量獲取是一種選擇,也不會將其轉換爲矢量。也許你可以運行,看看它如何與你的實現進行比較。

+0

你可以直接使用'Mat'迭代器。它們也處理正確的非連續矩陣 – Miki