mirror of
https://github.com/opencv/opencv.git
synced 2026-07-21 19:33:03 +04:00
Merge pull request #28807 from abhishek-gola:eyelike_layer_add
Added EyeLike layer support
This commit is contained in:
@@ -1557,6 +1557,12 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
static Ptr<DetLayer> create(const LayerParams ¶ms);
|
||||
};
|
||||
|
||||
class CV_EXPORTS EyeLikeLayer : public Layer
|
||||
{
|
||||
public:
|
||||
static Ptr<EyeLikeLayer> create(const LayerParams ¶ms);
|
||||
};
|
||||
|
||||
class CV_EXPORTS CenterCropPadLayer : public Layer
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -120,6 +120,7 @@ void initializeLayerFactory()
|
||||
CV_DNN_REGISTER_LAYER_CLASS(IsInf, IsInfLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(OneHot, OneHotLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Det, DetLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(EyeLike, EyeLikeLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(BlackmanWindow, BlackmanWindowLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(HannWindow, HannWindowLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(HammingWindow, HammingWindowLayer);
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
// 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) 2026, BigVision LLC, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "../precomp.hpp"
|
||||
#include "layers_common.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
|
||||
namespace cv {
|
||||
namespace dnn {
|
||||
|
||||
// ONNX EyeLike operator
|
||||
// Spec: https://onnx.ai/onnx/operators/onnx__EyeLike.html
|
||||
// Supported opsets: 9-22
|
||||
|
||||
class EyeLikeLayerImpl CV_FINAL : public EyeLikeLayer
|
||||
{
|
||||
public:
|
||||
int k; // diagonal offset
|
||||
int outputDtype; // -1 means use input dtype
|
||||
|
||||
EyeLikeLayerImpl(const LayerParams& params)
|
||||
{
|
||||
setParamsFrom(params);
|
||||
k = params.get<int>("k", 0);
|
||||
outputDtype = params.get<int>("dtype", -1);
|
||||
}
|
||||
|
||||
bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV;
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape>& inputs,
|
||||
const int /*requiredOutputs*/,
|
||||
std::vector<MatShape>& outputs,
|
||||
std::vector<MatShape>& /*internals*/) const CV_OVERRIDE
|
||||
{
|
||||
CV_Assert(inputs.size() == 1);
|
||||
const MatShape& in = inputs[0];
|
||||
CV_Assert(in.size() == 2);
|
||||
outputs.assign(1, in);
|
||||
return false;
|
||||
}
|
||||
|
||||
void getTypes(const std::vector<MatType>& inputs,
|
||||
const int requiredOutputs,
|
||||
const int requiredInternals,
|
||||
std::vector<MatType>& outputs,
|
||||
std::vector<MatType>& internals) const CV_OVERRIDE
|
||||
{
|
||||
CV_Assert(!inputs.empty());
|
||||
int t = (outputDtype >= 0) ? outputDtype : inputs[0];
|
||||
outputs.assign(requiredOutputs, MatType(t));
|
||||
internals.assign(requiredInternals, MatType(t));
|
||||
}
|
||||
|
||||
void forward(InputArrayOfArrays inputs_arr,
|
||||
OutputArrayOfArrays outputs_arr,
|
||||
OutputArrayOfArrays /*internals_arr*/) CV_OVERRIDE
|
||||
{
|
||||
std::vector<Mat> inputs, outputs;
|
||||
inputs_arr.getMatVector(inputs);
|
||||
outputs_arr.getMatVector(outputs);
|
||||
|
||||
CV_Assert(inputs.size() == 1);
|
||||
const Mat& X = inputs[0];
|
||||
CV_Assert(X.dims == 2);
|
||||
|
||||
int rows = X.size[0];
|
||||
int cols = X.size[1];
|
||||
|
||||
int outType = (outputDtype >= 0) ? outputDtype : X.type();
|
||||
outputs[0].create(rows, cols, outType);
|
||||
Mat& Y = outputs[0];
|
||||
Y.setTo(Scalar::all(0));
|
||||
|
||||
// Set ones on the k-th diagonal: Y[i, i+k] = 1
|
||||
int iStart = (k >= 0) ? 0 : -k;
|
||||
int jStart = (k >= 0) ? k : 0;
|
||||
int diagLen = std::min(rows - iStart, cols - jStart);
|
||||
|
||||
switch (outType)
|
||||
{
|
||||
case CV_32F: fillDiag<float> (Y, iStart, jStart, diagLen, 1.0f); break;
|
||||
case CV_64F: fillDiag<double> (Y, iStart, jStart, diagLen, 1.0); break;
|
||||
case CV_32S: fillDiag<int32_t> (Y, iStart, jStart, diagLen, 1); break;
|
||||
case CV_64S: fillDiag<int64_t> (Y, iStart, jStart, diagLen, 1); break;
|
||||
case CV_8U: fillDiag<uint8_t> (Y, iStart, jStart, diagLen, 1); break;
|
||||
case CV_8S: fillDiag<int8_t> (Y, iStart, jStart, diagLen, 1); break;
|
||||
case CV_16U: fillDiag<uint16_t>(Y, iStart, jStart, diagLen, 1); break;
|
||||
case CV_16S: fillDiag<int16_t> (Y, iStart, jStart, diagLen, 1); break;
|
||||
case CV_16F: fillDiag<hfloat> (Y, iStart, jStart, diagLen, hfloat(1.0f)); break;
|
||||
case CV_16BF: fillDiag<bfloat> (Y, iStart, jStart, diagLen, bfloat(1.0f)); break;
|
||||
case CV_Bool: fillDiag<bool> (Y, iStart, jStart, diagLen, true); break;
|
||||
default:
|
||||
CV_Error(Error::BadDepth, "Unsupported output depth for EyeLikeLayer");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
static void fillDiag(Mat& Y, int iStart, int jStart, int diagLen, T one)
|
||||
{
|
||||
for (int d = 0; d < diagLen; ++d)
|
||||
Y.at<T>(iStart + d, jStart + d) = one;
|
||||
}
|
||||
};
|
||||
|
||||
Ptr<EyeLikeLayer> EyeLikeLayer::create(const LayerParams& params)
|
||||
{
|
||||
return Ptr<EyeLikeLayer>(new EyeLikeLayerImpl(params));
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -221,6 +221,7 @@ protected:
|
||||
void parseOneHot (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
|
||||
void parseDFT (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
|
||||
void parseDet (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
|
||||
void parseEyeLike (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
|
||||
void parseBlackmanWindow (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
|
||||
void parseHannWindow (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
|
||||
void parseHammingWindow (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
|
||||
@@ -1764,6 +1765,17 @@ void ONNXImporter2::parseDet(LayerParams& layerParams, const opencv_onnx::NodePr
|
||||
addLayer(layerParams, node_proto);
|
||||
}
|
||||
|
||||
void ONNXImporter2::parseEyeLike(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto)
|
||||
{
|
||||
layerParams.type = "EyeLike";
|
||||
if (layerParams.has("dtype"))
|
||||
{
|
||||
int onnxDtype = layerParams.get<int>("dtype");
|
||||
layerParams.set("dtype", dataType2cv((opencv_onnx::TensorProto_DataType)onnxDtype));
|
||||
}
|
||||
addLayer(layerParams, node_proto);
|
||||
}
|
||||
|
||||
void ONNXImporter2::parseBlackmanWindow(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto)
|
||||
{
|
||||
layerParams.type = "BlackmanWindow";
|
||||
@@ -2731,6 +2743,7 @@ void ONNXImporter2::buildDispatchMap_ONNX_AI()
|
||||
dispatch["OneHot"] = &ONNXImporter2::parseOneHot;
|
||||
dispatch["DFT"] = &ONNXImporter2::parseDFT;
|
||||
dispatch["Det"] = &ONNXImporter2::parseDet;
|
||||
dispatch["EyeLike"] = &ONNXImporter2::parseEyeLike;
|
||||
dispatch["BlackmanWindow"] = &ONNXImporter2::parseBlackmanWindow;
|
||||
dispatch["HannWindow"] = &ONNXImporter2::parseHannWindow;
|
||||
dispatch["HammingWindow"] = &ONNXImporter2::parseHammingWindow;
|
||||
|
||||
@@ -717,11 +717,11 @@ CASE(test_expand_dim_changed)
|
||||
CASE(test_expand_dim_unchanged)
|
||||
SKIP;
|
||||
CASE(test_eyelike_populate_off_main_diagonal)
|
||||
// no filter
|
||||
SKIP;
|
||||
CASE(test_eyelike_with_dtype)
|
||||
// no filter
|
||||
SKIP;
|
||||
CASE(test_eyelike_without_dtype)
|
||||
// no filter
|
||||
SKIP;
|
||||
CASE(test_flatten_axis0)
|
||||
// no filter
|
||||
CASE(test_flatten_axis1)
|
||||
|
||||
@@ -735,3 +735,6 @@
|
||||
"test_reduce_sum_square_empty_set_expanded",
|
||||
"test_reduce_log_sum_exp_empty_set_expanded",
|
||||
"test_loop11",
|
||||
"test_eyelike_populate_off_main_diagonal",
|
||||
"test_eyelike_with_dtype",
|
||||
"test_eyelike_without_dtype",
|
||||
|
||||
@@ -305,9 +305,6 @@
|
||||
"test_einsum_scalar",
|
||||
"test_equal_string",
|
||||
"test_equal_string_broadcast",
|
||||
"test_eyelike_populate_off_main_diagonal", // Issues::Layer::Can't create layer::Can't create layer "onnx_node_output_0!y" of type "EyeLike" in function 'getLayerInstance'
|
||||
"test_eyelike_with_dtype", // ---- same as above ---
|
||||
"test_eyelike_without_dtype", // ---- same as above ---
|
||||
"test_gridsample_bicubic", // ---- same as above ---
|
||||
"test_gridsample_bicubic_align_corners_0_additional_1",
|
||||
"test_gridsample_bicubic_align_corners_1_additional_1",
|
||||
|
||||
Reference in New Issue
Block a user