Merge remote-tracking branch 'upstream/3.4' into merge-3.4
authorAlexander Alekhin <alexander.a.alekhin@gmail.com>
Sat, 3 Dec 2022 05:46:23 +0000 (05:46 +0000)
committerAlexander Alekhin <alexander.a.alekhin@gmail.com>
Sat, 3 Dec 2022 12:39:41 +0000 (12:39 +0000)
18 files changed:
1  2 
cmake/OpenCVUtils.cmake
modules/core/src/minmax.cpp
modules/dnn/src/ie_ngraph.cpp
modules/dnn/test/test_backends.cpp
modules/dnn/test/test_caffe_importer.cpp
modules/dnn/test/test_darknet_importer.cpp
modules/dnn/test/test_halide_layers.cpp
modules/dnn/test/test_layers.cpp
modules/dnn/test/test_model.cpp
modules/dnn/test/test_onnx_importer.cpp
modules/dnn/test/test_tf_importer.cpp
modules/dnn/test/test_torch_importer.cpp
modules/highgui/src/window_w32.cpp
modules/imgcodecs/include/opencv2/imgcodecs.hpp
modules/imgcodecs/src/loadsave.cpp
modules/imgcodecs/test/test_grfmt.cpp
modules/imgcodecs/test/test_read_write.cpp
modules/video/src/bgfg_gaussmix2.cpp

Simple merge
Simple merge
Simple merge
Simple merge
index 3ea8d17102149fce662c7254f92a7628815da66e,c66f46d8b0c7f514fac93f701d4c9fe74bc877cb..4043bd118e7372605060bcc613d83a66dbf1d92a
@@@ -789,28 -750,19 +779,19 @@@ TEST_P(Test_Caffe_nets, RFCN
          CV_TEST_TAG_DEBUG_VERYLONG
      );
  
 -    double scoreDiff = (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16) ? 4e-3 : default_l1;
 -    double iouDiff = (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16) ? 8e-2 : default_lInf;
 +    float scoreDiff = default_l1, iouDiff = default_lInf;
 +    if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
 +    {
 +        scoreDiff = 4e-3;
 +        iouDiff = 8e-2;
 +    }
 +    if (target == DNN_TARGET_CUDA_FP16)
 +    {
 +        scoreDiff = 0.0034;
 +        iouDiff = 0.12;
 +    }
  
  #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
--    // Exception: Cannot get memory!
--    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
--        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
--    // Sporadic: "Cannot get memory!"
--    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
--        applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
--            CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
--        );
--
      if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
      {
          scoreDiff = 0.1f;
Simple merge
index 25d1a18d5262ba835486b39879c3750113311a9c,0000000000000000000000000000000000000000..d7fc2af73dd755f3f2ed2694b96f595378301926
mode 100644,000000..100644
--- /dev/null
@@@ -1,811 -1,0 +1,800 @@@
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
-         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +// 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 "test_precomp.hpp"
 +#include <opencv2/dnn/shape_utils.hpp>
 +#include "npy_blob.hpp"
 +namespace opencv_test { namespace {
 +
 +template<typename TString>
 +static std::string _tf(TString filename, bool required = true)
 +{
 +    String rootFolder = "dnn/";
 +    return findDataFile(rootFolder + filename, required);
 +}
 +
 +
 +class Test_Model : public DNNTestLayer
 +{
 +public:
 +    void testDetectModel(const std::string& weights, const std::string& cfg,
 +                         const std::string& imgPath, const std::vector<int>& refClassIds,
 +                         const std::vector<float>& refConfidences,
 +                         const std::vector<Rect2d>& refBoxes,
 +                         double scoreDiff, double iouDiff,
 +                         double confThreshold = 0.24, double nmsThreshold = 0.0,
 +                         const Size& size = {-1, -1}, Scalar mean = Scalar(),
 +                         double scale = 1.0, bool swapRB = false, bool crop = false,
 +                         bool nmsAcrossClasses = false)
 +    {
 +        checkBackend();
 +
 +        Mat frame = imread(imgPath);
 +        DetectionModel model(weights, cfg);
 +
 +        model.setInputSize(size).setInputMean(mean).setInputScale(scale)
 +             .setInputSwapRB(swapRB).setInputCrop(crop);
 +
 +        model.setPreferableBackend(backend);
 +        model.setPreferableTarget(target);
 +
 +        model.setNmsAcrossClasses(nmsAcrossClasses);
 +
 +        std::vector<int> classIds;
 +        std::vector<float> confidences;
 +        std::vector<Rect> boxes;
 +
 +        model.detect(frame, classIds, confidences, boxes, confThreshold, nmsThreshold);
 +
 +        std::vector<Rect2d> boxesDouble(boxes.size());
 +        for (int i = 0; i < boxes.size(); i++) {
 +            boxesDouble[i] = boxes[i];
 +        }
 +        normAssertDetections(refClassIds, refConfidences, refBoxes, classIds,
 +                             confidences, boxesDouble, "",
 +                             confThreshold, scoreDiff, iouDiff);
 +    }
 +
 +    void testClassifyModel(const std::string& weights, const std::string& cfg,
 +                           const std::string& imgPath, std::pair<int, float> ref, float norm,
 +                           const Size& size = {-1, -1}, Scalar mean = Scalar(),
 +                           double scale = 1.0, bool swapRB = false, bool crop = false)
 +    {
 +        checkBackend();
 +
 +        Mat frame = imread(imgPath);
 +        ClassificationModel model(weights, cfg);
 +        model.setInputSize(size).setInputMean(mean).setInputScale(scale)
 +             .setInputSwapRB(swapRB).setInputCrop(crop);
 +
 +        std::pair<int, float> prediction = model.classify(frame);
 +        EXPECT_EQ(prediction.first, ref.first);
 +        ASSERT_NEAR(prediction.second, ref.second, norm);
 +    }
 +
 +    void testKeypointsModel(const std::string& weights, const std::string& cfg,
 +                            const Mat& frame, const Mat& exp, float norm,
 +                            const Size& size = {-1, -1}, Scalar mean = Scalar(),
 +                            double scale = 1.0, bool swapRB = false, bool crop = false)
 +    {
 +        checkBackend();
 +
 +        std::vector<Point2f> points;
 +
 +        KeypointsModel model(weights, cfg);
 +        model.setInputSize(size).setInputMean(mean).setInputScale(scale)
 +             .setInputSwapRB(swapRB).setInputCrop(crop);
 +
 +        model.setPreferableBackend(backend);
 +        model.setPreferableTarget(target);
 +
 +        points = model.estimate(frame, 0.5);
 +
 +        Mat out = Mat(points).reshape(1);
 +        normAssert(exp, out, "", norm, norm);
 +    }
 +
 +    void testSegmentationModel(const std::string& weights_file, const std::string& config_file,
 +                               const std::string& inImgPath, const std::string& outImgPath,
 +                               float norm, const Size& size = {-1, -1}, Scalar mean = Scalar(),
 +                               double scale = 1.0, bool swapRB = false, bool crop = false)
 +    {
 +        checkBackend();
 +
 +        Mat frame = imread(inImgPath);
 +        Mat mask;
 +        Mat exp = imread(outImgPath, 0);
 +
 +        SegmentationModel model(weights_file, config_file);
 +        model.setInputSize(size).setInputMean(mean).setInputScale(scale)
 +             .setInputSwapRB(swapRB).setInputCrop(crop);
 +
 +        model.setPreferableBackend(backend);
 +        model.setPreferableTarget(target);
 +
 +        model.segment(frame, mask);
 +        normAssert(mask, exp, "", norm, norm);
 +    }
 +
 +    void testTextRecognitionModel(const std::string& weights, const std::string& cfg,
 +                                  const std::string& imgPath, const std::string& seq,
 +                                  const std::string& decodeType, const std::vector<std::string>& vocabulary,
 +                                  const Size& size = {-1, -1}, Scalar mean = Scalar(),
 +                                  double scale = 1.0, bool swapRB = false, bool crop = false)
 +    {
 +        checkBackend();
 +
 +        Mat frame = imread(imgPath, IMREAD_GRAYSCALE);
 +
 +        TextRecognitionModel model(weights, cfg);
 +        model.setDecodeType(decodeType)
 +             .setVocabulary(vocabulary)
 +             .setInputSize(size).setInputMean(mean).setInputScale(scale)
 +             .setInputSwapRB(swapRB).setInputCrop(crop);
 +
 +        model.setPreferableBackend(backend);
 +        model.setPreferableTarget(target);
 +
 +        std::string result = model.recognize(frame);
 +        EXPECT_EQ(result, seq) << "Full frame: " << imgPath;
 +
 +        std::vector<Rect> rois;
 +        rois.push_back(Rect(0, 0, frame.cols, frame.rows));
 +        rois.push_back(Rect(0, 0, frame.cols, frame.rows));  // twice
 +        std::vector<std::string> results;
 +        model.recognize(frame, rois, results);
 +        EXPECT_EQ((size_t)2u, results.size()) << "ROI: " << imgPath;
 +        EXPECT_EQ(results[0], seq) << "ROI[0]: " << imgPath;
 +        EXPECT_EQ(results[1], seq) << "ROI[1]: " << imgPath;
 +    }
 +
 +    void testTextDetectionModelByDB(const std::string& weights, const std::string& cfg,
 +                                    const std::string& imgPath, const std::vector<std::vector<Point>>& gt,
 +                                    float binThresh, float polyThresh,
 +                                    uint maxCandidates, double unclipRatio,
 +                                    const Size& size = {-1, -1}, Scalar mean = Scalar(),
 +                                    double scale = 1.0, bool swapRB = false, bool crop = false)
 +    {
 +        checkBackend();
 +
 +        Mat frame = imread(imgPath);
 +
 +        TextDetectionModel_DB model(weights, cfg);
 +        model.setBinaryThreshold(binThresh)
 +             .setPolygonThreshold(polyThresh)
 +             .setUnclipRatio(unclipRatio)
 +             .setMaxCandidates(maxCandidates)
 +             .setInputSize(size).setInputMean(mean).setInputScale(scale)
 +             .setInputSwapRB(swapRB).setInputCrop(crop);
 +
 +        model.setPreferableBackend(backend);
 +        model.setPreferableTarget(target);
 +
 +        // 1. Check common TextDetectionModel API through RotatedRect
 +        std::vector<cv::RotatedRect> results;
 +        model.detectTextRectangles(frame, results);
 +
 +        EXPECT_GT(results.size(), (size_t)0);
 +
 +        std::vector< std::vector<Point> > contours;
 +        for (size_t i = 0; i < results.size(); i++)
 +        {
 +            const RotatedRect& box = results[i];
 +            Mat contour;
 +            boxPoints(box, contour);
 +            std::vector<Point> contour2i(4);
 +            for (int i = 0; i < 4; i++)
 +            {
 +                contour2i[i].x = cvRound(contour.at<float>(i, 0));
 +                contour2i[i].y = cvRound(contour.at<float>(i, 1));
 +            }
 +            contours.push_back(contour2i);
 +        }
 +#if 0 // test debug
 +        Mat result = frame.clone();
 +        drawContours(result, contours, -1, Scalar(0, 0, 255), 1);
 +        imshow("result", result); // imwrite("result.png", result);
 +        waitKey(0);
 +#endif
 +        normAssertTextDetections(gt, contours, "", 0.05f);
 +
 +        // 2. Check quadrangle-based API
 +        // std::vector< std::vector<Point> > contours;
 +        model.detect(frame, contours);
 +
 +#if 0 // test debug
 +        Mat result = frame.clone();
 +        drawContours(result, contours, -1, Scalar(0, 0, 255), 1);
 +        imshow("result_contours", result); // imwrite("result_contours.png", result);
 +        waitKey(0);
 +#endif
 +        normAssertTextDetections(gt, contours, "", 0.05f);
 +    }
 +
 +    void testTextDetectionModelByEAST(
 +            const std::string& weights, const std::string& cfg,
 +            const std::string& imgPath, const std::vector<RotatedRect>& gt,
 +            float confThresh, float nmsThresh,
 +            const Size& size = {-1, -1}, Scalar mean = Scalar(),
 +            double scale = 1.0, bool swapRB = false, bool crop = false,
 +            double eps_center = 5/*pixels*/, double eps_size = 5/*pixels*/, double eps_angle = 1
 +    )
 +    {
 +        checkBackend();
 +
 +        Mat frame = imread(imgPath);
 +
 +        TextDetectionModel_EAST model(weights, cfg);
 +        model.setConfidenceThreshold(confThresh)
 +             .setNMSThreshold(nmsThresh)
 +             .setInputSize(size).setInputMean(mean).setInputScale(scale)
 +             .setInputSwapRB(swapRB).setInputCrop(crop);
 +
 +        model.setPreferableBackend(backend);
 +        model.setPreferableTarget(target);
 +
 +        std::vector<cv::RotatedRect> results;
 +        model.detectTextRectangles(frame, results);
 +
 +        EXPECT_EQ(results.size(), (size_t)1);
 +        for (size_t i = 0; i < results.size(); i++)
 +        {
 +            const RotatedRect& box = results[i];
 +#if 0 // test debug
 +            Mat contour;
 +            boxPoints(box, contour);
 +            std::vector<Point> contour2i(4);
 +            for (int i = 0; i < 4; i++)
 +            {
 +                contour2i[i].x = cvRound(contour.at<float>(i, 0));
 +                contour2i[i].y = cvRound(contour.at<float>(i, 1));
 +            }
 +            std::vector< std::vector<Point> > contours;
 +            contours.push_back(contour2i);
 +
 +            Mat result = frame.clone();
 +            drawContours(result, contours, -1, Scalar(0, 0, 255), 1);
 +            imshow("result", result); //imwrite("result.png", result);
 +            waitKey(0);
 +#endif
 +            const RotatedRect& gtBox = gt[i];
 +            EXPECT_NEAR(box.center.x, gtBox.center.x, eps_center);
 +            EXPECT_NEAR(box.center.y, gtBox.center.y, eps_center);
 +            EXPECT_NEAR(box.size.width, gtBox.size.width, eps_size);
 +            EXPECT_NEAR(box.size.height, gtBox.size.height, eps_size);
 +            EXPECT_NEAR(box.angle, gtBox.angle, eps_angle);
 +        }
 +    }
 +};
 +
 +TEST_P(Test_Model, Classify)
 +{
 +    std::pair<int, float> ref(652, 0.641789);
 +
 +    std::string img_path = _tf("grace_hopper_227.png");
 +    std::string config_file = _tf("bvlc_alexnet.prototxt");
 +    std::string weights_file = _tf("bvlc_alexnet.caffemodel", false);
 +
 +    Size size{227, 227};
 +    float norm = 1e-4;
 +
 +    testClassifyModel(weights_file, config_file, img_path, ref, norm, size);
 +}
 +
 +
 +TEST_P(Test_Model, DetectRegion)
 +{
 +    applyTestTag(
 +        CV_TEST_TAG_LONG,
 +        CV_TEST_TAG_MEMORY_2GB
 +    );
 +
 +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
 +    // accuracy
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
 +    // accuracy
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000)  // nGraph compilation failure
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
 +    // FIXIT DNN_BACKEND_INFERENCE_ENGINE is misused
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
 +#endif
 +
 +#if defined(INF_ENGINE_RELEASE)
 +    if (target == DNN_TARGET_MYRIAD
 +        && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
 +#endif
 +
 +    std::vector<int> refClassIds = {6, 1, 11};
 +    std::vector<float> refConfidences = {0.750469f, 0.780879f, 0.901615f};
 +    std::vector<Rect2d> refBoxes = {Rect2d(240, 53, 135, 72),
 +                                    Rect2d(112, 109, 192, 200),
 +                                    Rect2d(58, 141, 117, 249)};
 +
 +    std::string img_path = _tf("dog416.png");
 +    std::string weights_file = _tf("yolo-voc.weights", false);
 +    std::string config_file = _tf("yolo-voc.cfg");
 +
 +    double scale = 1.0 / 255.0;
 +    Size size{416, 416};
 +    bool swapRB = true;
 +
 +    double confThreshold = 0.24;
 +    double nmsThreshold = (target == DNN_TARGET_MYRIAD) ? 0.397 : 0.4;
 +    double scoreDiff = 8e-5, iouDiff = 1e-5;
 +    if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CUDA_FP16)
 +    {
 +        scoreDiff = 1e-2;
 +        iouDiff = 1.6e-2;
 +    }
 +
 +    testDetectModel(weights_file, config_file, img_path, refClassIds, refConfidences,
 +                    refBoxes, scoreDiff, iouDiff, confThreshold, nmsThreshold, size,
 +                    Scalar(), scale, swapRB);
 +}
 +
 +TEST_P(Test_Model, DetectRegionWithNmsAcrossClasses)
 +{
 +    applyTestTag(
 +        CV_TEST_TAG_LONG,
 +        CV_TEST_TAG_MEMORY_2GB
 +    );
 +
 +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
 +    // accuracy
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
 +    // accuracy
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000)  // nGraph compilation failure
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
 +#endif
 +
 +#if defined(INF_ENGINE_RELEASE)
 +    if (target == DNN_TARGET_MYRIAD
 +        && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
 +#endif
 +
 +    std::vector<int> refClassIds = { 6, 11 };
 +    std::vector<float> refConfidences = { 0.750469f, 0.901615f };
 +    std::vector<Rect2d> refBoxes = { Rect2d(240, 53, 135, 72),
 +                                    Rect2d(58, 141, 117, 249) };
 +
 +    std::string img_path = _tf("dog416.png");
 +    std::string weights_file = _tf("yolo-voc.weights", false);
 +    std::string config_file = _tf("yolo-voc.cfg");
 +
 +    double scale = 1.0 / 255.0;
 +    Size size{ 416, 416 };
 +    bool swapRB = true;
 +    bool crop = false;
 +    bool nmsAcrossClasses = true;
 +
 +    double confThreshold = 0.24;
 +    double nmsThreshold = (target == DNN_TARGET_MYRIAD) ? 0.15: 0.15;
 +    double scoreDiff = 8e-5, iouDiff = 1e-5;
 +    if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CUDA_FP16)
 +    {
 +        scoreDiff = 1e-2;
 +        iouDiff = 1.6e-2;
 +    }
 +
 +    testDetectModel(weights_file, config_file, img_path, refClassIds, refConfidences,
 +        refBoxes, scoreDiff, iouDiff, confThreshold, nmsThreshold, size,
 +        Scalar(), scale, swapRB, crop,
 +        nmsAcrossClasses);
 +}
 +
 +TEST_P(Test_Model, DetectionOutput)
 +{
 +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
-         applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
-             CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
-         );
 +    // Check 'backward_compatible_check || in_out_elements_equal' failed at core/src/op/reshape.cpp:427:
 +    // While validating node 'v1::Reshape bbox_pred_reshape (ave_bbox_pred_rois[0]:f32{1,8,1,1}, Constant_388[0]:i64{4}) -> (f32{?,?,?,?})' with friendly_name 'bbox_pred_reshape':
 +    // Requested output shape {1,300,8,1} is incompatible with input shape {1, 8, 1, 1}
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
-         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
 +    // Exception: Function contains several inputs and outputs with one friendly name! (HETERO bug?)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target != DNN_TARGET_CPU)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE)
 +    // FIXIT DNN_BACKEND_INFERENCE_ENGINE is misused
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
 +
 +    if (target == DNN_TARGET_MYRIAD)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
 +#endif
 +
 +    std::vector<int> refClassIds = {7, 12};
 +    std::vector<float> refConfidences = {0.991359f, 0.94786f};
 +    std::vector<Rect2d> refBoxes = {Rect2d(491, 81, 212, 98),
 +                                    Rect2d(132, 223, 207, 344)};
 +
 +    std::string img_path = _tf("dog416.png");
 +    std::string weights_file = _tf("resnet50_rfcn_final.caffemodel", false);
 +    std::string config_file = _tf("rfcn_pascal_voc_resnet50.prototxt");
 +
 +    Scalar mean = Scalar(102.9801, 115.9465, 122.7717);
 +    Size size{800, 600};
 +
 +    double scoreDiff = default_l1, iouDiff = 1e-5;
 +    float confThreshold = 0.8;
 +    double nmsThreshold = 0.0;
 +    if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_CUDA_FP16)
 +    {
 +        if (backend == DNN_BACKEND_OPENCV)
 +            scoreDiff = 4e-3;
 +        else
 +            scoreDiff = 2e-2;
 +        iouDiff = 1.8e-1;
 +    }
 +
 +    testDetectModel(weights_file, config_file, img_path, refClassIds, refConfidences, refBoxes,
 +                    scoreDiff, iouDiff, confThreshold, nmsThreshold, size, mean);
 +}
 +
 +
 +TEST_P(Test_Model, DetectionMobilenetSSD)
 +{
 +    Mat ref = blobFromNPY(_tf("mobilenet_ssd_caffe_out.npy"));
 +    ref = ref.reshape(1, ref.size[2]);
 +
 +    std::string img_path = _tf("street.png");
 +    Mat frame = imread(img_path);
 +    int frameWidth  = frame.cols;
 +    int frameHeight = frame.rows;
 +
 +    std::vector<int> refClassIds;
 +    std::vector<float> refConfidences;
 +    std::vector<Rect2d> refBoxes;
 +    for (int i = 0; i < ref.rows; i++)
 +    {
 +        refClassIds.emplace_back(ref.at<float>(i, 1));
 +        refConfidences.emplace_back(ref.at<float>(i, 2));
 +        int left   = ref.at<float>(i, 3) * frameWidth;
 +        int top    = ref.at<float>(i, 4) * frameHeight;
 +        int right  = ref.at<float>(i, 5) * frameWidth;
 +        int bottom = ref.at<float>(i, 6) * frameHeight;
 +        int width  = right  - left + 1;
 +        int height = bottom - top + 1;
 +        refBoxes.emplace_back(left, top, width, height);
 +    }
 +
 +    std::string weights_file = _tf("MobileNetSSD_deploy.caffemodel", false);
 +    std::string config_file = _tf("MobileNetSSD_deploy.prototxt");
 +
 +    Scalar mean = Scalar(127.5, 127.5, 127.5);
 +    double scale = 1.0 / 127.5;
 +    Size size{300, 300};
 +
 +    double scoreDiff = 1e-5, iouDiff = 1e-5;
 +    if (target == DNN_TARGET_OPENCL_FP16)
 +    {
 +        scoreDiff = 1.7e-2;
 +        iouDiff = 6.91e-2;
 +    }
 +    else if (target == DNN_TARGET_MYRIAD)
 +    {
 +        scoreDiff = 0.017;
 +        if (getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
 +            iouDiff = 0.1;
 +    }
 +    else if (target == DNN_TARGET_CUDA_FP16)
 +    {
 +        scoreDiff = 0.0021;
 +        iouDiff = 1e-2;
 +    }
 +    float confThreshold = FLT_MIN;
 +    double nmsThreshold = 0.0;
 +
 +    testDetectModel(weights_file, config_file, img_path, refClassIds, refConfidences, refBoxes,
 +                    scoreDiff, iouDiff, confThreshold, nmsThreshold, size, mean, scale);
 +}
 +
 +TEST_P(Test_Model, Keypoints_pose)
 +{
 +    if (target == DNN_TARGET_OPENCL_FP16)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
 +#ifdef HAVE_INF_ENGINE
 +    if (target == DNN_TARGET_MYRIAD)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#endif
 +
 +    Mat inp = imread(_tf("pose.png"));
 +    std::string weights = _tf("onnx/models/lightweight_pose_estimation_201912.onnx", false);
 +    float kpdata[] = {
 +        237.65625f, 78.25f, 237.65625f, 136.9375f,
 +        190.125f, 136.9375f, 142.59375f, 195.625f, 79.21875f, 176.0625f, 285.1875f, 117.375f,
 +        348.5625f, 195.625f, 396.09375f, 176.0625f, 205.96875f, 313.0f, 205.96875f, 430.375f,
 +        205.96875f, 528.1875f, 269.34375f, 293.4375f, 253.5f, 430.375f, 237.65625f, 528.1875f,
 +        221.8125f, 58.6875f, 253.5f, 58.6875f, 205.96875f, 78.25f, 253.5f, 58.6875f
 +    };
 +    Mat exp(18, 2, CV_32FC1, kpdata);
 +
 +    Size size{256, 256};
 +    float norm = 1e-4;
 +    double scale = 1.0/255;
 +    Scalar mean = Scalar(128, 128, 128);
 +    bool swapRB = false;
 +
 +    // Ref. Range: [58.6875, 508.625]
 +    if (target == DNN_TARGET_CUDA_FP16)
 +        norm = 20; // l1 = 1.5, lInf = 20
 +
 +    testKeypointsModel(weights, "", inp, exp, norm, size, mean, scale, swapRB);
 +}
 +
 +TEST_P(Test_Model, Keypoints_face)
 +{
 +#if defined(INF_ENGINE_RELEASE)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#endif
 +
 +    Mat inp = imread(_tf("gray_face.png"), 0);
 +    std::string weights = _tf("onnx/models/facial_keypoints.onnx", false);
 +    Mat exp = blobFromNPY(_tf("facial_keypoints_exp.npy"));
 +
 +    Size size{224, 224};
 +    double scale = 1.0/255;
 +    Scalar mean = Scalar();
 +    bool swapRB = false;
 +
 +    // Ref. Range: [-1.1784188, 1.7758257]
 +    float norm = 1e-4;
 +    if (target == DNN_TARGET_OPENCL_FP16)
 +        norm = 5e-3;
 +    if (target == DNN_TARGET_MYRIAD)
 +    {
 +        // Myriad2: l1 = 0.0004, lInf = 0.002
 +        // MyriadX: l1 = 0.003, lInf = 0.009
 +        norm = 0.009;
 +    }
 +    if (target == DNN_TARGET_CUDA_FP16)
 +        norm = 0.004; // l1 = 0.0006, lInf = 0.004
 +
 +    testKeypointsModel(weights, "", inp, exp, norm, size, mean, scale, swapRB);
 +}
 +
 +TEST_P(Test_Model, Detection_normalized)
 +{
 +    std::string img_path = _tf("grace_hopper_227.png");
 +    std::vector<int> refClassIds = {15};
 +    std::vector<float> refConfidences = {0.999222f};
 +    std::vector<Rect2d> refBoxes = {Rect2d(0, 4, 227, 222)};
 +
 +    std::string weights_file = _tf("MobileNetSSD_deploy.caffemodel", false);
 +    std::string config_file = _tf("MobileNetSSD_deploy.prototxt");
 +
 +    Scalar mean = Scalar(127.5, 127.5, 127.5);
 +    double scale = 1.0 / 127.5;
 +    Size size{300, 300};
 +
 +    double scoreDiff = 1e-5, iouDiff = 1e-5;
 +    float confThreshold = FLT_MIN;
 +    double nmsThreshold = 0.0;
 +    if (target == DNN_TARGET_CUDA)
 +    {
 +        scoreDiff = 3e-4;
 +        iouDiff = 0.018;
 +    }
 +    if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CUDA_FP16)
 +    {
 +        scoreDiff = 5e-3;
 +        iouDiff = 0.09;
 +    }
 +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020040000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
 +    {
 +        scoreDiff = 0.02;
 +        iouDiff = 0.1f;
 +    }
 +#endif
 +    testDetectModel(weights_file, config_file, img_path, refClassIds, refConfidences, refBoxes,
 +                    scoreDiff, iouDiff, confThreshold, nmsThreshold, size, mean, scale);
 +}
 +
 +TEST_P(Test_Model, Segmentation)
 +{
 +    applyTestTag(
 +        CV_TEST_TAG_MEMORY_2GB
 +    );
 +
 +    float norm = 0;
 +
 +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
 +    // Failed to allocate graph: NC_ERROR
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +    // accuracy
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
 +    {
 +        norm = 25.0f;  // depends on OS/OpenCL version
 +    }
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
 +    // Failed to allocate graph: NC_ERROR
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +    // cnn_network_ngraph_impl.cpp:104 Function contains several inputs and outputs with one friendly name: 'upscore2'!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +    // cnn_network_ngraph_impl.cpp:104 Function contains several inputs and outputs with one friendly name: 'upscore2'!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE)
 +    // Failed to allocate graph: NC_ERROR
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#endif
 +
 +    if ((backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
 +        || (backend == DNN_BACKEND_CUDA && target == DNN_TARGET_CUDA_FP16))
 +    {
 +        norm = 2.0f;  // l1 = 0.01 lInf = 2
 +    }
 +
 +    std::string inp = _tf("dog416.png");
 +    std::string weights_file = _tf("fcn8s-heavy-pascal.prototxt");
 +    std::string config_file = _tf("fcn8s-heavy-pascal.caffemodel", false);
 +    std::string exp = _tf("segmentation_exp.png");
 +
 +    Size size{128, 128};
 +    double scale = 1.0;
 +    Scalar mean = Scalar();
 +    bool swapRB = false;
 +
 +    testSegmentationModel(weights_file, config_file, inp, exp, norm, size, mean, scale, swapRB);
 +}
 +
 +TEST_P(Test_Model, TextRecognition)
 +{
 +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
 +    // FIXIT: dnn/src/ie_ngraph.cpp:494: error: (-215:Assertion failed) !inps.empty() in function 'createNet'
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +    // Node Transpose_79 was not assigned on any pointed device
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
 +        applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
 +            CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
 +        );
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
 +    // IE Exception: Ngraph operation Reshape with name 71 has dynamic output shape on 0 port, but CPU plug-in supports only static shape
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
 +        applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
 +            CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
 +        );
 +#endif
 +
 +    std::string imgPath = _tf("text_rec_test.png");
 +    std::string weightPath = _tf("onnx/models/crnn.onnx", false);
 +    std::string seq = "welcome";
 +
 +    Size size{100, 32};
 +    double scale = 1.0 / 127.5;
 +    Scalar mean = Scalar(127.5);
 +    std::string decodeType = "CTC-greedy";
 +    std::vector<std::string> vocabulary = {"0","1","2","3","4","5","6","7","8","9",
 +                                           "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
 +
 +    testTextRecognitionModel(weightPath, "", imgPath, seq, decodeType, vocabulary, size, mean, scale);
 +}
 +
 +TEST_P(Test_Model, TextRecognitionWithCTCPrefixBeamSearch)
 +{
 +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
 +    // Node Transpose_79 was not assigned on any pointed device
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
 +        applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
 +            CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
 +        );
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
 +    // IE Exception: Ngraph operation Reshape with name 71 has dynamic output shape on 0 port, but CPU plug-in supports only static shape
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
 +        applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
 +            CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
 +        );
 +#endif
 +
 +
 +    std::string imgPath = _tf("text_rec_test.png");
 +    std::string weightPath = _tf("onnx/models/crnn.onnx", false);
 +    std::string seq = "welcome";
 +
 +    Size size{100, 32};
 +    double scale = 1.0 / 127.5;
 +    Scalar mean = Scalar(127.5);
 +    std::string decodeType = "CTC-prefix-beam-search";
 +    std::vector<std::string> vocabulary = {"0","1","2","3","4","5","6","7","8","9",
 +                                           "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
 +
 +    testTextRecognitionModel(weightPath, "", imgPath, seq, decodeType, vocabulary, size, mean, scale);
 +}
 +
 +TEST_P(Test_Model, TextDetectionByDB)
 +{
 +    if (target == DNN_TARGET_OPENCL_FP16)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
 +
 +    std::string imgPath = _tf("text_det_test1.png");
 +    std::string weightPath = _tf("onnx/models/DB_TD500_resnet50.onnx", false);
 +
 +    // GroundTruth
 +    std::vector<std::vector<Point>> gt = {
 +        { Point(142, 193), Point(136, 164), Point(213, 150), Point(219, 178) },
 +        { Point(136, 165), Point(122, 114), Point(319, 71), Point(330, 122) }
 +    };
 +
 +    Size size{736, 736};
 +    double scale = 1.0 / 255.0;
 +    Scalar mean = Scalar(122.67891434, 116.66876762, 104.00698793);
 +
 +    float binThresh = 0.3;
 +    float polyThresh = 0.5;
 +    uint maxCandidates = 200;
 +    double unclipRatio = 2.0;
 +
 +    testTextDetectionModelByDB(weightPath, "", imgPath, gt, binThresh, polyThresh, maxCandidates, unclipRatio, size, mean, scale);
 +}
 +
 +TEST_P(Test_Model, TextDetectionByEAST)
 +{
 +    std::string imgPath = _tf("text_det_test2.jpg");
 +    std::string weightPath = _tf("frozen_east_text_detection.pb", false);
 +
 +    // GroundTruth
 +    std::vector<RotatedRect> gt = {
 +        RotatedRect(Point2f(657.55f, 409.5f), Size2f(316.84f, 62.45f), -4.79)
 +    };
 +
 +    // Model parameters
 +    Size size{320, 320};
 +    double scale = 1.0;
 +    Scalar mean = Scalar(123.68, 116.78, 103.94);
 +    bool swapRB = true;
 +
 +    // Detection algorithm parameters
 +    float confThresh = 0.5;
 +    float nmsThresh = 0.4;
 +
 +    double eps_center = 5/*pixels*/;
 +    double eps_size = 5/*pixels*/;
 +    double eps_angle = 1;
 +
 +    if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_MYRIAD)
 +    {
 +        eps_center = 10;
 +        eps_size = 25;
 +        eps_angle = 3;
 +    }
 +
 +    testTextDetectionModelByEAST(weightPath, "", imgPath, gt, confThresh, nmsThresh, size, mean, scale, swapRB, false/*crop*/,
 +        eps_center, eps_size, eps_angle
 +    );
 +}
 +
 +INSTANTIATE_TEST_CASE_P(/**/, Test_Model, dnnBackendsAndTargets());
 +
 +}} // namespace
index 1c9a6d009fd2c8a94bcb353574c79f42e2fde7c5,607302cf0f15dbef6f62d1b9b9b800312b64e548..6583134fa78e98211741ec1539516ffecfc0db64
@@@ -539,244 -426,6 +533,208 @@@ TEST_P(Test_ONNX_layers, Exp
      testONNXModels("exp");
  }
  
- #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
-         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
-         applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
-             CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
-         );
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
-         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
- #elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
 +TEST_P(Test_ONNX_layers, Elementwise_Ceil)
 +{
 +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
 +#endif
 +    testONNXModels("ceil");
 +}
 +
 +TEST_P(Test_ONNX_layers, Elementwise_Floor)
 +{
 +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
 +#endif
 +    testONNXModels("floor");
 +}
 +
 +TEST_P(Test_ONNX_layers, Elementwise_Log)
 +{
 +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
 +#endif
 +    testONNXModels("log");
 +}
 +
 +TEST_P(Test_ONNX_layers, Elementwise_Round)
 +{
 +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
 +#endif
 +    testONNXModels("round");
 +}
 +
 +TEST_P(Test_ONNX_layers, Elementwise_Sqrt)
 +{
 +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
 +    testONNXModels("sqrt");
 +#endif
 +}
 +
 +TEST_P(Test_ONNX_layers, Elementwise_not)
 +{
- #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
-         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
- #elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
++#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
 +#endif
 +    testONNXModels("not");
 +}
 +
 +TEST_P(Test_ONNX_layers, Compare_EQ)
 +{
- #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
-         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
- #elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
++#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
 +    // IE exception: Function contains several inputs and outputs with one friendly name!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
 +        applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
 +            CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
 +        );
 +    // IE exception: Function contains several inputs and outputs with one friendly name!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
 +#endif
 +
 +    testONNXModels("equal");
 +}
 +
 +TEST_P(Test_ONNX_layers, Compare_GT)
 +{
- #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
-         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
- #elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
++#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
 +    // IE exception: Function contains several inputs and outputs with one friendly name!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
 +        applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
 +            CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
 +        );
 +    // IE exception: Function contains several inputs and outputs with one friendly name!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
 +#endif
 +
 +    testONNXModels("greater");
 +}
 +
 +TEST_P(Test_ONNX_layers, Compare_LT)
 +{
- #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
-         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
- #elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
++#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
 +    // IE exception: Function contains several inputs and outputs with one friendly name!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
 +        applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
 +            CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
 +        );
 +    // IE exception: Function contains several inputs and outputs with one friendly name!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
 +#endif
 +
 +    testONNXModels("less");
 +}
 +
 +TEST_P(Test_ONNX_layers, Compare_GTorEQ)
 +{
 +    testONNXModels("greater_or_equal");
 +}
 +
 +TEST_P(Test_ONNX_layers, Compare_LEorEQ)
 +{
 +    testONNXModels("less_or_equal");
 +}
 +
 +TEST_P(Test_ONNX_layers, CompareSameDims_EQ)
 +{
- #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
-         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
- #elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
++#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
 +    // IE exception: Function contains several inputs and outputs with one friendly name!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
 +        applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
 +            CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
 +        );
 +    // IE exception: Function contains several inputs and outputs with one friendly name!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
 +#endif
 +
 +    testONNXModels("equal_same_dims", npy, 0, 0, false, true, 2);
 +}
 +
 +TEST_P(Test_ONNX_layers, CompareSameDims_GT)
 +{
- #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
-         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
- #elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
++#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
 +    // IE exception: Function contains several inputs and outputs with one friendly name!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
 +        applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
 +            CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
 +        );
 +    // IE exception: Function contains several inputs and outputs with one friendly name!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
 +#endif
 +
 +    testONNXModels("greater_same_dims", npy, 0, 0, false, true, 2);
 +}
 +
 +TEST_P(Test_ONNX_layers, CompareSameDims_LT)
 +{
++#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
 +    // IE exception: Function contains several inputs and outputs with one friendly name!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
 +        applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
 +            CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
 +        );
 +    // IE exception: Function contains several inputs and outputs with one friendly name!
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
 +#endif
 +
 +    testONNXModels("less_same_dims", npy, 0, 0, false, true, 2);
 +}
 +
  TEST_P(Test_ONNX_layers, Concatenation)
  {
      if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
@@@ -1305,26 -865,6 +1232,23 @@@ TEST_P(Test_ONNX_layers, LSTM_hidden_bi
      testONNXModels("hidden_lstm_bi", npy, 0, 0, false, false);
  }
  
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
-         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
 +TEST_P(Test_ONNX_layers, GRU)
 +{
 +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
 +    // IE exception: Node GRU_22 was not assigned on any pointed device
 +    if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
 +        applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
 +            CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
 +        );
 +#endif
 +    testONNXModels("gru", npy, 0, 0, false, false);
 +}
 +
 +TEST_P(Test_ONNX_layers, GRU_bidirectional)
 +{
 +    testONNXModels("gru_bi", npy, 0, 0, false, false);
 +}
 +
  TEST_P(Test_ONNX_layers, LSTM_cell_forward)
  {
  #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
Simple merge
index 260e95537d002d5ec01fcfb5c1856bc1e08421e9,d94ff4368abcc0cefab2bcf4696868512879a707..2e18ac8c48d99d51a77c7bd52fa248b1d226fccf
@@@ -285,23 -255,6 +285,9 @@@ TEST_P(Test_Torch_layers, net_inception
  
  TEST_P(Test_Torch_layers, net_normalize)
  {
- #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
-         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
-         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
-     // Cannot get memory!
-     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
-         applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
-             CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
-         );
- #endif
 +    if(backend == DNN_BACKEND_CUDA)
 +        applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA); /* only L1 and L2 norms are supported */
 +
      runTorchNet("net_normalize", "", false, true);
  }
  
index 7110417e7aa7cdc4d6cd9109047e33c131179cb1,eb17d5fc012fb98d2a57c9a64d4c1ca471564d26..aad5b7db679ffb7f77671998acb69b984e2602e9
@@@ -2066,29 -1938,20 +2066,24 @@@ static LRESULT CALLBACK HGToolbarProc(H
  
      case WM_NCCALCSIZE:
          {
 -            LRESULT ret = CallWindowProc(window->toolbar.toolBarProc, hwnd, uMsg, wParam, lParam);
 -            CvTrackbar* trackbar = window->toolbar.first;
 +            LRESULT ret = CallWindowProc(window.toolbar.toolBarProc, hwnd, uMsg, wParam, lParam);
-             int rows = (int)SendMessage(hwnd, TB_GETROWS, 0, 0);
 +
-             if (window.toolbar.rows != rows)
-             {
-                 SendMessage(window.toolbar.toolbar, TB_BUTTONCOUNT, 0, 0);
-                 auto& trakbars = window.toolbar.trackbars;
++            auto& trakbars = window.toolbar.trackbars;
  
-                 for (auto it = trakbars.begin(); it != trakbars.end(); ++it)
-                 {
-                     auto trackbar = *it;
-                     CV_Assert(trackbar);
-                     RECT rect = { 0 };
-                     SendMessage(window.toolbar.toolbar, TB_GETITEMRECT,
-                                (WPARAM)trackbar->id, (LPARAM)&rect);
-                     MoveWindow(trackbar->hwnd, rect.left + HG_BUDDY_WIDTH, rect.top,
-                                rect.right - rect.left - HG_BUDDY_WIDTH,
-                                rect.bottom - rect.top, FALSE);
-                     MoveWindow(trackbar->buddy, rect.left, rect.top,
-                                HG_BUDDY_WIDTH, rect.bottom - rect.top, FALSE);
-                 }
-                 window.toolbar.rows = rows;
 -            for (; trackbar != 0; trackbar = trackbar->next) {
++            for (auto it = trakbars.begin(); it != trakbars.end(); ++it)
++            {
++                auto trackbar = *it;
++                CV_Assert(trackbar);
+                 RECT rect = { 0 };
 -                SendMessage(window->toolbar.toolbar, TB_GETITEMRECT,
 -                    (WPARAM)trackbar->id, (LPARAM)&rect);
++                SendMessage(window.toolbar.toolbar, TB_GETITEMRECT,
++                           (WPARAM)trackbar->id, (LPARAM)&rect);
+                 MoveWindow(trackbar->hwnd, rect.left + HG_BUDDY_WIDTH, rect.top,
 -                    rect.right - rect.left - HG_BUDDY_WIDTH,
 -                    rect.bottom - rect.top, FALSE);
++                           rect.right - rect.left - HG_BUDDY_WIDTH,
++                           rect.bottom - rect.top, FALSE);
+                 MoveWindow(trackbar->buddy, rect.left, rect.top,
 -                    HG_BUDDY_WIDTH, rect.bottom - rect.top, FALSE);
++                           HG_BUDDY_WIDTH, rect.bottom - rect.top, FALSE);
              }
 -            window->toolbar.rows = static_cast<int>(SendMessage(hwnd, TB_GETROWS, 0, 0));
++            window.toolbar.rows = static_cast<int>(SendMessage(hwnd, TB_GETROWS, 0, 0));
              return ret;
          }
      }
@@@ -2317,136 -2064,169 +2312,136 @@@ cvWaitKey(int delay
              continue;
          }
  
 -        for( window = hg_windows; window != 0 && is_processed == 0; window = window->next )
 -        {
 -            if( window->hwnd == message.hwnd || window->frame == message.hwnd )
 -            {
 -                is_processed = 1;
 -                switch(message.message)
 -                {
 -                case WM_DESTROY:
 -                case WM_CHAR:
 -                    DispatchMessage(&message);
 -                    return (int)message.wParam;
 +        int keyCode = -1;
 +        if (handleMessage(message, keyCode))
 +            return keyCode;
 +    }
 +}
  
 -                case WM_SYSKEYDOWN:
 -                    if( message.wParam == VK_F10 )
 -                    {
 -                        is_processed = 1;
 -                        return (int)(message.wParam << 16);
 -                    }
 -                    break;
  
 -                case WM_KEYDOWN:
 -                    TranslateMessage(&message);
 -                    if( (message.wParam >= VK_F1 && message.wParam <= VK_F24)       ||
 -                        message.wParam == VK_HOME   || message.wParam == VK_END     ||
 -                        message.wParam == VK_UP     || message.wParam == VK_DOWN    ||
 -                        message.wParam == VK_LEFT   || message.wParam == VK_RIGHT   ||
 -                        message.wParam == VK_INSERT || message.wParam == VK_DELETE  ||
 -                        message.wParam == VK_PRIOR  || message.wParam == VK_NEXT )
 -                    {
 -                        DispatchMessage(&message);
 -                        is_processed = 1;
 -                        return (int)(message.wParam << 16);
 -                    }
 +static
 +std::shared_ptr<CvTrackbar> icvFindTrackbarByName(CvWindow& window, const std::string& name)
 +{
 +    auto trackbars = window.toolbar.trackbars;
 +    for (auto it = trackbars.begin(); it != trackbars.end(); ++it)
 +    {
 +        auto& trackbar = *it;
 +        CV_Assert(trackbar);
 +        if (trackbar->name == name)
 +            return trackbar;
 +    }
 +    return std::shared_ptr<CvTrackbar>();
 +}
  
 -                    // Intercept Ctrl+C for copy to clipboard
 -                    if ('C' == message.wParam && (::GetKeyState(VK_CONTROL)>>15))
 -                        ::SendMessage(message.hwnd, WM_COPY, 0, 0);
 +static
 +std::shared_ptr<CvTrackbar> createTrackbar_(CvWindow& window, const std::string& trackbar_name,
 +    int count,
 +    TrackbarCallback onChange, void* userdata);
  
 -                    // Intercept Ctrl+S for "save as" dialog
 -                    if ('S' == message.wParam && (::GetKeyState(VK_CONTROL)>>15))
 -                        showSaveDialog(window);
 +static int
 +icvCreateTrackbar(const char* trackbar_name, const char* window_name,
 +                  int* val, int count, CvTrackbarCallback on_notify,
 +                  CvTrackbarCallback2 on_notify2, void* userdata)
 +{
 +    CV_FUNCNAME("icvCreateTrackbar");
  
 -                default:
 -                    DispatchMessage(&message);
 -                    is_processed = 1;
 -                    break;
 -                }
 -            }
 -        }
 +    AutoLock lock(getWindowMutex());
  
 -        if( !is_processed )
 -        {
 -            TranslateMessage(&message);
 -            DispatchMessage(&message);
 -        }
 -    }
 -}
 +    if (!window_name || !trackbar_name)
 +        CV_Error(Error::StsNullPtr, "NULL window or trackbar name");
  
 +    if (count < 0)
 +        CV_Error(Error::StsOutOfRange, "Bad trackbar maximal value");
  
 -static CvTrackbar*
 -icvFindTrackbarByName( const CvWindow* window, const char* name )
 -{
 -    CvTrackbar* trackbar = window->toolbar.first;
 +    auto window = icvFindWindowByName(window_name);
 +    if (!window)
 +        CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", window_name));
  
 -    for( ; trackbar != 0 && strcmp( trackbar->name, name ) != 0; trackbar = trackbar->next )
 -        ;
 +    auto trackbar = icvFindTrackbarByName(*window, trackbar_name);
 +    if (!trackbar)
 +        trackbar = createTrackbar_(*window, trackbar_name, count, nullptr, userdata);
 +    CV_Assert(trackbar);
  
 -    return trackbar;
 -}
 +    trackbar->notify = on_notify;
 +    trackbar->notify2 = on_notify2;
 +    trackbar->userdata = userdata;
 +    trackbar->data = val;
  
 +    return 1;
 +}
  
 -static int
 -icvCreateTrackbar( const char* trackbar_name, const char* window_name,
 -                   int* val, int count, CvTrackbarCallback on_notify,
 -                   CvTrackbarCallback2 on_notify2, void* userdata )
 +static void createToolbar_(CvWindow& window)
  {
 -    int result = 0;
 +    CV_Assert(!window.toolbar.toolbar);
  
 -    CV_FUNCNAME( "icvCreateTrackbar" );
 +    const int default_height = 30;
  
 -    __BEGIN__;
 +    // CreateToolbarEx is deprecated and forces linking against Comctl32.lib.
 +    window.toolbar.toolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
 +                                WS_CHILD | CCS_TOP | TBSTYLE_WRAPABLE | BTNS_AUTOSIZE | BTNS_BUTTON,
 +                                0, 0, 0, 0,
 +                                window.frame, NULL, GetModuleHandle(NULL), NULL);
 +    // CreateToolbarEx automatically sends this but CreateWindowEx doesn't.
 +    SendMessage(window.toolbar.toolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
  
 -    char slider_name[32];
 -    CvWindow* window = 0;
 -    CvTrackbar* trackbar = 0;
 -    int pos = 0;
 +    RECT rect;
 +    GetClientRect(window.frame, &rect);
 +    MoveWindow(window.toolbar.toolbar, 0, 0,
 +               rect.right - rect.left, default_height, TRUE);
 +    SendMessage(window.toolbar.toolbar, TB_AUTOSIZE, 0, 0);
 +    ShowWindow(window.toolbar.toolbar, SW_SHOW);
  
 -    if( !window_name || !trackbar_name )
 -        CV_ERROR( CV_StsNullPtr, "NULL window or trackbar name" );
 +    window.toolbar.pos = 0;
 +    window.toolbar.rows = 0;
 +    window.toolbar.toolBarProc =
 +        (WNDPROC)icvGetWindowLongPtr(window.toolbar.toolbar, CV_WNDPROC);
  
 -    if( count < 0 )
 -        CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" );
 +    icvUpdateWindowPos(window);
  
 -    window = icvFindWindowByName(window_name);
 -    if( !window )
 -        EXIT;
 +    // Subclassing from toolbar
 +    icvSetWindowLongPtr(window.toolbar.toolbar, CV_WNDPROC, HGToolbarProc);
 +    icvSetWindowLongPtr(window.toolbar.toolbar, CV_USERDATA, (void*)&window);
  
 -    trackbar = icvFindTrackbarByName(window,trackbar_name);
 -    if( !trackbar )
 -    {
 -        TBBUTTON tbs = {};
 -        TBBUTTONINFO tbis = {};
 -        RECT rect = { 0 };
 -        int bcount;
 -        int len = (int)strlen( trackbar_name );
 +}
  
 -        // create toolbar if it is not created yet
 -        if( !window->toolbar.toolbar )
 -        {
 -            const int default_height = 30;
 -
 -            // CreateToolbarEx is deprecated and forces linking against Comctl32.lib.
 -            window->toolbar.toolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
 -                                        WS_CHILD | CCS_TOP | TBSTYLE_WRAPABLE | BTNS_AUTOSIZE | BTNS_BUTTON,
 -                                        0, 0, 0, 0,
 -                                        window->frame, NULL, GetModuleHandle(NULL), NULL);
 -            // CreateToolbarEx automatically sends this but CreateWindowEx doesn't.
 -            SendMessage(window->toolbar.toolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
 -
 -            GetClientRect(window->frame, &rect);
 -            MoveWindow( window->toolbar.toolbar, 0, 0,
 -                        rect.right - rect.left, default_height, TRUE);
 -            SendMessage(window->toolbar.toolbar, TB_AUTOSIZE, 0, 0);
 -            ShowWindow(window->toolbar.toolbar, SW_SHOW);
 -
 -            window->toolbar.first = 0;
 -            window->toolbar.pos = 0;
 -            window->toolbar.rows = 0;
 -            window->toolbar.toolBarProc =
 -                (WNDPROC)icvGetWindowLongPtr(window->toolbar.toolbar, CV_WNDPROC);
 -
 -            icvUpdateWindowPos(window);
 -
 -            // Subclassing from toolbar
 -            icvSetWindowLongPtr(window->toolbar.toolbar, CV_WNDPROC, HGToolbarProc);
 -            icvSetWindowLongPtr(window->toolbar.toolbar, CV_USERDATA, window);
 -        }
 +static
 +std::shared_ptr<CvTrackbar> createTrackbar_(CvWindow& window, const std::string& trackbar_name,
 +    int count,
 +    TrackbarCallback onChange, void* userdata)
 +{
 +    // create toolbar if it is not created yet
 +    if (!window.toolbar.toolbar)
 +    {
 +        createToolbar_(window);
 +    }
  
 -        /* Retrieve current buttons count */
 -        bcount = (int)SendMessage(window->toolbar.toolbar, TB_BUTTONCOUNT, 0, 0);
 +    TBBUTTON tbs = {};
  
 -        if (bcount > 0)
 -        {
 -            /* If this is not the first button then we need to
 -            separate it from the previous one */
 -            tbs.iBitmap = 0;
 -            tbs.idCommand = bcount; // Set button id to it's number
 -            tbs.iString = 0;
 -            tbs.fsStyle = TBSTYLE_SEP;
 -            tbs.fsState = TBSTATE_ENABLED;
 -            SendMessage(window->toolbar.toolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbs);
 -
 -            // Retrieve current buttons count
 -            bcount = (int)SendMessage(window->toolbar.toolbar, TB_BUTTONCOUNT, 0, 0);
 -        }
 +    /* Retrieve current buttons count */
 +    int bcount = (int)SendMessage(window.toolbar.toolbar, TB_BUTTONCOUNT, 0, 0);
  
-     if (bcount > 1)
 -        /* Add a button which we're going to cover with the slider */
++    if (bcount > 0)
 +    {
 +        /* If this is not the first button then we need to
 +        separate it from the previous one */
          tbs.iBitmap = 0;
          tbs.idCommand = bcount; // Set button id to it's number
 +        tbs.iString = 0;
 +        tbs.fsStyle = TBSTYLE_SEP;
          tbs.fsState = TBSTATE_ENABLED;
 +        SendMessage(window.toolbar.toolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbs);
 +
 +        // Retrieve current buttons count
 +        bcount = (int)SendMessage(window.toolbar.toolbar, TB_BUTTONCOUNT, 0, 0);
 +    }
 +
 +    /* Add a button which we're going to cover with the slider */
 +    tbs.iBitmap = 0;
 +    tbs.idCommand = bcount; // Set button id to it's number
 +    tbs.fsState = TBSTATE_ENABLED;
  #if 0/*!defined WIN64 && !defined EM64T*/
 -        tbs.fsStyle = 0;
 -        tbs.iString = 0;
 +    tbs.fsStyle = 0;
 +    tbs.iString = 0;
  #else
  
  #ifndef TBSTYLE_AUTOSIZE
  #ifndef TBSTYLE_GROUP
  #define TBSTYLE_GROUP           0x0004
  #endif
 -        //tbs.fsStyle = TBSTYLE_AUTOSIZE;
 -        tbs.fsStyle = TBSTYLE_GROUP;
 -        tbs.iString = (INT_PTR)trackbar_text;
 +    //tbs.fsStyle = TBSTYLE_AUTOSIZE;
 +    tbs.fsStyle = TBSTYLE_GROUP;
 +    tbs.iString = (INT_PTR)trackbar_text;
  #endif
 -        SendMessage(window->toolbar.toolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbs);
 -
 -        /* Adjust button size to the slider */
 -        tbis.cbSize = sizeof(tbis);
 -        tbis.dwMask = TBIF_SIZE;
 -
 -        GetClientRect(window->toolbar.toolbar, &rect);
 -        tbis.cx = (unsigned short)(rect.right - rect.left);
 -
 -        SendMessage(window->toolbar.toolbar, TB_SETBUTTONINFO,
 -            (WPARAM)tbs.idCommand, (LPARAM)&tbis);
 -
 -        /* Get button pos */
 -        SendMessage(window->toolbar.toolbar, TB_GETITEMRECT,
 -            (WPARAM)tbs.idCommand, (LPARAM)&rect);
 -
 -        /* Create a slider */
 -        trackbar = (CvTrackbar*)cvAlloc( sizeof(CvTrackbar) + len + 1 );
 -        trackbar->signature = CV_TRACKBAR_MAGIC_VAL;
 -        trackbar->notify = 0;
 -        trackbar->notify2 = 0;
 -        trackbar->parent = window;
 -        trackbar->pos = 0;
 -        trackbar->data = 0;
 -        trackbar->id = tbs.idCommand;
 -        trackbar->next = window->toolbar.first;
 -        trackbar->name = (char*)(trackbar + 1);
 -        memcpy( trackbar->name, trackbar_name, len + 1 );
 -        window->toolbar.first = trackbar;
 -
 -        sprintf(slider_name, "Trackbar%p", val);
 -        trackbar->hwnd = CreateWindowEx(0, TRACKBAR_CLASS, slider_name,
 -                            WS_CHILD | WS_VISIBLE | TBS_AUTOTICKS |
 -                            TBS_FIXEDLENGTH | TBS_HORZ | TBS_BOTTOM,
 -                            rect.left + HG_BUDDY_WIDTH, rect.top,
 -                            rect.right - rect.left - HG_BUDDY_WIDTH,
 -                            rect.bottom - rect.top, window->toolbar.toolbar,
 -                            (HMENU)(size_t)bcount, hg_hinstance, 0);
 -
 -        sprintf(slider_name,"Buddy%p", val);
 -        trackbar->buddy = CreateWindowEx(0, "STATIC", slider_name,
 -                            WS_CHILD | SS_RIGHT,
 -                            rect.left, rect.top,
 -                            HG_BUDDY_WIDTH, rect.bottom - rect.top,
 -                            window->toolbar.toolbar, 0, hg_hinstance, 0);
 -
 -        icvSetWindowLongPtr( trackbar->hwnd, CV_USERDATA, trackbar );
 -
 -        /* Minimize the number of rows */
 -        SendMessage( window->toolbar.toolbar, TB_SETROWS,
 -                     MAKEWPARAM(1, FALSE), (LPARAM)&rect );
 -    }
 -    else
 -    {
 -        trackbar->data = 0;
 -        trackbar->notify = 0;
 -        trackbar->notify2 = 0;
 -    }
 +    SendMessage(window.toolbar.toolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbs);
 +
 +    TBBUTTONINFO tbis = {};
 +
 +    /* Adjust button size to the slider */
 +    tbis.cbSize = sizeof(tbis);
 +    tbis.dwMask = TBIF_SIZE;
 +
 +    RECT rect = { 0 };
-     GetClientRect(window.hwnd, &rect);
++    GetClientRect(window.toolbar.toolbar, &rect);
 +    tbis.cx = (unsigned short)(rect.right - rect.left);
 +
 +    SendMessage(window.toolbar.toolbar, TB_SETBUTTONINFO,
 +        (WPARAM)tbs.idCommand, (LPARAM)&tbis);
 +
 +    /* Get button pos */
 +    SendMessage(window.toolbar.toolbar, TB_GETITEMRECT,
 +        (WPARAM)tbs.idCommand, (LPARAM)&rect);
 +
 +    /* Create a slider */
 +    auto trackbar = std::make_shared<CvTrackbar>(window, trackbar_name);
-     trackbar->id = bcount;
++    trackbar->id = tbs.idCommand;
 +    window.toolbar.trackbars.push_back(trackbar);
 +
 +    auto slider_name = cv::format("Trackbar%p", trackbar.get());
 +    trackbar->hwnd = CreateWindowEx(0, TRACKBAR_CLASS, slider_name.c_str(),
 +                        WS_CHILD | WS_VISIBLE | TBS_AUTOTICKS |
 +                        TBS_FIXEDLENGTH | TBS_HORZ | TBS_BOTTOM,
 +                        rect.left + HG_BUDDY_WIDTH, rect.top,
 +                        rect.right - rect.left - HG_BUDDY_WIDTH,
 +                        rect.bottom - rect.top, window.toolbar.toolbar,
 +                        (HMENU)(size_t)bcount, hg_hinstance, 0);
 +
 +    slider_name = cv::format("Buddy%p", trackbar.get());
 +    trackbar->buddy = CreateWindowEx(0, "STATIC", slider_name.c_str(),
 +                        WS_CHILD | SS_RIGHT,
 +                        rect.left, rect.top,
 +                        HG_BUDDY_WIDTH, rect.bottom - rect.top,
 +                        window.toolbar.toolbar, 0, hg_hinstance, 0);
 +
 +    icvSetWindowLongPtr(trackbar->hwnd, CV_USERDATA, (void*)trackbar.get());
 +
 +    /* Minimize the number of rows */
 +    SendMessage(window.toolbar.toolbar, TB_SETROWS,
 +                MAKEWPARAM(1, FALSE), (LPARAM)&rect);
  
      trackbar->maxval = count;
  
index b651fdff3f73c2f299bd35e991f1342961ad0f1d,c4b570e68c89805c254fca4779a9bd37ac784541..52495eb651f3be94cd66ddb557e5e5b6374dd331
@@@ -96,15 -95,13 +96,16 @@@ enum ImwriteFlags 
         IMWRITE_PNG_BILEVEL         = 18, //!< Binary level PNG, 0 or 1, default is 0.
         IMWRITE_PXM_BINARY          = 32, //!< For PPM, PGM, or PBM, it can be a binary format flag, 0 or 1. Default value is 1.
         IMWRITE_EXR_TYPE            = (3 << 4) + 0, /* 48 */ //!< override EXR storage type (FLOAT (FP32) is default)
 +       IMWRITE_EXR_COMPRESSION     = (3 << 4) + 1, /* 49 */ //!< override EXR compression type (ZIP_COMPRESSION = 3 is default)
 +       IMWRITE_EXR_DWA_COMPRESSION_LEVEL = (3 << 4) + 2, /* 50 */ //!< override EXR DWA compression level (45 is default)
         IMWRITE_WEBP_QUALITY        = 64, //!< For WEBP, it can be a quality from 1 to 100 (the higher is the better). By default (without any parameter) and for quality above 100 the lossless compression is used.
+        IMWRITE_HDR_COMPRESSION     = (5 << 4) + 0, /* 80 */ //!< specify HDR compression
         IMWRITE_PAM_TUPLETYPE       = 128,//!< For PAM, sets the TUPLETYPE field to the corresponding string value that is defined for the format
 -       IMWRITE_TIFF_RESUNIT        = 256,//!< For TIFF, use to specify which DPI resolution unit to set; see libtiff documentation for valid values.
 -       IMWRITE_TIFF_XDPI           = 257,//!< For TIFF, use to specify the X direction DPI.
 -       IMWRITE_TIFF_YDPI           = 258,//!< For TIFF, use to specify the Y direction DPI.
 -       IMWRITE_TIFF_COMPRESSION    = 259 //!< For TIFF, use to specify the image compression scheme. See libtiff for integer constants corresponding to compression formats. Note, for images whose depth is CV_32F, only libtiff's SGILOG compression scheme is used. For other supported depths, the compression scheme can be specified by this flag; LZW compression is the default.
 +       IMWRITE_TIFF_RESUNIT        = 256,//!< For TIFF, use to specify which DPI resolution unit to set; see libtiff documentation for valid values
 +       IMWRITE_TIFF_XDPI           = 257,//!< For TIFF, use to specify the X direction DPI
 +       IMWRITE_TIFF_YDPI           = 258,//!< For TIFF, use to specify the Y direction DPI
 +       IMWRITE_TIFF_COMPRESSION    = 259,//!< For TIFF, use to specify the image compression scheme. See libtiff for integer constants corresponding to compression formats. Note, for images whose depth is CV_32F, only libtiff's SGILOG compression scheme is used. For other supported depths, the compression scheme can be specified by this flag; LZW compression is the default.
 +       IMWRITE_JPEG2000_COMPRESSION_X1000 = 272 //!< For JPEG2000, use to specify the target compression rate (multiplied by 1000). The value can be from 0 to 1000. Default is 1000.
       };
  
  enum ImwriteJPEGSamplingFactorParams {
index 10c4dcad2d1f33787eca9e4098de2166f0050421,1bdc7029c09385386504e93376bc866a3d83c248..7d980b9343c3261583a720c14addc5031e1b5872
@@@ -649,40 -658,11 +649,40 @@@ bool imreadmulti(const String& filename
  {
      CV_TRACE_FUNCTION();
  
 -    return imreadmulti_(filename, flags, mats);
 +    return imreadmulti_(filename, flags, mats, 0, -1);
  }
  
 +
 +bool imreadmulti(const String& filename, std::vector<Mat>& mats, int start, int count, int flags)
 +{
 +    CV_TRACE_FUNCTION();
 +
 +    return imreadmulti_(filename, flags, mats, start, count);
 +}
 +
 +static
 +size_t imcount_(const String& filename, int flags)
 +{
 +    try{
 +        ImageCollection collection(filename, flags);
 +        return collection.size();
 +    } catch(cv::Exception const& e) {
 +        // Reading header or finding decoder for the filename is failed
 +        std::cerr << "imcount_('" << filename << "'): can't read header or can't find decoder: " << e.what() << std::endl << std::flush;
 +    }
 +    return 0;
 +}
 +
 +size_t imcount(const String& filename, int flags)
 +{
 +    CV_TRACE_FUNCTION();
 +
 +    return imcount_(filename, flags);
 +}
 +
 +
  static bool imwrite_( const String& filename, const std::vector<Mat>& img_vec,
-                       const std::vector<int>& params, bool flipv )
+                       const std::vector<int>& params_, bool flipv )
  {
      bool isMultiImg = img_vec.size() > 1;
      std::vector<Mat> write_vec;
@@@ -929,159 -955,8 +949,159 @@@ Mat imdecode( InputArray _buf, int flag
      return *dst;
  }
  
 +static bool
 +imdecodemulti_(const Mat& buf, int flags, std::vector<Mat>& mats, int start, int count)
 +{
 +    CV_Assert(!buf.empty());
 +    CV_Assert(buf.isContinuous());
 +    CV_Assert(buf.checkVector(1, CV_8U) > 0);
 +    Mat buf_row = buf.reshape(1, 1);  // decoders expects single row, avoid issues with vector columns
 +
 +    String filename;
 +
 +    ImageDecoder decoder = findDecoder(buf_row);
 +    if (!decoder)
 +        return 0;
 +
 +    if (count < 0) {
 +        count = std::numeric_limits<int>::max();
 +    }
 +
 +    if (!decoder->setSource(buf_row))
 +    {
 +        filename = tempfile();
 +        FILE* f = fopen(filename.c_str(), "wb");
 +        if (!f)
 +            return 0;
 +        size_t bufSize = buf_row.total() * buf.elemSize();
 +        if (fwrite(buf_row.ptr(), 1, bufSize, f) != bufSize)
 +        {
 +            fclose(f);
 +            CV_Error(Error::StsError, "failed to write image data to temporary file");
 +        }
 +        if (fclose(f) != 0)
 +        {
 +            CV_Error(Error::StsError, "failed to write image data to temporary file");
 +        }
 +        decoder->setSource(filename);
 +    }
 +
 +    // read the header to make sure it succeeds
 +    bool success = false;
 +    try
 +    {
 +        // read the header to make sure it succeeds
 +        if (decoder->readHeader())
 +            success = true;
 +    }
 +    catch (const cv::Exception& e)
 +    {
 +        std::cerr << "imreadmulti_('" << filename << "'): can't read header: " << e.what() << std::endl << std::flush;
 +    }
 +    catch (...)
 +    {
 +        std::cerr << "imreadmulti_('" << filename << "'): can't read header: unknown exception" << std::endl << std::flush;
 +    }
 +
 +    int current = start;
 +    while (success && current > 0)
 +    {
 +        if (!decoder->nextPage())
 +        {
 +            success = false;
 +            break;
 +        }
 +        --current;
 +    }
 +
 +    if (!success)
 +    {
 +        decoder.release();
 +        if (!filename.empty())
 +        {
 +            if (0 != remove(filename.c_str()))
 +            {
 +                std::cerr << "unable to remove temporary file:" << filename << std::endl << std::flush;
 +            }
 +        }
 +        return 0;
 +    }
 +
 +    while (current < count)
 +    {
 +        // grab the decoded type
 +        int type = decoder->type();
 +        if ((flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && flags != IMREAD_UNCHANGED)
 +        {
 +            if ((flags & IMREAD_ANYDEPTH) == 0)
 +                type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));
 +
 +            if ((flags & IMREAD_COLOR) != 0 ||
 +                ((flags & IMREAD_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1))
 +                type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3);
 +            else
 +                type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);
 +        }
 +
 +        // established the required input image size
 +        Size size = validateInputImageSize(Size(decoder->width(), decoder->height()));
 +
 +        // read the image data
 +        Mat mat(size.height, size.width, type);
 +        success = false;
 +        try
 +        {
 +            if (decoder->readData(mat))
 +                success = true;
 +        }
 +        catch (const cv::Exception& e)
 +        {
 +            std::cerr << "imreadmulti_('" << filename << "'): can't read data: " << e.what() << std::endl << std::flush;
 +        }
 +        catch (...)
 +        {
 +            std::cerr << "imreadmulti_('" << filename << "'): can't read data: unknown exception" << std::endl << std::flush;
 +        }
 +        if (!success)
 +            break;
 +
 +        // optionally rotate the data if EXIF' orientation flag says so
 +        if ((flags & IMREAD_IGNORE_ORIENTATION) == 0 && flags != IMREAD_UNCHANGED)
 +        {
 +            ApplyExifOrientation(decoder->getExifTag(ORIENTATION), mat);
 +        }
 +
 +        mats.push_back(mat);
 +        if (!decoder->nextPage())
 +        {
 +            break;
 +        }
 +        ++current;
 +    }
 +
 +    if (!filename.empty())
 +    {
 +        if (0 != remove(filename.c_str()))
 +        {
 +            std::cerr << "unable to remove temporary file:" << filename << std::endl << std::flush;
 +        }
 +    }
 +
 +    if (!success)
 +        mats.clear();
 +    return !mats.empty();
 +}
 +
 +bool imdecodemulti(InputArray _buf, int flags, CV_OUT std::vector<Mat>& mats)
 +{
 +    CV_TRACE_FUNCTION();
 +
 +    Mat buf = _buf.getMat();
 +    return imdecodemulti_(buf, flags, mats, 0, -1);
 +}
 +
  bool imencode( const String& ext, InputArray _image,
-                std::vector<uchar>& buf, const std::vector<int>& params )
+                std::vector<uchar>& buf, const std::vector<int>& params_ )
  {
      CV_TRACE_FUNCTION();
  
Simple merge
index 0b0b0ecd0596d179c02bc4c2f7fd8eb517690b6c,30692452b2571644a590ed4b2391dd78c9c85bd6..2320147a4ecc38058969f7313977cffbe3f99373
@@@ -303,181 -288,23 +303,201 @@@ TEST(Imgcodecs_Image, write_umat
      EXPECT_EQ(0, remove(dst_name.c_str()));
  }
  
 +TEST(Imgcodecs_Image, multipage_collection_size)
 +{
 +    const string root = cvtest::TS::ptr()->get_data_path();
 +    const string filename = root + "readwrite/multipage.tif";
 +
 +    ImageCollection collection(filename, IMREAD_ANYCOLOR);
 +    EXPECT_EQ((std::size_t)6, collection.size());
 +}
 +
 +TEST(Imgcodecs_Image, multipage_collection_read_pages_iterator)
 +{
 +    const string root = cvtest::TS::ptr()->get_data_path();
 +    const string filename = root + "readwrite/multipage.tif";
 +    const string page_files[] = {
 +            root + "readwrite/multipage_p1.tif",
 +            root + "readwrite/multipage_p2.tif",
 +            root + "readwrite/multipage_p3.tif",
 +            root + "readwrite/multipage_p4.tif",
 +            root + "readwrite/multipage_p5.tif",
 +            root + "readwrite/multipage_p6.tif"
 +    };
 +
 +    ImageCollection collection(filename, IMREAD_ANYCOLOR);
 +
 +    auto collectionBegin = collection.begin();
 +    for(size_t i = 0; i < collection.size(); ++i, ++collectionBegin)
 +    {
 +        double diff = cv::norm(collectionBegin.operator*(), imread(page_files[i]), NORM_INF);
 +        EXPECT_EQ(0., diff);
 +    }
 +}
 +
 +TEST(Imgcodecs_Image, multipage_collection_two_iterator)
 +{
 +    const string root = cvtest::TS::ptr()->get_data_path();
 +    const string filename = root + "readwrite/multipage.tif";
 +    const string page_files[] = {
 +            root + "readwrite/multipage_p1.tif",
 +            root + "readwrite/multipage_p2.tif",
 +            root + "readwrite/multipage_p3.tif",
 +            root + "readwrite/multipage_p4.tif",
 +            root + "readwrite/multipage_p5.tif",
 +            root + "readwrite/multipage_p6.tif"
 +    };
 +
 +    ImageCollection collection(filename, IMREAD_ANYCOLOR);
 +    auto firstIter = collection.begin();
 +    auto secondIter = collection.begin();
 +
 +    // Decode all odd pages then decode even pages -> 1, 0, 3, 2 ...
 +    firstIter++;
 +    for(size_t i = 1; i < collection.size(); i += 2, ++firstIter, ++firstIter, ++secondIter, ++secondIter) {
 +        Mat mat = *firstIter;
 +        double diff = cv::norm(mat, imread(page_files[i]), NORM_INF);
 +        EXPECT_EQ(0., diff);
 +        Mat evenMat = *secondIter;
 +        diff = cv::norm(evenMat, imread(page_files[i-1]), NORM_INF);
 +        EXPECT_EQ(0., diff);
 +    }
 +}
 +
 +TEST(Imgcodecs_Image, multipage_collection_operator_plusplus)
 +{
 +    const string root = cvtest::TS::ptr()->get_data_path();
 +    const string filename = root + "readwrite/multipage.tif";
 +
 +    // operator++ test
 +    ImageCollection collection(filename, IMREAD_ANYCOLOR);
 +    auto firstIter = collection.begin();
 +    auto secondIter = firstIter++;
 +
 +    // firstIter points to second page, secondIter points to first page
 +    double diff = cv::norm(*firstIter, *secondIter, NORM_INF);
 +    EXPECT_NE(diff, 0.);
 +}
 +
 +TEST(Imgcodecs_Image, multipage_collection_backward_decoding)
 +{
 +    const string root = cvtest::TS::ptr()->get_data_path();
 +    const string filename = root + "readwrite/multipage.tif";
 +    const string page_files[] = {
 +            root + "readwrite/multipage_p1.tif",
 +            root + "readwrite/multipage_p2.tif",
 +            root + "readwrite/multipage_p3.tif",
 +            root + "readwrite/multipage_p4.tif",
 +            root + "readwrite/multipage_p5.tif",
 +            root + "readwrite/multipage_p6.tif"
 +    };
 +
 +    ImageCollection collection(filename, IMREAD_ANYCOLOR);
 +    EXPECT_EQ((size_t)6, collection.size());
 +
 +    // backward decoding -> 5,4,3,2,1,0
 +    for(int i = (int)collection.size() - 1; i >= 0; --i)
 +    {
 +        cv::Mat ithPage = imread(page_files[i]);
 +        EXPECT_FALSE(ithPage.empty());
 +        double diff = cv::norm(collection[i], ithPage, NORM_INF);
 +        EXPECT_EQ(diff, 0.);
 +    }
 +
 +    for(int i = 0; i < (int)collection.size(); ++i)
 +    {
 +        collection.releaseCache(i);
 +    }
 +
 +    double diff = cv::norm(collection[2], imread(page_files[2]), NORM_INF);
 +    EXPECT_EQ(diff, 0.);
 +}
 +
 +TEST(ImgCodecs, multipage_collection_decoding_range_based_for_loop_test)
 +{
 +    const string root = cvtest::TS::ptr()->get_data_path();
 +    const string filename = root + "readwrite/multipage.tif";
 +    const string page_files[] = {
 +            root + "readwrite/multipage_p1.tif",
 +            root + "readwrite/multipage_p2.tif",
 +            root + "readwrite/multipage_p3.tif",
 +            root + "readwrite/multipage_p4.tif",
 +            root + "readwrite/multipage_p5.tif",
 +            root + "readwrite/multipage_p6.tif"
 +    };
 +
 +    ImageCollection collection(filename, IMREAD_ANYCOLOR);
 +
 +    size_t index = 0;
 +    for(auto &i: collection)
 +    {
 +        cv::Mat ithPage = imread(page_files[index]);
 +        EXPECT_FALSE(ithPage.empty());
 +        double diff = cv::norm(i, ithPage, NORM_INF);
 +        EXPECT_EQ(0., diff);
 +        ++index;
 +    }
 +    EXPECT_EQ(index, collection.size());
 +
 +    index = 0;
 +    for(auto &&i: collection)
 +    {
 +        cv::Mat ithPage = imread(page_files[index]);
 +        EXPECT_FALSE(ithPage.empty());
 +        double diff = cv::norm(i, ithPage, NORM_INF);
 +        EXPECT_EQ(0., diff);
 +        ++index;
 +    }
 +    EXPECT_EQ(index, collection.size());
 +}
 +
 +TEST(ImgCodecs, multipage_collection_two_iterator_operatorpp)
 +{
 +    const string root = cvtest::TS::ptr()->get_data_path();
 +    const string filename = root + "readwrite/multipage.tif";
 +
 +    ImageCollection imcol(filename, IMREAD_ANYCOLOR);
 +
 +    auto it0 = imcol.begin(), it1 = it0, it2 = it0;
 +    vector<Mat> img(6);
 +    for (int i = 0; i < 6; i++) {
 +        img[i] = *it0;
 +        it0->release();
 +        ++it0;
 +    }
 +
 +    for (int i = 0; i < 3; i++) {
 +        ++it2;
 +    }
 +
 +    for (int i = 0; i < 3; i++) {
 +         auto img2 = *it2;
 +         auto img1 = *it1;
 +         ++it2;
 +         ++it1;
 +         EXPECT_TRUE(cv::norm(img2, img[i+3], NORM_INF) == 0);
 +         EXPECT_TRUE(cv::norm(img1, img[i], NORM_INF) == 0);
 +    }
 +}
 +
++
+ TEST(Imgcodecs_Params, imwrite_regression_22752)
+ {
+     const Mat img(16, 16, CV_8UC3, cv::Scalar::all(0));
+     vector<int> params;
+     params.push_back(IMWRITE_JPEG_QUALITY);
+ //  params.push_back(100)); // Forget it.
+     EXPECT_ANY_THROW(cv::imwrite("test.jpg", img, params));  // parameters size or missing JPEG codec
+ }
+ TEST(Imgcodecs_Params, imencode_regression_22752)
+ {
+     const Mat img(16, 16, CV_8UC3, cv::Scalar::all(0));
+     vector<int> params;
+     params.push_back(IMWRITE_JPEG_QUALITY);
+ //  params.push_back(100)); // Forget it.
+     vector<uchar> buf;
+     EXPECT_ANY_THROW(cv::imencode("test.jpg", img, buf, params));  // parameters size or missing JPEG codec
+ }
  }} // namespace
Simple merge