diff --git a/modules/dnn/include/opencv2/dnn/all_layers.hpp b/modules/dnn/include/opencv2/dnn/all_layers.hpp index 5824e1467c..c584499ee2 100644 --- a/modules/dnn/include/opencv2/dnn/all_layers.hpp +++ b/modules/dnn/include/opencv2/dnn/all_layers.hpp @@ -723,7 +723,7 @@ CV__DNN_INLINE_NS_BEGIN static Ptr create(const LayerParams ¶ms); }; - class CV_EXPORTS NotLayer : public ActivationLayer + class CV_EXPORTS NotLayer : public Layer { public: static Ptr create(const LayerParams ¶ms); diff --git a/modules/dnn/src/ie_ngraph.cpp b/modules/dnn/src/ie_ngraph.cpp index 432cce4924..dd48704e2c 100644 --- a/modules/dnn/src/ie_ngraph.cpp +++ b/modules/dnn/src/ie_ngraph.cpp @@ -61,6 +61,8 @@ ov::element::Type cvTypeToOvType(MatType cvType) return ov::element::i32; case CV_64S: return ov::element::i64; + case CV_Bool: + return ov::element::boolean; default: CV_Error(Error::StsNotImplemented, format("Unsupported data type %s", typeToString(cvType).c_str())); } @@ -84,6 +86,8 @@ MatType ovTypeToCvType(ov::element::Type ovType) return CV_32S; case ov::element::i64: return CV_64S; + case ov::element::boolean: + return CV_Bool; default: CV_Error(Error::StsNotImplemented, format("Unsupported data type %s", ovType.get_type_name().c_str())); } diff --git a/modules/dnn/src/layers/blank_layer.cpp b/modules/dnn/src/layers/blank_layer.cpp index bc6dacc2b6..e95991b3d2 100644 --- a/modules/dnn/src/layers/blank_layer.cpp +++ b/modules/dnn/src/layers/blank_layer.cpp @@ -175,7 +175,10 @@ public: ) override { auto context = reinterpret_cast(context_); - return make_cuda_node_with_type(preferableTarget, inputs[0]->getHostMatDepth(), std::move(context->stream)); + if (inputs[0]->getHostMatDepth() == CV_Bool) + return make_cuda_node_bool(std::move(context->stream)); + else + return make_cuda_node_with_type(preferableTarget, inputs[0]->getHostMatDepth(), std::move(context->stream)); } #endif }; diff --git a/modules/dnn/src/layers/elementwise_layers.cpp b/modules/dnn/src/layers/elementwise_layers.cpp index deb3388594..e7b8c38302 100644 --- a/modules/dnn/src/layers/elementwise_layers.cpp +++ b/modules/dnn/src/layers/elementwise_layers.cpp @@ -1372,33 +1372,6 @@ struct SqrtFunctor : public BaseDefaultFunctor template<> const char* const BaseDefaultFunctor::ocl_kernel_name = "SqrtForward"; -struct NotFunctor : public BaseDefaultFunctor -{ - typedef NotLayer Layer; - - bool supportBackend(int backendId, int) - { - return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_CUDA; - } - - inline float calculate(float x) const - { - return floor(1.f - x); - } - -#ifdef HAVE_CUDA - Ptr initCUDA(int target, csl::Stream stream) - { - return make_cuda_node(target, stream); - } -#endif - - int64 getFLOPSPerElement() const { return 2; } -}; - -template<> -const char* const BaseDefaultFunctor::ocl_kernel_name = "NotForward"; - struct AcosFunctor : public BaseDefaultFunctor { typedef AcosLayer Layer; @@ -2650,14 +2623,6 @@ Ptr SqrtLayer::create(const LayerParams& params) return l; } -Ptr NotLayer::create(const LayerParams& params) -{ - Ptr l(new ElementWiseLayer()); - l->setParamsFrom(params); - - return l; -} - Ptr AcosLayer::create(const LayerParams& params) { Ptr l(new ElementWiseLayer()); diff --git a/modules/dnn/src/layers/flatten_layer.cpp b/modules/dnn/src/layers/flatten_layer.cpp index 617870dbf5..41f49362c9 100644 --- a/modules/dnn/src/layers/flatten_layer.cpp +++ b/modules/dnn/src/layers/flatten_layer.cpp @@ -260,7 +260,10 @@ public: ) override { auto context = reinterpret_cast(context_); - return make_cuda_node_with_type(preferableTarget, inputs[0]->getHostMatDepth(), std::move(context->stream)); + if (inputs[0]->getHostMatDepth() == CV_Bool) + return make_cuda_node_bool(std::move(context->stream)); + else + return make_cuda_node_with_type(preferableTarget, inputs[0]->getHostMatDepth(), std::move(context->stream)); } #endif diff --git a/modules/dnn/src/layers/nary_eltwise_layers.cpp b/modules/dnn/src/layers/nary_eltwise_layers.cpp index 47adb0648e..b7cb566fb4 100644 --- a/modules/dnn/src/layers/nary_eltwise_layers.cpp +++ b/modules/dnn/src/layers/nary_eltwise_layers.cpp @@ -103,24 +103,6 @@ public: } } - void reInit(size_t newElemSize) { - std::vector newElemSizes(elemsize.size(), newElemSize); - reInit(newElemSizes); - } - - void reInit(std::vector newElemSizes) { - for (size_t array_index = 0; array_index < orig_steps.size(); array_index++) { - auto &step = orig_steps[array_index]; - int esz = elemsize[array_index]; - int new_esz = newElemSizes[array_index]; - for (size_t step_index = 0; step_index < step.size(); step_index++) { - step[step_index] = static_cast(step[step_index] / esz * new_esz); - } - elemsize[array_index] = newElemSizes[array_index]; - } - prepare_for_broadcast_op(); - } - bool prepare_for_broadcast_op() { int i, j, k; @@ -281,8 +263,15 @@ public: if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) return (op == OPERATION::ADD || op == OPERATION::PROD || + op == OPERATION::EQUAL || + op == OPERATION::GREATER || op == OPERATION::GREATER_EQUAL || + op == OPERATION::LESS || op == OPERATION::LESS_EQUAL || + op == OPERATION::AND || + op == OPERATION::OR || + op == OPERATION::XOR || + op == OPERATION::WHERE || op == OPERATION::MOD || op == OPERATION::FMOD ); @@ -355,6 +344,22 @@ public: std::vector& outputs, std::vector& internals) const CV_OVERRIDE { + if (op == OPERATION::WHERE) + { + CV_CheckTypeEQ(inputs[0], CV_Bool, ""); + CV_CheckTypeEQ(inputs[1], inputs[2], ""); + outputs.assign(1, inputs[1]); + return; + } + + if (op == OPERATION::AND || op == OPERATION::OR || op == OPERATION::XOR) + { + CV_CheckTypeEQ(inputs[0], CV_Bool, ""); + CV_CheckTypeEQ(inputs[1], CV_Bool, ""); + outputs.assign(1, CV_Bool); + return; + } + CV_Assert(inputs.size()); for (auto input : inputs) { @@ -365,11 +370,14 @@ public: CV_CheckType(input, input == CV_32F || input == CV_8S || input == CV_8U || input == CV_32S || input == CV_64S, ""); } - outputs.assign(requiredOutputs, inputs[0]); + if (op == OPERATION::EQUAL || op == OPERATION::GREATER || op == OPERATION::GREATER_EQUAL || op == OPERATION::LESS || op == OPERATION::LESS_EQUAL) + outputs.assign(1, CV_Bool); + else + outputs.assign(requiredOutputs, inputs[0]); } - template + template void binary_forward_impl( int ndims, const std::vector& shape, const char* data1, const std::vector& step1, @@ -385,7 +393,7 @@ public: if (ndims >= 1) { dp1 = step1[ndims-1]/sizeof(T); dp2 = step2[ndims-1]/sizeof(T); - dp = step[ndims-1]/sizeof(T); + dp = step[ndims-1]/sizeof(RESULT_T); n1 = shape[ndims-1]; if (ndims >= 2) { @@ -417,7 +425,7 @@ public: { const T* ptr1 = (const T*)ptr1_; const T* ptr2 = (const T*)ptr2_; - T* ptr = (T*)ptr_; + RESULT_T* ptr = (RESULT_T*)ptr_; if (dp1 == 1 && dp2 == 1 && dp == 1) { for(int i1 = 0; i1 < n1; i1++) ptr[i1] = op(ptr1[i1], ptr2[i1]); @@ -437,14 +445,14 @@ public: } } - template + template void binary_forward(const Functor& f, const std::vector& inputs, std::vector& outputs) { const Mat& a = inputs[0]; const Mat& b = inputs[1]; Mat& out = outputs[0]; CV_Assert(helper.shapes.size() == 3 && helper.steps.size() == 3); - binary_forward_impl( + binary_forward_impl( helper.max_ndims, helper.shapes[0], a.ptr(), helper.steps[1], b.ptr(), helper.steps[2], out.ptr(), helper.steps[0], f); @@ -551,7 +559,7 @@ public: f, scale, helper.ninputs, helper.max_ndims, helper.shapes[0], inp, out, helper.steps, helper.ptrs); } - template + template void trinary_forward(const Functor& f, const std::vector& inputs, std::vector& outputs) { const Mat& a = inputs[0]; @@ -561,13 +569,13 @@ public: CV_Assert(helper.shapes.size() == 4 && helper.steps.size() == 4); - trinary_forward_impl( + trinary_forward_impl( helper.max_ndims, helper.shapes[0], a.ptr(), helper.steps[1], b.ptr(), helper.steps[2], c.ptr(), helper.steps[3], out.ptr(), helper.steps[0], f); } - template + template void trinary_forward_impl( int ndims, const std::vector& shape, const char* data1, const std::vector& step1, @@ -577,10 +585,10 @@ public: const Functor& op) { assert(ndims >= 2); - size_t dp1 = step1[ndims-1]/sizeof(T); - size_t dp2 = step2[ndims-1]/sizeof(T); - size_t dp3 = step3[ndims-1]/sizeof(T); - size_t dp = step[ndims-1]/sizeof(T); + size_t dp1 = step1[ndims-1]/sizeof(T_INP1); + size_t dp2 = step2[ndims-1]/sizeof(T_INP2); + size_t dp3 = step3[ndims-1]/sizeof(T_INP3); + size_t dp = step[ndims-1]/sizeof(T_OUT); int k, n1 = shape[ndims-1], n2 = shape[ndims-2]; size_t plane_idx, nplanes = 1; for (k = 0; k < ndims-2; k++) nplanes *= shape[k]; @@ -608,10 +616,10 @@ public: ptr3_ += step3[ndims-2], ptr_ += step[ndims-2]) { - const T* ptr1 = (const T*)ptr1_; - const T* ptr2 = (const T*)ptr2_; - const T* ptr3 = (const T*)ptr3_; - T* ptr = (T*)ptr_; + const T_INP1* ptr1 = (const T_INP1*)ptr1_; + const T_INP2* ptr2 = (const T_INP2*)ptr2_; + const T_INP3* ptr3 = (const T_INP3*)ptr3_; + T_OUT* ptr = (T_OUT*)ptr_; if (dp1 == 1 && dp2 == 1 && dp3 == 1 && dp == 1) { @@ -634,7 +642,6 @@ public: if (inputs_arr.depth() == CV_16F) { - helper.reInit(sizeof(float)); forward_fallback(inputs_arr, outputs_arr, internals_arr); return; } @@ -644,7 +651,7 @@ public: outputs_arr.getMatVector(outputs); // TODO: assert types - typeDispatch(outputs[0].type(), inputs.size(), inputs, outputs); + typeDispatch(inputs.back().type(), inputs.size(), inputs, outputs); } template @@ -655,43 +662,43 @@ public: case OPERATION::EQUAL: { auto equal = [](const T &a, const T &b) { return a == b; }; - binary_forward(equal, std::forward(args)...); + binary_forward(equal, std::forward(args)...); break; } case OPERATION::GREATER: { auto greater = [](const T &a, const T &b) { return a > b; }; - binary_forward(greater, std::forward(args)...); + binary_forward(greater, std::forward(args)...); break; } case OPERATION::GREATER_EQUAL: { auto greater_equal = [](const T &a, const T &b) { return a >= b; }; - binary_forward(greater_equal, std::forward(args)...); + binary_forward(greater_equal, std::forward(args)...); break; } case OPERATION::LESS: { auto less = [](const T &a, const T &b) { return a < b; }; - binary_forward(less, std::forward(args)...); + binary_forward(less, std::forward(args)...); break; } case OPERATION::LESS_EQUAL: { auto less_equal = [](const T &a, const T &b) { return a <= b; }; - binary_forward(less_equal, std::forward(args)...); + binary_forward(less_equal, std::forward(args)...); break; } case OPERATION::POW: { auto pow = [] (const T& a, const T& b) { return std::pow(a, b); }; - binary_forward(pow, std::forward(args)...); + binary_forward(pow, std::forward(args)...); break; } case OPERATION::BITSHIFT: { auto bitshift = [] (const uint8_t &a, const uint8_t &b) { return a << b; }; - binary_forward(bitshift, std::forward(args)...); + binary_forward(bitshift, std::forward(args)...); break; } case OPERATION::MAX: @@ -715,25 +722,25 @@ public: case OPERATION::MOD: { auto mod = [] (const T &a, const T &b) { return static_cast(_mod(int(a), int(b))); }; - binary_forward(mod, std::forward(args)...); + binary_forward(mod, std::forward(args)...); break; } case OPERATION::FMOD: { auto fmod = [](const T &a, const T &b) { return std::fmod(a, b); }; - binary_forward(fmod, std::forward(args)...); + binary_forward(fmod, std::forward(args)...); break; } case OPERATION::PROD: { auto prod = [](const T &a, const T &b) { return a * b; }; - binary_forward(prod, std::forward(args)...); + binary_forward(prod, std::forward(args)...); break; } case OPERATION::SUB: { auto sub = [](const T &a, const T &b) { return a - b; }; - binary_forward(sub, std::forward(args)...); + binary_forward(sub, std::forward(args)...); break; } case OPERATION::SUM: @@ -745,37 +752,47 @@ public: case OPERATION::ADD: { auto add = [](const T &a, const T &b) { return a + b; }; - binary_forward(add, std::forward(args)...); + binary_forward(add, std::forward(args)...); break; } case OPERATION::DIV: { auto div = [](const T &a, const T &b) { return a / b; }; - binary_forward(div, std::forward(args)...); + binary_forward(div, std::forward(args)...); break; } - case OPERATION::AND: + case OPERATION::WHERE: { - auto op_and = [](const uint8_t &a, const uint8_t &b) { return a & b; }; - binary_forward(op_and, std::forward(args)...); + auto op_where = [](const bool &a, const T &b, const T &c) { return a ? b : c; }; + trinary_forward(op_where, std::forward(args)...); break; } - case OPERATION::OR: + default: + CV_Error(Error::StsBadArg, "Unsupported operation."); + }; + } + + template + inline void boolOpDispatch(size_t ninputs, Args&&... args) + { + switch (op) + { + case OPERATION::AND: { - auto op_or = [](const uint8_t &a, const uint8_t &b) { return a | b; }; - binary_forward(op_or, std::forward(args)...); + auto op_and = [](const bool &a, const bool &b) { return a && b; }; + binary_forward(op_and, std::forward(args)...); break; } - case OPERATION::XOR: + case OPERATION::OR: { - auto op_xor = [](const uint8_t &a, const uint8_t &b) { return a ^ b; }; - binary_forward(op_xor, std::forward(args)...); + auto op_or = [](const bool &a, const bool &b) { return a || b; }; + binary_forward(op_or, std::forward(args)...); break; } - case OPERATION::WHERE: + case OPERATION::XOR: { - auto op_where = [](const T &a, const T &b, const T &c) { return a ? b : c; }; - trinary_forward(op_where, std::forward(args)...); + auto op_xor = [](const bool &a, const bool &b) { return a != b; }; + binary_forward(op_xor, std::forward(args)...); break; } default: @@ -788,17 +805,16 @@ public: { switch (type) { + case CV_Bool: + boolOpDispatch(std::forward(args)...); + break; case CV_8U: - // TODO: integrate with type inference - helper.reInit(sizeof(uint8_t)); opDispatch(std::forward(args)...); break; case CV_8S: opDispatch(std::forward(args)...); break; case CV_32S: - // TODO: integrate with type inference - helper.reInit(sizeof(int32_t)); opDispatch(std::forward(args)...); break; case CV_64S: @@ -916,11 +932,16 @@ public: #ifdef HAVE_DNN_NGRAPH virtual Ptr initNgraph(const std::vector >& inputs, const std::vector >& nodes) CV_OVERRIDE { - CV_Assert(inputs.size() == 2); + if (op == OPERATION::WHERE) + CV_CheckEQ(inputs.size(), 3u, ""); + else + CV_CheckEQ(inputs.size(), 2u, ""); auto& inp0 = nodes[0].dynamicCast()->node; auto& inp1 = nodes[1].dynamicCast()->node; - if (inp0.get_element_type() != inp1.get_element_type()) { + if (op != OPERATION::WHERE && inp0.get_element_type() != inp1.get_element_type()) { + CV_Assert(inp0.get_element_type() == ov::element::f16 || inp0.get_element_type() == ov::element::f32); + CV_Assert(inp1.get_element_type() == ov::element::f16 || inp1.get_element_type() == ov::element::f32); auto dtype = preferableTarget == DNN_TARGET_OPENCL_FP16 || preferableTarget == DNN_TARGET_MYRIAD ? ov::element::f16 : ov::element::f32; if (inp0.get_element_type() != dtype) @@ -934,10 +955,27 @@ public: node = std::make_shared(inp0, inp1); else if (op == OPERATION::PROD) node = std::make_shared(inp0, inp1); + else if (op == OPERATION::EQUAL) + node = std::make_shared(inp0, inp1); + else if (op == OPERATION::GREATER) + node = std::make_shared(inp0, inp1); else if (op == OPERATION::GREATER_EQUAL) node = std::make_shared(inp0, inp1); + else if (op == OPERATION::LESS) + node = std::make_shared(inp0, inp1); else if (op == OPERATION::LESS_EQUAL) node = std::make_shared(inp0, inp1); + else if (op == OPERATION::AND) + node = std::make_shared(inp0, inp1); + else if (op == OPERATION::OR) + node = std::make_shared(inp0, inp1); + else if (op == OPERATION::XOR) + node = std::make_shared(inp0, inp1); + else if (op == OPERATION::WHERE) + { + auto& inp2 = nodes[2].dynamicCast()->node; + node = std::make_shared(inp0, inp1, inp2); + } // Ideally we should do this but int32 internal blobs are converted to float32 data type in inference. // TODO: Remove data type convertion when we have type inference. else if (op == OPERATION::MOD) { diff --git a/modules/dnn/src/layers/not_layer.cpp b/modules/dnn/src/layers/not_layer.cpp new file mode 100644 index 0000000000..7f589a9ba6 --- /dev/null +++ b/modules/dnn/src/layers/not_layer.cpp @@ -0,0 +1,83 @@ +// 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. + +#include "../precomp.hpp" +#include "layers_common.hpp" +#include "../op_inf_engine.hpp" +#include "../ie_ngraph.hpp" + + +namespace cv { namespace dnn { + +class NotLayerImpl CV_FINAL : public NotLayer +{ +public: + NotLayerImpl(const LayerParams& params) + { + setParamsFrom(params); + } + + virtual bool supportBackend(int backendId) CV_OVERRIDE + { + return backendId == DNN_BACKEND_OPENCV || + backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH; + } + + virtual bool getMemoryShapes(const std::vector &inputs, + const int requiredOutputs, + std::vector &outputs, + std::vector &internals) const CV_OVERRIDE + { + CV_CheckEQ(inputs.size(), (size_t)1, ""); + outputs.assign(1, inputs[0]); + return true; + } + + virtual void getTypes(const std::vector& inputs, + const int requiredOutputs, + const int requiredInternals, + std::vector& outputs, + std::vector& internals) const CV_OVERRIDE + { + CV_CheckTypeEQ(inputs[0], CV_Bool, ""); + outputs.assign(1, CV_Bool); + } + + 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_CheckTypeEQ(inputs[0].type(), CV_Bool, ""); + CV_CheckTypeEQ(outputs[0].type(), CV_Bool, ""); + + bool* input = inputs[0].ptr(); + bool* output = outputs[0].ptr(); + int size = inputs[0].total(); + + for (int i = 0; i < size; ++i) + output[i] = !input[i]; + } + +#ifdef HAVE_DNN_NGRAPH + virtual Ptr initNgraph(const std::vector >& inputs, + const std::vector >& nodes) CV_OVERRIDE + { + auto node = std::make_shared(nodes[0].dynamicCast()->node); + return Ptr(new InfEngineNgraphNode(node)); + } +#endif // HAVE_DNN_NGRAPH + +}; + +Ptr NotLayer::create(const LayerParams& params) +{ + return makePtr(params); +} + +}} // namespace cv::dnn diff --git a/modules/dnn/src/layers/reshape_layer.cpp b/modules/dnn/src/layers/reshape_layer.cpp index 8ced83b402..8ba50a7d11 100644 --- a/modules/dnn/src/layers/reshape_layer.cpp +++ b/modules/dnn/src/layers/reshape_layer.cpp @@ -417,7 +417,10 @@ public: ) override { auto context = reinterpret_cast(context_); - return make_cuda_node_with_type(preferableTarget, inputs[0]->getHostMatDepth(), std::move(context->stream)); + if (inputs[0]->getHostMatDepth() == CV_Bool) + return make_cuda_node_bool(std::move(context->stream)); + else + return make_cuda_node_with_type(preferableTarget, inputs[0]->getHostMatDepth(), std::move(context->stream)); } #endif diff --git a/modules/dnn/src/legacy_backend.cpp b/modules/dnn/src/legacy_backend.cpp index cc8aec69d2..00577edd0c 100644 --- a/modules/dnn/src/legacy_backend.cpp +++ b/modules/dnn/src/legacy_backend.cpp @@ -90,7 +90,7 @@ Ptr wrapMat(int backendId, int targetId, cv::Mat& m) CV_Assert(haveCUDA()); #ifdef HAVE_CUDA - CV_CheckType(m.depth(), m.depth() == CV_32F || m.depth() == CV_8S || m.depth() == CV_8U || m.depth() == CV_32S || m.depth() == CV_64S, "Unsupported type for CUDA"); + CV_CheckType(m.depth(), m.depth() == CV_32F || m.depth() == CV_8S || m.depth() == CV_8U || m.depth() == CV_32S || m.depth() == CV_64S || m.depth() == CV_Bool, "Unsupported type for CUDA"); CV_Assert(IS_DNN_CUDA_TARGET(targetId)); switch (m.depth()) { @@ -107,6 +107,8 @@ Ptr wrapMat(int backendId, int targetId, cv::Mat& m) return CUDABackendWrapperINT32::create(m); case CV_64S: return CUDABackendWrapperINT64::create(m); + case CV_Bool: + return CUDABackendWrapperBOOL::create(m); default: CV_Error(Error::BadDepth, "Unsupported mat type for CUDA"); } diff --git a/modules/dnn/src/net_impl_backend.cpp b/modules/dnn/src/net_impl_backend.cpp index 4c73a04507..cb39c48b49 100644 --- a/modules/dnn/src/net_impl_backend.cpp +++ b/modules/dnn/src/net_impl_backend.cpp @@ -62,7 +62,7 @@ Ptr Net::Impl::wrap(Mat& host) { CV_Assert(haveCUDA()); #ifdef HAVE_CUDA - CV_CheckType(host.depth(), host.depth() == CV_32F || host.depth() == CV_8S || host.depth() == CV_8U || host.depth() == CV_32S || host.depth() == CV_64S, "Unsupported type for CUDA"); + CV_CheckType(host.depth(), host.depth() == CV_32F || host.depth() == CV_8S || host.depth() == CV_8U || host.depth() == CV_32S || host.depth() == CV_64S || host.depth() == CV_Bool, "Unsupported type for CUDA"); CV_Assert(IS_DNN_CUDA_TARGET(preferableTarget)); switch (host.depth()) { @@ -79,6 +79,8 @@ Ptr Net::Impl::wrap(Mat& host) return CUDABackendWrapperINT32::create(baseBuffer, shape); case CV_64S: return CUDABackendWrapperINT64::create(baseBuffer, shape); + case CV_Bool: + return CUDABackendWrapperBOOL::create(baseBuffer, shape); default: CV_Error(Error::BadDepth, "Unsupported mat type for CUDA"); } diff --git a/modules/dnn/src/onnx/onnx_graph_simplifier.cpp b/modules/dnn/src/onnx/onnx_graph_simplifier.cpp index af664348fe..d40ac36ece 100644 --- a/modules/dnn/src/onnx/onnx_graph_simplifier.cpp +++ b/modules/dnn/src/onnx/onnx_graph_simplifier.cpp @@ -1868,6 +1868,11 @@ Mat getMatFromTensor(const opencv_onnx::TensorProto& tensor_proto, bool uint8ToI Mat(sizes, CV_8U, val).copyTo(blob); } } + else if (datatype == opencv_onnx::TensorProto_DataType_BOOL) + { + char* val = const_cast(tensor_proto.raw_data().c_str()); + Mat(sizes, CV_Bool, val).copyTo(blob); + } else { std::string errorMsg = "Unsupported data type: " + diff --git a/modules/dnn/src/onnx/onnx_importer.cpp b/modules/dnn/src/onnx/onnx_importer.cpp index 8f45cec33a..e7503ac9b8 100644 --- a/modules/dnn/src/onnx/onnx_importer.cpp +++ b/modules/dnn/src/onnx/onnx_importer.cpp @@ -2839,7 +2839,7 @@ void ONNXImporter::parseCumSum(LayerParams& layerParams, const opencv_onnx::Node addLayer(layerParams, node_proto); } -// "Equal" "Greater" "Less" "Pow" "Add" "Sub" "Mul" "Div" "Sum" "Min" "Max" "GreaterOrEqual" "LessOrEqual" +// "Equal" "Greater" "Less" "Pow" "Add" "Sub" "Mul" "Div" "Sum" "Min" "Max" "GreaterOrEqual" "LessOrEqual" "And" "Or" "Xor" void ONNXImporter::parseElementWise(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto_) { opencv_onnx::NodeProto node_proto = node_proto_; @@ -4038,7 +4038,7 @@ void ONNXImporter::buildDispatchMap_ONNX_AI(int opset_version) dispatch["Equal"] = dispatch["Greater"] = dispatch["Less"] = dispatch["Pow"] = dispatch["Add"] = dispatch["Sub"] = dispatch["Mul"] = dispatch["Div"] = dispatch["GreaterOrEqual"] = - dispatch["LessOrEqual"] = dispatch["Mod"] = &ONNXImporter::parseElementWise; + dispatch["LessOrEqual"] = dispatch["Mod"] = dispatch["And"] = dispatch["Or"] = dispatch["Xor"] = &ONNXImporter::parseElementWise; dispatch["Sum"] = dispatch["Min"] = dispatch["Max"] = &ONNXImporter::parseElementWise; dispatch["Where"] = &ONNXImporter::parseElementWise; diff --git a/modules/dnn/src/op_cuda.hpp b/modules/dnn/src/op_cuda.hpp index 71fad02837..db6e16f554 100644 --- a/modules/dnn/src/op_cuda.hpp +++ b/modules/dnn/src/op_cuda.hpp @@ -273,6 +273,11 @@ namespace cv { namespace dnn { return Ptr(); } + template