mirror of
https://github.com/opencv/opencv.git
synced 2025-06-06 00:43:52 +08:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
This commit is contained in:
commit
2155296a13
@ -51,7 +51,10 @@ endif(WITH_CUDA)
|
||||
|
||||
# --- Eigen ---
|
||||
if(WITH_EIGEN AND NOT HAVE_EIGEN)
|
||||
if(NOT OPENCV_SKIP_EIGEN_FIND_PACKAGE_CONFIG)
|
||||
if((OPENCV_FORCE_EIGEN_FIND_PACKAGE_CONFIG
|
||||
OR NOT (CMAKE_VERSION VERSION_LESS "3.0.0") # Eigen3Targets.cmake required CMake 3.0.0+
|
||||
) AND NOT OPENCV_SKIP_EIGEN_FIND_PACKAGE_CONFIG
|
||||
)
|
||||
find_package(Eigen3 CONFIG QUIET) # Ceres 2.0.0 CMake scripts doesn't work with CMake's FindEigen3.cmake module (due to missing EIGEN3_VERSION_STRING)
|
||||
endif()
|
||||
if(NOT Eigen3_FOUND)
|
||||
|
@ -209,7 +209,7 @@ find the average error, we calculate the arithmetical mean of the errors calcula
|
||||
calibration images.
|
||||
@code{.py}
|
||||
mean_error = 0
|
||||
for i in xrange(len(objpoints)):
|
||||
for i in range(len(objpoints)):
|
||||
imgpoints2, _ = cv.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
|
||||
error = cv.norm(imgpoints[i], imgpoints2, cv.NORM_L2)/len(imgpoints2)
|
||||
mean_error += error
|
||||
|
@ -32,7 +32,7 @@ automatically available with the platform (e.g. APPLE GCD) but chances are that
|
||||
have access to a parallel framework either directly or by enabling the option in CMake and rebuild the library.
|
||||
|
||||
The second (weak) precondition is more related to the task you want to achieve as not all computations
|
||||
are suitable / can be adatapted to be run in a parallel way. To remain simple, tasks that can be split
|
||||
are suitable / can be adapted to be run in a parallel way. To remain simple, tasks that can be split
|
||||
into multiple elementary operations with no memory dependency (no possible race condition) are easily
|
||||
parallelizable. Computer vision processing are often easily parallelizable as most of the time the processing of
|
||||
one pixel does not depend to the state of other pixels.
|
||||
|
@ -1032,8 +1032,7 @@ void flip( InputArray _src, OutputArray _dst, int flip_mode )
|
||||
}
|
||||
|
||||
if ((size.width == 1 && flip_mode > 0) ||
|
||||
(size.height == 1 && flip_mode == 0) ||
|
||||
(size.height == 1 && size.width == 1 && flip_mode < 0))
|
||||
(size.height == 1 && flip_mode == 0))
|
||||
{
|
||||
return _src.copyTo(_dst);
|
||||
}
|
||||
|
@ -915,7 +915,7 @@ bool _InputArray::isContinuous(int i) const
|
||||
if( k == STD_ARRAY_MAT )
|
||||
{
|
||||
const Mat* vv = (const Mat*)obj;
|
||||
CV_Assert(i > 0 && i < sz.height);
|
||||
CV_Assert(i >= 0 && i < sz.height);
|
||||
return vv[i].isContinuous();
|
||||
}
|
||||
|
||||
@ -949,21 +949,21 @@ bool _InputArray::isSubmatrix(int i) const
|
||||
if( k == STD_VECTOR_MAT )
|
||||
{
|
||||
const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
|
||||
CV_Assert((size_t)i < vv.size());
|
||||
CV_Assert(i >= 0 && (size_t)i < vv.size());
|
||||
return vv[i].isSubmatrix();
|
||||
}
|
||||
|
||||
if( k == STD_ARRAY_MAT )
|
||||
{
|
||||
const Mat* vv = (const Mat*)obj;
|
||||
CV_Assert(i < sz.height);
|
||||
CV_Assert(i >= 0 && i < sz.height);
|
||||
return vv[i].isSubmatrix();
|
||||
}
|
||||
|
||||
if( k == STD_VECTOR_UMAT )
|
||||
{
|
||||
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
|
||||
CV_Assert((size_t)i < vv.size());
|
||||
CV_Assert(i >= 0 && (size_t)i < vv.size());
|
||||
return vv[i].isSubmatrix();
|
||||
}
|
||||
|
||||
@ -994,9 +994,7 @@ size_t _InputArray::offset(int i) const
|
||||
if( k == STD_VECTOR_MAT )
|
||||
{
|
||||
const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
|
||||
if( i < 0 )
|
||||
return 1;
|
||||
CV_Assert( i < (int)vv.size() );
|
||||
CV_Assert( i >= 0 && i < (int)vv.size() );
|
||||
|
||||
return (size_t)(vv[i].ptr() - vv[i].datastart);
|
||||
}
|
||||
@ -1004,16 +1002,14 @@ size_t _InputArray::offset(int i) const
|
||||
if( k == STD_ARRAY_MAT )
|
||||
{
|
||||
const Mat* vv = (const Mat*)obj;
|
||||
if( i < 0 )
|
||||
return 1;
|
||||
CV_Assert( i < sz.height );
|
||||
CV_Assert( i >= 0 && i < sz.height );
|
||||
return (size_t)(vv[i].ptr() - vv[i].datastart);
|
||||
}
|
||||
|
||||
if( k == STD_VECTOR_UMAT )
|
||||
{
|
||||
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
|
||||
CV_Assert((size_t)i < vv.size());
|
||||
CV_Assert(i >= 0 && (size_t)i < vv.size());
|
||||
return vv[i].offset;
|
||||
}
|
||||
|
||||
@ -1027,7 +1023,7 @@ size_t _InputArray::offset(int i) const
|
||||
if (k == STD_VECTOR_CUDA_GPU_MAT)
|
||||
{
|
||||
const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
|
||||
CV_Assert((size_t)i < vv.size());
|
||||
CV_Assert(i >= 0 && (size_t)i < vv.size());
|
||||
return (size_t)(vv[i].data - vv[i].datastart);
|
||||
}
|
||||
|
||||
@ -1057,25 +1053,21 @@ size_t _InputArray::step(int i) const
|
||||
if( k == STD_VECTOR_MAT )
|
||||
{
|
||||
const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
|
||||
if( i < 0 )
|
||||
return 1;
|
||||
CV_Assert( i < (int)vv.size() );
|
||||
CV_Assert( i >= 0 && i < (int)vv.size() );
|
||||
return vv[i].step;
|
||||
}
|
||||
|
||||
if( k == STD_ARRAY_MAT )
|
||||
{
|
||||
const Mat* vv = (const Mat*)obj;
|
||||
if( i < 0 )
|
||||
return 1;
|
||||
CV_Assert( i < sz.height );
|
||||
CV_Assert( i >= 0 && i < sz.height );
|
||||
return vv[i].step;
|
||||
}
|
||||
|
||||
if( k == STD_VECTOR_UMAT )
|
||||
{
|
||||
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
|
||||
CV_Assert((size_t)i < vv.size());
|
||||
CV_Assert(i >= 0 && (size_t)i < vv.size());
|
||||
return vv[i].step;
|
||||
}
|
||||
|
||||
@ -1087,7 +1079,7 @@ size_t _InputArray::step(int i) const
|
||||
if (k == STD_VECTOR_CUDA_GPU_MAT)
|
||||
{
|
||||
const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
|
||||
CV_Assert((size_t)i < vv.size());
|
||||
CV_Assert(i >= 0 && (size_t)i < vv.size());
|
||||
return vv[i].step;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "opencv2/core/eigen.hpp"
|
||||
#endif
|
||||
|
||||
#include "opencv2/core/cuda.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
class Core_ReduceTest : public cvtest::BaseTest
|
||||
@ -1974,6 +1976,157 @@ TEST(Core_InputArray, fetch_MatExpr)
|
||||
}
|
||||
|
||||
|
||||
#ifdef CV_CXX11
|
||||
class TestInputArrayRangeChecking {
|
||||
static const char *kind2str(cv::_InputArray ia)
|
||||
{
|
||||
switch (ia.kind())
|
||||
{
|
||||
#define C(x) case cv::_InputArray::x: return #x
|
||||
C(MAT);
|
||||
C(UMAT);
|
||||
C(EXPR);
|
||||
C(MATX);
|
||||
C(STD_VECTOR);
|
||||
C(STD_ARRAY);
|
||||
C(NONE);
|
||||
C(STD_VECTOR_VECTOR);
|
||||
C(STD_BOOL_VECTOR);
|
||||
C(STD_VECTOR_MAT);
|
||||
C(STD_ARRAY_MAT);
|
||||
C(STD_VECTOR_UMAT);
|
||||
C(CUDA_GPU_MAT);
|
||||
C(STD_VECTOR_CUDA_GPU_MAT);
|
||||
#undef C
|
||||
default:
|
||||
return "<unsupported>";
|
||||
}
|
||||
}
|
||||
|
||||
static void banner(cv::_InputArray ia, const char *label, const char *name)
|
||||
{
|
||||
std::cout << std::endl
|
||||
<< label << " = " << name << ", Kind: " << kind2str(ia)
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
template<typename I, typename F>
|
||||
static void testA(I ia, F f, const char *mfname)
|
||||
{
|
||||
banner(ia, "f", mfname);
|
||||
EXPECT_THROW(f(ia, -1), cv::Exception)
|
||||
<< "f(ia, " << -1 << ") should throw cv::Exception";
|
||||
for (int i = 0; i < int(ia.size()); i++)
|
||||
{
|
||||
EXPECT_NO_THROW(f(ia, i))
|
||||
<< "f(ia, " << i << ") should not throw an exception";
|
||||
}
|
||||
EXPECT_THROW(f(ia, int(ia.size())), cv::Exception)
|
||||
<< "f(ia, " << ia.size() << ") should throw cv::Exception";
|
||||
}
|
||||
|
||||
template<typename I, typename F>
|
||||
static void testB(I ia, F f, const char *mfname)
|
||||
{
|
||||
banner(ia, "f", mfname);
|
||||
EXPECT_THROW(f(ia, -1), cv::Exception)
|
||||
<< "f(ia, " << -1 << ") should throw cv::Exception";
|
||||
for (int i = 0; i < int(ia.size()); i++)
|
||||
{
|
||||
EXPECT_NO_THROW(f(ia, i))
|
||||
<< "f(ia, " << i << ") should not throw an exception";
|
||||
}
|
||||
EXPECT_THROW(f(ia, int(ia.size())), cv::Exception)
|
||||
<< "f(ia, " << ia.size() << ") should throw cv::Exception";
|
||||
}
|
||||
|
||||
static void test_isContinuous()
|
||||
{
|
||||
auto f = [](cv::_InputArray ia, int i) { (void)ia.isContinuous(i); };
|
||||
|
||||
cv::Mat M;
|
||||
cv::UMat uM;
|
||||
|
||||
std::vector<cv::Mat> vec = {M, M};
|
||||
std::array<cv::Mat, 2> arr = {M, M};
|
||||
std::vector<cv::UMat> uvec = {uM, uM};
|
||||
|
||||
testA(vec, f, "isContinuous");
|
||||
testA(arr, f, "isContinuous");
|
||||
testA(uvec, f, "isContinuous");
|
||||
}
|
||||
|
||||
static void test_isSubmatrix()
|
||||
{
|
||||
auto f = [](cv::_InputArray ia, int i) { (void)ia.isSubmatrix(i); };
|
||||
|
||||
cv::Mat M;
|
||||
cv::UMat uM;
|
||||
|
||||
std::vector<cv::Mat> vec = {M, M};
|
||||
std::array<cv::Mat, 2> arr = {M, M};
|
||||
std::vector<cv::UMat> uvec = {uM, uM};
|
||||
|
||||
testA(vec, f, "isSubmatrix");
|
||||
testA(arr, f, "isSubmatrix");
|
||||
testA(uvec, f, "isSubmatrix");
|
||||
}
|
||||
|
||||
static void test_offset()
|
||||
{
|
||||
auto f = [](cv::_InputArray ia, int i) { return ia.offset(i); };
|
||||
|
||||
cv::Mat M;
|
||||
cv::UMat uM;
|
||||
cv::cuda::GpuMat gM;
|
||||
|
||||
std::vector<cv::Mat> vec = {M, M};
|
||||
std::array<cv::Mat, 2> arr = {M, M};
|
||||
std::vector<cv::UMat> uvec = {uM, uM};
|
||||
std::vector<cv::cuda::GpuMat> gvec = {gM, gM};
|
||||
|
||||
testB(vec, f, "offset");
|
||||
testB(arr, f, "offset");
|
||||
testB(uvec, f, "offset");
|
||||
testB(gvec, f, "offset");
|
||||
}
|
||||
|
||||
static void test_step()
|
||||
{
|
||||
auto f = [](cv::_InputArray ia, int i) { return ia.step(i); };
|
||||
|
||||
cv::Mat M;
|
||||
cv::UMat uM;
|
||||
cv::cuda::GpuMat gM;
|
||||
|
||||
std::vector<cv::Mat> vec = {M, M};
|
||||
std::array<cv::Mat, 2> arr = {M, M};
|
||||
std::vector<cv::UMat> uvec = {uM, uM};
|
||||
std::vector<cv::cuda::GpuMat> gvec = {gM, gM};
|
||||
|
||||
testB(vec, f, "step");
|
||||
testB(arr, f, "step");
|
||||
testB(uvec, f, "step");
|
||||
testB(gvec, f, "step");
|
||||
}
|
||||
|
||||
public:
|
||||
static void run()
|
||||
{
|
||||
test_isContinuous();
|
||||
test_isSubmatrix();
|
||||
test_offset();
|
||||
test_step();
|
||||
}
|
||||
};
|
||||
|
||||
TEST(Core_InputArray, range_checking)
|
||||
{
|
||||
TestInputArrayRangeChecking::run();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
TEST(Core_Vectors, issue_13078)
|
||||
{
|
||||
float floats_[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
|
@ -248,8 +248,6 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
int type;
|
||||
std::vector<size_t> kernel_size, strides;
|
||||
std::vector<size_t> pads_begin, pads_end;
|
||||
CV_DEPRECATED_EXTERNAL Size kernel, stride, pad;
|
||||
CV_DEPRECATED_EXTERNAL int pad_l, pad_t, pad_r, pad_b;
|
||||
bool globalPooling; //!< Flag is true if at least one of the axes is global pooled.
|
||||
std::vector<bool> isGlobalPooling;
|
||||
bool computeMaxIdx;
|
||||
|
@ -95,8 +95,6 @@ public:
|
||||
computeMaxIdx = true;
|
||||
globalPooling = false;
|
||||
isGlobalPooling = std::vector<bool>(3, false);
|
||||
stride = Size(1, 1);
|
||||
pad_t = pad_l = pad_b = pad_r = 0;
|
||||
|
||||
hasDynamicShapes = params.get<bool>("has_dynamic_shapes", false);
|
||||
shapesInitialized = !hasDynamicShapes;
|
||||
@ -118,16 +116,6 @@ public:
|
||||
|
||||
getPoolingKernelParams(params, kernel_size, isGlobalPooling, pads_begin, pads_end, strides, padMode);
|
||||
globalPooling = isGlobalPooling[0] || isGlobalPooling[1] || isGlobalPooling[2];
|
||||
if (kernel_size.size() == 2) {
|
||||
kernel = Size(kernel_size[1], kernel_size[0]);
|
||||
stride = Size(strides[1], strides[0]);
|
||||
pad = Size(pads_begin[1], pads_begin[0]);
|
||||
|
||||
pad_t = pads_begin[0];
|
||||
pad_l = pads_begin[1];
|
||||
pad_b = pads_end[0];
|
||||
pad_r = pads_end[1];
|
||||
}
|
||||
}
|
||||
else if (params.has("pooled_w") || params.has("pooled_h"))
|
||||
{
|
||||
@ -175,17 +163,20 @@ public:
|
||||
finalKernel.push_back(isGlobalPooling[idx] ? inp[i] : kernel_size[idx]);
|
||||
}
|
||||
kernel_size = finalKernel;
|
||||
kernel = Size(kernel_size[1], kernel_size[0]);
|
||||
}
|
||||
|
||||
getConvPoolPaddings(inp, kernel_size, strides, padMode, pads_begin, pads_end);
|
||||
if (pads_begin.size() == 2) {
|
||||
pad_t = pads_begin[0];
|
||||
pad_l = pads_begin[1];
|
||||
pad_b = pads_end[0];
|
||||
pad_r = pads_end[1];
|
||||
|
||||
if (inputs[0].dims == 3)
|
||||
{
|
||||
//Pool1D
|
||||
kernel_size.erase(kernel_size.begin() + 1);
|
||||
strides.erase(strides.begin() + 1);
|
||||
pads_begin.erase(pads_begin.begin() + 1);
|
||||
pads_end.erase(pads_end.begin() + 1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
poolOp.release();
|
||||
#endif
|
||||
@ -205,9 +196,11 @@ public:
|
||||
return false;
|
||||
if (kernel_size.size() == 3)
|
||||
return preferableTarget == DNN_TARGET_CPU;
|
||||
if (kernel_size.size() == 1)
|
||||
return false;
|
||||
if (preferableTarget == DNN_TARGET_MYRIAD || preferableTarget == DNN_TARGET_HDDL) {
|
||||
#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1)
|
||||
if (type == MAX && (pad_l == 1 && pad_t == 1) && stride == Size(2, 2) ) {
|
||||
if (type == MAX && (pads_begin[1] == 1 && pads_begin[0] == 1) && (strides[0] == 2 && strides[1] == 2)) {
|
||||
return !isMyriadX();
|
||||
}
|
||||
#endif
|
||||
@ -219,21 +212,30 @@ public:
|
||||
#endif
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
{
|
||||
return !computeMaxIdx && type != STOCHASTIC;
|
||||
return !computeMaxIdx && type != STOCHASTIC && kernel_size.size() > 1;
|
||||
}
|
||||
if (backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_HALIDE || backendId == DNN_BACKEND_VKCOM)
|
||||
else if (backendId == DNN_BACKEND_OPENCV)
|
||||
{
|
||||
if (kernel_size.size() == 3)
|
||||
return (backendId == DNN_BACKEND_OPENCV && preferableTarget == DNN_TARGET_CPU);
|
||||
if (kernel_size.empty() || kernel_size.size() == 2)
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() &&
|
||||
(type == MAX || (type == AVE && !pad_t && !pad_l && !pad_b && !pad_r))) ||
|
||||
(backendId == DNN_BACKEND_VKCOM && haveVulkan() &&
|
||||
(type == MAX || type == AVE));
|
||||
return preferableTarget == DNN_TARGET_CPU;
|
||||
if (kernel_size.size() <= 2)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if (backendId == DNN_BACKEND_HALIDE)
|
||||
{
|
||||
if (kernel_size.empty() || kernel_size.size() == 2)
|
||||
return haveHalide() &&
|
||||
(type == MAX || (type == AVE && !pads_begin[0] && !pads_begin[1] && !pads_end[0] && !pads_end[1]));
|
||||
}
|
||||
else if (backendId == DNN_BACKEND_VKCOM)
|
||||
{
|
||||
if (kernel_size.empty() || kernel_size.size() == 2)
|
||||
return haveVulkan() &&
|
||||
(type == MAX || type == AVE);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -253,12 +255,25 @@ public:
|
||||
|
||||
config.in_shape = shape(inputs[0]);
|
||||
config.out_shape = shape(outputs[0]);
|
||||
config.kernel = kernel;
|
||||
config.pad_l = pad_l;
|
||||
config.pad_t = pad_t;
|
||||
config.pad_r = pad_r;
|
||||
config.pad_b = pad_b;
|
||||
config.stride = stride;
|
||||
if (inputs[0].dims == 3)
|
||||
{
|
||||
//Pool1D
|
||||
config.kernel = Size(kernel_size[0], 1);
|
||||
config.stride = Size(strides[0], 1);
|
||||
config.pad_l = pads_begin[0];
|
||||
config.pad_t = 0;
|
||||
config.pad_r = pads_end[0];
|
||||
config.pad_b = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
config.kernel = Size(kernel_size[1], kernel_size[0]);
|
||||
config.stride = Size(strides[1], strides[0]);
|
||||
config.pad_l = pads_begin[1];
|
||||
config.pad_t = pads_begin[0];
|
||||
config.pad_r = pads_end[1];
|
||||
config.pad_b = pads_end[0];
|
||||
}
|
||||
config.channels = inputs[0].size[1];
|
||||
config.pool_method = type == MAX ? LIBDNN_POOLING_METHOD_MAX :
|
||||
(type == AVE ? LIBDNN_POOLING_METHOD_AVE :
|
||||
@ -575,7 +590,6 @@ public:
|
||||
public:
|
||||
const Mat* src, *rois;
|
||||
Mat *dst, *mask;
|
||||
Size kernel, stride;
|
||||
int pad_l, pad_t, pad_r, pad_b;
|
||||
bool avePoolPaddedArea;
|
||||
int nstripes;
|
||||
@ -601,7 +615,7 @@ public:
|
||||
CV_Assert_N(
|
||||
src.isContinuous(), dst.isContinuous(),
|
||||
src.type() == CV_32F, src.type() == dst.type(),
|
||||
src.dims == 4 || src.dims == 5, dst.dims == 4 || dst.dims == 5,
|
||||
src.dims == 3 || src.dims == 4 || src.dims == 5, dst.dims == 3 || dst.dims == 4 || dst.dims == 5,
|
||||
(((poolingType == ROI || poolingType == PSROI) &&
|
||||
dst.size[0] == rois.size[0]) || src.size[0] == dst.size[0]),
|
||||
poolingType == PSROI || src.size[1] == dst.size[1],
|
||||
@ -609,6 +623,9 @@ public:
|
||||
|
||||
PoolingInvoker p;
|
||||
|
||||
bool isPool1D = src.dims == 3;
|
||||
bool isPool3D = src.dims == 5;
|
||||
|
||||
p.src = &src;
|
||||
p.rois = &rois;
|
||||
p.dst = &dst;
|
||||
@ -619,12 +636,10 @@ public:
|
||||
p.pads_end = pads_end;
|
||||
|
||||
p.mask = &mask;
|
||||
p.kernel = Size(kernel_size[1], kernel_size[0]);
|
||||
p.stride = Size(strides[1], strides[0]);
|
||||
p.pad_l = pads_begin.back();
|
||||
p.pad_t = pads_begin[pads_begin.size() - 2];
|
||||
p.pad_t = isPool1D ? 0 : pads_begin[pads_begin.size() - 2];
|
||||
p.pad_r = pads_end.back();
|
||||
p.pad_b = pads_end[pads_end.size() - 2];
|
||||
p.pad_b = isPool1D ? 0 : pads_end[pads_end.size() - 2];
|
||||
|
||||
p.avePoolPaddedArea = avePoolPaddedArea;
|
||||
p.nstripes = nstripes;
|
||||
@ -634,11 +649,11 @@ public:
|
||||
|
||||
if( !computeMaxIdx )
|
||||
{
|
||||
int height = src.size[src.dims - 2];
|
||||
int height = isPool1D ? 1 : src.size[src.dims - 2];
|
||||
int width = src.size[src.dims - 1];
|
||||
|
||||
int kernel_d = (kernel_size.size() == 3) ? kernel_size[0] : 1;
|
||||
int kernel_h = kernel_size[kernel_size.size() - 2];
|
||||
int kernel_d = isPool3D ? kernel_size[0] : 1;
|
||||
int kernel_h = isPool1D ? 1 : kernel_size[kernel_size.size() - 2];
|
||||
int kernel_w = kernel_size.back();
|
||||
|
||||
p.ofsbuf.resize(kernel_d * kernel_h * kernel_w);
|
||||
@ -658,13 +673,15 @@ public:
|
||||
{
|
||||
int channels = dst->size[1];
|
||||
|
||||
bool isPool3D = src->dims == 5;
|
||||
bool isPool2D = src->dims == 4;
|
||||
int depth = !isPool2D? dst->size[2] : 1;
|
||||
int height = dst->size[dst->dims - 2];
|
||||
bool isPool1D = src->dims == 3;
|
||||
int depth = isPool3D? dst->size[2] : 1;
|
||||
int height = isPool1D? 1 : dst->size[dst->dims - 2];
|
||||
int width = dst->size[dst->dims - 1];
|
||||
|
||||
int inp_depth = !isPool2D? src->size[2] : 1;
|
||||
int inp_height = src->size[src->dims - 2];
|
||||
int inp_depth = isPool3D? src->size[2] : 1;
|
||||
int inp_height = isPool1D? 1 : src->size[src->dims - 2];
|
||||
int inp_width = src->size[src->dims - 1];
|
||||
|
||||
size_t total = dst->total();
|
||||
@ -672,12 +689,12 @@ public:
|
||||
size_t stripeStart = r.start*stripeSize;
|
||||
size_t stripeEnd = std::min(r.end*stripeSize, total);
|
||||
|
||||
int kernel_d = !isPool2D? kernel_size[0] : 1;
|
||||
int kernel_h = kernel_size[kernel_size.size() - 2];
|
||||
int kernel_d = isPool3D? kernel_size[0] : 1;
|
||||
int kernel_h = isPool1D? 1 : kernel_size[kernel_size.size() - 2];
|
||||
int kernel_w = kernel_size.back();
|
||||
|
||||
int stride_d = !isPool2D? strides[0] : 0;
|
||||
int stride_h = strides[strides.size() - 2];
|
||||
int stride_d = isPool3D? strides[0] : 0;
|
||||
int stride_h = isPool1D? 1 :strides[strides.size() - 2];
|
||||
int stride_w = strides.back();
|
||||
bool compMaxIdx = computeMaxIdx;
|
||||
|
||||
@ -868,7 +885,24 @@ public:
|
||||
}
|
||||
}
|
||||
else
|
||||
#else
|
||||
CV_UNUSED(isPool2D);
|
||||
#endif
|
||||
if( isPool1D )
|
||||
{
|
||||
const float* first = srcData + xstart;
|
||||
const float* last = srcData + xend;
|
||||
const float* max_elem = std::max_element(first, last);
|
||||
if (max_elem!=last)
|
||||
{
|
||||
dstData[x0] = *max_elem;
|
||||
if( compMaxIdx )
|
||||
{
|
||||
dstMaskData[x0] = std::distance(first, max_elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float max_val = -FLT_MAX;
|
||||
if( compMaxIdx )
|
||||
@ -942,6 +976,14 @@ public:
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if( isPool1D )
|
||||
{
|
||||
const float* first = srcData + xstart;
|
||||
const float* last = srcData + xend;
|
||||
float sum_val = std::accumulate(first, last, 0.f);
|
||||
dstData[x0] = sum_val*inv_kernel_area;
|
||||
}
|
||||
else
|
||||
{
|
||||
float sum_val = 0.f;
|
||||
for (int d = dstart; d < dend; ++d) {
|
||||
@ -1055,20 +1097,26 @@ public:
|
||||
Halide::Buffer<float> inputBuffer = halideBuffer(inputs[0]);
|
||||
const int inWidth = inputBuffer.width();
|
||||
const int inHeight = inputBuffer.height();
|
||||
const size_t kernelHeight = kernel_size[0];
|
||||
const size_t kernelWidth = kernel_size[1];
|
||||
const size_t strideHeight = strides[0];
|
||||
const size_t strideWidth = strides[1];
|
||||
const size_t paddingTop = pads_begin[0];
|
||||
const size_t paddingLeft = pads_begin[1];
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
Halide::RDom r(0, kernel.width, 0, kernel.height);
|
||||
Halide::RDom r(0, kernelWidth, 0, kernelHeight);
|
||||
Halide::Expr kx, ky;
|
||||
if(pad_l || pad_t)
|
||||
if(paddingLeft || paddingTop)
|
||||
{
|
||||
kx = clamp(x * stride.width + r.x - pad_l, 0, inWidth - 1);
|
||||
ky = clamp(y * stride.height + r.y - pad_t, 0, inHeight - 1);
|
||||
kx = clamp(x * strideWidth + r.x - paddingLeft, 0, inWidth - 1);
|
||||
ky = clamp(y * strideHeight + r.y - paddingTop, 0, inHeight - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
kx = min(x * stride.width + r.x, inWidth - 1);
|
||||
ky = min(y * stride.height + r.y, inHeight - 1);
|
||||
kx = min(x * strideWidth + r.x, inWidth - 1);
|
||||
ky = min(y * strideHeight + r.y, inHeight - 1);
|
||||
}
|
||||
|
||||
// Halide::argmax returns tuple (r.x, r.y, max).
|
||||
@ -1076,17 +1124,17 @@ public:
|
||||
|
||||
// Compute offset from argmax in range [0, kernel_size).
|
||||
Halide::Expr max_index;
|
||||
if(pad_l || pad_t)
|
||||
if(paddingLeft || paddingTop)
|
||||
{
|
||||
max_index = clamp(y * stride.height + res[1] - pad_t,
|
||||
max_index = clamp(y * strideHeight + res[1] - paddingTop,
|
||||
0, inHeight - 1) * inWidth +
|
||||
clamp(x * stride.width + res[0] - pad_l,
|
||||
clamp(x * strideWidth + res[0] - paddingLeft,
|
||||
0, inWidth - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
max_index = min(y * stride.height + res[1], inHeight - 1) * inWidth +
|
||||
min(x * stride.width + res[0], inWidth - 1);
|
||||
max_index = min(y * strideHeight + res[1], inHeight - 1) * inWidth +
|
||||
min(x * strideWidth + res[0], inWidth - 1);
|
||||
}
|
||||
top(x, y, c, n) = { res[2], Halide::cast<float>(max_index) };
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
@ -1100,21 +1148,25 @@ public:
|
||||
Halide::Buffer<float> inputBuffer = halideBuffer(inputs[0]);
|
||||
|
||||
const int inW = inputBuffer.width(), inH = inputBuffer.height();
|
||||
if ((inW - kernel.width) % stride.width || (inH - kernel.height) % stride.height)
|
||||
const size_t kernelHeight = kernel_size[0];
|
||||
const size_t kernelWidth = kernel_size[1];
|
||||
const size_t strideHeight = strides[0];
|
||||
const size_t strideWidth = strides[1];
|
||||
if ((inW - kernelWidth) % strideWidth || (inH - kernelHeight) % strideHeight)
|
||||
{
|
||||
CV_Error(cv::Error::StsNotImplemented,
|
||||
"Halide backend for average pooling with partial "
|
||||
"kernels is not implemented");
|
||||
}
|
||||
|
||||
const float norm = 1.0f / (kernel.width * kernel.height);
|
||||
const float norm = 1.0f / (kernelWidth * kernelHeight);
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
Halide::RDom r(0, kernel.width, 0, kernel.height);
|
||||
Halide::RDom r(0, kernelWidth, 0, kernelHeight);
|
||||
top(x, y, c, n) = sum(
|
||||
inputBuffer(x * stride.width + r.x,
|
||||
y * stride.height + r.y, c, n)) * norm;
|
||||
inputBuffer(x * strideWidth + r.x,
|
||||
y * strideHeight + r.y, c, n)) * norm;
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
@ -1176,6 +1228,7 @@ public:
|
||||
{
|
||||
CV_Assert(inputs.size() != 0);
|
||||
|
||||
bool isPool1D = inputs[0].size() == 3;
|
||||
std::vector<int> inpShape(inputs[0].begin() + 2, inputs[0].end());
|
||||
std::vector<int> outShape(inputs[0].begin(), inputs[0].begin() + 2);
|
||||
|
||||
@ -1204,14 +1257,15 @@ public:
|
||||
}
|
||||
else if (padMode.empty())
|
||||
{
|
||||
for (int i = 0; i < local_kernel.size(); i++) {
|
||||
int addedDims = isPool1D? inpShape.size() : local_kernel.size();
|
||||
for (int i = 0; i < addedDims; i++) {
|
||||
float dst = (float) (inpShape[i] + pads_begin[i] + pads_end[i] - local_kernel[i]) / strides[i];
|
||||
outShape.push_back(1 + (ceilMode ? ceil(dst) : floor(dst)));
|
||||
}
|
||||
|
||||
// If we have padding, ensure that the last pooling starts strictly
|
||||
// inside the image (instead of at the padding); otherwise clip the last.
|
||||
for (int i = 0; i < pads_end.size(); i++) {
|
||||
for (int i = 0; i < addedDims; i++) {
|
||||
if (pads_end[i] && (outShape[2 + i] - 1) * strides[i] >= inpShape[i] + pads_end[i]) {
|
||||
--outShape[2 + i];
|
||||
CV_Assert((outShape[2 + i] - 1) * strides[i] < inpShape[i] + pads_end[i]);
|
||||
@ -1255,7 +1309,8 @@ public:
|
||||
{
|
||||
CV_UNUSED(inputs); // suppress unused variable warning
|
||||
long flops = 0;
|
||||
size_t karea = std::accumulate(kernel_size.begin(), kernel_size.end(),
|
||||
bool isPool1D = inputs[0].size() == 3;
|
||||
size_t karea = std::accumulate(kernel_size.begin(), isPool1D? kernel_size.begin() + 1 : kernel_size.end(),
|
||||
1, std::multiplies<size_t>());
|
||||
for(int i = 0; i < outputs.size(); i++)
|
||||
{
|
||||
|
@ -51,18 +51,20 @@ template<typename Dtype>
|
||||
OCL4DNNPool<Dtype>::OCL4DNNPool(OCL4DNNPoolConfig config)
|
||||
{
|
||||
int dims = config.in_shape.size();
|
||||
int spatial_dims = 2;
|
||||
int spatial_dims = config.in_shape.size()-2;
|
||||
|
||||
channels_ = config.channels;
|
||||
pool_method_ = config.pool_method;
|
||||
avePoolPaddedArea = config.avePoolPaddedArea;
|
||||
computeMaxIdx = config.computeMaxIdx;
|
||||
use_half = config.use_half;
|
||||
kernel_shape_.push_back(config.kernel.height);
|
||||
kernel_shape_.push_back(config.kernel.width);
|
||||
stride_.push_back(config.stride.height);
|
||||
stride_.push_back(config.stride.width);
|
||||
|
||||
for (int i = 0; i < spatial_dims; ++i)
|
||||
{
|
||||
kernel_shape_.push_back(i == 0 ? config.kernel.height : config.kernel.width);
|
||||
stride_.push_back(i == 0 ? config.stride.height : config.stride.width);
|
||||
im_in_shape_.push_back(config.in_shape[dims - spatial_dims + i]);
|
||||
im_out_shape_.push_back(config.out_shape[dims - spatial_dims + i]);
|
||||
}
|
||||
@ -75,10 +77,10 @@ OCL4DNNPool<Dtype>::OCL4DNNPool(OCL4DNNPoolConfig config)
|
||||
pad_l_ = config.pad_l;
|
||||
pad_r_ = config.pad_r;
|
||||
pad_b_ = config.pad_b;
|
||||
height_ = im_in_shape_[0];
|
||||
width_ = im_in_shape_[1];
|
||||
pooled_height_ = im_out_shape_[0];
|
||||
pooled_width_ = im_out_shape_[1];
|
||||
height_ = spatial_dims == 1? 1 : im_in_shape_[0];
|
||||
width_ = im_in_shape_.back();
|
||||
pooled_height_ = spatial_dims == 1? 1 : im_out_shape_[0];
|
||||
pooled_width_ = im_out_shape_.back();
|
||||
|
||||
count_ = 1;
|
||||
for (int i = 0; i < config.out_shape.size(); ++i)
|
||||
|
@ -500,14 +500,17 @@ void ONNXImporter::handleNode(const opencv_onnx::NodeProto& node_proto_)
|
||||
MatShape inpShape = outShapes[node_proto.input(0)];
|
||||
DictValue axes = layerParams.get("axes");
|
||||
bool keepdims = layerParams.get<int>("keepdims");
|
||||
MatShape targetShape = inpShape;
|
||||
MatShape targetShape;
|
||||
std::vector<bool> shouldDelete(inpShape.size(), false);
|
||||
for (int i = 0; i < axes.size(); i++) {
|
||||
int axis = clamp(axes.get<int>(i), inpShape.size());
|
||||
if (keepdims) {
|
||||
targetShape[axis] = 1;
|
||||
} else {
|
||||
targetShape.erase(targetShape.begin() + axis);
|
||||
}
|
||||
shouldDelete[axis] = true;
|
||||
}
|
||||
for (int axis = 0; axis < inpShape.size(); ++axis){
|
||||
if (!shouldDelete[axis])
|
||||
targetShape.push_back(inpShape[axis]);
|
||||
else if (keepdims)
|
||||
targetShape.push_back(1);
|
||||
}
|
||||
|
||||
if (inpShape.size() == 3 && axes.size() <= 2)
|
||||
|
@ -756,6 +756,9 @@ TEST_P(Test_ONNX_layers, Conv1d_variable_weight_bias)
|
||||
|
||||
TEST_P(Test_ONNX_layers, GatherMultiOutput)
|
||||
{
|
||||
if (cvtest::skipUnstableTests && backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
|
||||
throw SkipTestException("Skip unstable test: https://github.com/opencv/opencv/issues/18937");
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE);
|
||||
@ -785,6 +788,84 @@ TEST_P(Test_ONNX_layers, DynamicAxes)
|
||||
testONNXModels("maxpooling_sigmoid_dynamic_axes");
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_layers, MaxPool1d)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
}
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
}
|
||||
testONNXModels("maxpooling_1d");
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_layers, MaxPoolSigmoid1d)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
}
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
}
|
||||
testONNXModels("maxpooling_sigmoid_1d");
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_layers, MaxPool1d_Twise)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
}
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
}
|
||||
testONNXModels("two_maxpooling_1d");
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_layers, AvePool1d)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
}
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
}
|
||||
testONNXModels("average_pooling_1d");
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_layers, PoolConv1d)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
}
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
}
|
||||
testONNXModels("pool_conv_1d");
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_layers, ConvResizePool1d)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
}
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
}
|
||||
testONNXModels("conv_resize_pool_1d");
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/*nothing*/, Test_ONNX_layers, dnnBackendsAndTargets());
|
||||
|
||||
class Test_ONNX_nets : public Test_ONNX_layers
|
||||
|
@ -116,11 +116,11 @@ public:
|
||||
CvCapture_OpenNI2(const char * filename);
|
||||
virtual ~CvCapture_OpenNI2();
|
||||
|
||||
virtual int getCaptureDomain() CV_OVERRIDE { return cv::CAP_OPENNI2; }
|
||||
virtual double getProperty(int propIdx) const CV_OVERRIDE;
|
||||
virtual bool setProperty(int probIdx, double propVal) CV_OVERRIDE;
|
||||
virtual bool grabFrame() CV_OVERRIDE;
|
||||
virtual IplImage* retrieveFrame(int outputType) CV_OVERRIDE;
|
||||
virtual int getCaptureDomain() CV_OVERRIDE { return cv::CAP_OPENNI2; }
|
||||
|
||||
bool isOpened() const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user