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;
--- /dev/null
- // 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
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)
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)
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);
}
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;
}
}
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;
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 {
{
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;
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();
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