1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_TEST_REF_REDUCE_ARG_HPP
#define OPENCV_TEST_REF_REDUCE_ARG_HPP
#include "opencv2/core/detail/dispatch_helper.impl.hpp"
#include <algorithm>
#include <numeric>
namespace cvtest {
template <class Cmp, typename T>
struct reduceMinMaxImpl
{
void operator()(const cv::Mat& src, cv::Mat& dst, const int axis) const
{
Cmp cmp;
std::vector<int> sizes(src.dims);
std::copy(src.size.p, src.size.p + src.dims, sizes.begin());
std::vector<cv::Range> idx(sizes.size(), cv::Range(0, 1));
idx[axis] = cv::Range::all();
const int n = std::accumulate(begin(sizes), end(sizes), 1, std::multiplies<int>());
const std::vector<int> newShape{1, src.size[axis]};
for (int i = 0; i < n ; ++i)
{
cv::Mat sub = src(idx);
auto begin = sub.begin<T>();
auto it = std::min_element(begin, sub.end<T>(), cmp);
*dst(idx).ptr<int32_t>() = static_cast<int32_t>(std::distance(begin, it));
for (int j = static_cast<int>(idx.size()) - 1; j >= 0; --j)
{
if (j == axis)
{
continue;
}
const int old_s = idx[j].start;
const int new_s = (old_s + 1) % sizes[j];
if (new_s > old_s)
{
idx[j] = cv::Range(new_s, new_s + 1);
break;
}
idx[j] = cv::Range(0, 1);
}
}
}
};
template<template<class> class Cmp>
struct MinMaxReducer{
template <typename T>
using Impl = reduceMinMaxImpl<Cmp<T>, T>;
static void reduce(const Mat& src, Mat& dst, int axis)
{
axis = (axis + src.dims) % src.dims;
CV_Assert(src.channels() == 1 && axis >= 0 && axis < src.dims);
std::vector<int> sizes(src.dims);
std::copy(src.size.p, src.size.p + src.dims, sizes.begin());
sizes[axis] = 1;
dst.create(sizes, CV_32SC1); // indices
dst.setTo(cv::Scalar::all(0));
cv::detail::depthDispatch<Impl>(src.depth(), src, dst, axis);
}
};
}
#endif //OPENCV_TEST_REF_REDUCE_ARG_HPP
|