mirror of https://github.com/opencv/opencv.git
Merge pull request #20733 from rogday:argmaxnd
Implement ArgMax and ArgMin * add reduceArgMax and reduceArgMin * fix review comments * address review concernspull/21165/head
parent
a97f21ba4e
commit
f044037ec5
6 changed files with 378 additions and 2 deletions
@ -0,0 +1,49 @@ |
||||
// 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_CORE_DETAIL_DISPATCH_HELPER_IMPL_HPP |
||||
#define OPENCV_CORE_DETAIL_DISPATCH_HELPER_IMPL_HPP |
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv { |
||||
namespace detail { |
||||
|
||||
template<template<typename> class Functor, typename... Args> |
||||
static inline void depthDispatch(const int depth, Args&&... args) |
||||
{ |
||||
switch (depth) |
||||
{ |
||||
case CV_8U: |
||||
Functor<uint8_t>{}(std::forward<Args>(args)...); |
||||
break; |
||||
case CV_8S: |
||||
Functor<int8_t>{}(std::forward<Args>(args)...); |
||||
break; |
||||
case CV_16U: |
||||
Functor<uint16_t>{}(std::forward<Args>(args)...); |
||||
break; |
||||
case CV_16S: |
||||
Functor<int16_t>{}(std::forward<Args>(args)...); |
||||
break; |
||||
case CV_32S: |
||||
Functor<int32_t>{}(std::forward<Args>(args)...); |
||||
break; |
||||
case CV_32F: |
||||
Functor<float>{}(std::forward<Args>(args)...); |
||||
break; |
||||
case CV_64F: |
||||
Functor<double>{}(std::forward<Args>(args)...); |
||||
break; |
||||
case CV_16F: |
||||
default: |
||||
CV_Error(cv::Error::BadDepth, "Unsupported matrix type."); |
||||
}; |
||||
} |
||||
|
||||
}} |
||||
|
||||
//! @endcond
|
||||
|
||||
#endif //OPENCV_CORE_DETAIL_DISPATCH_HELPER_IMPL_HPP
|
@ -0,0 +1,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
|
Loading…
Reference in new issue