1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

Merge pull request #29323 from abhishek-gola:split_layer_extension

Extended support for Resize and Split layers #29323

Merge with: https://github.com/opencv/opencv_extra/pull/1379

Key changes: 

Resize layer: 
_antialias_ (linear & cubic) :- PIL-style separable resampling with stretched filter support and edge-clamped, renormalized weights.
_axes_ (incl. reversed [3,2]) :- getOutShape, the scale override, and runtime _tf_crop_and_resize_ ROI parsing now map 2-element sizes/scales/roi by the axes order instead of assuming [2,3].
_keep_aspect_ratio_policy_ (not_larger/not_smaller) :- output size from min/max per-axis scale.
_half_pixel_symmetric_ :- new coordinate-transform mode + importer mapping.
_align_corners_ downsampling :- coordinate scale uses the unfloored scaled length (in−1)/(in·x_scale−1).

Split Layer:
_convertTo empty 1-D Mat:_ the empty-Mat branch collapsed a 1-D [0] to 2-D [1,0] via cv::Size(); now uses allowTransposed like the non-empty path.
### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Abhishek Gola
2026-06-23 11:53:19 +05:30
committed by GitHub
parent 5049343874
commit 81621ced10
10 changed files with 445 additions and 110 deletions
+4 -4
View File
@@ -140,10 +140,10 @@ void Mat::convertTo(OutputArray dst, int type_, double alpha, double beta) const
const int dtype = CV_MAKETYPE(ddepth, channels());
dst.release();
if (dims <= 2)
dst.create(size(), dtype);
else
dst.create(dims, size.p, dtype);
bool allowTransposed = dims == 1 ||
dst.kind() == _InputArray::STD_VECTOR ||
(dst.fixedSize() && dst.dims() == 1);
dst.create(size, dtype, -1, allowTransposed);
return;
}
+17 -6
View File
@@ -41,6 +41,7 @@ static void avgPool32f(const void* inp_, void* out_,
int planesize = D*H*W*C0;
int SZ = cs.strides[0], SY = cs.strides[1], SX = cs.strides[2];
int padZ0 = cs.pads[0], padY0 = cs.pads[1], padX0 = cs.pads[2];
int padZ1 = cs.pads[MAX_POOL_DIMS], padY1 = cs.pads[MAX_POOL_DIMS+1], padX1 = cs.pads[MAX_POOL_DIMS+2];
int inner_z0 = cs.inner[0], inner_z1 = cs.inner[MAX_POOL_DIMS];
int inner_y0 = cs.inner[1], inner_y1 = cs.inner[MAX_POOL_DIMS + 1];
int inner_x0 = cs.inner[2], inner_x1 = cs.inner[MAX_POOL_DIMS + 2];
@@ -78,12 +79,15 @@ static void avgPool32f(const void* inp_, void* out_,
for (; x0 < x1; x0++) {
int xi_ = x0*SX - padX0;
v_float32 s0 = z;
int nitems = 0;
int nitems = 0, npadded = 0;
for (int k = 0; k < ksize; k++) {
int zi = zi_ + zyxtab[k*MAX_POOL_DIMS];
int yi = yi_ + zyxtab[k*MAX_POOL_DIMS+1];
int xi = xi_ + zyxtab[k*MAX_POOL_DIMS+2];
v_float32 v0;
npadded += (zi >= -padZ0 && zi < Di + padZ1 &&
yi >= -padY0 && yi < Hi + padY1 &&
xi >= -padX0 && xi < Wi + padX1);
if ((unsigned)zi >= (unsigned)Di ||
(unsigned)yi >= (unsigned)Hi ||
(unsigned)xi >= (unsigned)Wi)
@@ -92,7 +96,7 @@ static void avgPool32f(const void* inp_, void* out_,
s0 = v_add(s0, v0);
nitems++;
}
s0 = v_mul(s0, count_include_pad ? vscale0 : vx_setall_f32(1.f/nitems));
s0 = v_mul(s0, vx_setall_f32(1.f/(count_include_pad ? npadded : nitems)));
vx_store(out + x0*C0, s0);
}
} else {
@@ -100,12 +104,15 @@ static void avgPool32f(const void* inp_, void* out_,
int xi_ = x0*SX - padX0;
for (int c = 0; c < C0; c += nlanes*2) {
v_float32 s0 = z, s1 = z;
int nitems = 0;
int nitems = 0, npadded = 0;
for (int k = 0; k < ksize; k++) {
int zi = zi_ + zyxtab[k*MAX_POOL_DIMS];
int yi = yi_ + zyxtab[k*MAX_POOL_DIMS+1];
int xi = xi_ + zyxtab[k*MAX_POOL_DIMS+2];
v_float32 v0, v1;
npadded += (zi >= -padZ0 && zi < Di + padZ1 &&
yi >= -padY0 && yi < Hi + padY1 &&
xi >= -padX0 && xi < Wi + padX1);
if ((unsigned)zi >= (unsigned)Di ||
(unsigned)yi >= (unsigned)Hi ||
(unsigned)xi >= (unsigned)Wi)
@@ -117,7 +124,7 @@ static void avgPool32f(const void* inp_, void* out_,
s1 = v_add(s1, v1);
nitems++;
}
v_float32 vscale = count_include_pad ? vscale0 : vx_setall_f32(1.f/nitems);
v_float32 vscale = vx_setall_f32(1.f/(count_include_pad ? npadded : nitems));
s0 = v_mul(s0, vscale);
s1 = v_mul(s1, vscale);
vx_store(out + x0*C0 + c, s0);
@@ -128,11 +135,14 @@ static void avgPool32f(const void* inp_, void* out_,
#else
for (; x0 < x1; x0++) {
int xi_ = x0*SX - padX0;
int nitems = 0;
int nitems = 0, npadded = 0;
for (int k = 0; k < ksize; k++) {
int zi = zi_ + zyxtab[k*MAX_POOL_DIMS];
int yi = yi_ + zyxtab[k*MAX_POOL_DIMS+1];
int xi = xi_ + zyxtab[k*MAX_POOL_DIMS+2];
npadded += (zi >= -padZ0 && zi < Di + padZ1 &&
yi >= -padY0 && yi < Hi + padY1 &&
xi >= -padX0 && xi < Wi + padX1);
if ((unsigned)zi >= (unsigned)Di ||
(unsigned)yi >= (unsigned)Hi ||
(unsigned)xi >= (unsigned)Wi)
@@ -142,7 +152,7 @@ static void avgPool32f(const void* inp_, void* out_,
out[x0*C0 + c] += inptr[c];
nitems++;
}
float scale = count_include_pad ? iksize : 1.f/nitems;
float scale = count_include_pad ? 1.f/npadded : 1.f/nitems;
for (int c = 0; c < C0; c++)
out[x0*C0 + c] *= scale;
}
@@ -264,6 +274,7 @@ static void avgPool16xf(const _Tp* inp_, _Tp* out_,
int planesize = D*H*W*C0;
int SZ = cs.strides[0], SY = cs.strides[1], SX = cs.strides[2];
int padZ0 = cs.pads[0], padY0 = cs.pads[1], padX0 = cs.pads[2];
int padZ1 = cs.pads[MAX_POOL_DIMS], padY1 = cs.pads[MAX_POOL_DIMS+1], padX1 = cs.pads[MAX_POOL_DIMS+2];
int inner_z0 = cs.inner[0], inner_z1 = cs.inner[MAX_POOL_DIMS];
int inner_y0 = cs.inner[1], inner_y1 = cs.inner[MAX_POOL_DIMS + 1];
int inner_x0 = cs.inner[2], inner_x1 = cs.inner[MAX_POOL_DIMS + 2];
+6 -1
View File
@@ -91,11 +91,16 @@ MatShape convInferShape(const MatShape& inpShape, const MatShape& wshape,
int dilation = dilations.empty() ? 1 : dilations[i];
int outsz;
if (autoPad == AUTO_PAD_NONE || autoPad == AUTO_PAD_VALID) {
int pad = 0;
int pad0 = 0, pad = 0;
if (!pads.empty()) {
pad0 = pads[i];
pad = pads[i] + pads[i + nspatialdims];
}
outsz = (inpsz + pad - 1 - dilation * (k_i - 1) + (ceilMode ? stride - 1 : 0)) / stride + 1;
// ONNX: with ceil_mode a sliding window that starts in the right/bottom
// padding region is dropped
if (ceilMode && (outsz - 1) * stride >= inpsz + pad0)
outsz--;
} else {
if (ceilMode)
outsz = (inpsz + stride - 1)/stride;
+4 -3
View File
@@ -682,14 +682,15 @@ void LayerEinsumImpl::preProcessInputs(InputArrayOfArrays& inputs_arr)
// variable to hold processed version of the original input
MatShape input_dims = shape(input);
if (input_dims.empty()){
const auto& currSubscriptIndices = inputSubscriptIndices[inputIter];
if (input_dims.empty() || currSubscriptIndices.empty()){
CV_CheckEQ(total(input_dims), (size_t)1, "Einsum: input with no subscript labels must be a scalar");
homogenizedInputDims[inputIter] = MatShape(numLetterIndices, 1);
++inputIter;
continue;
}
const auto& currSubscriptIndices = inputSubscriptIndices[inputIter];
// There should be subscript index (subscript label) for each dim of the input
CV_CheckEQ(input_dims.size(), currSubscriptIndices.size(),
"Rank of the input must match number of subscript labels corresponding to the input");
+222 -22
View File
@@ -34,6 +34,7 @@ enum class CoordTransMode {
PYTORCH_HALF_PIXEL,
TF_HALF_PIXEL_FOR_NN,
TF_CROP_AND_RESIZE,
HALF_PIXEL_SYMMETRIC,
ASYMMETRIC
};
@@ -43,6 +44,7 @@ static inline CoordTransMode parseCoordTransMode(const String& s)
if (s == "pytorch_half_pixel") return CoordTransMode::PYTORCH_HALF_PIXEL;
if (s == "tf_half_pixel_for_nn") return CoordTransMode::TF_HALF_PIXEL_FOR_NN;
if (s == "tf_crop_and_resize") return CoordTransMode::TF_CROP_AND_RESIZE;
if (s == "half_pixel_symmetric") return CoordTransMode::HALF_PIXEL_SYMMETRIC;
return CoordTransMode::ASYMMETRIC;
}
@@ -90,6 +92,13 @@ inline float computeSrcGeneric(int dst, float scale, int limit, int len,
return (dst + 0.5f)*scale - 0.5f;
if (coordTransMode == CoordTransMode::TF_HALF_PIXEL_FOR_NN)
return (dst + 0.5f)*scale;
if (coordTransMode == CoordTransMode::HALF_PIXEL_SYMMETRIC)
{
// ONNX half_pixel_symmetric: offset = center*(1 - len_resized/(len_orig*x_scale)),
// with scale == 1/x_scale and limit == input length.
const float offset = limit*0.5f - len*scale*0.5f;
return offset + (dst + 0.5f)*scale - 0.5f;
}
return dst*scale;
}
@@ -122,7 +131,7 @@ static inline void buildNearestIndexMap(std::vector<int>& map,
map.resize(outLen);
for (int i = 0; i < outLen; ++i)
{
float src = computeSrcGeneric(i, scale, inLen - 1, len,
float src = computeSrcGeneric(i, scale, inLen, len,
coordTransMode, halfPixelCenters, start_coord, end_coord);
if (coordTransMode == CoordTransMode::TF_CROP_AND_RESIZE) {
if (src < 0.f || src >= float(inLen)) {
@@ -175,9 +184,9 @@ static inline void buildBilinearIndexAndLerp(std::vector<int>& i0,
}
else
{
src = std::min(std::max(src, 0.f), float(inLen - 1) - 1e-6f);
src = std::min(std::max(src, 0.f), std::max(0.f, float(inLen - 1) - 1e-6f));
int base = int(std::floor(src));
i0[o] = base;
i0[o] = clamp(base, 0, inLen - 1);
i1[o] = clamp(base + 1, 0, inLen - 1);
frac[o] = src - float(base);
}
@@ -773,6 +782,119 @@ void resizeCubic(const Mat &inp, Mat &out,
}
}, nstripes);
}
// ---- ONNX antialias (PIL-style) resampling ----------------------------------
static inline float aaTriangle(float x)
{
x = std::abs(x);
return x < 1.f ? 1.f - x : 0.f;
}
static inline float aaCubic(float x, float a)
{
x = std::abs(x);
if (x < 1.f) return ((a + 2.f)*x - (a + 3.f))*x*x + 1.f;
if (x < 2.f) return a*(((x - 5.f)*x + 8.f)*x - 4.f);
return 0.f;
}
// Per-output filter taps for one axis. After clamping out-of-bound samples to
// the edge (exclude_outside == false), the contributing indices are contiguous,
// so each output stores a start index 'lo', a 'cnt' and an offset into 'w'.
struct AAWeights
{
std::vector<int> lo, cnt, ofs;
std::vector<float> w;
};
static void buildAAWeights(AAWeights& p, int inS, int outS, float xscale,
bool cubic, float cubicA, CoordTransMode coordMode)
{
const float scaleC = 1.f / xscale; // input/output direction
const float radius = cubic ? 2.f : 1.f;
const float support = scaleC >= 1.f ? radius*scaleC : radius;
const float inv = scaleC >= 1.f ? 1.f/scaleC : 1.f;
p.lo.resize(outS); p.cnt.resize(outS); p.ofs.resize(outS);
p.w.clear();
std::vector<float> tmp;
for (int y = 0; y < outS; y++)
{
const float center = computeSrcGeneric(y, scaleC, inS, outS, coordMode, true);
const int xmin = (int)std::floor(center - support + 0.5f);
const int xmax = (int)std::floor(center + support + 0.5f); // inclusive
const int lo = std::min(std::max(xmin, 0), inS - 1);
const int hi = std::min(std::max(xmax, 0), inS - 1);
const int cnt = hi - lo + 1;
tmp.assign(cnt, 0.f);
float tot = 0.f;
for (int x = xmin; x <= xmax; x++)
{
const float wt = cubic ? aaCubic((x - center)*inv, cubicA)
: aaTriangle((x - center)*inv);
const int idx = std::min(std::max(x, 0), inS - 1);
tmp[idx - lo] += wt;
tot += wt;
}
p.lo[y] = lo; p.cnt[y] = cnt; p.ofs[y] = (int)p.w.size();
for (int k = 0; k < cnt; k++)
p.w.push_back(tot != 0.f ? tmp[k] / tot : 0.f);
}
}
template<typename T>
void resizeAntialias(const Mat& inp, Mat& out,
float xscaleH, float xscaleW,
bool cubic, float cubicA, CoordTransMode coordMode)
{
CV_Assert(inp.dims == 4 && out.dims == 4 && inp.isContinuous() && out.isContinuous());
const int N = inp.size[0], C = inp.size[1];
const int inH = inp.size[2], inW = inp.size[3];
const int outH = out.size[2], outW = out.size[3];
AAWeights px, py;
buildAAWeights(px, inW, outW, xscaleW, cubic, cubicA, coordMode);
buildAAWeights(py, inH, outH, xscaleH, cubic, cubicA, coordMode);
const int planes = N * C;
parallel_for_(Range(0, planes), [&](const Range& r) {
std::vector<float> buf((size_t)inH * outW);
for (int pl = r.start; pl < r.end; pl++)
{
const T* inPlane = inp.ptr<T>(0) + (size_t)pl * inH * inW;
T* outPlane = out.ptr<T>(0) + (size_t)pl * outH * outW;
// Horizontal pass: inp[inH x inW] -> buf[inH x outW].
for (int y = 0; y < inH; y++)
{
const T* inRow = inPlane + (size_t)y * inW;
float* bufRow = buf.data() + (size_t)y * outW;
for (int ox = 0; ox < outW; ox++)
{
const float* w = px.w.data() + px.ofs[ox];
const int lo = px.lo[ox], cnt = px.cnt[ox];
float acc = 0.f;
for (int k = 0; k < cnt; k++)
acc += w[k] * (float)inRow[lo + k];
bufRow[ox] = acc;
}
}
// Vertical pass: buf[inH x outW] -> out[outH x outW].
for (int oy = 0; oy < outH; oy++)
{
const float* w = py.w.data() + py.ofs[oy];
const int lo = py.lo[oy], cnt = py.cnt[oy];
T* outRow = outPlane + (size_t)oy * outW;
for (int ox = 0; ox < outW; ox++)
{
float acc = 0.f;
for (int k = 0; k < cnt; k++)
acc += w[k] * buf[(size_t)(lo + k) * outW + ox];
outRow[ox] = saturate_cast<T>(acc);
}
}
}
});
}
}
class Resize2LayerImpl : public Resize2Layer
@@ -811,6 +933,33 @@ public:
if (interpolation == "opencv_linear")
halfPixelCenters = true;
keepAspectPolicy = params.get<String>("keep_aspect_ratio_policy", "stretch");
antialias = params.get<int>("antialias", 0) != 0;
if (params.has("axes")) {
const DictValue& a = params.get("axes");
axesAttr.resize(a.size());
for (int i = 0; i < a.size(); i++)
axesAttr[i] = a.get<int>(i);
}
}
// Map the H (axis 2) and W (axis 3) entries within a 2- or 4-element
// sizes/scales vector, honoring the ONNX "axes" attribute order.
void spatialIndices(size_t nelems, int& hIdx, int& wIdx) const
{
if (nelems == 4) { hIdx = 2; wIdx = 3; }
else { hIdx = 0; wIdx = 1; }
if (axesAttr.size() == nelems) {
int foundH = -1, foundW = -1;
for (size_t k = 0; k < nelems; k++) {
int ax = axesAttr[k] < 0 ? axesAttr[k] + 4 : axesAttr[k];
if (ax == 2) foundH = (int)k;
else if (ax == 3) foundW = (int)k;
}
if (foundH >= 0 && foundW >= 0) { hIdx = foundH; wIdx = foundW; }
}
}
bool dynamicOutputShapes() const CV_OVERRIDE
@@ -868,22 +1017,26 @@ public:
: (sizes.size() == 4 || sizes.size() == 2)));
MatShape outShape = inpShape;
const int inH = inpShape[2], inW = inpShape[3];
if (!sizes.empty()) {
if (sizes.size() == 4) {
outShape[2] = sizes[2];
outShape[3] = sizes[3];
} else /* sizes.size() == 2 */ {
outShape[2] = sizes[0];
outShape[3] = sizes[1];
int hIdx, wIdx;
spatialIndices(sizes.size(), hIdx, wIdx);
int szH = sizes[hIdx], szW = sizes[wIdx];
if (keepAspectPolicy == "not_larger" || keepAspectPolicy == "not_smaller") {
float scH = float(szH) / inH, scW = float(szW) / inW;
float sc = keepAspectPolicy == "not_larger" ? std::min(scH, scW)
: std::max(scH, scW);
outShape[2] = int(std::round(sc * inH));
outShape[3] = int(std::round(sc * inW));
} else {
outShape[2] = szH;
outShape[3] = szW;
}
} else {
if (scales.size() == 4) {
outShape[2] = cvFloor(inpShape[2] * scales[2]);
outShape[3] = cvFloor(inpShape[3] * scales[3]);
} else /* scales.size() == 2 */ {
outShape[2] = cvFloor(inpShape[2] * scales[0]);
outShape[3] = cvFloor(inpShape[3] * scales[1]);
}
int hIdx, wIdx;
spatialIndices(scales.size(), hIdx, wIdx);
outShape[2] = cvFloor(inH * scales[hIdx]);
outShape[3] = cvFloor(inW * scales[wIdx]);
}
return outShape;
}
@@ -1016,7 +1169,20 @@ public:
Mat roiTensor = inputs[1];
std::vector<float> roi;
tensorToFloatVec(roiTensor, roi);
if (roi.size() >= 4)
if (axesAttr.size() == 2 && roi.size() == 4)
{
// ROI given per "axes": [start_axes[0], start_axes[1], end_axes[0], end_axes[1]]
float start[4] = {0.f, 0.f, 0.f, 0.f};
float end[4] = {1.f, 1.f, 1.f, 1.f};
for (int k = 0; k < 2; k++) {
int ax = axesAttr[k] < 0 ? axesAttr[k] + 4 : axesAttr[k];
start[ax] = roi[k];
end[ax] = roi[2 + k];
}
roi_start_y = start[2]; roi_start_x = start[3];
roi_end_y = end[2]; roi_end_x = end[3];
}
else if (roi.size() >= 4)
{
if (roi.size() == 4) {
roi_start_y = roi[0];
@@ -1039,10 +1205,19 @@ public:
if (sizes.empty() && !scales.empty() && halfPixelCenters)
{
float sH = (scales.size() == 4) ? scales[2] : scales[0];
float sW = (scales.size() == 4) ? scales[3] : scales[1];
scaleHeight = 1.f / sH;
scaleWidth = 1.f / sW;
int hIdx, wIdx;
spatialIndices(scales.size(), hIdx, wIdx);
scaleHeight = 1.f / scales[hIdx];
scaleWidth = 1.f / scales[wIdx];
}
else if (sizes.empty() && !scales.empty() && alignCorners)
{
int hIdx, wIdx;
spatialIndices(scales.size(), hIdx, wIdx);
float lenH = inpShape[2] * scales[hIdx];
float lenW = inpShape[3] * scales[wIdx];
if (lenH > 1.f) scaleHeight = float(inpShape[2] - 1) / (lenH - 1.f);
if (lenW > 1.f) scaleWidth = float(inpShape[3] - 1) / (lenW - 1.f);
}
auto kind = outputs_arr.kind();
@@ -1084,7 +1259,29 @@ public:
out = out_;
}
if(interpolation=="nearest"){
if (antialias && inp.dims == 4 &&
(interpolation == "bilinear" || interpolation == "opencv_linear" || interpolation == "cubic"))
{
const bool cubic = (interpolation == "cubic");
float xsH, xsW;
if (!scales.empty()) {
int hIdx, wIdx;
spatialIndices(scales.size(), hIdx, wIdx);
xsH = scales[hIdx]; xsW = scales[wIdx];
} else {
xsH = float(outShape[2]) / inpShape[2];
xsW = float(outShape[3]) / inpShape[3];
}
switch (depth) {
case CV_8S: resizeAntialias<int8_t>(inp, out, xsH, xsW, cubic, cubicCoeffA, coordTransModeE); break;
case CV_8U: resizeAntialias<uint8_t>(inp, out, xsH, xsW, cubic, cubicCoeffA, coordTransModeE); break;
case CV_16F: resizeAntialias<hfloat>(inp, out, xsH, xsW, cubic, cubicCoeffA, coordTransModeE); break;
case CV_16BF: resizeAntialias<bfloat>(inp, out, xsH, xsW, cubic, cubicCoeffA, coordTransModeE); break;
case CV_32F: resizeAntialias<float>(inp, out, xsH, xsW, cubic, cubicCoeffA, coordTransModeE); break;
default: CV_Error(Error::StsUnsupportedFormat, "Unsupported depth");
}
}
else if(interpolation=="nearest"){
switch(depth){
case CV_8S:
resizeNearest<int8_t>(inp,out,scaleHeight,scaleWidth,length_resized_y,length_resized_x,nearestModeE,coordTransMode,halfPixelCenters,roi_start_y,roi_end_y,roi_start_x,roi_end_x,extrapolation_value);
@@ -1311,6 +1508,9 @@ protected:
float cubicCoeffA;
float roi_start_y, roi_end_y, roi_start_x, roi_end_x;
float extrapolation_value; // Extrapolation value for tf_crop_and_resize mode
std::vector<int> axesAttr; // ONNX "axes" attribute (subset of dims that sizes/scales refer to)
String keepAspectPolicy; // ONNX "keep_aspect_ratio_policy": stretch|not_larger|not_smaller
bool antialias; // ONNX "antialias" attribute (filter stretching when downsampling)
};
Ptr<Resize2Layer> Resize2Layer::create(const LayerParams& params)
+1 -1
View File
@@ -1740,7 +1740,7 @@ void ONNXImporter2::parseResize2(LayerParams& layerParams, const opencv_onnx::No
layerParams.type = "Resize2";
String interp_mode = layerParams.get<String>("coordinate_transformation_mode", "half_pixel");
bool halfPixel = interp_mode == "tf_half_pixel_for_nn" || interp_mode == "half_pixel" || interp_mode == "pytorch_half_pixel";
bool halfPixel = interp_mode == "tf_half_pixel_for_nn" || interp_mode == "half_pixel" || interp_mode == "pytorch_half_pixel" || interp_mode == "half_pixel_symmetric";
layerParams.set("align_corners", interp_mode == "align_corners");
layerParams.set("half_pixel_centers", halfPixel);
@@ -1897,6 +1897,12 @@ TEST_P(Test_ONNX_conformance, Layer_Test)
name == "test_reduce_sum_square_default_axes_keepdims_random_expanded") {
default_l1 = 2e-5; // Expected: (normL1) <= (l1), actual: 1.52588e-05 vs 1e-05
}
if (name == "test_nllloss_NCd1d2_reduction_sum_expanded") {
default_l1 = 2e-5; // Expected: (normL1) <= (l1), actual: 1.14441e-05 vs 1e-05
}
if (name == "test_nllloss_NCd1d2d3d4d5_mean_weight_expanded") {
default_l1 = 2e-5; // Expected: (normL1) <= (l1), actual: 1.06394e-05 vs 1e-05
}
}
#ifdef HAVE_HALIDE
else if (backend == DNN_BACKEND_HALIDE)
@@ -217,6 +217,10 @@ CASE(test_averagepool_1d_default)
// no filter
CASE(test_averagepool_2d_ceil)
// no filter
CASE(test_averagepool_2d_ceil_last_window_starts_on_pad)
SKIP;
CASE(test_averagepool_2d_dilations)
SKIP;
CASE(test_averagepool_2d_default)
// no filter
CASE(test_averagepool_2d_pads)
@@ -250,6 +254,16 @@ CASE(test_averagepool_2d_strides)
// no filter
CASE(test_averagepool_3d_default)
// no filter
CASE(test_averagepool_3d_dilations_large_count_include_pad_is_0_ceil_mode_is_False)
SKIP;
CASE(test_averagepool_3d_dilations_large_count_include_pad_is_0_ceil_mode_is_True)
SKIP;
CASE(test_averagepool_3d_dilations_large_count_include_pad_is_1_ceil_mode_is_False)
SKIP;
CASE(test_averagepool_3d_dilations_large_count_include_pad_is_1_ceil_mode_is_True)
SKIP;
CASE(test_averagepool_3d_dilations_small)
SKIP;
CASE(test_basic_conv_with_padding)
#if SKIP_SET_1
SKIP_MYRIAD;
@@ -513,7 +527,7 @@ CASE(test_constant_pad)
CASE(test_constantofshape_float_ones)
SKIP;
CASE(test_constantofshape_int_shape_zero)
// no filter
SKIP;
CASE(test_constantofshape_int_zeros)
SKIP;
CASE(test_conv_with_autopad_same)
@@ -677,11 +691,13 @@ CASE(test_einsum_batch_diagonal)
CASE(test_einsum_batch_matmul)
// no filter
CASE(test_einsum_inner_prod)
// no filter
SKIP;
CASE(test_einsum_sum)
// no filter
CASE(test_einsum_transpose)
// no filter
CASE(test_einsum_scalar)
SKIP;
CASE(test_elu)
// no filter
CASE(test_elu_default)
@@ -1204,6 +1220,14 @@ CASE(test_isnan)
SKIP;
CASE(test_isnan_float16)
SKIP;
CASE(test_l1normalization_axis_0)
SKIP;
CASE(test_l1normalization_axis_1)
SKIP;
CASE(test_l1normalization_axis_last)
SKIP;
CASE(test_l2normalization_axis_1)
SKIP;
CASE(test_layer_normalization_2d_axis0)
SKIP;
CASE(test_layer_normalization_2d_axis0_expanded)
@@ -2258,15 +2282,23 @@ CASE(test_resize_downsample_scales_cubic)
CASE(test_resize_downsample_scales_cubic_A_n0p5_exclude_outside)
SKIP;
CASE(test_resize_downsample_scales_cubic_align_corners)
// no filter
SKIP;
CASE(test_resize_downsample_scales_cubic_antialias)
SKIP;
CASE(test_resize_downsample_scales_linear)
SKIP;
CASE(test_resize_downsample_scales_linear_align_corners)
// no filter
SKIP;
CASE(test_resize_downsample_scales_linear_antialias)
SKIP;
CASE(test_resize_downsample_scales_nearest)
SKIP;
CASE(test_resize_downsample_sizes_cubic)
SKIP;
CASE(test_resize_downsample_sizes_cubic_antialias)
SKIP;
CASE(test_resize_downsample_scales_linear_half_pixel_symmetric)
SKIP;
CASE(test_resize_downsample_sizes_linear_pytorch_half_pixel)
SKIP;
CASE(test_resize_downsample_sizes_nearest)
@@ -2275,6 +2307,12 @@ CASE(test_resize_downsample_sizes_nearest_tf_half_pixel_for_nn)
SKIP;
CASE(test_resize_tf_crop_and_resize)
SKIP;
CASE(test_resize_tf_crop_and_resize_axes_2_3)
SKIP;
CASE(test_resize_tf_crop_and_resize_axes_3_2)
SKIP;
CASE(test_resize_tf_crop_and_resize_extrapolation_value)
SKIP;
CASE(test_resize_upsample_scales_cubic)
SKIP;
CASE(test_resize_upsample_scales_cubic_A_n0p5_exclude_outside)
@@ -2283,8 +2321,24 @@ CASE(test_resize_upsample_scales_cubic_align_corners)
SKIP;
CASE(test_resize_upsample_scales_cubic_asymmetric)
SKIP;
CASE(test_resize_upsample_scales_linear_half_pixel_symmetric)
SKIP;
CASE(test_resize_upsample_scales_nearest_axes_3_2)
SKIP;
CASE(test_resize_upsample_sizes_nearest_axes_3_2)
SKIP;
CASE(test_resize_upsample_sizes_nearest_not_larger)
SKIP;
CASE(test_resize_upsample_sizes_nearest_not_smaller)
SKIP;
CASE(test_resize_upsample_scales_linear)
SKIP;
CASE(test_resize_downsample_sizes_linear_antialias)
SKIP;
CASE(test_resize_downsample_sizes_nearest_not_larger)
SKIP;
CASE(test_resize_downsample_sizes_nearest_not_smaller)
SKIP;
CASE(test_resize_upsample_scales_linear_align_corners)
SKIP;
CASE(test_resize_upsample_scales_nearest)
@@ -2317,6 +2371,44 @@ CASE(test_roialign_mode_max)
SKIP;
CASE(test_round)
// no filter
CASE(test_rms_normalization_2d_axis0_expanded)
SKIP;
CASE(test_rms_normalization_2d_axis1_expanded)
SKIP;
CASE(test_rms_normalization_2d_axis_negative_1_expanded)
SKIP;
CASE(test_rms_normalization_2d_axis_negative_2_expanded)
SKIP;
CASE(test_rms_normalization_3d_axis0_epsilon_expanded)
SKIP;
CASE(test_rms_normalization_3d_axis1_epsilon_expanded)
SKIP;
CASE(test_rms_normalization_3d_axis2_epsilon_expanded)
SKIP;
CASE(test_rms_normalization_3d_axis_negative_1_epsilon_expanded)
SKIP;
CASE(test_rms_normalization_3d_axis_negative_2_epsilon_expanded)
SKIP;
CASE(test_rms_normalization_3d_axis_negative_3_epsilon_expanded)
SKIP;
CASE(test_rms_normalization_4d_axis0_expanded)
SKIP;
CASE(test_rms_normalization_4d_axis1_expanded)
SKIP;
CASE(test_rms_normalization_4d_axis2_expanded)
SKIP;
CASE(test_rms_normalization_4d_axis3_expanded)
SKIP;
CASE(test_rms_normalization_4d_axis_negative_1_expanded)
SKIP;
CASE(test_rms_normalization_4d_axis_negative_2_expanded)
SKIP;
CASE(test_rms_normalization_4d_axis_negative_3_expanded)
SKIP;
CASE(test_rms_normalization_4d_axis_negative_4_expanded)
SKIP;
CASE(test_rms_normalization_default_axis_expanded)
SKIP;
CASE(test_scan9_sum)
// no filter
CASE(test_scan_sum)
@@ -2643,6 +2735,24 @@ CASE(test_spacetodepth)
// no filter
CASE(test_spacetodepth_example)
// no filter
CASE(test_split_1d_uneven_split_opset18)
SKIP;
CASE(test_split_2d_uneven_split_opset18)
SKIP;
CASE(test_split_equal_parts_1d_opset13)
SKIP;
CASE(test_split_equal_parts_1d_opset18)
SKIP;
CASE(test_split_equal_parts_default_axis_opset13)
SKIP;
CASE(test_split_equal_parts_default_axis_opset18)
SKIP;
CASE(test_split_zero_size_splits)
SKIP;
CASE(test_split_zero_size_splits_opset13)
SKIP;
CASE(test_split_zero_size_splits_opset18)
SKIP;
CASE(test_split_equal_parts_1d)
SKIP;
CASE(test_split_equal_parts_2d)
@@ -2721,6 +2831,8 @@ CASE(test_sum_two_inputs)
// no filter
CASE(test_swish)
SKIP;
CASE(test_swish_expanded)
SKIP;
CASE(test_tan)
// no filter
CASE(test_tan_example)
@@ -2816,7 +2928,7 @@ CASE(test_tril_square)
CASE(test_tril_square_neg)
SKIP;
CASE(test_tril_zero)
// no filter
SKIP;
CASE(test_triu)
SKIP;
CASE(test_triu_neg)
@@ -2834,7 +2946,7 @@ CASE(test_triu_square)
CASE(test_triu_square_neg)
SKIP;
CASE(test_triu_zero)
// no filter
SKIP;
CASE(test_unique_not_sorted_without_axis)
SKIP;
CASE(test_unique_sorted_with_axis)
@@ -271,8 +271,8 @@
"test_top_k_same_values_2d",
"test_top_k_same_values_largest",
"test_top_k_uint64",
"test_training_dropout_zero_ratio", // ---- same as above ---
"test_wrap_pad", // type mismatch
"test_training_dropout_zero_ratio",
"test_wrap_pad",
"test_div_int16",
"test_div_uint8",
"test_div_int8",
@@ -756,3 +756,67 @@
"test_maxpool_3d_dilations",
"test_maxpool_3d_dilations_use_ref_impl",
"test_maxpool_3d_dilations_use_ref_impl_large",
"test_einsum_inner_prod",
"test_einsum_scalar",
"test_averagepool_2d_ceil_last_window_starts_on_pad",
"test_averagepool_2d_dilations",
"test_averagepool_3d_dilations_large_count_include_pad_is_0_ceil_mode_is_False",
"test_averagepool_3d_dilations_large_count_include_pad_is_0_ceil_mode_is_True",
"test_averagepool_3d_dilations_large_count_include_pad_is_1_ceil_mode_is_False",
"test_averagepool_3d_dilations_large_count_include_pad_is_1_ceil_mode_is_True",
"test_averagepool_3d_dilations_small",
"test_constantofshape_int_shape_zero",
"test_l1normalization_axis_0",
"test_l1normalization_axis_1",
"test_l1normalization_axis_last",
"test_l2normalization_axis_1",
"test_nllloss_NCd1d2d3d4d5_mean_weight_expanded",
"test_nllloss_NCd1d2_reduction_sum_expanded",
"test_rms_normalization_2d_axis0_expanded",
"test_rms_normalization_2d_axis1_expanded",
"test_rms_normalization_2d_axis_negative_1_expanded",
"test_rms_normalization_2d_axis_negative_2_expanded",
"test_rms_normalization_3d_axis0_epsilon_expanded",
"test_rms_normalization_3d_axis1_epsilon_expanded",
"test_rms_normalization_3d_axis2_epsilon_expanded",
"test_rms_normalization_3d_axis_negative_1_epsilon_expanded",
"test_rms_normalization_3d_axis_negative_2_epsilon_expanded",
"test_rms_normalization_3d_axis_negative_3_epsilon_expanded",
"test_rms_normalization_4d_axis0_expanded",
"test_rms_normalization_4d_axis1_expanded",
"test_rms_normalization_4d_axis2_expanded",
"test_rms_normalization_4d_axis3_expanded",
"test_rms_normalization_4d_axis_negative_1_expanded",
"test_rms_normalization_4d_axis_negative_2_expanded",
"test_rms_normalization_4d_axis_negative_3_expanded",
"test_rms_normalization_4d_axis_negative_4_expanded",
"test_rms_normalization_default_axis_expanded",
"test_split_1d_uneven_split_opset18",
"test_split_2d_uneven_split_opset18",
"test_split_equal_parts_1d_opset13",
"test_split_equal_parts_1d_opset18",
"test_split_equal_parts_default_axis_opset13",
"test_split_equal_parts_default_axis_opset18",
"test_split_zero_size_splits",
"test_split_zero_size_splits_opset13",
"test_split_zero_size_splits_opset18",
"test_swish_expanded",
"test_tril_zero",
"test_triu_zero",
"test_resize_downsample_scales_cubic_align_corners",
"test_resize_downsample_scales_cubic_antialias",
"test_resize_downsample_scales_linear_align_corners",
"test_resize_downsample_scales_linear_antialias",
"test_resize_downsample_scales_linear_half_pixel_symmetric",
"test_resize_downsample_sizes_cubic_antialias",
"test_resize_downsample_sizes_linear_antialias",
"test_resize_downsample_sizes_nearest_not_larger",
"test_resize_downsample_sizes_nearest_not_smaller",
"test_resize_tf_crop_and_resize_axes_2_3",
"test_resize_tf_crop_and_resize_axes_3_2",
"test_resize_tf_crop_and_resize_extrapolation_value",
"test_resize_upsample_scales_linear_half_pixel_symmetric",
"test_resize_upsample_scales_nearest_axes_3_2",
"test_resize_upsample_sizes_nearest_axes_3_2",
"test_resize_upsample_sizes_nearest_not_larger",
"test_resize_upsample_sizes_nearest_not_smaller",
@@ -114,13 +114,6 @@
"test_attention_4d_with_qk_matmul_softcap_expanded",
"test_attention_4d_with_qk_matmul_softmax",
"test_attention_4d_with_qk_matmul_softmax_expanded",
"test_averagepool_2d_ceil_last_window_starts_on_pad",
"test_averagepool_2d_dilations",
"test_averagepool_3d_dilations_large_count_include_pad_is_0_ceil_mode_is_False",
"test_averagepool_3d_dilations_large_count_include_pad_is_0_ceil_mode_is_True",
"test_averagepool_3d_dilations_large_count_include_pad_is_1_ceil_mode_is_False",
"test_averagepool_3d_dilations_large_count_include_pad_is_1_ceil_mode_is_True",
"test_averagepool_3d_dilations_small",
"test_basic_convinteger", // Issues::Layer::Can't create layer "onnx_node_output_0!y" of type "ConvInteger" in function 'getLayerInstance'
"test_basic_deform_conv_with_padding",
"test_basic_deform_conv_without_padding",
@@ -266,7 +259,6 @@
"test_compress_negative_axis", // ---- same as above ---
"test_constant_pad_axes", //type mismatch
"test_constant_pad_negative_axes",
"test_constantofshape_int_shape_zero", // Issue::Parser::Weights are required as inputs
"test_convinteger_with_padding", // Issues::Layer::Can't create layer "onnx_node_output_0!y" of type "ConvInteger" in function 'getLayerInstance'
"test_convinteger_without_padding", //Issues::Layer::Can't create layer "onnx_node_output_0!y" of type "ConvInteger" in function 'getLayerInstance'
"test_convtranspose_autopad_same",
@@ -290,8 +282,6 @@
"test_dynamicquantizelinear_max_adjusted_expanded", // ---- same as above ---
"test_dynamicquantizelinear_min_adjusted", // ---- same as above ---
"test_dynamicquantizelinear_min_adjusted_expanded", // ---- same as above ---
"test_einsum_inner_prod", // Issue::Output shape does not match with reference
"test_einsum_scalar",
"test_equal_string",
"test_equal_string_broadcast",
"test_gridsample_bicubic", // ---- same as above ---
@@ -312,11 +302,7 @@
"test_image_decoder_decode_pnm_rgb",
"test_image_decoder_decode_tiff_rgb",
"test_image_decoder_decode_webp_rgb",
"test_l1normalization_axis_0",
"test_l1normalization_axis_1",
"test_l1normalization_axis_last",
"test_l2normalization_axis_0",
"test_l2normalization_axis_1",
"test_l2normalization_axis_0", //nan
"test_loop13_seq", // Loop with tensor sequences output, not yet supported in OpenCV
"test_loop16_seq_none", // Loop with optional tensor sequences, not yet supported in OpenCV
"test_lppool_1d_default",
@@ -336,8 +322,6 @@
"test_mvn_expanded", // Issues::Wrong answer
"test_mvn_expanded_ver18",
"test_nesterov_momentum", // Issues::Layer does not exist (NesterovsAcceleratedGradient) Can't create layer "onnx_node_output_0!X_new" of type "ai.onnx.preview.training.Momentum" in function 'getLayerInstance'
"test_nllloss_NCd1d2_reduction_sum_expanded",
"test_nllloss_NCd1d2d3d4d5_mean_weight_expanded",
"test_optional_get_element", // Issue::out of memory :: Failed to allocate 1044051907127083008 bytes in function 'OutOfMemoryError'
"test_optional_get_element_optional_sequence",
"test_optional_get_element_optional_tensor",
@@ -377,44 +361,8 @@
"test_regex_full_match_email_domain",
"test_regex_full_match_empty",
"test_reshape_allowzero_reordered", // incompatible type of input tensor #0 'data': CV_8UC1 given, CV_32FC1 expected in function 'setGraphInput'
"test_resize_downsample_scales_cubic_align_corners", // ---- same as above ---
"test_resize_downsample_scales_cubic_antialias",
"test_resize_downsample_scales_linear_align_corners", // ---- same as above ---
"test_resize_downsample_scales_linear_antialias", //incorrect output
"test_resize_downsample_scales_linear_half_pixel_symmetric",
"test_resize_downsample_sizes_cubic_antialias",
"test_resize_downsample_sizes_linear_antialias",
"test_resize_downsample_sizes_nearest_not_larger",
"test_resize_downsample_sizes_nearest_not_smaller",
"test_resize_tf_crop_and_resize_axes_2_3",
"test_resize_tf_crop_and_resize_axes_3_2",
"test_resize_tf_crop_and_resize_extrapolation_value",
"test_resize_upsample_scales_linear_half_pixel_symmetric", //shape mismatch
"test_resize_upsample_scales_nearest_axes_3_2",
"test_resize_upsample_sizes_nearest_axes_3_2",
"test_resize_upsample_sizes_nearest_not_larger",
"test_resize_upsample_sizes_nearest_not_smaller",
"test_reversesequence_batch", // Issue:: Parser: Can't create layer "onnx_node_output_0!y" of type "ReverseSequence" in function 'getLayerInstance'
"test_reversesequence_time", // ---- same as above ---
"test_rms_normalization_2d_axis0_expanded",
"test_rms_normalization_2d_axis1_expanded",
"test_rms_normalization_2d_axis_negative_1_expanded",
"test_rms_normalization_2d_axis_negative_2_expanded",
"test_rms_normalization_3d_axis0_epsilon_expanded",
"test_rms_normalization_3d_axis1_epsilon_expanded",
"test_rms_normalization_3d_axis2_epsilon_expanded",
"test_rms_normalization_3d_axis_negative_1_epsilon_expanded",
"test_rms_normalization_3d_axis_negative_2_epsilon_expanded",
"test_rms_normalization_3d_axis_negative_3_epsilon_expanded",
"test_rms_normalization_4d_axis0_expanded",
"test_rms_normalization_4d_axis1_expanded",
"test_rms_normalization_4d_axis2_expanded",
"test_rms_normalization_4d_axis3_expanded",
"test_rms_normalization_4d_axis_negative_1_expanded",
"test_rms_normalization_4d_axis_negative_2_expanded",
"test_rms_normalization_4d_axis_negative_3_expanded",
"test_rms_normalization_4d_axis_negative_4_expanded",
"test_rms_normalization_default_axis_expanded",
"test_rnn_seq_length", // Issue:: Parser: Can't create layer "onnx_node_output_1!Y_h" of type "RNN" in function 'getLayerInstance'
"test_scan9_sum", // Issue:: Parser: 'Graph' is not supported in function 'getLayerParams'
"test_scan_sum", // ---- same as above ---
@@ -437,18 +385,9 @@
"test_simple_rnn_defaults", // ---- same as above ---
"test_simple_rnn_with_initial_bias", // ---- same as above ---
"test_slice_start_out_of_bounds",
"test_split_1d_uneven_split_opset18", //type mismatch
"test_split_2d_uneven_split_opset18",
"test_split_equal_parts_1d_opset13",
"test_split_equal_parts_1d_opset18",
"test_split_equal_parts_default_axis_opset13",
"test_split_equal_parts_default_axis_opset18",
"test_split_to_sequence_1",
"test_split_to_sequence_2",
"test_split_to_sequence_nokeepdims",
"test_split_zero_size_splits", // ---- incompatible type of input tensor #0 'input': CV_8UC1 given, CV_32FC1 expected in function 'setGraphInput' ---
"test_split_zero_size_splits_opset13", // type mismatch
"test_split_zero_size_splits_opset18", // type mismatch
"test_stft",
"test_stft_with_window",
"test_string_concat",
@@ -468,7 +407,6 @@
"test_strnormalizer_export_monday_empty_output", // ---- same as above ---
"test_strnormalizer_export_monday_insensintive_upper_twodim", // ---- same as above ---
"test_strnormalizer_nostopwords_nochangecase", // Issue:: Parser: Can't create layer "onnx_node_output_0!y" of type "StringNormalizer" in function 'getLayerInstance'
"test_swish_expanded",
"test_tensorscatter",
"test_tensorscatter_3d",
"test_tensorscatter_circular",
@@ -484,6 +422,4 @@
"test_training_dropout_default_mask", // ---- same as above ---
"test_training_dropout_mask", // ---- same as above ---
"test_training_dropout_zero_ratio_mask", // ---- same as above ---
"test_tril_zero", // ---- same as above --- type mismatch
"test_triu_zero", // ---- same as above --- type mismatch
"test_unique_length_1", //incorrect output