From 1719aa1339968188e6c8e84861cf2576327d9514 Mon Sep 17 00:00:00 2001 From: Abhishek Gola Date: Tue, 10 Feb 2026 17:15:56 +0530 Subject: [PATCH] Merge pull request #28453 from abhishek-gola:roialign_layer_add Added RoiAlign layer support in new DNN engine #28453 Fixes `Unsupported Operation: RoiAlign` issue in https://github.com/opencv/opencv/issues/20258 and https://github.com/opencv/opencv/issues/22099, model parsing is successful now. Merge with: https://github.com/opencv/opencv_extra/pull/1310 ### 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 --- .../dnn/include/opencv2/dnn/all_layers.hpp | 6 + modules/dnn/src/init.cpp | 1 + modules/dnn/src/layers/roialign_layer.cpp | 406 ++++++++++++++++++ modules/dnn/src/onnx/onnx_importer2.cpp | 8 + modules/dnn/test/test_onnx_conformance.cpp | 9 +- ...conformance_layer_filter__openvino.inl.hpp | 6 +- ...yer_filter_opencv_classic_denylist.inl.hpp | 3 + ..._conformance_layer_parser_denylist.inl.hpp | 3 - 8 files changed, 436 insertions(+), 6 deletions(-) create mode 100644 modules/dnn/src/layers/roialign_layer.cpp diff --git a/modules/dnn/include/opencv2/dnn/all_layers.hpp b/modules/dnn/include/opencv2/dnn/all_layers.hpp index bb0085201b..6afe873768 100644 --- a/modules/dnn/include/opencv2/dnn/all_layers.hpp +++ b/modules/dnn/include/opencv2/dnn/all_layers.hpp @@ -1420,6 +1420,12 @@ CV__DNN_INLINE_NS_BEGIN static Ptr create(const LayerParams& params); }; + class CV_EXPORTS RoiAlignLayer : public Layer + { + public: + static Ptr create(const LayerParams& params); + }; + class CV_EXPORTS CumSumLayer : public Layer { public: diff --git a/modules/dnn/src/init.cpp b/modules/dnn/src/init.cpp index 81c5e48039..d8ba3c6056 100644 --- a/modules/dnn/src/init.cpp +++ b/modules/dnn/src/init.cpp @@ -90,6 +90,7 @@ void initializeLayerFactory() CV_DNN_REGISTER_LAYER_CLASS(ConstantOfShape, ConstantOfShapeLayer); CV_DNN_REGISTER_LAYER_CLASS(RandomNormalLike, RandomNormalLikeLayer); CV_DNN_REGISTER_LAYER_CLASS(CropAndResize, CropAndResizeLayer); + CV_DNN_REGISTER_LAYER_CLASS(RoiAlign, RoiAlignLayer); CV_DNN_REGISTER_LAYER_CLASS(DequantizeLinear, DequantizeLinearLayer); CV_DNN_REGISTER_LAYER_CLASS(Expand2, Expand2Layer); CV_DNN_REGISTER_LAYER_CLASS(Flatten, FlattenLayer); diff --git a/modules/dnn/src/layers/roialign_layer.cpp b/modules/dnn/src/layers/roialign_layer.cpp new file mode 100644 index 0000000000..8f42c9cc90 --- /dev/null +++ b/modules/dnn/src/layers/roialign_layer.cpp @@ -0,0 +1,406 @@ +// 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. +// Copyright (C) 2025, BigVision LLC, all rights reserved. +// Third party copyrights are property of their respective owners. + +#include "../precomp.hpp" +#include "layers_common.hpp" +#include + +namespace cv { +namespace dnn { + +// ONNX RoiAlign operator +// Spec: https://onnx.ai/onnx/operators/onnx__RoiAlign.html +// Supported opsets: 10-22 + +namespace { + +enum class RoiAlignMode +{ + AVG = 0, + MAX = 1 +}; + +enum class CoordTransformMode +{ + HALF_PIXEL = 0, + OUTPUT_HALF_PIXEL = 1 +}; + +template +class RoiAlignForwardInvoker CV_FINAL : public ParallelLoopBody +{ +public: + RoiAlignForwardInvoker(const Mat& X_, Mat& Y_, + const Mat& rois_, const Mat& batch_indices_, + const int* Xsize, + int pooled_h_, int pooled_w_, int sampling_ratio_, + float spatial_scale_, float offset_, + bool clampMalformedRoi_) + : X(X_), Y(Y_), rois(rois_), batch_indices(batch_indices_), + output_height(pooled_h_), output_width(pooled_w_), sampling_ratio(sampling_ratio_), + spatial_scale(spatial_scale_), offset(offset_), + clampMalformedRoi(clampMalformedRoi_) + { + CV_Assert(X.isContinuous() && Y.isContinuous()); + CV_Assert(rois.isContinuous() && batch_indices.isContinuous()); + CV_Assert(Xsize); + N = Xsize[0]; C = Xsize[1]; H = Xsize[2]; W = Xsize[3]; + + Xdata = X.ptr(); + Ydata = Y.ptr(); + + spatialSize = static_cast(H) * W; + channelStride = spatialSize; + batchStride = static_cast(C) * spatialSize; + outSpatial = output_height * output_width; + + Rdepth = rois.depth(); + + const int bdepth = batch_indices.depth(); + if (bdepth == CV_32S) + { + batch32 = batch_indices.ptr(); + } + else if (bdepth == CV_64S) + { + batch64 = batch_indices.ptr(); + } + else + { + CV_Error(Error::StsUnsupportedFormat, "Unsupported batch_indices depth (expected int32 or int64)"); + } + } + + void operator()(const Range& range) const CV_OVERRIDE + { + for (int r = range.start; r < range.end; ++r) + { + const int b = batch64 ? static_cast(batch64[r]) : batch32[r]; + CV_Assert(0 <= b && b < N); + + float x1, y1, x2, y2; + if (Rdepth == CV_32F) + readScaledRoiCoords(rois, r, spatial_scale, offset, x1, y1, x2, y2); + else if (Rdepth == CV_64F) + readScaledRoiCoords(rois, r, spatial_scale, offset, x1, y1, x2, y2); + else if (Rdepth == CV_16F) + readScaledRoiCoords(rois, r, spatial_scale, offset, x1, y1, x2, y2); + else if (Rdepth == CV_16BF) + readScaledRoiCoords(rois, r, spatial_scale, offset, x1, y1, x2, y2); + else + CV_Error(Error::StsUnsupportedFormat, "Unsupported rois depth"); + + float roi_width = x2 - x1; + float roi_height = y2 - y1; + + if (clampMalformedRoi) + { + roi_width = std::max(roi_width, 1.f); + roi_height = std::max(roi_height, 1.f); + } + + const float bin_size_w = roi_width / output_width; + const float bin_size_h = roi_height / output_height; + + const int gw = std::max((sampling_ratio > 0) ? sampling_ratio + : cvCeil(roi_width / output_width), 1); + const int gh = std::max((sampling_ratio > 0) ? sampling_ratio + : cvCeil(roi_height / output_height), 1); + const int sample_count_i = gw * gh; + const float inv_sample_count = 1.f / static_cast(sample_count_i); + const float step_y = bin_size_h / gh; + const float step_x = bin_size_w / gw; + + AutoBuffer samples(static_cast(outSpatial) * sample_count_i); + for (int outIdx = 0; outIdx < outSpatial; ++outIdx) + { + const int ph = outIdx / output_width; + const int pw = outIdx - ph * output_width; + const float ph_off = ph * bin_size_h; + const float pw_off = pw * bin_size_w; + + BilinearSample* dst = samples.data() + static_cast(outIdx) * sample_count_i; + for (int s = 0; s < sample_count_i; ++s) + { + const int iy = s / gw; + const int ix = s - iy * gw; + const float yy = y1 + ph_off + (iy + 0.5f) * step_y; + const float xx = x1 + pw_off + (ix + 0.5f) * step_x; + dst[s] = precomputeBilinearSample(H, W, yy, xx); + } + } + + const size_t y_roi_base = static_cast(r) * static_cast(C) * outSpatial; + const size_t x_batch_base = static_cast(b) * batchStride; + + for (int outPlane = 0; outPlane < C * outSpatial; ++outPlane) + { + const int c = outPlane / outSpatial; + const int outIdx = outPlane - c * outSpatial; + + const T* img = Xdata + x_batch_base + static_cast(c) * channelStride; + const BilinearSample* src = samples.data() + static_cast(outIdx) * sample_count_i; + + float outv = MaxMode ? -FLT_MAX : 0.f; + for (int s = 0; s < sample_count_i; ++s) + { + const BilinearSample& bs = src[s]; + const float v00 = static_cast(img[bs.idx00]); + const float v01 = static_cast(img[bs.idx01]); + const float v10 = static_cast(img[bs.idx10]); + const float v11 = static_cast(img[bs.idx11]); + + const float v = MaxMode + ? std::max(std::max(bs.w1 * v00, bs.w2 * v01), std::max(bs.w3 * v10, bs.w4 * v11)) + : (bs.w1 * v00 + bs.w2 * v01 + bs.w3 * v10 + bs.w4 * v11); + + outv = MaxMode ? std::max(outv, v) : (outv + v); + } + + outv = MaxMode ? ((outv == -FLT_MAX) ? 0.f : outv) : (outv * inv_sample_count); + + Ydata[y_roi_base + static_cast(outPlane)] = saturate_cast(outv); + } + } + } + +private: + struct BilinearSample + { + size_t idx00 = 0, idx01 = 0, idx10 = 0, idx11 = 0; + float w1 = 0.f, w2 = 0.f, w3 = 0.f, w4 = 0.f; + }; + + template + static inline void readScaledRoiCoords(const Mat& rois, int r, float spatial_scale, float offset, + float& x1, float& y1, float& x2, float& y2) + { + const TRoi* p = rois.ptr(r); + x1 = static_cast(p[0]) * spatial_scale - offset; + y1 = static_cast(p[1]) * spatial_scale - offset; + x2 = static_cast(p[2]) * spatial_scale - offset; + y2 = static_cast(p[3]) * spatial_scale - offset; + } + + static inline BilinearSample precomputeBilinearSample(int height, int width, float y, float x) + { + BilinearSample s; + if (y < -1.f || y > height || x < -1.f || x > width) + return s; + + y = std::min(std::max(y, 0.f), static_cast(height - 1)); + x = std::min(std::max(x, 0.f), static_cast(width - 1)); + + const int y_low = static_cast(y); + const int x_low = static_cast(x); + const int y_high = std::min(y_low + 1, height - 1); + const int x_high = std::min(x_low + 1, width - 1); + + const float ly = y - y_low; + const float lx = x - x_low; + const float hy = 1.f - ly; + const float hx = 1.f - lx; + + s.w1 = hy * hx; + s.w2 = hy * lx; + s.w3 = ly * hx; + s.w4 = ly * lx; + + s.idx00 = static_cast(y_low) * width + x_low; + s.idx01 = static_cast(y_low) * width + x_high; + s.idx10 = static_cast(y_high) * width + x_low; + s.idx11 = static_cast(y_high) * width + x_high; + + return s; + } + + const Mat& X; + Mat& Y; + const Mat& rois; + const Mat& batch_indices; + + int N = 0, C = 0, H = 0, W = 0; + int output_height, output_width, sampling_ratio; + float spatial_scale, offset; + bool clampMalformedRoi; + + const T* Xdata = nullptr; + T* Ydata = nullptr; + + int Rdepth = -1; + int outSpatial = 0; + + size_t spatialSize = 0; + size_t channelStride = 0; + size_t batchStride = 0; + + const int* batch32 = nullptr; + const int64* batch64 = nullptr; +}; + +} + +class RoiAlignLayerImpl CV_FINAL : public RoiAlignLayer +{ +public: + RoiAlignLayerImpl(const LayerParams& params) + { + setParamsFrom(params); + + output_height = params.get("output_height", 1); + output_width = params.get("output_width", 1); + sampling_ratio = params.get("sampling_ratio", 0); + spatial_scale = params.get("spatial_scale", 1.f); + const String modeStr = params.get("mode", "avg"); + CV_Assert(modeStr == "avg" || modeStr == "max"); + mode_ = (modeStr == "max") ? RoiAlignMode::MAX : RoiAlignMode::AVG; + + const String coordStr = params.get("coordinate_transformation_mode", "half_pixel"); + CV_Assert(coordStr == "half_pixel" || coordStr == "output_half_pixel"); + coord_mode_ = (coordStr == "half_pixel") ? CoordTransformMode::HALF_PIXEL + : CoordTransformMode::OUTPUT_HALF_PIXEL; + + CV_Assert(output_height > 0 && output_width > 0); + CV_Assert(sampling_ratio >= 0); + } + + bool supportBackend(int backendId) CV_OVERRIDE + { + return backendId == DNN_BACKEND_OPENCV; + } + + bool getMemoryShapes(const std::vector& inputs, + const int /*requiredOutputs*/, + std::vector& outputs, + std::vector& /*internals*/) const CV_OVERRIDE + { + CV_Assert(inputs.size() == 3); + + const MatShape& X = inputs[0]; + const MatShape& rois = inputs[1]; + const MatShape& batch_indices = inputs[2]; + + CV_Assert(X.size() == 4); + CV_Assert(rois.size() == 2); + CV_Assert(rois[1] == 4); + CV_Assert(batch_indices.size() == 1 || (batch_indices.size() == 2 && batch_indices[1] == 1)); + + MatShape out(4); + out[0] = rois[0]; + out[1] = X[1]; + out[2] = output_height; + out[3] = output_width; + + outputs.assign(1, out); + return false; + } + + void getTypes(const std::vector& inputs, + const int requiredOutputs, + const int requiredInternals, + std::vector& outputs, + std::vector& internals) const CV_OVERRIDE + { + CV_Assert(inputs.size() == 3); + CV_Assert(CV_MAT_DEPTH(inputs[0]) == CV_32F || CV_MAT_DEPTH(inputs[0]) == CV_64F || + CV_MAT_DEPTH(inputs[0]) == CV_16F || CV_MAT_DEPTH(inputs[0]) == CV_16BF); + CV_Assert(CV_MAT_DEPTH(inputs[1]) == CV_32F || CV_MAT_DEPTH(inputs[1]) == CV_64F || + CV_MAT_DEPTH(inputs[1]) == CV_16F || CV_MAT_DEPTH(inputs[1]) == CV_16BF); + CV_Assert(CV_MAT_DEPTH(inputs[2]) == CV_32S || CV_MAT_DEPTH(inputs[2]) == CV_64S); + + outputs.assign(requiredOutputs, MatType(inputs[0])); + internals.assign(requiredInternals, MatType(inputs[0])); + } + + void forward(InputArrayOfArrays inputs_arr, + OutputArrayOfArrays outputs_arr, + OutputArrayOfArrays /*internals_arr*/) CV_OVERRIDE + { + CV_TRACE_FUNCTION(); + CV_TRACE_ARG_VALUE(name, "name", name.c_str()); + + std::vector inputs, outputs; + inputs_arr.getMatVector(inputs); + outputs_arr.getMatVector(outputs); + + CV_Assert(inputs.size() == 3); + CV_Assert(outputs.size() == 1); + + const Mat& X = inputs[0]; + Mat rois = inputs[1]; + Mat batch_indices = inputs[2]; + Mat& Y = outputs[0]; + + CV_Assert(X.dims == 4); + const int C = X.size[1]; + + CV_Assert(X.depth() == CV_32F || X.depth() == CV_64F || X.depth() == CV_16F || X.depth() == CV_16BF); + CV_Assert(rois.depth() == CV_32F || rois.depth() == CV_64F || rois.depth() == CV_16F || rois.depth() == CV_16BF); + CV_Assert(batch_indices.depth() == CV_32S || batch_indices.depth() == CV_64S); + + CV_Assert(rois.total() % 4 == 0); + const int num_rois = static_cast(rois.total() / 4); + rois = rois.reshape(1, num_rois); + batch_indices = batch_indices.reshape(1, static_cast(batch_indices.total())); + + CV_Assert(rois.rows == num_rois && rois.cols == 4); + CV_Assert(static_cast(batch_indices.total()) == num_rois); + + CV_Assert(Y.dims == 4); + CV_Assert(Y.size[0] == num_rois && Y.size[1] == C && Y.size[2] == output_height && Y.size[3] == output_width); + + const bool isMaxMode = (mode_ == RoiAlignMode::MAX); + const float offset = (coord_mode_ == CoordTransformMode::HALF_PIXEL) ? 0.5f : 0.0f; + const bool clampMalformedRoi = (coord_mode_ != CoordTransformMode::HALF_PIXEL); + const int* Xsize = X.size.p; + const int Xdepth = X.depth(); + if (Xdepth == CV_32F) + { + if (isMaxMode) + parallel_for_(Range(0, num_rois), RoiAlignForwardInvoker(X, Y, rois, batch_indices, Xsize, output_height, output_width, sampling_ratio, spatial_scale, offset, clampMalformedRoi)); + else + parallel_for_(Range(0, num_rois), RoiAlignForwardInvoker(X, Y, rois, batch_indices, Xsize, output_height, output_width, sampling_ratio, spatial_scale, offset, clampMalformedRoi)); + } + else if (Xdepth == CV_64F) + { + if (isMaxMode) + parallel_for_(Range(0, num_rois), RoiAlignForwardInvoker(X, Y, rois, batch_indices, Xsize, output_height, output_width, sampling_ratio, spatial_scale, offset, clampMalformedRoi)); + else + parallel_for_(Range(0, num_rois), RoiAlignForwardInvoker(X, Y, rois, batch_indices, Xsize, output_height, output_width, sampling_ratio, spatial_scale, offset, clampMalformedRoi)); + } + else if (Xdepth == CV_16F) + { + if (isMaxMode) + parallel_for_(Range(0, num_rois), RoiAlignForwardInvoker(X, Y, rois, batch_indices, Xsize, output_height, output_width, sampling_ratio, spatial_scale, offset, clampMalformedRoi)); + else + parallel_for_(Range(0, num_rois), RoiAlignForwardInvoker(X, Y, rois, batch_indices, Xsize, output_height, output_width, sampling_ratio, spatial_scale, offset, clampMalformedRoi)); + } + else if (Xdepth == CV_16BF) + { + if (isMaxMode) + parallel_for_(Range(0, num_rois), RoiAlignForwardInvoker(X, Y, rois, batch_indices, Xsize, output_height, output_width, sampling_ratio, spatial_scale, offset, clampMalformedRoi)); + else + parallel_for_(Range(0, num_rois), RoiAlignForwardInvoker(X, Y, rois, batch_indices, Xsize, output_height, output_width, sampling_ratio, spatial_scale, offset, clampMalformedRoi)); + } + else + CV_Error(Error::StsUnsupportedFormat, "Unsupported X depth"); + } + +private: + int output_height = 1; + int output_width = 1; + int sampling_ratio = 0; + float spatial_scale = 1.f; + RoiAlignMode mode_ = RoiAlignMode::AVG; + CoordTransformMode coord_mode_ = CoordTransformMode::HALF_PIXEL; +}; + +Ptr RoiAlignLayer::create(const LayerParams& params) +{ + return Ptr(new RoiAlignLayerImpl(params)); +} + +}} // namespace cv::dnn diff --git a/modules/dnn/src/onnx/onnx_importer2.cpp b/modules/dnn/src/onnx/onnx_importer2.cpp index a8176cc9e6..d740e3f818 100644 --- a/modules/dnn/src/onnx/onnx_importer2.cpp +++ b/modules/dnn/src/onnx/onnx_importer2.cpp @@ -253,6 +253,7 @@ protected: void parseRMSNormalization (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto); void parseRotaryEmbedding (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto); void parseRandomNormalLike (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto); + void parseRoiAlign (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto); // Domain: com.microsoft // URL: https://github.com/microsoft/onnxruntime/blob/master/docs/ContribOperators.md @@ -2682,6 +2683,12 @@ void ONNXImporter2::parseAttentionOnnxAi(LayerParams& params, const opencv_onnx: addLayer(params, node_proto, n_inputs); } +void ONNXImporter2::parseRoiAlign(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto) +{ + layerParams.type = "RoiAlign"; + addLayer(layerParams, node_proto, 3); +} + // Domain: ai.onnx (default) // URL: https://github.com/onnx/onnx/blob/master/docs/Operators.md void ONNXImporter2::buildDispatchMap_ONNX_AI() @@ -2748,6 +2755,7 @@ void ONNXImporter2::buildDispatchMap_ONNX_AI() dispatch["HammingWindow"] = &ONNXImporter2::parseHammingWindow; dispatch["GridSample"] = &ONNXImporter2::parseGridSample; dispatch["AffineGrid"] = &ONNXImporter2::parseAffineGrid; + dispatch["RoiAlign"] = &ONNXImporter2::parseRoiAlign; dispatch["Upsample"] = &ONNXImporter2::parseUpsample; dispatch["BitShift"] = &ONNXImporter2::parseBitShift; dispatch["BitwiseAnd"] = &ONNXImporter2::parseBitwise; diff --git a/modules/dnn/test/test_onnx_conformance.cpp b/modules/dnn/test/test_onnx_conformance.cpp index dbb809010f..e4cbaaacfb 100644 --- a/modules/dnn/test/test_onnx_conformance.cpp +++ b/modules/dnn/test/test_onnx_conformance.cpp @@ -1580,7 +1580,7 @@ static const TestCase testConformanceConfig[] = { {"test_rms_normalization_4d_axis_negative_4_expanded", 0, 0}, {"test_rms_normalization_default_axis", 0, 0}, {"test_rms_normalization_default_axis_expanded", 0, 0}, - {"test_roialign_mode_max", 0, 0}, + {"test_roialign_mode_max", 3, 1}, {"test_rotary_embedding", 0, 0}, {"test_rotary_embedding_3d_input", 0, 0}, {"test_rotary_embedding_3d_input_expanded", 0, 0}, @@ -1892,6 +1892,10 @@ TEST_P(Test_ONNX_conformance, Layer_Test) { applyTestTag(CV_TEST_TAG_DNN_SKIP_CPU, CV_TEST_TAG_DNN_SKIP_OPENCV_BACKEND, CV_TEST_TAG_DNN_SKIP_ONNX_CONFORMANCE); } + if (name == "test_roialign_aligned_false" || name == "test_roialign_aligned_true") + { + default_l1 = std::max(default_l1, 3e-5); + } if (name == "test_gelu_tanh_1") { default_l1 = 0.00011; // Expected: (normL1) <= (l1), actual: 0.000101805 vs 1e-05 default_lInf = 0.00016; // Expected: (normInf) <= (lInf), actual: 0.000152707 vs 0.0001 @@ -1964,6 +1968,9 @@ TEST_P(Test_ONNX_conformance, Layer_Test) default_lInf = 0.0005; // Expected: (normInf) <= (lInf), actual: 0.000455445 vs 0.0001 } } + if (name == "test_roialign_aligned_false" || name == "test_roialign_aligned_true") { + default_l1 = 3e-5; + } } #endif else diff --git a/modules/dnn/test/test_onnx_conformance_layer_filter__openvino.inl.hpp b/modules/dnn/test/test_onnx_conformance_layer_filter__openvino.inl.hpp index fe8b2992d8..c0fb5cda1f 100644 --- a/modules/dnn/test/test_onnx_conformance_layer_filter__openvino.inl.hpp +++ b/modules/dnn/test/test_onnx_conformance_layer_filter__openvino.inl.hpp @@ -2268,9 +2268,11 @@ CASE(test_reversesequence_time) CASE(test_rnn_seq_length) // no filter CASE(test_roialign_aligned_false) - // no filter + SKIP; CASE(test_roialign_aligned_true) - // no filter + SKIP; +CASE(test_roialign_mode_max) + SKIP; CASE(test_round) // no filter CASE(test_scan9_sum) diff --git a/modules/dnn/test/test_onnx_conformance_layer_filter_opencv_classic_denylist.inl.hpp b/modules/dnn/test/test_onnx_conformance_layer_filter_opencv_classic_denylist.inl.hpp index 6d1e283787..e15af3d8e7 100644 --- a/modules/dnn/test/test_onnx_conformance_layer_filter_opencv_classic_denylist.inl.hpp +++ b/modules/dnn/test/test_onnx_conformance_layer_filter_opencv_classic_denylist.inl.hpp @@ -709,3 +709,6 @@ "test_layer_normalization_default_axis", "test_layer_normalization_default_axis_expanded", "test_layer_normalization_default_axis_expanded_ver18", +"test_roialign_aligned_false", +"test_roialign_aligned_true", +"test_roialign_mode_max", diff --git a/modules/dnn/test/test_onnx_conformance_layer_parser_denylist.inl.hpp b/modules/dnn/test/test_onnx_conformance_layer_parser_denylist.inl.hpp index 3e2064fb16..94bb1ce17d 100644 --- a/modules/dnn/test/test_onnx_conformance_layer_parser_denylist.inl.hpp +++ b/modules/dnn/test/test_onnx_conformance_layer_parser_denylist.inl.hpp @@ -459,9 +459,6 @@ "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_roialign_aligned_false", // Issue:: Parser: Layer does not exist (RoiAlign) -"test_roialign_aligned_true", // ---- same as above --- -"test_roialign_mode_max", "test_scan9_sum", // Issue:: Parser: 'Graph' is not supported in function 'getLayerParams' "test_scan_sum", // ---- same as above --- "test_sequence_insert_at_back", // Issue:: Parser: typeProto.has_tensor_type() in function 'populateNet'