1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 07:13:02 +04:00

add cv::flipND; support onnx slice with negative steps via cv::flipND

This commit is contained in:
fengyuentau
2022-12-01 17:41:54 +08:00
parent 91ac790249
commit 34a0897f90
5 changed files with 193 additions and 26 deletions
+45
View File
@@ -6,6 +6,8 @@
#include "opencl_kernels_core.hpp"
#include "opencv2/core/detail/dispatch_helper.impl.hpp"
#include <algorithm> // std::swap_ranges
namespace cv {
////////////////////////////////////// transpose /////////////////////////////////////////
@@ -812,6 +814,49 @@ void flip( InputArray _src, OutputArray _dst, int flip_mode )
flipHoriz( dst.ptr(), dst.step, dst.ptr(), dst.step, dst.size(), esz );
}
static void
flipNDImpl(uchar* data, const int* shape, const size_t* step, int axis)
{
int total = 1;
for (int i = 0; i < axis; ++i)
total *= shape[i];
int shape_at_axis = shape[axis];
size_t step_at_axis = step[axis];
size_t offset = 0;
size_t offset_increment = axis == 0 ? 0 : step[axis - 1];
for (int i = 0; i < total; ++i, offset += offset_increment)
for (int j = 0, k = shape_at_axis - 1; j < shape_at_axis / 2; ++j, --k)
std::swap_ranges(data + offset + j * step_at_axis,
data + offset + j * step_at_axis + step_at_axis,
data + offset + k * step_at_axis);
}
void flipND(InputArray _src, OutputArray _dst, int _axis)
{
CV_INSTRUMENT_REGION();
Mat src = _src.getMat();
// verify axis
int ndim = src.dims;
CV_CheckLT(_axis, ndim, "flipND: given axis is out of range");
CV_CheckGE(_axis, -ndim, "flipND: given axis is out of range");
int axis = (_axis + ndim) % ndim;
// in-place flip
_src.copyTo(_dst);
// return the src if it has only one element on the flip axis
const auto shape = src.size.p;
if (shape[axis] == 1)
return ;
// call impl
Mat dst = _dst.getMat();
flipNDImpl(dst.ptr(), dst.size.p, dst.step.p, axis);
}
void rotate(InputArray _src, OutputArray _dst, int rotateMode)
{
CV_Assert(_src.dims() <= 2);