From e0b664f390d26575e651587cfcb64c9ba8a161e7 Mon Sep 17 00:00:00 2001 From: take1014 Date: Wed, 13 Mar 2019 00:27:56 +0900 Subject: [PATCH 01/19] fix dftFilter2D --- modules/imgproc/src/filter.dispatch.cpp | 24 +++++++--- modules/imgproc/test/test_filter.cpp | 61 +++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/modules/imgproc/src/filter.dispatch.cpp b/modules/imgproc/src/filter.dispatch.cpp index b6f5331028..24e1a74e88 100644 --- a/modules/imgproc/src/filter.dispatch.cpp +++ b/modules/imgproc/src/filter.dispatch.cpp @@ -1112,6 +1112,7 @@ static bool ippFilter2D(int stype, int dtype, int kernel_type, static bool dftFilter2D(int stype, int dtype, int kernel_type, uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, + int width, int height, int full_width, int full_height, int offset_x, int offset_y, uchar * kernel_data, size_t kernel_step, @@ -1125,13 +1126,23 @@ static bool dftFilter2D(int stype, int dtype, int kernel_type, int dft_filter_size = checkHardwareSupport(CV_CPU_SSE3) && ((sdepth == CV_8U && (ddepth == CV_8U || ddepth == CV_16S)) || (sdepth == CV_32F && ddepth == CV_32F)) ? 130 : 50; if (kernel_width * kernel_height < dft_filter_size) return false; + + // detect roi case + if( (offset_x != 0) || (offset_y != 0) ) + { + return false; + } + if( (width != full_width) || (height != full_height) ) + { + return false; + } } Point anchor = Point(anchor_x, anchor_y); Mat kernel = Mat(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step); - Mat src(Size(full_width-offset_x, full_height-offset_y), stype, src_data, src_step); - Mat dst(Size(full_width, full_height), dtype, dst_data, dst_step); + Mat src(Size(width, height), stype, src_data, src_step); + Mat dst(Size(width, height), dtype, dst_data, dst_step); Mat temp; int src_channels = CV_MAT_CN(stype); int dst_channels = CV_MAT_CN(dtype); @@ -1144,10 +1155,10 @@ static bool dftFilter2D(int stype, int dtype, int kernel_type, // we just use that. int corrDepth = ddepth; if ((ddepth == CV_32F || ddepth == CV_64F) && src_data != dst_data) { - temp = Mat(Size(full_width, full_height), dtype, dst_data, dst_step); + temp = Mat(Size(width, height), dtype, dst_data, dst_step); } else { corrDepth = ddepth == CV_64F ? CV_64F : CV_32F; - temp.create(Size(full_width, full_height), CV_MAKETYPE(corrDepth, dst_channels)); + temp.create(Size(width, height), CV_MAKETYPE(corrDepth, dst_channels)); } crossCorr(src, kernel, temp, src.size(), CV_MAKETYPE(corrDepth, src_channels), @@ -1158,9 +1169,9 @@ static bool dftFilter2D(int stype, int dtype, int kernel_type, } } else { if (src_data != dst_data) - temp = Mat(Size(full_width, full_height), dtype, dst_data, dst_step); + temp = Mat(Size(width, height), dtype, dst_data, dst_step); else - temp.create(Size(full_width, full_height), dtype); + temp.create(Size(width, height), dtype); crossCorr(src, kernel, temp, src.size(), CV_MAKETYPE(ddepth, src_channels), anchor, delta, borderType); @@ -1293,6 +1304,7 @@ void filter2D(int stype, int dtype, int kernel_type, res = dftFilter2D(stype, dtype, kernel_type, src_data, src_step, dst_data, dst_step, + width, height, full_width, full_height, offset_x, offset_y, kernel_data, kernel_step, diff --git a/modules/imgproc/test/test_filter.cpp b/modules/imgproc/test/test_filter.cpp index 5b73e3bf8e..55efae23f9 100644 --- a/modules/imgproc/test/test_filter.cpp +++ b/modules/imgproc/test/test_filter.cpp @@ -2201,6 +2201,67 @@ TEST(Imgproc_Filter2D, dftFilter2d_regression_10683) EXPECT_LE(cvtest::norm(dst, expected, NORM_INF), 2); } +TEST(Imgproc_Filter2D, dftFilter2d_regression_13179) +{ + uchar src_[24*24] = { + 0, 40, 0, 0, 255, 0, 0, 78, 131, 0, 196, 0, 255, 0, 0, 0, 0, 255, 70, 0, 255, 0, 0, 0, + 0, 0, 255, 204, 0, 0, 255, 93, 255, 0, 0, 255, 12, 0, 0, 0, 255, 121, 0, 255, 0, 0, 0, 255, + 0, 178, 0, 25, 67, 0, 165, 0, 255, 0, 0, 181, 151, 175, 0, 0, 32, 0, 0, 255, 165, 93, 0, 255, + 255, 255, 0, 0, 255, 126, 0, 0, 0, 0, 133, 29, 9, 0, 220, 255, 0, 142, 255, 255, 255, 0, 255, 0, + 255, 32, 255, 0, 13, 237, 0, 0, 0, 0, 0, 19, 90, 0, 0, 85, 122, 62, 95, 29, 255, 20, 0, 0, + 0, 0, 166, 41, 0, 48, 70, 0, 68, 0, 255, 0, 139, 7, 63, 144, 0, 204, 0, 0, 0, 98, 114, 255, + 105, 0, 0, 0, 0, 255, 91, 0, 73, 0, 255, 0, 0, 0, 255, 198, 21, 0, 0, 0, 255, 43, 153, 128, + 0, 98, 26, 0, 101, 0, 0, 0, 255, 0, 0, 0, 255, 77, 56, 0, 241, 0, 169, 132, 0, 255, 186, 255, + 255, 87, 0, 1, 0, 0, 10, 39, 120, 0, 23, 69, 207, 0, 0, 0, 0, 84, 0, 0, 0, 0, 255, 0, + 255, 0, 0, 136, 255, 77, 247, 0, 67, 0, 15, 255, 0, 143, 0, 243, 255, 0, 0, 238, 255, 0, 255, 8, + 42, 0, 0, 255, 29, 0, 0, 0, 255, 255, 255, 75, 0, 0, 0, 255, 0, 0, 255, 38, 197, 0, 255, 87, + 0, 123, 17, 0, 234, 0, 0, 149, 0, 0, 255, 16, 0, 0, 0, 255, 0, 255, 0, 38, 0, 114, 255, 76, + 0, 0, 8, 0, 255, 0, 0, 0, 220, 0, 11, 255, 0, 0, 55, 98, 0, 0, 0, 255, 0, 175, 255, 110, + 235, 0, 175, 0, 255, 227, 38, 206, 0, 0, 255, 246, 0, 0, 123, 183, 255, 0, 0, 255, 0, 156, 0, 54, + 0, 255, 0, 202, 0, 0, 0, 0, 157, 0, 255, 63, 0, 0, 0, 0, 0, 255, 132, 0, 255, 0, 0, 0, + 0, 0, 0, 255, 0, 0, 128, 126, 0, 243, 46, 7, 0, 211, 108, 166, 0, 0, 162, 227, 0, 204, 0, 51, + 255, 216, 0, 0, 43, 0, 255, 40, 188, 188, 255, 0, 0, 255, 34, 0, 0, 168, 0, 0, 0, 35, 0, 0, + 0, 80, 131, 255, 0, 255, 10, 0, 0, 0, 180, 255, 209, 255, 173, 34, 0, 66, 0, 49, 0, 255, 83, 0, + 0, 204, 0, 91, 0, 0, 0, 205, 84, 0, 0, 0, 92, 255, 91, 0, 126, 0, 185, 145, 0, 0, 9, 0, + 255, 0, 0, 255, 255, 0, 0, 255, 0, 0, 216, 0, 187, 221, 0, 0, 141, 0, 0, 209, 0, 0, 255, 0, + 255, 0, 0, 154, 150, 0, 0, 0, 148, 0, 201, 255, 0, 255, 16, 0, 0, 160, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 198, 255, 147, 131, 0, 255, 202, 0, 0, 0, 0, 255, 0, + 0, 0, 0, 164, 181, 0, 0, 0, 69, 255, 31, 0, 255, 195, 0, 0, 255, 164, 109, 0, 0, 202, 0, 206, + 0, 0, 61, 235, 33, 255, 77, 0, 0, 0, 0, 85, 0, 228, 0, 0, 0, 0, 255, 0, 0, 5, 255, 255 + }; + cv::Mat_ src(24, 24, src_); + + uchar expected_[16*16] = { + 0,255, 0, 0,255, 0, 0,255, 0, 0,255,255, 0,255, 0, 0, + 0,255, 0, 0,255, 0, 0,255, 0, 0,255,255, 0,255, 0, 0, + 0,255, 0, 0,255, 0, 0,255, 70, 0,255,255, 0,255, 0, 0, + 0,234,138, 0,255, 0, 0,255, 8, 0,255,255, 0,255, 0, 0, + 0, 0,255, 0,255,228, 0,255,255, 0,255,255, 0,255, 0, 5, + 0, 0,255, 0,255, 0, 0,255, 0, 0,255,255, 0,255, 0, 0, + 0,253, 0, 0,255, 0, 0,255, 0, 0,255,255, 0,255, 0, 0, + 0,255, 0, 0,255, 0, 0,255, 0, 0,255, 93, 0,255, 0,255, + 0,255, 0, 0,255, 0,182,255, 0, 0,255, 0, 0,255, 0, 0, + 0, 0,253, 0,228, 0,255,255, 0, 0,255, 0, 0, 0, 0, 75, + 0, 0,255, 0, 0, 0,255,255, 0,255,206, 0, 1,162, 0,255, + 0, 0,255, 0, 0, 0,255,255, 0,255,255, 0, 0,255, 0,255, + 0, 0,255, 0, 0, 0,255,255, 0,255,255, 0,255,255, 0,255, + 0, 0,255,255, 0, 0,255, 0, 0,255,255, 0,255,168, 0,255, + 0, 0,255,255, 0, 0,255, 26, 0,255,255, 0,255,255, 0,255, + 0, 0,255,255, 0, 0,255, 0, 0,255,255, 0,255,255, 0,255, + }; + cv::Mat_ expected(16, 16, expected_); + + cv::Mat kernel = cv::getGaborKernel(cv::Size(13, 13), 8, 0, 3, 0.25); + + cv::Mat roi(src, cv::Rect(0, 0, 16, 16)); + + cv::Mat filtered(16, 16, roi.type()); + + cv::filter2D(roi, filtered, -1, kernel); + + EXPECT_LE(cvtest::norm(filtered, expected, cv::NORM_INF), 2); +} + TEST(Imgproc_MedianBlur, hires_regression_13409) { Mat src(2048, 2048, CV_8UC1), dst_hires, dst_ref; From 13a782c0390b034440379c6abbb92c2c7680dddd Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 20 Jun 2019 16:43:28 +0300 Subject: [PATCH 02/19] test: fix usage of findDataFile() misused 'optional' mode --- modules/dnn/perf/perf_caffe.cpp | 2 +- modules/dnn/perf/perf_net.cpp | 6 ++-- modules/dnn/test/test_backends.cpp | 22 ++++++------ modules/dnn/test/test_caffe_importer.cpp | 39 ++++++++++---------- modules/dnn/test/test_darknet_importer.cpp | 11 +++--- modules/dnn/test/test_googlenet.cpp | 6 ++-- modules/dnn/test/test_misc.cpp | 8 ++--- modules/dnn/test/test_onnx_importer.cpp | 24 ++++++++----- modules/dnn/test/test_tf_importer.cpp | 42 +++++++++++----------- modules/dnn/test/test_torch_importer.cpp | 8 ++--- modules/objdetect/test/test_qrcode.cpp | 2 +- modules/ts/src/ts.cpp | 28 ++++++++++++--- 12 files changed, 114 insertions(+), 84 deletions(-) diff --git a/modules/dnn/perf/perf_caffe.cpp b/modules/dnn/perf/perf_caffe.cpp index b3f518ec5b..370f06dba2 100644 --- a/modules/dnn/perf/perf_caffe.cpp +++ b/modules/dnn/perf/perf_caffe.cpp @@ -38,7 +38,7 @@ namespace opencv_test { static caffe::Net* initNet(std::string proto, std::string weights) { - proto = findDataFile(proto, false); + proto = findDataFile(proto); weights = findDataFile(weights, false); #ifdef HAVE_CLCAFFE diff --git a/modules/dnn/perf/perf_net.cpp b/modules/dnn/perf/perf_net.cpp index f5daa27fcd..bba1eb5dae 100644 --- a/modules/dnn/perf/perf_net.cpp +++ b/modules/dnn/perf/perf_net.cpp @@ -35,7 +35,7 @@ public: weights = findDataFile(weights, false); if (!proto.empty()) - proto = findDataFile(proto, false); + proto = findDataFile(proto); if (backend == DNN_BACKEND_HALIDE) { if (halide_scheduler == "disabled") @@ -198,10 +198,10 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv3) { if (backend == DNN_BACKEND_HALIDE) throw SkipTestException(""); - Mat sample = imread(findDataFile("dnn/dog416.png", false)); + Mat sample = imread(findDataFile("dnn/dog416.png")); Mat inp; sample.convertTo(inp, CV_32FC3); - processNet("dnn/yolov3.cfg", "dnn/yolov3.weights", "", inp / 255); + processNet("dnn/yolov3.weights", "dnn/yolov3.cfg", "", inp / 255); } PERF_TEST_P_(DNNTestNetwork, EAST_text_detection) diff --git a/modules/dnn/test/test_backends.cpp b/modules/dnn/test/test_backends.cpp index 17a37a44da..457f5557e9 100644 --- a/modules/dnn/test/test_backends.cpp +++ b/modules/dnn/test/test_backends.cpp @@ -37,7 +37,7 @@ public: weights = findDataFile(weights, false); if (!proto.empty()) - proto = findDataFile(proto, false); + proto = findDataFile(proto); // Create two networks - with default backend and target and a tested one. Net netDefault = readNet(weights, proto); @@ -51,7 +51,7 @@ public: net.setPreferableTarget(target); if (backend == DNN_BACKEND_HALIDE && !halideScheduler.empty()) { - halideScheduler = findDataFile(halideScheduler, false); + halideScheduler = findDataFile(halideScheduler); net.setHalideScheduler(halideScheduler); } Mat out = net.forward(outputLayer).clone(); @@ -171,7 +171,7 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe) applyTestTag(CV_TEST_TAG_MEMORY_512MB); if (backend == DNN_BACKEND_HALIDE) throw SkipTestException(""); - Mat sample = imread(findDataFile("dnn/street.png", false)); + Mat sample = imread(findDataFile("dnn/street.png")); Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), false); float diffScores = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 1.5e-2 : 0.0; float diffSquares = (target == DNN_TARGET_MYRIAD) ? 0.063 : 0.0; @@ -190,7 +190,7 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe_Different_Width_Height) && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X) throw SkipTestException("Test is disabled for MyriadX"); #endif - Mat sample = imread(findDataFile("dnn/street.png", false)); + Mat sample = imread(findDataFile("dnn/street.png")); Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 560), Scalar(127.5, 127.5, 127.5), false); float diffScores = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.029 : 0.0; float diffSquares = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.09 : 0.0; @@ -204,7 +204,7 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow) applyTestTag(target == DNN_TARGET_CPU ? "" : CV_TEST_TAG_MEMORY_512MB); if (backend == DNN_BACKEND_HALIDE) throw SkipTestException(""); - Mat sample = imread(findDataFile("dnn/street.png", false)); + Mat sample = imread(findDataFile("dnn/street.png")); Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false); float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.095 : 0.0; float lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.09 : 0.0; @@ -223,7 +223,7 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow_Different_Width_Height) && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X) throw SkipTestException("Test is disabled for MyriadX"); #endif - Mat sample = imread(findDataFile("dnn/street.png", false)); + Mat sample = imread(findDataFile("dnn/street.png")); Mat inp = blobFromImage(sample, 1.0f, Size(300, 560), Scalar(), false); float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.012 : 0.0; float lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.06 : 0.0; @@ -237,7 +237,7 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v2_TensorFlow) applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB); if (backend == DNN_BACKEND_HALIDE) throw SkipTestException(""); - Mat sample = imread(findDataFile("dnn/street.png", false)); + Mat sample = imread(findDataFile("dnn/street.png")); Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false); float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.013 : 2e-5; float lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.062 : 0.0; @@ -254,7 +254,7 @@ TEST_P(DNNTestNetwork, SSD_VGG16) throw SkipTestException(""); double scoreThreshold = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0325 : 0.0; const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.032 : 0.0; - Mat sample = imread(findDataFile("dnn/street.png", false)); + Mat sample = imread(findDataFile("dnn/street.png")); Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false); processNet("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel", "dnn/ssd_vgg16.prototxt", inp, "detection_out", "", scoreThreshold, lInf); @@ -337,7 +337,7 @@ TEST_P(DNNTestNetwork, opencv_face_detector) { if (backend == DNN_BACKEND_HALIDE) throw SkipTestException(""); - Mat img = imread(findDataFile("gpu/lbpcascade/er.png", false)); + Mat img = imread(findDataFile("gpu/lbpcascade/er.png")); Mat inp = blobFromImage(img, 1.0, Size(), Scalar(104.0, 177.0, 123.0), false, false); processNet("dnn/opencv_face_detector.caffemodel", "dnn/opencv_face_detector.prototxt", inp, "detection_out"); @@ -357,7 +357,7 @@ TEST_P(DNNTestNetwork, Inception_v2_SSD_TensorFlow) #endif if (backend == DNN_BACKEND_HALIDE) throw SkipTestException(""); - Mat sample = imread(findDataFile("dnn/street.png", false)); + Mat sample = imread(findDataFile("dnn/street.png")); Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false); float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.015 : 0.0; float lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0731 : 0.0; @@ -400,7 +400,7 @@ TEST_P(DNNTestNetwork, FastNeuralStyle_eccv16) #endif #endif - Mat img = imread(findDataFile("dnn/googlenet_1.png", false)); + Mat img = imread(findDataFile("dnn/googlenet_1.png")); Mat inp = blobFromImage(img, 1.0, Size(320, 240), Scalar(103.939, 116.779, 123.68), false, false); // Output image has values in range [-143.526, 148.539]. float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.4 : 4e-5; diff --git a/modules/dnn/test/test_caffe_importer.cpp b/modules/dnn/test/test_caffe_importer.cpp index b9f07e5c76..4ac3e7e63a 100644 --- a/modules/dnn/test/test_caffe_importer.cpp +++ b/modules/dnn/test/test_caffe_importer.cpp @@ -48,7 +48,7 @@ namespace opencv_test { namespace { template static std::string _tf(TString filename) { - return (getOpenCVExtraDir() + "/dnn/") + filename; + return findDataFile(std::string("dnn/") + filename); } class Test_Caffe_nets : public DNNTestLayer @@ -58,11 +58,11 @@ public: double scoreDiff = 0.0, double iouDiff = 0.0) { checkBackend(); - Net net = readNetFromCaffe(findDataFile("dnn/" + proto, false), + Net net = readNetFromCaffe(findDataFile("dnn/" + proto), findDataFile("dnn/" + model, false)); net.setPreferableBackend(backend); net.setPreferableTarget(target); - Mat img = imread(findDataFile("dnn/dog416.png", false)); + Mat img = imread(findDataFile("dnn/dog416.png")); resize(img, img, Size(800, 600)); Mat blob = blobFromImage(img, 1.0, Size(), Scalar(102.9801, 115.9465, 122.7717), false, false); Mat imInfo = (Mat_(1, 3) << img.rows, img.cols, 1.6f); @@ -80,11 +80,12 @@ public: TEST(Test_Caffe, memory_read) { - const string proto = findDataFile("dnn/bvlc_googlenet.prototxt", false); + const string proto = findDataFile("dnn/bvlc_googlenet.prototxt"); const string model = findDataFile("dnn/bvlc_googlenet.caffemodel", false); std::vector dataProto; readFileContent(proto, dataProto); + std::vector dataModel; readFileContent(model, dataModel); @@ -163,7 +164,7 @@ TEST_P(Reproducibility_AlexNet, Accuracy) bool readFromMemory = get<0>(GetParam()); Net net; { - const string proto = findDataFile("dnn/bvlc_alexnet.prototxt", false); + const string proto = findDataFile("dnn/bvlc_alexnet.prototxt"); const string model = findDataFile("dnn/bvlc_alexnet.caffemodel", false); if (readFromMemory) { @@ -204,8 +205,8 @@ TEST(Reproducibility_FCN, Accuracy) Net net; { - const string proto = findDataFile("dnn/fcn8s-heavy-pascal.prototxt", false); - const string model = findDataFile("dnn/fcn8s-heavy-pascal.caffemodel", false); + const string proto = findDataFile("dnn/fcn8s-heavy-pascal.prototxt"); + const string model = findDataFile("dnn/fcn8s-heavy-pascal.caffemodel"); net = readNetFromCaffe(proto, model); ASSERT_FALSE(net.empty()); } @@ -233,7 +234,7 @@ TEST(Reproducibility_SSD, Accuracy) applyTestTag(CV_TEST_TAG_MEMORY_512MB, CV_TEST_TAG_DEBUG_LONG); Net net; { - const string proto = findDataFile("dnn/ssd_vgg16.prototxt", false); + const string proto = findDataFile("dnn/ssd_vgg16.prototxt"); const string model = findDataFile("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel", false); net = readNetFromCaffe(proto, model); ASSERT_FALSE(net.empty()); @@ -331,7 +332,7 @@ TEST_P(Reproducibility_ResNet50, Accuracy) if (!ocl::useOpenCL() && targetId != DNN_TARGET_CPU) throw SkipTestException("OpenCL is disabled"); - Net net = readNetFromCaffe(findDataFile("dnn/ResNet-50-deploy.prototxt", false), + Net net = readNetFromCaffe(findDataFile("dnn/ResNet-50-deploy.prototxt"), findDataFile("dnn/ResNet-50-model.caffemodel", false)); net.setPreferableBackend(DNN_BACKEND_OPENCV); @@ -369,7 +370,7 @@ TEST_P(Reproducibility_SqueezeNet_v1_1, Accuracy) int targetId = GetParam(); if(targetId == DNN_TARGET_OPENCL_FP16) throw SkipTestException("This test does not support FP16"); - Net net = readNetFromCaffe(findDataFile("dnn/squeezenet_v1.1.prototxt", false), + Net net = readNetFromCaffe(findDataFile("dnn/squeezenet_v1.1.prototxt"), findDataFile("dnn/squeezenet_v1.1.caffemodel", false)); net.setPreferableBackend(DNN_BACKEND_OPENCV); net.setPreferableTarget(targetId); @@ -400,18 +401,18 @@ TEST(Reproducibility_AlexNet_fp16, Accuracy) const float l1 = 1e-5; const float lInf = 3e-3; - const string proto = findDataFile("dnn/bvlc_alexnet.prototxt", false); + const string proto = findDataFile("dnn/bvlc_alexnet.prototxt"); const string model = findDataFile("dnn/bvlc_alexnet.caffemodel", false); shrinkCaffeModel(model, "bvlc_alexnet.caffemodel_fp16"); Net net = readNetFromCaffe(proto, "bvlc_alexnet.caffemodel_fp16"); net.setPreferableBackend(DNN_BACKEND_OPENCV); - Mat sample = imread(findDataFile("dnn/grace_hopper_227.png", false)); + Mat sample = imread(findDataFile("dnn/grace_hopper_227.png")); - net.setInput(blobFromImage(sample, 1.0f, Size(227, 227), Scalar(), false)); + net.setInput(blobFromImage(sample, 1.0f, Size(227, 227), Scalar())); Mat out = net.forward(); - Mat ref = blobFromNPY(findDataFile("dnn/caffe_alexnet_prob.npy", false)); + Mat ref = blobFromNPY(findDataFile("dnn/caffe_alexnet_prob.npy")); normAssert(ref, out, "", l1, lInf); } @@ -420,7 +421,7 @@ TEST(Reproducibility_GoogLeNet_fp16, Accuracy) const float l1 = 1e-5; const float lInf = 3e-3; - const string proto = findDataFile("dnn/bvlc_googlenet.prototxt", false); + const string proto = findDataFile("dnn/bvlc_googlenet.prototxt"); const string model = findDataFile("dnn/bvlc_googlenet.caffemodel", false); shrinkCaffeModel(model, "bvlc_googlenet.caffemodel_fp16"); @@ -506,7 +507,7 @@ TEST_P(Test_Caffe_nets, DenseNet_121) TEST(Test_Caffe, multiple_inputs) { - const string proto = findDataFile("dnn/layers/net_input.prototxt", false); + const string proto = findDataFile("dnn/layers/net_input.prototxt"); Net net = readNetFromCaffe(proto); net.setPreferableBackend(DNN_BACKEND_OPENCV); @@ -534,8 +535,8 @@ TEST(Test_Caffe, multiple_inputs) TEST(Test_Caffe, shared_weights) { - const string proto = findDataFile("dnn/layers/shared_weights.prototxt", false); - const string model = findDataFile("dnn/layers/shared_weights.caffemodel", false); + const string proto = findDataFile("dnn/layers/shared_weights.prototxt"); + const string model = findDataFile("dnn/layers/shared_weights.caffemodel"); Net net = readNetFromCaffe(proto, model); @@ -563,7 +564,7 @@ TEST_P(opencv_face_detector, Accuracy) dnn::Target targetId = (dnn::Target)(int)get<1>(GetParam()); Net net = readNetFromCaffe(proto, model); - Mat img = imread(findDataFile("gpu/lbpcascade/er.png", false)); + Mat img = imread(findDataFile("gpu/lbpcascade/er.png")); Mat blob = blobFromImage(img, 1.0, Size(), Scalar(104.0, 177.0, 123.0), false, false); net.setPreferableBackend(DNN_BACKEND_OPENCV); diff --git a/modules/dnn/test/test_darknet_importer.cpp b/modules/dnn/test/test_darknet_importer.cpp index e70e21141f..6a5f5024fe 100644 --- a/modules/dnn/test/test_darknet_importer.cpp +++ b/modules/dnn/test/test_darknet_importer.cpp @@ -82,7 +82,7 @@ TEST(Test_Darknet, read_yolo_voc_stream) Mat ref; Mat sample = imread(_tf("dog416.png")); Mat inp = blobFromImage(sample, 1.0/255, Size(416, 416), Scalar(), true, false); - const std::string cfgFile = findDataFile("dnn/yolo-voc.cfg", false); + const std::string cfgFile = findDataFile("dnn/yolo-voc.cfg"); const std::string weightsFile = findDataFile("dnn/yolo-voc.weights", false); // Import by paths. { @@ -110,12 +110,13 @@ class Test_Darknet_layers : public DNNTestLayer public: void testDarknetLayer(const std::string& name, bool hasWeights = false) { - std::string cfg = findDataFile("dnn/darknet/" + name + ".cfg", false); + Mat inp = blobFromNPY(findDataFile("dnn/darknet/" + name + "_in.npy")); + Mat ref = blobFromNPY(findDataFile("dnn/darknet/" + name + "_out.npy")); + + std::string cfg = findDataFile("dnn/darknet/" + name + ".cfg"); std::string model = ""; if (hasWeights) model = findDataFile("dnn/darknet/" + name + ".weights", false); - Mat inp = blobFromNPY(findDataFile("dnn/darknet/" + name + "_in.npy", false)); - Mat ref = blobFromNPY(findDataFile("dnn/darknet/" + name + "_out.npy", false)); checkBackend(&inp, &ref); @@ -152,7 +153,7 @@ public: Mat inp = blobFromImages(samples, 1.0/255, Size(416, 416), Scalar(), true, false); - Net net = readNet(findDataFile("dnn/" + cfg, false), + Net net = readNet(findDataFile("dnn/" + cfg), findDataFile("dnn/" + weights, false)); net.setPreferableBackend(backend); net.setPreferableTarget(target); diff --git a/modules/dnn/test/test_googlenet.cpp b/modules/dnn/test/test_googlenet.cpp index 3db0c47997..4db04e0b35 100644 --- a/modules/dnn/test/test_googlenet.cpp +++ b/modules/dnn/test/test_googlenet.cpp @@ -58,7 +58,7 @@ TEST_P(Reproducibility_GoogLeNet, Batching) const int targetId = GetParam(); if(targetId == DNN_TARGET_OPENCL_FP16) throw SkipTestException("This test does not support FP16"); - Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt", false), + Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt"), findDataFile("dnn/bvlc_googlenet.caffemodel", false)); net.setPreferableBackend(DNN_BACKEND_OPENCV); net.setPreferableTarget(targetId); @@ -89,7 +89,7 @@ TEST_P(Reproducibility_GoogLeNet, IntermediateBlobs) const int targetId = GetParam(); if(targetId == DNN_TARGET_OPENCL_FP16) throw SkipTestException("This test does not support FP16"); - Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt", false), + Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt"), findDataFile("dnn/bvlc_googlenet.caffemodel", false)); net.setPreferableBackend(DNN_BACKEND_OPENCV); net.setPreferableTarget(targetId); @@ -120,7 +120,7 @@ TEST_P(Reproducibility_GoogLeNet, SeveralCalls) const int targetId = GetParam(); if(targetId == DNN_TARGET_OPENCL_FP16) throw SkipTestException("This test does not support FP16"); - Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt", false), + Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt"), findDataFile("dnn/bvlc_googlenet.caffemodel", false)); net.setPreferableBackend(DNN_BACKEND_OPENCV); net.setPreferableTarget(targetId); diff --git a/modules/dnn/test/test_misc.cpp b/modules/dnn/test/test_misc.cpp index c83dbc741d..4babc7cd5f 100644 --- a/modules/dnn/test/test_misc.cpp +++ b/modules/dnn/test/test_misc.cpp @@ -62,18 +62,18 @@ TEST(imagesFromBlob, Regression) TEST(readNet, Regression) { - Net net = readNet(findDataFile("dnn/squeezenet_v1.1.prototxt", false), + Net net = readNet(findDataFile("dnn/squeezenet_v1.1.prototxt"), findDataFile("dnn/squeezenet_v1.1.caffemodel", false)); EXPECT_FALSE(net.empty()); net = readNet(findDataFile("dnn/opencv_face_detector.caffemodel", false), - findDataFile("dnn/opencv_face_detector.prototxt", false)); + findDataFile("dnn/opencv_face_detector.prototxt")); EXPECT_FALSE(net.empty()); net = readNet(findDataFile("dnn/openface_nn4.small2.v1.t7", false)); EXPECT_FALSE(net.empty()); - net = readNet(findDataFile("dnn/tiny-yolo-voc.cfg", false), + net = readNet(findDataFile("dnn/tiny-yolo-voc.cfg"), findDataFile("dnn/tiny-yolo-voc.weights", false)); EXPECT_FALSE(net.empty()); - net = readNet(findDataFile("dnn/ssd_mobilenet_v1_coco.pbtxt", false), + net = readNet(findDataFile("dnn/ssd_mobilenet_v1_coco.pbtxt"), findDataFile("dnn/ssd_mobilenet_v1_coco.pb", false)); EXPECT_FALSE(net.empty()); } diff --git a/modules/dnn/test/test_onnx_importer.cpp b/modules/dnn/test/test_onnx_importer.cpp index e132bf6923..63f47c05e2 100644 --- a/modules/dnn/test/test_onnx_importer.cpp +++ b/modules/dnn/test/test_onnx_importer.cpp @@ -12,15 +12,18 @@ namespace opencv_test { namespace { template -static std::string _tf(TString filename) +static std::string _tf(TString filename, bool required = true) { - String rootFolder = "dnn/onnx/"; - return findDataFile(rootFolder + filename, false); + return findDataFile(std::string("dnn/onnx/") + filename, required); } class Test_ONNX_layers : public DNNTestLayer { public: + bool required; + + Test_ONNX_layers() : required(true) { } + enum Extension { npy, @@ -31,7 +34,7 @@ public: const double l1 = 0, const float lInf = 0, const bool useSoftmax = false, bool checkNoFallbacks = true) { - String onnxmodel = _tf("models/" + basename + ".onnx"); + String onnxmodel = _tf("models/" + basename + ".onnx", required); Mat inp, ref; if (ext == npy) { inp = blobFromNPY(_tf("data/input_" + basename + ".npy")); @@ -275,11 +278,16 @@ TEST_P(Test_ONNX_layers, Softmax) INSTANTIATE_TEST_CASE_P(/*nothing*/, Test_ONNX_layers, dnnBackendsAndTargets()); -class Test_ONNX_nets : public Test_ONNX_layers {}; +class Test_ONNX_nets : public Test_ONNX_layers +{ +public: + Test_ONNX_nets() { required = false; } +}; + TEST_P(Test_ONNX_nets, Alexnet) { applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB); - const String model = _tf("models/alexnet.onnx"); + const String model = _tf("models/alexnet.onnx", false); Net net = readNetFromONNX(model); ASSERT_FALSE(net.empty()); @@ -309,7 +317,7 @@ TEST_P(Test_ONNX_nets, Googlenet) if (backend == DNN_BACKEND_INFERENCE_ENGINE) throw SkipTestException(""); - const String model = _tf("models/googlenet.onnx"); + const String model = _tf("models/googlenet.onnx", false); Net net = readNetFromONNX(model); ASSERT_FALSE(net.empty()); @@ -527,7 +535,7 @@ TEST_P(Test_ONNX_nets, Resnet34_kinetics) if (backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_CPU) throw SkipTestException("Only DLIE backend on CPU is supported"); - String onnxmodel = findDataFile("dnn/resnet-34_kinetics.onnx"); + String onnxmodel = findDataFile("dnn/resnet-34_kinetics.onnx", false); Mat image0 = imread(findDataFile("dnn/dog416.png")); Mat image1 = imread(findDataFile("dnn/street.png")); diff --git a/modules/dnn/test/test_tf_importer.cpp b/modules/dnn/test/test_tf_importer.cpp index 83b0562571..d3d138daa4 100644 --- a/modules/dnn/test/test_tf_importer.cpp +++ b/modules/dnn/test/test_tf_importer.cpp @@ -74,7 +74,7 @@ TEST(Test_TensorFlow, inception_accuracy) static std::string path(const std::string& file) { - return findDataFile("dnn/tensorflow/" + file, false); + return findDataFile("dnn/tensorflow/" + file); } class Test_TensorFlow_layers : public DNNTestLayer @@ -360,15 +360,15 @@ TEST_P(Test_TensorFlow_nets, MobileNet_SSD) #endif checkBackend(); + std::string imgPath = findDataFile("dnn/street.png"); + std::string netConfig = findDataFile("dnn/ssd_mobilenet_v1_coco.pbtxt"); std::string netPath = findDataFile("dnn/ssd_mobilenet_v1_coco.pb", false); - std::string netConfig = findDataFile("dnn/ssd_mobilenet_v1_coco.pbtxt", false); - std::string imgPath = findDataFile("dnn/street.png", false); Mat inp; resize(imread(imgPath), inp, Size(300, 300)); inp = blobFromImage(inp, 1.0f / 127.5, Size(), Scalar(127.5, 127.5, 127.5), true); - Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco.detection_out.npy", false)); + Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco.detection_out.npy")); Net net = readNetFromTensorflow(netPath, netConfig); net.setPreferableBackend(backend); @@ -397,11 +397,11 @@ TEST_P(Test_TensorFlow_nets, Inception_v2_SSD) #endif checkBackend(); - std::string proto = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pbtxt", false); + Mat img = imread(findDataFile("dnn/street.png")); + std::string proto = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pbtxt"); std::string model = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pb", false); Net net = readNetFromTensorflow(model, proto); - Mat img = imread(findDataFile("dnn/street.png", false)); Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false); net.setPreferableBackend(backend); @@ -434,11 +434,11 @@ TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD) throw SkipTestException("Test is disabled for MyriadX"); #endif + std::string proto = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt"); std::string model = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", false); - std::string proto = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt", false); Net net = readNetFromTensorflow(model, proto); - Mat img = imread(findDataFile("dnn/dog416.png", false)); + Mat img = imread(findDataFile("dnn/dog416.png")); Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false); net.setPreferableBackend(backend); @@ -473,13 +473,13 @@ TEST_P(Test_TensorFlow_nets, Faster_RCNN) double scoresDiff = backend == DNN_BACKEND_INFERENCE_ENGINE ? 2.9e-5 : 1e-5; for (int i = 0; i < 2; ++i) { - std::string proto = findDataFile("dnn/" + names[i] + ".pbtxt", false); + std::string proto = findDataFile("dnn/" + names[i] + ".pbtxt"); std::string model = findDataFile("dnn/" + names[i] + ".pb", false); Net net = readNetFromTensorflow(model, proto); net.setPreferableBackend(backend); net.setPreferableTarget(target); - Mat img = imread(findDataFile("dnn/dog416.png", false)); + Mat img = imread(findDataFile("dnn/dog416.png")); Mat blob = blobFromImage(img, 1.0f, Size(800, 600), Scalar(), true, false); net.setInput(blob); @@ -498,12 +498,12 @@ TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD_PPN) #endif checkBackend(); - std::string proto = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pbtxt", false); + std::string proto = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pbtxt"); std::string model = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pb", false); Net net = readNetFromTensorflow(model, proto); - Mat img = imread(findDataFile("dnn/dog416.png", false)); - Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_ppn_coco.detection_out.npy", false)); + Mat img = imread(findDataFile("dnn/dog416.png")); + Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_ppn_coco.detection_out.npy")); Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false); net.setPreferableBackend(backend); @@ -521,11 +521,11 @@ TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD_PPN) TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8) { checkBackend(); - std::string proto = findDataFile("dnn/opencv_face_detector.pbtxt", false); + std::string proto = findDataFile("dnn/opencv_face_detector.pbtxt"); std::string model = findDataFile("dnn/opencv_face_detector_uint8.pb", false); Net net = readNetFromTensorflow(model, proto); - Mat img = imread(findDataFile("gpu/lbpcascade/er.png", false)); + Mat img = imread(findDataFile("gpu/lbpcascade/er.png")); Mat blob = blobFromImage(img, 1.0, Size(), Scalar(104.0, 177.0, 123.0), false, false); net.setPreferableBackend(backend); @@ -572,11 +572,11 @@ TEST_P(Test_TensorFlow_nets, EAST_text_detection) checkBackend(); std::string netPath = findDataFile("dnn/frozen_east_text_detection.pb", false); - std::string imgPath = findDataFile("cv/ximgproc/sources/08.png", false); - std::string refScoresPath = findDataFile("dnn/east_text_detection.scores.npy", false); - std::string refGeometryPath = findDataFile("dnn/east_text_detection.geometry.npy", false); + std::string imgPath = findDataFile("cv/ximgproc/sources/08.png"); + std::string refScoresPath = findDataFile("dnn/east_text_detection.scores.npy"); + std::string refGeometryPath = findDataFile("dnn/east_text_detection.geometry.npy"); - Net net = readNet(findDataFile("dnn/frozen_east_text_detection.pb", false)); + Net net = readNet(netPath); net.setPreferableBackend(backend); net.setPreferableTarget(target); @@ -793,11 +793,11 @@ TEST(Test_TensorFlow, two_inputs) TEST(Test_TensorFlow, Mask_RCNN) { applyTestTag(CV_TEST_TAG_MEMORY_1GB, CV_TEST_TAG_DEBUG_VERYLONG); - std::string proto = findDataFile("dnn/mask_rcnn_inception_v2_coco_2018_01_28.pbtxt", false); + Mat img = imread(findDataFile("dnn/street.png")); + std::string proto = findDataFile("dnn/mask_rcnn_inception_v2_coco_2018_01_28.pbtxt"); std::string model = findDataFile("dnn/mask_rcnn_inception_v2_coco_2018_01_28.pb", false); Net net = readNetFromTensorflow(model, proto); - Mat img = imread(findDataFile("dnn/street.png", false)); Mat refDetections = blobFromNPY(path("mask_rcnn_inception_v2_coco_2018_01_28.detection_out.npy")); Mat refMasks = blobFromNPY(path("mask_rcnn_inception_v2_coco_2018_01_28.detection_masks.npy")); Mat blob = blobFromImage(img, 1.0f, Size(800, 800), Scalar(), true, false); diff --git a/modules/dnn/test/test_torch_importer.cpp b/modules/dnn/test/test_torch_importer.cpp index 6aaec8e1a7..5bd79c081b 100644 --- a/modules/dnn/test/test_torch_importer.cpp +++ b/modules/dnn/test/test_torch_importer.cpp @@ -53,13 +53,13 @@ using namespace cv; using namespace cv::dnn; template -static std::string _tf(TStr filename, bool inTorchDir = true) +static std::string _tf(TStr filename, bool inTorchDir = true, bool required = true) { String path = "dnn/"; if (inTorchDir) path += "torch/"; path += filename; - return findDataFile(path, false); + return findDataFile(path, required); } TEST(Torch_Importer, simple_read) @@ -274,7 +274,7 @@ TEST_P(Test_Torch_nets, OpenFace_accuracy) net.setPreferableBackend(backend); net.setPreferableTarget(target); - Mat sample = imread(findDataFile("cv/shared/lena.png", false)); + Mat sample = imread(findDataFile("cv/shared/lena.png")); Mat sampleF32(sample.size(), CV_32FC3); sample.convertTo(sampleF32, sampleF32.type()); sampleF32 /= 255; @@ -415,7 +415,7 @@ TEST_P(Test_Torch_nets, FastNeuralStyle_accuracy) net.setPreferableBackend(backend); net.setPreferableTarget(target); - Mat img = imread(findDataFile("dnn/googlenet_1.png", false)); + Mat img = imread(findDataFile("dnn/googlenet_1.png")); Mat inputBlob = blobFromImage(img, 1.0, Size(), Scalar(103.939, 116.779, 123.68), false); net.setInput(inputBlob); diff --git a/modules/objdetect/test/test_qrcode.cpp b/modules/objdetect/test/test_qrcode.cpp index d13fef9654..15474b05aa 100644 --- a/modules/objdetect/test/test_qrcode.cpp +++ b/modules/objdetect/test/test_qrcode.cpp @@ -75,7 +75,7 @@ TEST_P(Objdetect_QRCode, regression) ASSERT_TRUE(qrcode.detect(src, corners)); #endif - const std::string dataset_config = findDataFile(root + "dataset_config.json", false); + const std::string dataset_config = findDataFile(root + "dataset_config.json"); FileStorage file_config(dataset_config, FileStorage::READ); ASSERT_TRUE(file_config.isOpened()) << "Can't read validation data: " << dataset_config; { diff --git a/modules/ts/src/ts.cpp b/modules/ts/src/ts.cpp index 1963988a34..acb7459a48 100644 --- a/modules/ts/src/ts.cpp +++ b/modules/ts/src/ts.cpp @@ -911,25 +911,35 @@ void addDataSearchSubDirectory(const std::string& subdir) static std::string findData(const std::string& relative_path, bool required, bool findDirectory) { -#define TEST_TRY_FILE_WITH_PREFIX(prefix) \ +#define CHECK_FILE_WITH_PREFIX(prefix, result) \ { \ + result.clear(); \ std::string path = path_join(prefix, relative_path); \ /*printf("Trying %s\n", path.c_str());*/ \ if (findDirectory) \ { \ if (isDirectory(path)) \ - return path; \ + result = path; \ } \ else \ { \ FILE* f = fopen(path.c_str(), "rb"); \ if(f) { \ fclose(f); \ - return path; \ + result = path; \ } \ } \ } +#define TEST_TRY_FILE_WITH_PREFIX(prefix) \ +{ \ + std::string result__; \ + CHECK_FILE_WITH_PREFIX(prefix, result__); \ + if (!result__.empty()) \ + return result__; \ +} + + const std::vector& search_path = TS::ptr()->data_search_path; for(size_t i = search_path.size(); i > 0; i--) { @@ -956,7 +966,17 @@ static std::string findData(const std::string& relative_path, bool required, boo { const std::string& subdir = search_subdir[i - 1]; std::string prefix = path_join(datapath, subdir); - TEST_TRY_FILE_WITH_PREFIX(prefix); + std::string result_; + CHECK_FILE_WITH_PREFIX(prefix, result_); +#if 1 // check for misused 'optional' mode + if (!required && !result_.empty()) + { + std::cout << "TEST ERROR: Don't use 'optional' findData() for " << relative_path << std::endl; + CV_Assert(required || result_.empty()); + } +#endif + if (!result_.empty()) + return result_; } } } From 2a6737523919a49d992a564a622a9bb4318c00ea Mon Sep 17 00:00:00 2001 From: Thang Tran Date: Thu, 20 Jun 2019 19:56:23 +0200 Subject: [PATCH 03/19] js: added fillPoly() and fillConvexPoly() --- modules/js/src/embindgen.py | 3 +- modules/js/test/test_imgproc.js | 83 +++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/modules/js/src/embindgen.py b/modules/js/src/embindgen.py index 9319e5f2a4..e4723a6ce6 100644 --- a/modules/js/src/embindgen.py +++ b/modules/js/src/embindgen.py @@ -112,7 +112,8 @@ imgproc = {'': ['Canny', 'GaussianBlur', 'Laplacian', 'HoughLines', 'HoughLinesP 'goodFeaturesToTrack','grabCut','initUndistortRectifyMap', 'integral','integral2', 'isContourConvex', 'line', \ 'matchShapes', 'matchTemplate','medianBlur', 'minAreaRect', 'minEnclosingCircle', 'moments', 'morphologyEx', \ 'pointPolygonTest', 'putText','pyrDown','pyrUp','rectangle','remap', 'resize','sepFilter2D','threshold', \ - 'undistort','warpAffine','warpPerspective','watershed'], + 'undistort','warpAffine','warpPerspective','watershed', \ + 'fillPoly', 'fillConvexPoly'], 'CLAHE': ['apply', 'collectGarbage', 'getClipLimit', 'getTilesGridSize', 'setClipLimit', 'setTilesGridSize']} objdetect = {'': ['groupRectangles'], diff --git a/modules/js/test/test_imgproc.js b/modules/js/test/test_imgproc.js index 15bc56c65c..1f6c4c227d 100644 --- a/modules/js/test/test_imgproc.js +++ b/modules/js/test/test_imgproc.js @@ -201,6 +201,89 @@ QUnit.test('test_imgProc', function(assert) { expected_img.delete(); compare_result.delete(); } + + // fillPoly + { + let img_width = 6; + let img_height = 6; + + let img = new cv.Mat.zeros(img_height, img_width, cv.CV_8UC1); + + let npts = 4; + let square_point_data = new Uint8Array([ + 1, 1, + 4, 1, + 4, 4, + 1, 4]); + let square_points = cv.matFromArray(npts, 1, cv.CV_32SC2, square_point_data); + let pts = new cv.MatVector(); + pts.push_back (square_points); + let color = new cv.Scalar (255); + + let expected_img_data = new Uint8Array([ + 0, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, + 0, 255, 255, 255, 255, 0, + 0, 255, 255, 255, 255, 0, + 0, 255, 255, 255, 255, 0, + 0, 0, 0, 0, 0, 0]); + let expected_img = cv.matFromArray(img_height, img_width, cv.CV_8UC1, expected_img_data); + + cv.fillPoly(img, pts, color); + + let compare_result = new cv.Mat(img_height, img_width, cv.CV_8UC1); + + cv.compare (img, expected_img, compare_result, cv.CMP_EQ); + + // expect every pixels are the same. + assert.equal (cv.countNonZero(compare_result), img.total()); + + img.delete(); + square_points.delete(); + pts.delete(); + expected_img.delete(); + compare_result.delete(); + } + + // fillConvexPoly + { + let img_width = 6; + let img_height = 6; + + let img = new cv.Mat.zeros(img_height, img_width, cv.CV_8UC1); + + let npts = 4; + let square_point_data = new Uint8Array([ + 1, 1, + 4, 1, + 4, 4, + 1, 4]); + let square_points = cv.matFromArray(npts, 1, cv.CV_32SC2, square_point_data); + let color = new cv.Scalar (255); + + let expected_img_data = new Uint8Array([ + 0, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, + 0, 255, 255, 255, 255, 0, + 0, 255, 255, 255, 255, 0, + 0, 255, 255, 255, 255, 0, + 0, 0, 0, 0, 0, 0]); + let expected_img = cv.matFromArray(img_height, img_width, cv.CV_8UC1, expected_img_data); + + cv.fillConvexPoly(img, square_points, color); + + let compare_result = new cv.Mat(img_height, img_width, cv.CV_8UC1); + + cv.compare (img, expected_img, compare_result, cv.CMP_EQ); + + // expect every pixels are the same. + assert.equal (cv.countNonZero(compare_result), img.total()); + + img.delete(); + square_points.delete(); + expected_img.delete(); + compare_result.delete(); + } }); QUnit.test('test_segmentation', function(assert) { From 0ae053fdf820aa7e94c2df25a2344e3dcc45f771 Mon Sep 17 00:00:00 2001 From: Cameron Martin Date: Fri, 12 Apr 2019 00:13:12 +0100 Subject: [PATCH 04/19] js: Add findHomography js bindings. Removed constants from legacy C api and switched out header with shorter version. Removed blank line that was failing CI. --- modules/calib3d/CMakeLists.txt | 4 ++- modules/js/src/embindgen.py | 4 ++- modules/js/test/test_calib3d.js | 43 +++++++++++++++++++++++++++++++++ modules/js/test/tests.html | 1 + modules/js/test/tests.js | 4 ++- platforms/js/build_js.py | 2 +- 6 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 modules/js/test/test_calib3d.js diff --git a/modules/calib3d/CMakeLists.txt b/modules/calib3d/CMakeLists.txt index cba3f811b5..a38fdf18d8 100644 --- a/modules/calib3d/CMakeLists.txt +++ b/modules/calib3d/CMakeLists.txt @@ -3,4 +3,6 @@ set(debug_modules "") if(DEBUG_opencv_calib3d) list(APPEND debug_modules opencv_highgui) endif() -ocv_define_module(calib3d opencv_imgproc opencv_features2d ${debug_modules} WRAP java python) +ocv_define_module(calib3d opencv_imgproc opencv_features2d ${debug_modules} + WRAP java python js +) diff --git a/modules/js/src/embindgen.py b/modules/js/src/embindgen.py index 9319e5f2a4..d3ddb138fb 100644 --- a/modules/js/src/embindgen.py +++ b/modules/js/src/embindgen.py @@ -142,6 +142,8 @@ features2d = {'Feature2D': ['detect', 'compute', 'detectAndCompute', 'descriptor 'BFMatcher': ['isMaskSupported', 'create'], '': ['drawKeypoints', 'drawMatches']} +calib3d = {'': ['findHomography']} + def makeWhiteList(module_list): wl = {} for m in module_list: @@ -152,7 +154,7 @@ def makeWhiteList(module_list): wl[k] = m[k] return wl -white_list = makeWhiteList([core, imgproc, objdetect, video, dnn, features2d]) +white_list = makeWhiteList([core, imgproc, objdetect, video, dnn, features2d, calib3d]) # Features to be exported export_enums = False diff --git a/modules/js/test/test_calib3d.js b/modules/js/test/test_calib3d.js new file mode 100644 index 0000000000..1c8e61086e --- /dev/null +++ b/modules/js/test/test_calib3d.js @@ -0,0 +1,43 @@ +// 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. + +if (typeof module !== 'undefined' && module.exports) { + // The envrionment is Node.js + var cv = require('./opencv.js'); // eslint-disable-line no-var +} + +QUnit.module('Camera Calibration and 3D Reconstruction', {}); + +QUnit.test('constants', function(assert) { + assert.strictEqual(typeof cv.LMEDS, 'number'); + assert.strictEqual(typeof cv.RANSAC, 'number'); + assert.strictEqual(typeof cv.RHO, 'number'); +}); + +QUnit.test('findHomography', function(assert) { + let srcPoints = cv.matFromArray(4, 1, cv.CV_32FC2, [ + 56, + 65, + 368, + 52, + 28, + 387, + 389, + 390, + ]); + let dstPoints = cv.matFromArray(4, 1, cv.CV_32FC2, [ + 0, + 0, + 300, + 0, + 0, + 300, + 300, + 300, + ]); + + const mat = cv.findHomography(srcPoints, dstPoints); + + assert.ok(mat instanceof cv.Mat); +}); diff --git a/modules/js/test/tests.html b/modules/js/test/tests.html index c476dbb3b2..f2f6ad66c7 100644 --- a/modules/js/test/tests.html +++ b/modules/js/test/tests.html @@ -29,6 +29,7 @@ + + + + From e755c66418184769d5aca9d1f60c0963613656ef Mon Sep 17 00:00:00 2001 From: Dal Rupnik Date: Mon, 24 Jun 2019 14:42:03 +0200 Subject: [PATCH 11/19] [#14873] Fix code signing issue in Try Compile script --- platforms/ios/cmake/Toolchains/common-ios-toolchain.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platforms/ios/cmake/Toolchains/common-ios-toolchain.cmake b/platforms/ios/cmake/Toolchains/common-ios-toolchain.cmake index 4da7d79542..13aea357f1 100644 --- a/platforms/ios/cmake/Toolchains/common-ios-toolchain.cmake +++ b/platforms/ios/cmake/Toolchains/common-ios-toolchain.cmake @@ -112,9 +112,9 @@ if(NOT __IN_TRY_COMPILE) message(FATAL_ERROR "Can't prepare xcodebuild_wrapper") endif() if(APPLE_FRAMEWORK AND BUILD_SHARED_LIBS) - set(XCODEBUILD_EXTRA_ARGS "${XCODEBUILD_EXTRA_ARGS} IPHONEOS_DEPLOYMENT_TARGET=${IPHONEOS_DEPLOYMENT_TARGET} -sdk ${CMAKE_OSX_SYSROOT}") + set(XCODEBUILD_EXTRA_ARGS "${XCODEBUILD_EXTRA_ARGS} IPHONEOS_DEPLOYMENT_TARGET=${IPHONEOS_DEPLOYMENT_TARGET} CODE_SIGN_IDENTITY='' CODE_SIGNING_REQUIRED=NO -sdk ${CMAKE_OSX_SYSROOT}") else() - set(XCODEBUILD_EXTRA_ARGS "${XCODEBUILD_EXTRA_ARGS} IPHONEOS_DEPLOYMENT_TARGET=${IPHONEOS_DEPLOYMENT_TARGET} ARCHS=${IOS_ARCH} -sdk ${CMAKE_OSX_SYSROOT}") + set(XCODEBUILD_EXTRA_ARGS "${XCODEBUILD_EXTRA_ARGS} IPHONEOS_DEPLOYMENT_TARGET=${IPHONEOS_DEPLOYMENT_TARGET} CODE_SIGN_IDENTITY='' CODE_SIGNING_REQUIRED=NO ARCHS=${IOS_ARCH} -sdk ${CMAKE_OSX_SYSROOT}") endif() configure_file("${CMAKE_CURRENT_LIST_DIR}/xcodebuild_wrapper.in" "${_xcodebuild_wrapper_tmp}" @ONLY) file(COPY "${_xcodebuild_wrapper_tmp}" DESTINATION ${CMAKE_BINARY_DIR} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) From 4a6888ccf617271333a30e00f239209a26aeef3a Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Tue, 25 Jun 2019 13:42:04 +0300 Subject: [PATCH 12/19] imgproc: fix kmeans() call from grabCut() --- modules/core/src/kmeans.cpp | 2 +- modules/imgproc/src/grabcut.cpp | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/modules/core/src/kmeans.cpp b/modules/core/src/kmeans.cpp index 3f10780cd3..bca8b9bd79 100644 --- a/modules/core/src/kmeans.cpp +++ b/modules/core/src/kmeans.cpp @@ -238,7 +238,7 @@ double cv::kmeans( InputArray _data, int K, attempts = std::max(attempts, 1); CV_Assert( data0.dims <= 2 && type == CV_32F && K > 0 ); - CV_Assert( N >= K ); + CV_CheckGE(N, K, "Number of clusters should be more than number of elements"); Mat data(N, dims, CV_32F, data0.ptr(), isrow ? dims * sizeof(float) : static_cast(data0.step)); diff --git a/modules/imgproc/src/grabcut.cpp b/modules/imgproc/src/grabcut.cpp index d68077de1e..7442066eea 100644 --- a/modules/imgproc/src/grabcut.cpp +++ b/modules/imgproc/src/grabcut.cpp @@ -45,6 +45,8 @@ using namespace cv; +namespace { + /* This is implementation of image segmentation algorithm GrabCut described in "GrabCut - Interactive Foreground Extraction using Iterated Graph Cuts". @@ -228,6 +230,8 @@ void GMM::calcInverseCovAndDeterm(int ci, const double singularFix) } } +} // namespace + /* Calculate beta - parameter of GrabCut algorithm. beta = 1/(2*avg(sqr(||color[i] - color[j]||))) @@ -379,12 +383,20 @@ static void initGMMs( const Mat& img, const Mat& mask, GMM& bgdGMM, GMM& fgdGMM } } CV_Assert( !bgdSamples.empty() && !fgdSamples.empty() ); - Mat _bgdSamples( (int)bgdSamples.size(), 3, CV_32FC1, &bgdSamples[0][0] ); - kmeans( _bgdSamples, GMM::componentsCount, bgdLabels, - TermCriteria( CV_TERMCRIT_ITER, kMeansItCount, 0.0), 0, kMeansType ); - Mat _fgdSamples( (int)fgdSamples.size(), 3, CV_32FC1, &fgdSamples[0][0] ); - kmeans( _fgdSamples, GMM::componentsCount, fgdLabels, - TermCriteria( CV_TERMCRIT_ITER, kMeansItCount, 0.0), 0, kMeansType ); + { + Mat _bgdSamples( (int)bgdSamples.size(), 3, CV_32FC1, &bgdSamples[0][0] ); + int num_clusters = GMM::componentsCount; + num_clusters = std::min(num_clusters, (int)bgdSamples.size()); + kmeans( _bgdSamples, num_clusters, bgdLabels, + TermCriteria( CV_TERMCRIT_ITER, kMeansItCount, 0.0), 0, kMeansType ); + } + { + Mat _fgdSamples( (int)fgdSamples.size(), 3, CV_32FC1, &fgdSamples[0][0] ); + int num_clusters = GMM::componentsCount; + num_clusters = std::min(num_clusters, (int)fgdSamples.size()); + kmeans( _fgdSamples, num_clusters, fgdLabels, + TermCriteria( CV_TERMCRIT_ITER, kMeansItCount, 0.0), 0, kMeansType ); + } bgdGMM.initLearning(); for( int i = 0; i < (int)bgdSamples.size(); i++ ) From e8a703a71dcd0b34499356c70b63e1e42f7fd533 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Tue, 25 Jun 2019 17:24:50 +0300 Subject: [PATCH 13/19] core(intrin): v_load_low() workaround for aarch64+clang --- .../include/opencv2/core/hal/intrin_neon.hpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/modules/core/include/opencv2/core/hal/intrin_neon.hpp b/modules/core/include/opencv2/core/hal/intrin_neon.hpp index 9547a860db..46d347d234 100644 --- a/modules/core/include/opencv2/core/hal/intrin_neon.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_neon.hpp @@ -875,13 +875,27 @@ OPENCV_HAL_IMPL_NEON_ROTATE_OP(v_int64x2, s64) OPENCV_HAL_IMPL_NEON_ROTATE_OP(v_float64x2, f64) #endif +#if defined(__clang__) && defined(__aarch64__) +// avoid LD2 instruction. details: https://github.com/opencv/opencv/issues/14863 +#define OPENCV_HAL_IMPL_NEON_LOAD_LOW_OP(_Tpvec, _Tp, suffix) \ +inline _Tpvec v_load_low(const _Tp* ptr) \ +{ \ +typedef uint64 CV_DECL_ALIGNED(1) unaligned_uint64; \ +uint64 v = *(unaligned_uint64*)ptr; \ +return _Tpvec(v_reinterpret_as_##suffix(v_uint64x2(v, (uint64)123456))); \ +} +#else +#define OPENCV_HAL_IMPL_NEON_LOAD_LOW_OP(_Tpvec, _Tp, suffix) \ +inline _Tpvec v_load_low(const _Tp* ptr) \ +{ return _Tpvec(vcombine_##suffix(vld1_##suffix(ptr), vdup_n_##suffix((_Tp)0))); } +#endif + #define OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(_Tpvec, _Tp, suffix) \ inline _Tpvec v_load(const _Tp* ptr) \ { return _Tpvec(vld1q_##suffix(ptr)); } \ inline _Tpvec v_load_aligned(const _Tp* ptr) \ { return _Tpvec(vld1q_##suffix(ptr)); } \ -inline _Tpvec v_load_low(const _Tp* ptr) \ -{ return _Tpvec(vcombine_##suffix(vld1_##suffix(ptr), vdup_n_##suffix((_Tp)0))); } \ +OPENCV_HAL_IMPL_NEON_LOAD_LOW_OP(_Tpvec, _Tp, suffix) \ inline _Tpvec v_load_halves(const _Tp* ptr0, const _Tp* ptr1) \ { return _Tpvec(vcombine_##suffix(vld1_##suffix(ptr0), vld1_##suffix(ptr1))); } \ inline void v_store(_Tp* ptr, const _Tpvec& a) \ From f3e9eb33718f47a6e55fb5c646da9a8935d103c6 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Tue, 25 Jun 2019 18:03:04 +0300 Subject: [PATCH 14/19] dnn: both protobuf readers have similar behavior - ReadProtoFromTextFile - ReadProtoFromTextBuffer --- modules/dnn/src/caffe/caffe_io.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/dnn/src/caffe/caffe_io.cpp b/modules/dnn/src/caffe/caffe_io.cpp index 501e49e72f..e3f1113242 100644 --- a/modules/dnn/src/caffe/caffe_io.cpp +++ b/modules/dnn/src/caffe/caffe_io.cpp @@ -1137,7 +1137,12 @@ bool ReadProtoFromBinaryFile(const char* filename, Message* proto) { bool ReadProtoFromTextBuffer(const char* data, size_t len, Message* proto) { ArrayInputStream input(data, len); - return google::protobuf::TextFormat::Parse(&input, proto); +#ifndef OPENCV_DNN_EXTERNAL_PROTOBUF + return google::protobuf::TextFormat::Parser(true).Parse(&input, proto); +#else + return google::protobuf::TextFormat::Parser().Parse(&input, proto); +#endif + } From 333e51b2171f51f6a75b49958038b76c51afd67c Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Wed, 26 Jun 2019 06:41:01 +0000 Subject: [PATCH 15/19] dnn: configure plugin path for InferenceEngine --- modules/dnn/src/op_inf_engine.cpp | 52 +++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/modules/dnn/src/op_inf_engine.cpp b/modules/dnn/src/op_inf_engine.cpp index a24273338e..3f96a1db37 100644 --- a/modules/dnn/src/op_inf_engine.cpp +++ b/modules/dnn/src/op_inf_engine.cpp @@ -409,6 +409,14 @@ void InfEngineBackendNet::initPlugin(InferenceEngine::ICNNNetwork& net) enginePtr = dispatcher.getSuitablePlugin(targetDevice); sharedPlugins[targetDevice] = enginePtr; + std::vector candidates; + + std::string param_pluginPath = utils::getConfigurationParameterString("OPENCV_DNN_IE_EXTRA_PLUGIN_PATH", ""); + if (!param_pluginPath.empty()) + { + candidates.push_back(param_pluginPath); + } + if (targetDevice == InferenceEngine::TargetDevice::eCPU || targetDevice == InferenceEngine::TargetDevice::eFPGA) { @@ -422,24 +430,36 @@ void InfEngineBackendNet::initPlugin(InferenceEngine::ICNNNetwork& net) { if (!haveFeature[i]) continue; - #ifdef _WIN32 - std::string libName = "cpu_extension" + suffixes[i] + ".dll"; - #elif defined(__APPLE__) - std::string libName = "libcpu_extension" + suffixes[i] + ".dylib"; - #else - std::string libName = "libcpu_extension" + suffixes[i] + ".so"; - #endif // _WIN32 - try - { - InferenceEngine::IExtensionPtr extension = - InferenceEngine::make_so_pointer(libName); - enginePtr->AddExtension(extension, 0); - break; - } - catch(...) {} +#ifdef _WIN32 + candidates.push_back("cpu_extension" + suffixes[i] + ".dll"); +#elif defined(__APPLE__) + candidates.push_back("libcpu_extension" + suffixes[i] + ".so"); // built as loadable module + candidates.push_back("libcpu_extension" + suffixes[i] + ".dylib"); // built as shared library +#else + candidates.push_back("libcpu_extension" + suffixes[i] + ".so"); +#endif // _WIN32 } - // Some of networks can work without a library of extra layers. } + bool found = false; + for (size_t i = 0; i != candidates.size(); ++i) + { + const std::string& libName = candidates[i]; + try + { + InferenceEngine::IExtensionPtr extension = + InferenceEngine::make_so_pointer(libName); + enginePtr->AddExtension(extension, 0); + CV_LOG_INFO(NULL, "DNN-IE: Loaded extension plugin: " << libName); + found = true; + break; + } + catch(...) {} + } + if (!found && !candidates.empty()) + { + CV_LOG_WARNING(NULL, "DNN-IE: Can't load extension plugin (extra layers for some networks). Specify path via OPENCV_DNN_IE_EXTRA_PLUGIN_PATH parameter"); + } + // Some of networks can work without a library of extra layers. } plugin = InferenceEngine::InferencePlugin(enginePtr); From daa308f81c8c114f06b93b834313db9acd3f71e0 Mon Sep 17 00:00:00 2001 From: James Bowley Date: Mon, 10 Jun 2019 17:42:37 +0100 Subject: [PATCH 16/19] Update obsolete flag in Intel video decoder. Old flag resulted in software implementation being selected when the Intel decoder is not the primary adapter. --- modules/videoio/src/cap_mfx_common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/videoio/src/cap_mfx_common.cpp b/modules/videoio/src/cap_mfx_common.cpp index 705d180687..55c2450b80 100644 --- a/modules/videoio/src/cap_mfx_common.cpp +++ b/modules/videoio/src/cap_mfx_common.cpp @@ -17,7 +17,7 @@ using namespace cv; bool DeviceHandler::init(MFXVideoSession &session) { mfxStatus res = MFX_ERR_NONE; - mfxIMPL impl = MFX_IMPL_AUTO; + mfxIMPL impl = MFX_IMPL_AUTO_ANY; mfxVersion ver = { {19, 1} }; res = session.Init(impl, &ver); From 411ca87a86434570dae2adb6c62240d3c1956c5b Mon Sep 17 00:00:00 2001 From: Dmitry Kurtaev Date: Wed, 26 Jun 2019 17:27:56 +0300 Subject: [PATCH 17/19] Remove extra ")" --- samples/dnn/js_face_recognition.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/dnn/js_face_recognition.html b/samples/dnn/js_face_recognition.html index 27b74c9ec0..daf47b82fe 100644 --- a/samples/dnn/js_face_recognition.html +++ b/samples/dnn/js_face_recognition.html @@ -190,7 +190,7 @@ function main() { // Load opencv.js cv['onRuntimeInitialized']=()=>{ main(); -}); +}; From 5b521bb7785456376366ca5558eb0ac7b0c172b8 Mon Sep 17 00:00:00 2001 From: Apoorv Goel <35146783+UnderscoreAsterisk@users.noreply.github.com> Date: Wed, 26 Jun 2019 19:35:11 +0300 Subject: [PATCH 18/19] Merge pull request #14898 from UnderscoreAsterisk:flann-warnings-and-4376 Keep a local copy of `features` from `flann::GenericIndex ` constructor (#14898) * Fix warnings on Windows * Fix #4376 --- modules/flann/include/opencv2/flann.hpp | 6 ++++-- modules/flann/include/opencv2/flann/dist.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/flann/include/opencv2/flann.hpp b/modules/flann/include/opencv2/flann.hpp index fec3d067c8..050b5f7f58 100644 --- a/modules/flann/include/opencv2/flann.hpp +++ b/modules/flann/include/opencv2/flann.hpp @@ -289,7 +289,7 @@ public: int veclen() const { return nnIndex->veclen(); } - int size() const { return nnIndex->size(); } + int size() const { return (int)nnIndex->size(); } ::cvflann::IndexParams getParameters() { return nnIndex->getParameters(); } @@ -297,6 +297,7 @@ public: private: ::cvflann::Index* nnIndex; + Mat _dataset; }; //! @cond IGNORED @@ -312,10 +313,11 @@ private: template GenericIndex::GenericIndex(const Mat& dataset, const ::cvflann::IndexParams& params, Distance distance) +: _dataset(dataset) { CV_Assert(dataset.type() == CvType::type()); CV_Assert(dataset.isContinuous()); - ::cvflann::Matrix m_dataset((ElementType*)dataset.ptr(0), dataset.rows, dataset.cols); + ::cvflann::Matrix m_dataset((ElementType*)_dataset.ptr(0), _dataset.rows, _dataset.cols); nnIndex = new ::cvflann::Index(m_dataset, params, distance); diff --git a/modules/flann/include/opencv2/flann/dist.h b/modules/flann/include/opencv2/flann/dist.h index 2bb4fc947a..0670122c16 100644 --- a/modules/flann/include/opencv2/flann/dist.h +++ b/modules/flann/include/opencv2/flann/dist.h @@ -114,7 +114,7 @@ struct L2_Simple ResultType result = ResultType(); ResultType diff; for(size_t i = 0; i < size; ++i ) { - diff = *a++ - *b++; + diff = (ResultType)(*a++ - *b++); result += diff*diff; } return result; From 24790e4061c8b92667087b8fa32ea8478785a64b Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Wed, 26 Jun 2019 23:04:26 +0300 Subject: [PATCH 19/19] Merge pull request #14899 from alalek:dnn_fix_bnll_layer * dnn: fix BNLLLayer implementation details: https://github.com/BVLC/caffe/blame/1.0/src/caffe/layers/bnll_layer.cpp#L17 * dnn: enable OCV/OpenCL BNLL layer --- modules/dnn/src/layers/elementwise_layers.cpp | 30 ++++++++++++++++--- modules/dnn/src/opencl/activations.cl | 3 +- modules/dnn/test/test_halide_layers.cpp | 5 ++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/modules/dnn/src/layers/elementwise_layers.cpp b/modules/dnn/src/layers/elementwise_layers.cpp index 762afdd3d0..dd250d8c8c 100644 --- a/modules/dnn/src/layers/elementwise_layers.cpp +++ b/modules/dnn/src/layers/elementwise_layers.cpp @@ -771,7 +771,8 @@ struct BNLLFunctor for( int i = 0; i < len; i++ ) { float x = srcptr[i]; - dstptr[i] = log(1.f + exp(-abs(x))); + // https://github.com/BVLC/caffe/blame/1.0/src/caffe/layers/bnll_layer.cpp#L17 + dstptr[i] = x > 0 ? x + log(1. + exp(-x)) : log(1. + exp(x)); } } } @@ -779,8 +780,28 @@ struct BNLLFunctor #ifdef HAVE_OPENCL bool applyOCL(InputArrayOfArrays inps, OutputArrayOfArrays outs, OutputArrayOfArrays internals) { - // TODO: implement OCL version - return false; + std::vector inputs; + std::vector outputs; + + inps.getUMatVector(inputs); + outs.getUMatVector(outputs); + String buildopt = oclGetTMacro(inputs[0]); + + for (size_t i = 0; i < inputs.size(); i++) + { + UMat& src = inputs[i]; + UMat& dst = outputs[i]; + + ocl::Kernel kernel("BNLLForward", ocl::dnn::activations_oclsrc, buildopt); + kernel.set(0, (int)src.total()); + kernel.set(1, ocl::KernelArg::PtrReadOnly(src)); + kernel.set(2, ocl::KernelArg::PtrWriteOnly(dst)); + + size_t gSize = src.total(); + CV_Assert(kernel.run(1, &gSize, NULL, false)); + } + + return true; } #endif @@ -788,7 +809,8 @@ struct BNLLFunctor void attachHalide(const Halide::Expr& input, Halide::Func& top) { Halide::Var x("x"), y("y"), c("c"), n("n"); - top(x, y, c, n) = log(1.0f + exp(-abs(input))); + // https://github.com/BVLC/caffe/blame/1.0/src/caffe/layers/bnll_layer.cpp#L17 + top(x, y, c, n) = max(input, 0) + log(1.0f + exp(-abs(input))); } #endif // HAVE_HALIDE diff --git a/modules/dnn/src/opencl/activations.cl b/modules/dnn/src/opencl/activations.cl index 9b5a9bb322..ff9d2401d3 100644 --- a/modules/dnn/src/opencl/activations.cl +++ b/modules/dnn/src/opencl/activations.cl @@ -98,7 +98,8 @@ __kernel void SigmoidForward(const int count, __global const T* in, __global T* __kernel void BNLLForward(const int n, __global const T* in, __global T* out) { int index = get_global_id(0); if (index < n) { - out[index] = in[index] > 0 ? in[index] + log(1.0f + exp(-in[index])) : log(1.0f + exp(in[index])); + T x = in[index]; + out[index] = x > 0 ? x + log(1.0f + exp(-x)) : log(1.0f + exp(x)); } } diff --git a/modules/dnn/test/test_halide_layers.cpp b/modules/dnn/test/test_halide_layers.cpp index 42f67f4817..d019b1d1ed 100644 --- a/modules/dnn/test/test_halide_layers.cpp +++ b/modules/dnn/test/test_halide_layers.cpp @@ -34,6 +34,11 @@ static void test(Mat& input, Net& net, Backend backendId, Target targetId, bool double l1, lInf; DNNTestLayer::getDefaultThresholds(backendId, targetId, &l1, &lInf); +#if 0 + std::cout << "l1=" << l1 << " lInf=" << lInf << std::endl; + std::cout << outputDefault.reshape(1, outputDefault.total()).t() << std::endl; + std::cout << outputHalide.reshape(1, outputDefault.total()).t() << std::endl; +#endif normAssert(outputDefault, outputHalide, "", l1, lInf); }