这是最初的MATLAB实现
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;
}
}
你能建议一种更有效的方法吗? 我找到每列的局部最大值和该值的索引。
后来我发现所有指数的全局最大值。
答案 0 :(得分: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 :(得分:1)
如果有办法将输入作为矢量获取,您可以获取数字col列,例如使用:
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;
但是,我不确定将数据作为矢量获取是一种选择,也不确定将其转换为矢量的性能。也许你可以运行,看看它与你的实现相比如何。
答案 2 :(得分:1)
第一段代码本质上是在我的理解中找到图像中的最大值及其索引(x和y)。
function[m, p] = max2(im)
[m1, k1] = max(im); %find the max value in each col
[m, k2] = max(m1); %find the max value among maxes
x = k2; %find the "row" of the max value
y = k1(k2); %and its "col"
p = [y, x];
这可以通过一些迭代来完成,但是迭代总是比矢量操作或Opencv函数慢得多。
因此,如果我的理解是正确的,则只需执行以下操作即可
double minVal, maxVal;
Point minLoc, maxLoc;
minMaxLoc(im, &minVal, &maxVal, &minLoc, &maxLoc);
maxLoc.y
将显示行,maxLoc.x
将显示行。
更新:您的Matlab代码也可以简化(可能也会加快速度)
[mx, ind] = max(im(:));
p = [rem(ind,size(im,1)) ceil(ind/size(im,1))];
答案 3 :(得分:0)
您还可以尝试以下操作:
// creating a random matrix with 2 rows and 4 columns
Mat1d mat(2, 4);
double low = -7000.0; // minimum value for generating random numbers
double high = +7000.0; // maximum value for generating random numbers
randu(mat, Scalar(low), Scalar(high)); // generating random number matrix
double max_element = *std::max_element(mat.begin(),mat.end()); // get the max element in the matrix
int max_element_index = std::max_element(mat.begin(),mat.end()) - mat.begin(); // get the max_element_index from the matrix`
最大元素索引是从0到矩阵中的项目数(在本例中为7)的行主要订单值。
cout << mat << endl;
cout << max_element << endl;
cout << max_element_index << endl;