mirror of
https://github.com/opencv/opencv.git
synced 2025-07-24 14:06:27 +08:00
Merge pull request #25605 from alexlyulkov:al/bool-dnn
Added bool support to dnn #25605 Added bool support to dnn pipeline (CPU, OpenVINO and CUDA pipelines). Added bool support to these layers(CPU and OpenVINO): - Equal, Greater, GreaterOrEqual, Less, LessOrEqual - Not - And, Or, Xor - Where Enabled all the conformance tests for these layers. ### 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 - [ ] 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:
parent
5bc450d211
commit
70df023317
@ -723,7 +723,7 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
static Ptr<SqrtLayer> create(const LayerParams ¶ms);
|
||||
};
|
||||
|
||||
class CV_EXPORTS NotLayer : public ActivationLayer
|
||||
class CV_EXPORTS NotLayer : public Layer
|
||||
{
|
||||
public:
|
||||
static Ptr<NotLayer> create(const LayerParams ¶ms);
|
||||
|
@ -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()));
|
||||
}
|
||||
|
@ -175,7 +175,10 @@ public:
|
||||
) override
|
||||
{
|
||||
auto context = reinterpret_cast<csl::CSLContext*>(context_);
|
||||
return make_cuda_node_with_type<cuda4dnn::ReshapeOp>(preferableTarget, inputs[0]->getHostMatDepth(), std::move(context->stream));
|
||||
if (inputs[0]->getHostMatDepth() == CV_Bool)
|
||||
return make_cuda_node_bool<cuda4dnn::ReshapeOp>(std::move(context->stream));
|
||||
else
|
||||
return make_cuda_node_with_type<cuda4dnn::ReshapeOp>(preferableTarget, inputs[0]->getHostMatDepth(), std::move(context->stream));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
@ -1372,33 +1372,6 @@ struct SqrtFunctor : public BaseDefaultFunctor<SqrtFunctor>
|
||||
template<>
|
||||
const char* const BaseDefaultFunctor<SqrtFunctor>::ocl_kernel_name = "SqrtForward";
|
||||
|
||||
struct NotFunctor : public BaseDefaultFunctor<NotFunctor>
|
||||
{
|
||||
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<BackendNode> initCUDA(int target, csl::Stream stream)
|
||||
{
|
||||
return make_cuda_node<cuda4dnn::NotOp>(target, stream);
|
||||
}
|
||||
#endif
|
||||
|
||||
int64 getFLOPSPerElement() const { return 2; }
|
||||
};
|
||||
|
||||
template<>
|
||||
const char* const BaseDefaultFunctor<NotFunctor>::ocl_kernel_name = "NotForward";
|
||||
|
||||
struct AcosFunctor : public BaseDefaultFunctor<AcosFunctor>
|
||||
{
|
||||
typedef AcosLayer Layer;
|
||||
@ -2650,14 +2623,6 @@ Ptr<SqrtLayer> SqrtLayer::create(const LayerParams& params)
|
||||
return l;
|
||||
}
|
||||
|
||||
Ptr<NotLayer> NotLayer::create(const LayerParams& params)
|
||||
{
|
||||
Ptr<NotLayer> l(new ElementWiseLayer<NotFunctor>());
|
||||
l->setParamsFrom(params);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
Ptr<AcosLayer> AcosLayer::create(const LayerParams& params)
|
||||
{
|
||||
Ptr<AcosLayer> l(new ElementWiseLayer<AcosFunctor>());
|
||||
|
@ -260,7 +260,10 @@ public:
|
||||
) override
|
||||
{
|
||||
auto context = reinterpret_cast<csl::CSLContext*>(context_);
|
||||
return make_cuda_node_with_type<cuda4dnn::ReshapeOp>(preferableTarget, inputs[0]->getHostMatDepth(), std::move(context->stream));
|
||||
if (inputs[0]->getHostMatDepth() == CV_Bool)
|
||||
return make_cuda_node_bool<cuda4dnn::ReshapeOp>(std::move(context->stream));
|
||||
else
|
||||
return make_cuda_node_with_type<cuda4dnn::ReshapeOp>(preferableTarget, inputs[0]->getHostMatDepth(), std::move(context->stream));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -103,24 +103,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void reInit(size_t newElemSize) {
|
||||
std::vector<size_t> newElemSizes(elemsize.size(), newElemSize);
|
||||
reInit(newElemSizes);
|
||||
}
|
||||
|
||||
void reInit(std::vector<size_t> 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<size_t>(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<MatType>& outputs,
|
||||
std::vector<MatType>& 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 <typename T, typename Functor>
|
||||
template <typename T, typename RESULT_T, typename Functor>
|
||||
void binary_forward_impl(
|
||||
int ndims, const std::vector<int>& shape,
|
||||
const char* data1, const std::vector<size_t>& 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 <typename T, typename Functor>
|
||||
template <typename T, typename RESULT_T, typename Functor>
|
||||
void binary_forward(const Functor& f, const std::vector<Mat>& inputs, std::vector<Mat>& 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<T, Functor>(
|
||||
binary_forward_impl<T, RESULT_T, Functor>(
|
||||
helper.max_ndims, helper.shapes[0], a.ptr<char>(), helper.steps[1],
|
||||
b.ptr<char>(), helper.steps[2], out.ptr<char>(), 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 <typename T, typename Functor>
|
||||
template <typename T_INP1, typename T_INP2, typename T_INP3, typename T_OUT, typename Functor>
|
||||
void trinary_forward(const Functor& f, const std::vector<Mat>& inputs, std::vector<Mat>& outputs)
|
||||
{
|
||||
const Mat& a = inputs[0];
|
||||
@ -561,13 +569,13 @@ public:
|
||||
|
||||
CV_Assert(helper.shapes.size() == 4 && helper.steps.size() == 4);
|
||||
|
||||
trinary_forward_impl<T, Functor>(
|
||||
trinary_forward_impl<T_INP1, T_INP2, T_INP3, T_OUT, Functor>(
|
||||
helper.max_ndims, helper.shapes[0], a.ptr<char>(), helper.steps[1], b.ptr<char>(), helper.steps[2],
|
||||
c.ptr<char>(), helper.steps[3], out.ptr<char>(), helper.steps[0],
|
||||
f);
|
||||
}
|
||||
|
||||
template <typename T, typename Functor>
|
||||
template <typename T_INP1, typename T_INP2, typename T_INP3, typename T_OUT, typename Functor>
|
||||
void trinary_forward_impl(
|
||||
int ndims, const std::vector<int>& shape,
|
||||
const char* data1, const std::vector<size_t>& 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<typename T, typename... Args>
|
||||
@ -655,43 +662,43 @@ public:
|
||||
case OPERATION::EQUAL:
|
||||
{
|
||||
auto equal = [](const T &a, const T &b) { return a == b; };
|
||||
binary_forward<T>(equal, std::forward<Args>(args)...);
|
||||
binary_forward<T, bool>(equal, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::GREATER:
|
||||
{
|
||||
auto greater = [](const T &a, const T &b) { return a > b; };
|
||||
binary_forward<T>(greater, std::forward<Args>(args)...);
|
||||
binary_forward<T, bool>(greater, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::GREATER_EQUAL:
|
||||
{
|
||||
auto greater_equal = [](const T &a, const T &b) { return a >= b; };
|
||||
binary_forward<T>(greater_equal, std::forward<Args>(args)...);
|
||||
binary_forward<T, bool>(greater_equal, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::LESS:
|
||||
{
|
||||
auto less = [](const T &a, const T &b) { return a < b; };
|
||||
binary_forward<T>(less, std::forward<Args>(args)...);
|
||||
binary_forward<T, bool>(less, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::LESS_EQUAL:
|
||||
{
|
||||
auto less_equal = [](const T &a, const T &b) { return a <= b; };
|
||||
binary_forward<T>(less_equal, std::forward<Args>(args)...);
|
||||
binary_forward<T, bool>(less_equal, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::POW:
|
||||
{
|
||||
auto pow = [] (const T& a, const T& b) { return std::pow(a, b); };
|
||||
binary_forward<T>(pow, std::forward<Args>(args)...);
|
||||
binary_forward<T, T>(pow, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::BITSHIFT:
|
||||
{
|
||||
auto bitshift = [] (const uint8_t &a, const uint8_t &b) { return a << b; };
|
||||
binary_forward<T>(bitshift, std::forward<Args>(args)...);
|
||||
binary_forward<T, T>(bitshift, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::MAX:
|
||||
@ -715,25 +722,25 @@ public:
|
||||
case OPERATION::MOD:
|
||||
{
|
||||
auto mod = [] (const T &a, const T &b) { return static_cast<T>(_mod(int(a), int(b))); };
|
||||
binary_forward<T>(mod, std::forward<Args>(args)...);
|
||||
binary_forward<T, T>(mod, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::FMOD:
|
||||
{
|
||||
auto fmod = [](const T &a, const T &b) { return std::fmod(a, b); };
|
||||
binary_forward<T>(fmod, std::forward<Args>(args)...);
|
||||
binary_forward<T, T>(fmod, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::PROD:
|
||||
{
|
||||
auto prod = [](const T &a, const T &b) { return a * b; };
|
||||
binary_forward<T>(prod, std::forward<Args>(args)...);
|
||||
binary_forward<T, T>(prod, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::SUB:
|
||||
{
|
||||
auto sub = [](const T &a, const T &b) { return a - b; };
|
||||
binary_forward<T>(sub, std::forward<Args>(args)...);
|
||||
binary_forward<T, T>(sub, std::forward<Args>(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<T>(add, std::forward<Args>(args)...);
|
||||
binary_forward<T, T>(add, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::DIV:
|
||||
{
|
||||
auto div = [](const T &a, const T &b) { return a / b; };
|
||||
binary_forward<T>(div, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::AND:
|
||||
{
|
||||
auto op_and = [](const uint8_t &a, const uint8_t &b) { return a & b; };
|
||||
binary_forward<T>(op_and, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::OR:
|
||||
{
|
||||
auto op_or = [](const uint8_t &a, const uint8_t &b) { return a | b; };
|
||||
binary_forward<T>(op_or, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::XOR:
|
||||
{
|
||||
auto op_xor = [](const uint8_t &a, const uint8_t &b) { return a ^ b; };
|
||||
binary_forward<T>(op_xor, std::forward<Args>(args)...);
|
||||
binary_forward<T, T>(div, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::WHERE:
|
||||
{
|
||||
auto op_where = [](const T &a, const T &b, const T &c) { return a ? b : c; };
|
||||
trinary_forward<T>(op_where, std::forward<Args>(args)...);
|
||||
auto op_where = [](const bool &a, const T &b, const T &c) { return a ? b : c; };
|
||||
trinary_forward<bool, T, T, T>(op_where, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CV_Error(Error::StsBadArg, "Unsupported operation.");
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
inline void boolOpDispatch(size_t ninputs, Args&&... args)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case OPERATION::AND:
|
||||
{
|
||||
auto op_and = [](const bool &a, const bool &b) { return a && b; };
|
||||
binary_forward<bool, bool>(op_and, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::OR:
|
||||
{
|
||||
auto op_or = [](const bool &a, const bool &b) { return a || b; };
|
||||
binary_forward<bool, bool>(op_or, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
case OPERATION::XOR:
|
||||
{
|
||||
auto op_xor = [](const bool &a, const bool &b) { return a != b; };
|
||||
binary_forward<bool, bool>(op_xor, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -788,17 +805,16 @@ public:
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case CV_Bool:
|
||||
boolOpDispatch(std::forward<Args>(args)...);
|
||||
break;
|
||||
case CV_8U:
|
||||
// TODO: integrate with type inference
|
||||
helper.reInit(sizeof(uint8_t));
|
||||
opDispatch<uint8_t>(std::forward<Args>(args)...);
|
||||
break;
|
||||
case CV_8S:
|
||||
opDispatch<int8_t>(std::forward<Args>(args)...);
|
||||
break;
|
||||
case CV_32S:
|
||||
// TODO: integrate with type inference
|
||||
helper.reInit(sizeof(int32_t));
|
||||
opDispatch<int32_t>(std::forward<Args>(args)...);
|
||||
break;
|
||||
case CV_64S:
|
||||
@ -916,11 +932,16 @@ public:
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> >& inputs, const std::vector<Ptr<BackendNode> >& 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<InfEngineNgraphNode>()->node;
|
||||
auto& inp1 = nodes[1].dynamicCast<InfEngineNgraphNode>()->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<ov::op::v1::Add>(inp0, inp1);
|
||||
else if (op == OPERATION::PROD)
|
||||
node = std::make_shared<ov::op::v1::Multiply>(inp0, inp1);
|
||||
else if (op == OPERATION::EQUAL)
|
||||
node = std::make_shared<ov::op::v1::Equal>(inp0, inp1);
|
||||
else if (op == OPERATION::GREATER)
|
||||
node = std::make_shared<ov::op::v1::Greater>(inp0, inp1);
|
||||
else if (op == OPERATION::GREATER_EQUAL)
|
||||
node = std::make_shared<ov::op::v1::GreaterEqual>(inp0, inp1);
|
||||
else if (op == OPERATION::LESS)
|
||||
node = std::make_shared<ov::op::v1::Less>(inp0, inp1);
|
||||
else if (op == OPERATION::LESS_EQUAL)
|
||||
node = std::make_shared<ov::op::v1::LessEqual>(inp0, inp1);
|
||||
else if (op == OPERATION::AND)
|
||||
node = std::make_shared<ov::op::v1::LogicalAnd>(inp0, inp1);
|
||||
else if (op == OPERATION::OR)
|
||||
node = std::make_shared<ov::op::v1::LogicalOr>(inp0, inp1);
|
||||
else if (op == OPERATION::XOR)
|
||||
node = std::make_shared<ov::op::v1::LogicalXor>(inp0, inp1);
|
||||
else if (op == OPERATION::WHERE)
|
||||
{
|
||||
auto& inp2 = nodes[2].dynamicCast<InfEngineNgraphNode>()->node;
|
||||
node = std::make_shared<ov::op::v1::Select>(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) {
|
||||
|
83
modules/dnn/src/layers/not_layer.cpp
Normal file
83
modules/dnn/src/layers/not_layer.cpp
Normal file
@ -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<MatShape> &inputs,
|
||||
const int requiredOutputs,
|
||||
std::vector<MatShape> &outputs,
|
||||
std::vector<MatShape> &internals) const CV_OVERRIDE
|
||||
{
|
||||
CV_CheckEQ(inputs.size(), (size_t)1, "");
|
||||
outputs.assign(1, inputs[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual 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_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<Mat> 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>();
|
||||
bool* output = outputs[0].ptr<bool>();
|
||||
int size = inputs[0].total();
|
||||
|
||||
for (int i = 0; i < size; ++i)
|
||||
output[i] = !input[i];
|
||||
}
|
||||
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> >& inputs,
|
||||
const std::vector<Ptr<BackendNode> >& nodes) CV_OVERRIDE
|
||||
{
|
||||
auto node = std::make_shared<ov::op::v1::LogicalNot>(nodes[0].dynamicCast<InfEngineNgraphNode>()->node);
|
||||
return Ptr<BackendNode>(new InfEngineNgraphNode(node));
|
||||
}
|
||||
#endif // HAVE_DNN_NGRAPH
|
||||
|
||||
};
|
||||
|
||||
Ptr<NotLayer> NotLayer::create(const LayerParams& params)
|
||||
{
|
||||
return makePtr<NotLayerImpl>(params);
|
||||
}
|
||||
|
||||
}} // namespace cv::dnn
|
@ -417,7 +417,10 @@ public:
|
||||
) override
|
||||
{
|
||||
auto context = reinterpret_cast<csl::CSLContext*>(context_);
|
||||
return make_cuda_node_with_type<cuda4dnn::ReshapeOp>(preferableTarget, inputs[0]->getHostMatDepth(), std::move(context->stream));
|
||||
if (inputs[0]->getHostMatDepth() == CV_Bool)
|
||||
return make_cuda_node_bool<cuda4dnn::ReshapeOp>(std::move(context->stream));
|
||||
else
|
||||
return make_cuda_node_with_type<cuda4dnn::ReshapeOp>(preferableTarget, inputs[0]->getHostMatDepth(), std::move(context->stream));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -90,7 +90,7 @@ Ptr<BackendWrapper> 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<BackendWrapper> 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");
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ Ptr<BackendWrapper> 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<BackendWrapper> 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");
|
||||
}
|
||||
|
@ -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<char*>(tensor_proto.raw_data().c_str());
|
||||
Mat(sizes, CV_Bool, val).copyTo(blob);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string errorMsg = "Unsupported data type: " +
|
||||
|
@ -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;
|
||||
|
@ -273,6 +273,11 @@ namespace cv { namespace dnn {
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
template <template <class> class NodeType, class ...Args>
|
||||
cv::Ptr<BackendNode> make_cuda_node_bool(Args&& ...args) {
|
||||
return Ptr<BackendNode>(new NodeType<bool>(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
/* base class for all CUDA backend/target wrappers */
|
||||
class CUDABackendWrapper : public BackendWrapper {
|
||||
public:
|
||||
@ -335,6 +340,11 @@ namespace cv { namespace dnn {
|
||||
cuda4dnn::csl::memcpy<int64_t>(reinterpret_cast<int64_t*>(mat.data), view.data(), view.size(), stream);
|
||||
}
|
||||
|
||||
template <> inline
|
||||
void convert_D2H<bool, bool>(const cv::Mat& mat, cuda4dnn::csl::View<bool> view, cuda4dnn::csl::ManagedPtr<bool>& device_temp, const cuda4dnn::csl::Stream& stream) {
|
||||
cuda4dnn::csl::memcpy<bool>(reinterpret_cast<bool*>(mat.data), view.data(), view.size(), stream);
|
||||
}
|
||||
|
||||
template <class DEVICE_T, class HOST_T>
|
||||
void convert_D2H_background(const cv::Mat& mat, cuda4dnn::csl::View<DEVICE_T> view, cuda4dnn::csl::ManagedPtr<HOST_T>& device_temp, const cuda4dnn::csl::Stream& stream, const cuda4dnn::csl::Stream& d2h_stream, cuda4dnn::csl::Event& d2h_event);
|
||||
|
||||
@ -393,6 +403,13 @@ namespace cv { namespace dnn {
|
||||
cuda4dnn::csl::memcpy<int64_t>(reinterpret_cast<int64_t*>(mat.data), view.data(), view.size(), d2h_stream);
|
||||
}
|
||||
|
||||
template <> inline
|
||||
void convert_D2H_background<bool, bool>(const cv::Mat& mat, cuda4dnn::csl::View<bool> view, cuda4dnn::csl::ManagedPtr<bool>& device_temp, const cuda4dnn::csl::Stream& stream, const cuda4dnn::csl::Stream& d2h_stream, cuda4dnn::csl::Event& d2h_event) {
|
||||
d2h_event.record(stream);
|
||||
cuda4dnn::csl::StreamWaitOnEvent(d2h_stream, d2h_event);
|
||||
cuda4dnn::csl::memcpy<bool>(reinterpret_cast<bool*>(mat.data), view.data(), view.size(), d2h_stream);
|
||||
}
|
||||
|
||||
template <class DEVICE_T, class HOST_T>
|
||||
void convert_H2D(cuda4dnn::csl::Span<DEVICE_T> span, const cv::Mat& mat, cuda4dnn::csl::ManagedPtr<HOST_T>& device_temp, const cuda4dnn::csl::Stream& stream);
|
||||
|
||||
@ -430,6 +447,11 @@ namespace cv { namespace dnn {
|
||||
void convert_H2D<int64_t, int64_t>(cuda4dnn::csl::Span<int64_t> span, const cv::Mat& mat, cuda4dnn::csl::ManagedPtr<int64_t>& device_temp, const cuda4dnn::csl::Stream& stream) {
|
||||
cuda4dnn::csl::memcpy<int64_t>(span.data(), reinterpret_cast<int64_t*>(mat.data), span.size(), stream);
|
||||
}
|
||||
|
||||
template <> inline
|
||||
void convert_H2D<bool, bool>(cuda4dnn::csl::Span<bool> span, const cv::Mat& mat, cuda4dnn::csl::ManagedPtr<bool>& device_temp, const cuda4dnn::csl::Stream& stream) {
|
||||
cuda4dnn::csl::memcpy<bool>(span.data(), reinterpret_cast<bool*>(mat.data), span.size(), stream);
|
||||
}
|
||||
}} /* namespace cuda4dnn::detail */
|
||||
|
||||
template <class DEVICE_T, class HOST_T, int TargetID>
|
||||
@ -662,6 +684,7 @@ namespace cv { namespace dnn {
|
||||
using CUDABackendWrapperUINT8 = GenericCUDABackendWrapper<uint8_t, uint8_t, DNN_TARGET_CUDA>;
|
||||
using CUDABackendWrapperINT32 = GenericCUDABackendWrapper<int32_t, int32_t, DNN_TARGET_CUDA>;
|
||||
using CUDABackendWrapperINT64 = GenericCUDABackendWrapper<int64_t, int64_t, DNN_TARGET_CUDA>;
|
||||
using CUDABackendWrapperBOOL = GenericCUDABackendWrapper<bool, bool, DNN_TARGET_CUDA>;
|
||||
|
||||
template <class T> struct GetCUDABackendWrapperType_ { };
|
||||
template <> struct GetCUDABackendWrapperType_<half> { typedef CUDABackendWrapperFP16 type; };
|
||||
@ -670,6 +693,7 @@ namespace cv { namespace dnn {
|
||||
template <> struct GetCUDABackendWrapperType_<uint8_t> { typedef CUDABackendWrapperUINT8 type; };
|
||||
template <> struct GetCUDABackendWrapperType_<int32_t> { typedef CUDABackendWrapperINT32 type; };
|
||||
template <> struct GetCUDABackendWrapperType_<int64_t> { typedef CUDABackendWrapperINT64 type; };
|
||||
template <> struct GetCUDABackendWrapperType_<bool> { typedef CUDABackendWrapperBOOL type; };
|
||||
|
||||
template <class T>
|
||||
using GetCUDABackendWrapperType = typename GetCUDABackendWrapperType_<T>::type;
|
||||
|
@ -53,6 +53,7 @@ Mat infEngineBlobToMat(const ov::Tensor& blob)
|
||||
case ov::element::i32: type = CV_32S; break;
|
||||
case ov::element::i64: type = CV_64S; break;
|
||||
case ov::element::u8: type = CV_8U; break;
|
||||
case ov::element::boolean: type = CV_Bool; break;
|
||||
default:
|
||||
CV_Error(Error::StsNotImplemented, "Unsupported blob precision");
|
||||
}
|
||||
|
@ -4,14 +4,6 @@
|
||||
"test_adagrad_multiple", // ---- same as above ---
|
||||
"test_adam", // Issues::Layer::Can't create layer "onnx_node_output_0!X1_new" of type "ai.onnx.preview.training.Adam" in function 'getLayerInstance'
|
||||
"test_adam_multiple", // ---- same as above ---
|
||||
"test_and2d", // Issue:: Unsupported data type BOOL
|
||||
"test_and3d", // Issue:: Unsupported data type BOOL
|
||||
"test_and4d", // Issue:: Unsupported data type BOOL
|
||||
"test_and_bcast3v1d", // Issue:: Unsupported data type BOOL
|
||||
"test_and_bcast3v2d", // Issue:: Unsupported data type BOOL
|
||||
"test_and_bcast4v2d", // Issue:: Unsupported data type BOOL
|
||||
"test_and_bcast4v3d", // Issue:: Unsupported data type BOOL
|
||||
"test_and_bcast4v4d", // Issue:: Unsupported data type BOOL
|
||||
"test_basic_convinteger", // Issues::Layer::Can't create layer "onnx_node_output_0!y" of type "ConvInteger" in function 'getLayerInstance'
|
||||
"test_batchnorm_epsilon", // Issue:: Unkonwn error::Blob mean not found in const blobs in function 'getBlob'
|
||||
"test_batchnorm_epsilon_training_mode", // ---- same as above ---
|
||||
@ -102,8 +94,6 @@
|
||||
"test_dynamicquantizelinear_min_adjusted_expanded", // ---- same as above ---
|
||||
"test_edge_pad", // Issue::Parser::Weights are required as inputs
|
||||
"test_einsum_inner_prod", // Issue::Output shape does not match with reference
|
||||
"test_equal", // Issue:: Unsupported data type BOOL
|
||||
"test_equal_bcast", // ---- same as above ---
|
||||
"test_expand_dim_changed", // Issue:: Unkonwn error
|
||||
"test_expand_dim_unchanged", // Issue:: Unkonwn error
|
||||
"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'
|
||||
@ -121,12 +111,6 @@
|
||||
"test_gemm_default_zero_bias", // Issue::Wrong output
|
||||
"test_gemm_transposeA", // Issue::Wrong output
|
||||
"test_gemm_transposeB", // Issue::Wrong output
|
||||
"test_greater", // Issue:: Unsupported data type BOOL
|
||||
"test_greater_bcast", // ---- same as above ---
|
||||
"test_greater_equal", // ---- same as above ---
|
||||
"test_greater_equal_bcast", // ---- same as above ---
|
||||
"test_greater_equal_bcast_expanded", // ---- same as above ---
|
||||
"test_greater_equal_expanded", // ---- same as above ---
|
||||
"test_gridsample", // Issues::Layer::Can't create layer "onnx_node_output_0!Y" of type "GridSample" in function 'getLayerInstance'
|
||||
"test_gridsample_aligncorners_true", // ---- same as above ---
|
||||
"test_gridsample_bicubic", // ---- same as above ---
|
||||
@ -155,12 +139,6 @@
|
||||
"test_isinf_negative", // Issue:: Unsupported data type BOOL
|
||||
"test_isinf_positive", // Issue:: Unsupported data type BOOL
|
||||
"test_isnan", // Issue:: Unsupported data type BOOL
|
||||
"test_less", // Issue:: Unsupported data type BOOL
|
||||
"test_less_bcast", // Issue:: Unsupported data type BOOL
|
||||
"test_less_equal", // Issue:: Unsupported data type BOOL
|
||||
"test_less_equal_bcast", // Issue:: Unsupported data type BOOL
|
||||
"test_less_equal_bcast_expanded", // Issue:: Unsupported data type BOOL
|
||||
"test_less_equal_expanded", // Issue:: Unsupported data type BOOL
|
||||
"test_loop11", // Issue:: Unsupported data type BOOL
|
||||
"test_loop13_seq", // Issue:: Unsupported data type BOOL
|
||||
"test_loop16_seq_none", // Issue:: Unsupported data type BOOL
|
||||
@ -228,9 +206,6 @@
|
||||
"test_nonmaxsuppression_two_batches", // ---- same as above ---
|
||||
"test_nonmaxsuppression_two_classes", // ---- same as above ---
|
||||
"test_nonzero_example", // Issue:: Unsupported data type: BOOL
|
||||
"test_not_2d", // ---- same as above ---
|
||||
"test_not_3d", // ---- same as above ---
|
||||
"test_not_4d", // ---- same as above ---
|
||||
"test_onehot_negative_indices", // Issue:: Layer does not exist (OneHot) :: Can't create layer "onnx_node_output_0!y" of type "OneHot" in function 'getLayerInstance'
|
||||
"test_onehot_with_axis", // ---- same as above ---
|
||||
"test_onehot_with_negative_axis", // ---- same as above ---
|
||||
@ -239,14 +214,6 @@
|
||||
"test_optional_get_element_sequence", // ---- same as above ---
|
||||
"test_optional_has_element", // Issue:: Unsupported data type BOOL
|
||||
"test_optional_has_element_empty", // ---- same as above ---
|
||||
"test_or2d",
|
||||
"test_or3d", // ---- same as above ---
|
||||
"test_or4d", // ---- same as above ---
|
||||
"test_or_bcast3v1d",
|
||||
"test_or_bcast3v2d", // ---- same as above ---
|
||||
"test_or_bcast4v2d", // ---- same as above ---
|
||||
"test_or_bcast4v3d", // ---- same as above ---
|
||||
"test_or_bcast4v4d", // ---- same as above ---
|
||||
"test_pow_types_float", // Issue:: Unsupported data type
|
||||
"test_pow_types_float32_int32", // ---- same as above ---
|
||||
"test_pow_types_float32_int64", // ---- same as above ---
|
||||
@ -471,16 +438,6 @@
|
||||
"test_unsqueeze_three_axes", // ---- same as above ---
|
||||
"test_unsqueeze_two_axes", // ---- same as above ---)
|
||||
"test_unsqueeze_unsorted_axes", // ---- same as above ---)
|
||||
"test_where_example", // Issue:: Parser: Unsupported data type: BOOL in function 'getMatFromTensor'
|
||||
"test_where_long_example", // ---- same as above ---
|
||||
"test_xor2d", // Issue:: Parser: Unsupported data type: BOOL in function 'getMatFromTensor'
|
||||
"test_xor3d", // ---- same as above ---
|
||||
"test_xor4d", // ---- same as above ---
|
||||
"test_xor_bcast3v1d", // ---- same as above ---
|
||||
"test_xor_bcast3v2d", // ---- same as above ---
|
||||
"test_xor_bcast4v2d", // ---- same as above ---
|
||||
"test_xor_bcast4v3d", // ---- same as above ---
|
||||
"test_xor_bcast4v4d", // ---- same as above ---
|
||||
// // Cumsum related issue: https://github.com/opencv/opencv/issues/24437
|
||||
"test_cumsum_1d", //Issue:: output shape creation mismatch
|
||||
"test_cumsum_1d_exclusive", // ---- same as above ---
|
||||
|
@ -1416,6 +1416,9 @@ double norm(InputArray _src, int normType, InputArray _mask)
|
||||
|
||||
switch( depth )
|
||||
{
|
||||
case CV_Bool:
|
||||
result = norm_((const bool*)sptr, total, cn, normType, result, mptr);
|
||||
break;
|
||||
case CV_8U:
|
||||
result = norm_((const uchar*)sptr, total, cn, normType, result, mptr);
|
||||
break;
|
||||
@ -1522,6 +1525,9 @@ double norm(InputArray _src1, InputArray _src2, int normType, InputArray _mask)
|
||||
|
||||
switch( depth )
|
||||
{
|
||||
case CV_Bool:
|
||||
result = norm_((const bool*)sptr1, (const bool*)sptr2, total, cn, normType, result, mptr);
|
||||
break;
|
||||
case CV_8U:
|
||||
result = norm_((const uchar*)sptr1, (const uchar*)sptr2, total, cn, normType, result, mptr);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user