From 6203c95d317e03bdc789e6cb48c79342eccdee87 Mon Sep 17 00:00:00 2001 From: Hamdi Sahloul Date: Tue, 18 Sep 2018 22:37:51 +0900 Subject: [PATCH 01/19] cuda::polarToCart: Support double precision --- modules/cudaarithm/src/cuda/polar_cart.cu | 73 +++++++++++++++-------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/modules/cudaarithm/src/cuda/polar_cart.cu b/modules/cudaarithm/src/cuda/polar_cart.cu index 0a949b42ed1f..2fb1315e619b 100644 --- a/modules/cudaarithm/src/cuda/polar_cart.cu +++ b/modules/cudaarithm/src/cuda/polar_cart.cu @@ -157,8 +157,23 @@ void cv::cuda::cartToPolar(InputArray _x, InputArray _y, OutputArray _mag, Outpu namespace { - template - __global__ void polarToCartImpl(const GlobPtr mag, const GlobPtr angle, GlobPtr xmat, GlobPtr ymat, const float scale, const int rows, const int cols) + template struct sincos_op + { + __device__ __forceinline__ void operator()(T a, T *sptr, T *cptr) const + { + ::sincos(a, sptr, cptr); + } + }; + template <> struct sincos_op + { + __device__ __forceinline__ void operator()(float a, float *sptr, float *cptr) const + { + ::sincosf(a, sptr, cptr); + } + }; + + template + __global__ void polarToCartImpl_(const GlobPtr mag, const GlobPtr angle, GlobPtr xmat, GlobPtr ymat, const T scale, const int rows, const int cols) { const int x = blockDim.x * blockIdx.x + threadIdx.x; const int y = blockDim.y * blockIdx.y + threadIdx.y; @@ -166,45 +181,53 @@ namespace if (x >= cols || y >= rows) return; - const float mag_val = useMag ? mag(y, x) : 1.0f; - const float angle_val = angle(y, x); + const T mag_val = useMag ? mag(y, x) : static_cast(1.0); + const T angle_val = angle(y, x); - float sin_a, cos_a; - ::sincosf(scale * angle_val, &sin_a, &cos_a); + T sin_a, cos_a; + sincos_op op; + op(scale * angle_val, &sin_a, &cos_a); xmat(y, x) = mag_val * cos_a; ymat(y, x) = mag_val * sin_a; } + + template + void polarToCartImpl(const GpuMat& mag, const GpuMat& angle, GpuMat& x, GpuMat& y, bool angleInDegrees, cudaStream_t& stream) + { + GpuMat_ xc(x.reshape(1)); + GpuMat_ yc(y.reshape(1)); + GpuMat_ magc(mag.reshape(1)); + GpuMat_ anglec(angle.reshape(1)); + + const dim3 block(32, 8); + const dim3 grid(divUp(anglec.cols, block.x), divUp(anglec.rows, block.y)); + + const T scale = angleInDegrees ? static_cast(CV_PI / 180.0) : static_cast(1.0); + + if (magc.empty()) + polarToCartImpl_ << > >(shrinkPtr(magc), shrinkPtr(anglec), shrinkPtr(xc), shrinkPtr(yc), scale, anglec.rows, anglec.cols); + else + polarToCartImpl_ << > >(shrinkPtr(magc), shrinkPtr(anglec), shrinkPtr(xc), shrinkPtr(yc), scale, anglec.rows, anglec.cols); + } } void cv::cuda::polarToCart(InputArray _mag, InputArray _angle, OutputArray _x, OutputArray _y, bool angleInDegrees, Stream& _stream) { + typedef void(*func_t)(const GpuMat& mag, const GpuMat& angle, GpuMat& x, GpuMat& y, bool angleInDegrees, cudaStream_t& stream); + static const func_t funcs[7] = { 0, 0, 0, 0, 0, polarToCartImpl, polarToCartImpl }; + GpuMat mag = getInputMat(_mag, _stream); GpuMat angle = getInputMat(_angle, _stream); - CV_Assert( angle.depth() == CV_32F ); + CV_Assert(angle.depth() == CV_32F || angle.depth() == CV_64F); CV_Assert( mag.empty() || (mag.type() == angle.type() && mag.size() == angle.size()) ); - GpuMat x = getOutputMat(_x, angle.size(), CV_32FC1, _stream); - GpuMat y = getOutputMat(_y, angle.size(), CV_32FC1, _stream); - - GpuMat_ xc(x.reshape(1)); - GpuMat_ yc(y.reshape(1)); - GpuMat_ magc(mag.reshape(1)); - GpuMat_ anglec(angle.reshape(1)); - - const dim3 block(32, 8); - const dim3 grid(divUp(anglec.cols, block.x), divUp(anglec.rows, block.y)); - - const float scale = angleInDegrees ? (CV_PI_F / 180.0f) : 1.0f; + GpuMat x = getOutputMat(_x, angle.size(), CV_MAKETYPE(angle.depth(), 1), _stream); + GpuMat y = getOutputMat(_y, angle.size(), CV_MAKETYPE(angle.depth(), 1), _stream); cudaStream_t stream = StreamAccessor::getStream(_stream); - - if (magc.empty()) - polarToCartImpl<<>>(shrinkPtr(magc), shrinkPtr(anglec), shrinkPtr(xc), shrinkPtr(yc), scale, anglec.rows, anglec.cols); - else - polarToCartImpl<<>>(shrinkPtr(magc), shrinkPtr(anglec), shrinkPtr(xc), shrinkPtr(yc), scale, anglec.rows, anglec.cols); - + funcs[angle.depth()](mag, angle, x, y, angleInDegrees, stream); CV_CUDEV_SAFE_CALL( cudaGetLastError() ); syncOutput(x, _x, _stream); From 99326123733dfa9a24cc8c1dac4bc402310e0b06 Mon Sep 17 00:00:00 2001 From: Hamdi Sahloul Date: Tue, 18 Sep 2018 22:38:07 +0900 Subject: [PATCH 02/19] cuda::polarToCart: test double precision and tune tolerance --- .../perf/perf_element_operations.cpp | 11 ++++++---- .../test/test_element_operations.cpp | 22 +++++++++++-------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/modules/cudaarithm/perf/perf_element_operations.cpp b/modules/cudaarithm/perf/perf_element_operations.cpp index 02f412d9949c..9aa2d4e4e0f9 100644 --- a/modules/cudaarithm/perf/perf_element_operations.cpp +++ b/modules/cudaarithm/perf/perf_element_operations.cpp @@ -1346,6 +1346,7 @@ PERF_TEST_P(Sz, MagnitudeSqr, // Phase DEF_PARAM_TEST(Sz_AngleInDegrees, cv::Size, bool); +DEF_PARAM_TEST(Sz_Type_AngleInDegrees, cv::Size, MatType, bool); PERF_TEST_P(Sz_AngleInDegrees, Phase, Combine(CUDA_TYPICAL_MAT_SIZES, @@ -1423,17 +1424,19 @@ PERF_TEST_P(Sz_AngleInDegrees, CartToPolar, ////////////////////////////////////////////////////////////////////// // PolarToCart -PERF_TEST_P(Sz_AngleInDegrees, PolarToCart, +PERF_TEST_P(Sz_Type_AngleInDegrees, PolarToCart, Combine(CUDA_TYPICAL_MAT_SIZES, + testing::Values(CV_32FC1, CV_64FC1), Bool())) { const cv::Size size = GET_PARAM(0); - const bool angleInDegrees = GET_PARAM(1); + const int type = GET_PARAM(1); + const bool angleInDegrees = GET_PARAM(2); - cv::Mat magnitude(size, CV_32FC1); + cv::Mat magnitude(size, type); declare.in(magnitude, WARMUP_RNG); - cv::Mat angle(size, CV_32FC1); + cv::Mat angle(size, type); declare.in(angle, WARMUP_RNG); if (PERF_RUN_CUDA()) diff --git a/modules/cudaarithm/test/test_element_operations.cpp b/modules/cudaarithm/test/test_element_operations.cpp index cf133024e4bd..9d20046df975 100644 --- a/modules/cudaarithm/test/test_element_operations.cpp +++ b/modules/cudaarithm/test/test_element_operations.cpp @@ -2754,10 +2754,11 @@ INSTANTIATE_TEST_CASE_P(CUDA_Arithm, CartToPolar, testing::Combine( //////////////////////////////////////////////////////////////////////////////// // polarToCart -PARAM_TEST_CASE(PolarToCart, cv::cuda::DeviceInfo, cv::Size, AngleInDegrees, UseRoi) +PARAM_TEST_CASE(PolarToCart, cv::cuda::DeviceInfo, cv::Size, MatType, AngleInDegrees, UseRoi) { cv::cuda::DeviceInfo devInfo; cv::Size size; + int type; bool angleInDegrees; bool useRoi; @@ -2765,8 +2766,9 @@ PARAM_TEST_CASE(PolarToCart, cv::cuda::DeviceInfo, cv::Size, AngleInDegrees, Use { devInfo = GET_PARAM(0); size = GET_PARAM(1); - angleInDegrees = GET_PARAM(2); - useRoi = GET_PARAM(3); + type = GET_PARAM(2); + angleInDegrees = GET_PARAM(3); + useRoi = GET_PARAM(4); cv::cuda::setDevice(devInfo.deviceID()); } @@ -2774,24 +2776,26 @@ PARAM_TEST_CASE(PolarToCart, cv::cuda::DeviceInfo, cv::Size, AngleInDegrees, Use CUDA_TEST_P(PolarToCart, Accuracy) { - cv::Mat magnitude = randomMat(size, CV_32FC1); - cv::Mat angle = randomMat(size, CV_32FC1); + cv::Mat magnitude = randomMat(size, type); + cv::Mat angle = randomMat(size, type); + const double tol = (type == CV_32FC1 ? 1.6e-4 : 1e-4) * (angleInDegrees ? 1.0 : 19.0); - cv::cuda::GpuMat x = createMat(size, CV_32FC1, useRoi); - cv::cuda::GpuMat y = createMat(size, CV_32FC1, useRoi); + cv::cuda::GpuMat x = createMat(size, type, useRoi); + cv::cuda::GpuMat y = createMat(size, type, useRoi); cv::cuda::polarToCart(loadMat(magnitude, useRoi), loadMat(angle, useRoi), x, y, angleInDegrees); cv::Mat x_gold; cv::Mat y_gold; cv::polarToCart(magnitude, angle, x_gold, y_gold, angleInDegrees); - EXPECT_MAT_NEAR(x_gold, x, 1e-4); - EXPECT_MAT_NEAR(y_gold, y, 1e-4); + EXPECT_MAT_NEAR(x_gold, x, tol); + EXPECT_MAT_NEAR(y_gold, y, tol); } INSTANTIATE_TEST_CASE_P(CUDA_Arithm, PolarToCart, testing::Combine( ALL_DEVICES, DIFFERENT_SIZES, + testing::Values(CV_32FC1, CV_64FC1), testing::Values(AngleInDegrees(false), AngleInDegrees(true)), WHOLE_SUBMAT)); From 5db13fe2a7750592e829d4a4ec4c39ea03e948d2 Mon Sep 17 00:00:00 2001 From: Hamdi Sahloul Date: Sat, 22 Sep 2018 06:58:44 +0900 Subject: [PATCH 03/19] cuda::polarToCart: update documentation --- modules/cudaarithm/include/opencv2/cudaarithm.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/cudaarithm/include/opencv2/cudaarithm.hpp b/modules/cudaarithm/include/opencv2/cudaarithm.hpp index a482b49fcfd1..d040bb11f0d9 100644 --- a/modules/cudaarithm/include/opencv2/cudaarithm.hpp +++ b/modules/cudaarithm/include/opencv2/cudaarithm.hpp @@ -415,10 +415,10 @@ CV_EXPORTS void cartToPolar(InputArray x, InputArray y, OutputArray magnitude, O /** @brief Converts polar coordinates into Cartesian. -@param magnitude Source matrix containing magnitudes ( CV_32FC1 ). -@param angle Source matrix containing angles ( CV_32FC1 ). -@param x Destination matrix of real components ( CV_32FC1 ). -@param y Destination matrix of imaginary components ( CV_32FC1 ). +@param magnitude Source matrix containing magnitudes ( CV_32FC1 or CV_64FC1 ). +@param angle Source matrix containing angles ( same type as magnitude ). +@param x Destination matrix of real components ( same type as magnitude ). +@param y Destination matrix of imaginary components ( same type as magnitude ). @param angleInDegrees Flag that indicates angles in degrees. @param stream Stream for the asynchronous version. */ From 93b0b03447dbe594135e690b0e952d05da39aa5b Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Mon, 24 Sep 2018 11:34:03 +0300 Subject: [PATCH 04/19] docs: DOXYGEN_BLACKLIST CMake variable for modules exclusion --- doc/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 7fd97b1d244d..94dff9e76202 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -14,6 +14,7 @@ if(DOXYGEN_FOUND) add_custom_target(doxygen) # not documented modules list + set(blacklist "${DOXYGEN_BLACKLIST}") list(APPEND blacklist "ts" "java_bindings_generator" "java" "python_bindings_generator" "python2" "python3" "js" "world") unset(CMAKE_DOXYGEN_TUTORIAL_CONTRIB_ROOT) unset(CMAKE_DOXYGEN_TUTORIAL_JS_ROOT) From 9f0ff03da511a39daf7dd256bea69e4f992f77ce Mon Sep 17 00:00:00 2001 From: Peter Whidden Date: Thu, 27 Sep 2018 14:37:59 -0700 Subject: [PATCH 05/19] Fix typo "wit" -> "with" --- doc/tutorials/imgproc/pyramids/pyramids.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorials/imgproc/pyramids/pyramids.markdown b/doc/tutorials/imgproc/pyramids/pyramids.markdown index 9b507e604eac..90cb5652b05a 100644 --- a/doc/tutorials/imgproc/pyramids/pyramids.markdown +++ b/doc/tutorials/imgproc/pyramids/pyramids.markdown @@ -56,7 +56,7 @@ Theory entire pyramid. - The procedure above was useful to downsample an image. What if we want to make it bigger?: columns filled with zeros (\f$0 \f$) - - First, upsize the image to twice the original in each dimension, wit the new even rows and + - First, upsize the image to twice the original in each dimension, with the new even rows and - Perform a convolution with the same kernel shown above (multiplied by 4) to approximate the values of the "missing pixels" - These two procedures (downsampling and upsampling as explained above) are implemented by the From e9f99063c70699e48a7589f2958b348189d3b494 Mon Sep 17 00:00:00 2001 From: Dmitry Kurtaev Date: Wed, 26 Sep 2018 19:11:40 +0300 Subject: [PATCH 06/19] JavaScript bindings for features2d module --- modules/features2d/CMakeLists.txt | 2 +- .../features2d/include/opencv2/features2d.hpp | 4 +++ modules/js/src/embindgen.py | 27 ++++++++++++++----- platforms/js/build_js.py | 2 +- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/modules/features2d/CMakeLists.txt b/modules/features2d/CMakeLists.txt index 2a6456f69b67..f18f69edb397 100644 --- a/modules/features2d/CMakeLists.txt +++ b/modules/features2d/CMakeLists.txt @@ -1,2 +1,2 @@ set(the_description "2D Features Framework") -ocv_define_module(features2d opencv_imgproc OPTIONAL opencv_flann opencv_highgui WRAP java python) +ocv_define_module(features2d opencv_imgproc OPTIONAL opencv_flann opencv_highgui WRAP java python js) diff --git a/modules/features2d/include/opencv2/features2d.hpp b/modules/features2d/include/opencv2/features2d.hpp index 1ba4f0da2618..ee81ebe38562 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -137,7 +137,11 @@ class CV_EXPORTS KeyPointsFilter /** @brief Abstract base class for 2D image feature detectors and descriptor extractors */ +#ifdef __EMSCRIPTEN__ +class CV_EXPORTS_W Feature2D : public Algorithm +#else class CV_EXPORTS_W Feature2D : public virtual Algorithm +#endif { public: virtual ~Feature2D(); diff --git a/modules/js/src/embindgen.py b/modules/js/src/embindgen.py index 2e9811ada2d0..caa8d6067e24 100644 --- a/modules/js/src/embindgen.py +++ b/modules/js/src/embindgen.py @@ -126,7 +126,22 @@ 'BackgroundSubtractor': ['apply', 'getBackgroundImage']} dnn = {'dnn_Net': ['setInput', 'forward'], - '': ['readNetFromCaffe', 'readNetFromTensorflow', 'readNetFromTorch', 'readNetFromDarknet', 'blobFromImage']} + '': ['readNetFromCaffe', 'readNetFromTensorflow', 'readNetFromTorch', 'readNetFromDarknet', + 'readNetFromONNX', 'readNet', 'blobFromImage']} + +features2d = {'Feature2D': ['detect', 'compute', 'detectAndCompute', 'descriptorSize', 'descriptorType', 'defaultNorm', 'empty', 'getDefaultName'], + 'BRISK': ['create', 'getDefaultName'], + 'ORB': ['create', 'setMaxFeatures', 'setScaleFactor', 'setNLevels', 'setEdgeThreshold', 'setFirstLevel', 'setWTA_K', 'setScoreType', 'setPatchSize', 'getFastThreshold', 'getDefaultName'], + 'MSER': ['create', 'detectRegions', 'setDelta', 'getDelta', 'setMinArea', 'getMinArea', 'setMaxArea', 'getMaxArea', 'setPass2Only', 'getPass2Only', 'getDefaultName'], + 'FastFeatureDetector': ['create', 'setThreshold', 'getThreshold', 'setNonmaxSuppression', 'getNonmaxSuppression', 'setType', 'getType', 'getDefaultName'], + 'AgastFeatureDetector': ['create', 'setThreshold', 'getThreshold', 'setNonmaxSuppression', 'getNonmaxSuppression', 'setType', 'getType', 'getDefaultName'], + 'GFTTDetector': ['create', 'setMaxFeatures', 'getMaxFeatures', 'setQualityLevel', 'getQualityLevel', 'setMinDistance', 'getMinDistance', 'setBlockSize', 'getBlockSize', 'setHarrisDetector', 'getHarrisDetector', 'setK', 'getK', 'getDefaultName'], + # 'SimpleBlobDetector': ['create'], + 'KAZE': ['create', 'setExtended', 'getExtended', 'setUpright', 'getUpright', 'setThreshold', 'getThreshold', 'setNOctaves', 'getNOctaves', 'setNOctaveLayers', 'getNOctaveLayers', 'setDiffusivity', 'getDiffusivity', 'getDefaultName'], + 'AKAZE': ['create', 'setDescriptorType', 'getDescriptorType', 'setDescriptorSize', 'getDescriptorSize', 'setDescriptorChannels', 'getDescriptorChannels', 'setThreshold', 'getThreshold', 'setNOctaves', 'getNOctaves', 'setNOctaveLayers', 'getNOctaveLayers', 'setDiffusivity', 'getDiffusivity', 'getDefaultName'], + 'DescriptorMatcher': ['add', 'clear', 'empty', 'isMaskSupported', 'train', 'match', 'knnMatch', 'radiusMatch', 'clone', 'create'], + 'BFMatcher': ['isMaskSupported', 'create'], + '': ['FAST', 'AGAST', 'drawKeypoints', 'drawMatches']} def makeWhiteList(module_list): wl = {} @@ -138,7 +153,7 @@ def makeWhiteList(module_list): wl[k] = m[k] return wl -white_list = makeWhiteList([core, imgproc, objdetect, video, dnn]) +white_list = makeWhiteList([core, imgproc, objdetect, video, dnn, features2d]) # Features to be exported export_enums = False @@ -219,7 +234,8 @@ def handle_ptr(tp): def handle_vector(tp): if tp.startswith('vector_'): - tp = 'std::vector<' + "::".join(tp.split('_')[1:]) + '>' + tp = handle_vector(tp[tp.find('_') + 1:]) + tp = 'std::vector<' + "::".join(tp.split('_')) + '>' return tp @@ -845,13 +861,12 @@ def gen(self, dst_file, src_files, core_bindings): [class_info.cname, property.name]))) dv = '' - base = Template("""base<$base$isPoly>""") + base = Template("""base<$base>""") assert len(class_info.bases) <= 1 , "multiple inheritance not supported" if len(class_info.bases) == 1: - dv = "," + base.substitute(base=', '.join(class_info.bases), - isPoly = " ,true" if class_info.name=="Feature2D" else "") + dv = "," + base.substitute(base=', '.join(class_info.bases)) self.bindings.append(class_template.substitute(cpp_name=class_info.cname, js_name=name, diff --git a/platforms/js/build_js.py b/platforms/js/build_js.py index 3ff69c05e542..3cdce4aa2b51 100644 --- a/platforms/js/build_js.py +++ b/platforms/js/build_js.py @@ -131,7 +131,7 @@ def get_cmake_cmd(self): "-DBUILD_opencv_apps=OFF", "-DBUILD_opencv_calib3d=OFF", "-DBUILD_opencv_dnn=ON", - "-DBUILD_opencv_features2d=OFF", + "-DBUILD_opencv_features2d=ON", "-DBUILD_opencv_flann=OFF", "-DBUILD_opencv_ml=OFF", "-DBUILD_opencv_photo=OFF", From 3c5a6be835551afabebb14b00b8a1beb820cbddd Mon Sep 17 00:00:00 2001 From: Andrew Mroczkowski Date: Wed, 26 Sep 2018 17:20:37 -0400 Subject: [PATCH 07/19] Fix Xcode version parsing error (affects bitcode generation) The regex was only parsing for a single digit in the major version, causing Xcode 10 to be treated as version "1". Other parts of the script only turn on bitcode generation if the Xcode version is > 7. --- platforms/ios/build_framework.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platforms/ios/build_framework.py b/platforms/ios/build_framework.py index d624e08d90c2..f546c6af5d95 100755 --- a/platforms/ios/build_framework.py +++ b/platforms/ios/build_framework.py @@ -39,10 +39,11 @@ def execute(cmd, cwd = None): def getXCodeMajor(): ret = check_output(["xcodebuild", "-version"]) - m = re.match(r'XCode\s+(\d)\..*', ret, flags=re.IGNORECASE) + m = re.match(r'Xcode\s+(\d+)\..*', ret, flags=re.IGNORECASE) if m: return int(m.group(1)) - return 0 + else: + raise Exception("Failed to parse Xcode version") class Builder: def __init__(self, opencv, contrib, dynamic, bitcodedisabled, exclude, targets): From 9b9f38afc877439ea8cc29e78cd09a1651747b35 Mon Sep 17 00:00:00 2001 From: soonbro <37871515+soonbro@users.noreply.github.com> Date: Fri, 28 Sep 2018 19:13:39 +0900 Subject: [PATCH 08/19] fix typo in FpsMeter.java 'mFramesCouner' -> 'mFramesCounter' --- .../android/java/org/opencv/android/FpsMeter.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/java/generator/android/java/org/opencv/android/FpsMeter.java b/modules/java/generator/android/java/org/opencv/android/FpsMeter.java index 88e826cf965a..d22c68e41539 100644 --- a/modules/java/generator/android/java/org/opencv/android/FpsMeter.java +++ b/modules/java/generator/android/java/org/opencv/android/FpsMeter.java @@ -14,7 +14,7 @@ public class FpsMeter { private static final int STEP = 20; private static final DecimalFormat FPS_FORMAT = new DecimalFormat("0.00"); - private int mFramesCouner; + private int mFramesCounter; private double mFrequency; private long mprevFrameTime; private String mStrfps; @@ -24,7 +24,7 @@ public class FpsMeter { int mHeight = 0; public void init() { - mFramesCouner = 0; + mFramesCounter = 0; mFrequency = Core.getTickFrequency(); mprevFrameTime = Core.getTickCount(); mStrfps = ""; @@ -39,8 +39,8 @@ public void measure() { init(); mIsInitialized = true; } else { - mFramesCouner++; - if (mFramesCouner % STEP == 0) { + mFramesCounter++; + if (mFramesCounter % STEP == 0) { long time = Core.getTickCount(); double fps = STEP * mFrequency / (time - mprevFrameTime); mprevFrameTime = time; From e6ef9221cbfbcc74485e2d8b717f6c2fb852967e Mon Sep 17 00:00:00 2001 From: Tomoaki Teshima Date: Sat, 29 Sep 2018 23:13:12 +0900 Subject: [PATCH 09/19] fix test failure of cudev * follow the implementation of Luv2RGBfloat in imgproc/src/color_lab.cpp * loosen threshold in cudaimgproc --- modules/cudaimgproc/test/test_color.cpp | 22 ++++++++-------- .../cudev/functional/detail/color_cvt.hpp | 26 ++++++++++--------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/modules/cudaimgproc/test/test_color.cpp b/modules/cudaimgproc/test/test_color.cpp index e4f91ea1bcb7..3362fe5faf5f 100644 --- a/modules/cudaimgproc/test/test_color.cpp +++ b/modules/cudaimgproc/test/test_color.cpp @@ -1740,7 +1740,7 @@ CUDA_TEST_P(CvtColor, Lab2BGR) cv::Mat dst_gold; cv::cvtColor(src, dst_gold, cv::COLOR_Lab2BGR); - EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 1 : 1e-5); + EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 2 : 1e-5); } CUDA_TEST_P(CvtColor, Lab2RGB) @@ -1757,7 +1757,7 @@ CUDA_TEST_P(CvtColor, Lab2RGB) cv::Mat dst_gold; cv::cvtColor(src, dst_gold, cv::COLOR_Lab2RGB); - EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 1 : 1e-5); + EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 2 : 1e-5); } CUDA_TEST_P(CvtColor, Lab2BGRA) @@ -1776,7 +1776,7 @@ CUDA_TEST_P(CvtColor, Lab2BGRA) cv::Mat dst_gold; cv::cvtColor(src, dst_gold, cv::COLOR_Lab2BGR, 4); - EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 1 : 1e-5); + EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 2 : 1e-5); } CUDA_TEST_P(CvtColor, Lab2LBGR) @@ -1793,7 +1793,7 @@ CUDA_TEST_P(CvtColor, Lab2LBGR) cv::Mat dst_gold; cv::cvtColor(src, dst_gold, cv::COLOR_Lab2LBGR); - EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 1 : 1e-5); + EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 2 : 1e-5); } CUDA_TEST_P(CvtColor, Lab2LRGB) @@ -1810,7 +1810,7 @@ CUDA_TEST_P(CvtColor, Lab2LRGB) cv::Mat dst_gold; cv::cvtColor(src, dst_gold, cv::COLOR_Lab2LRGB); - EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 1 : 1e-5); + EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 2 : 1e-5); } CUDA_TEST_P(CvtColor, Lab2LRGBA) @@ -1827,7 +1827,7 @@ CUDA_TEST_P(CvtColor, Lab2LRGBA) cv::Mat dst_gold; cv::cvtColor(src, dst_gold, cv::COLOR_Lab2LRGB, 4); - EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 1 : 1e-5); + EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 2 : 1e-5); } CUDA_TEST_P(CvtColor, BGR2Luv) @@ -1958,7 +1958,7 @@ CUDA_TEST_P(CvtColor, Luv2BGR) cv::Mat dst_gold; cv::cvtColor(src, dst_gold, cv::COLOR_Luv2BGR); - EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 1 : 1e-4); + EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 2 : 1e-4); } CUDA_TEST_P(CvtColor, Luv2RGB) @@ -1975,7 +1975,7 @@ CUDA_TEST_P(CvtColor, Luv2RGB) cv::Mat dst_gold; cv::cvtColor(src, dst_gold, cv::COLOR_Luv2RGB); - EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 1 : 1e-4); + EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 2 : 1e-4); } CUDA_TEST_P(CvtColor, Luv2BGRA) @@ -1994,7 +1994,7 @@ CUDA_TEST_P(CvtColor, Luv2BGRA) cv::Mat dst_gold; cv::cvtColor(src, dst_gold, cv::COLOR_Luv2BGR, 4); - EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 1 : 1e-4); + EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 2 : 1e-4); } CUDA_TEST_P(CvtColor, Luv2LBGR) @@ -2011,7 +2011,7 @@ CUDA_TEST_P(CvtColor, Luv2LBGR) cv::Mat dst_gold; cv::cvtColor(src, dst_gold, cv::COLOR_Luv2LBGR); - EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 1 : 1e-4); + EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 2 : 1e-4); } CUDA_TEST_P(CvtColor, Luv2LRGB) @@ -2028,7 +2028,7 @@ CUDA_TEST_P(CvtColor, Luv2LRGB) cv::Mat dst_gold; cv::cvtColor(src, dst_gold, cv::COLOR_Luv2LRGB); - EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 1 : 1e-4); + EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_8U ? 2 : 1e-4); } CUDA_TEST_P(CvtColor, Luv2LRGBA) diff --git a/modules/cudev/include/opencv2/cudev/functional/detail/color_cvt.hpp b/modules/cudev/include/opencv2/cudev/functional/detail/color_cvt.hpp index a456dfad4805..f485e09e5b6f 100644 --- a/modules/cudev/include/opencv2/cudev/functional/detail/color_cvt.hpp +++ b/modules/cudev/include/opencv2/cudev/functional/detail/color_cvt.hpp @@ -1207,27 +1207,29 @@ namespace color_cvt_detail __device__ typename MakeVec::type operator ()(const typename MakeVec::type& src) const { const float _d = 1.f / (0.950456f + 15 + 1.088754f * 3); - const float _un = 4 * 0.950456f * _d; - const float _vn = 9 * _d; + const float _un = 13 * 4 * 0.950456f * _d; + const float _vn = 13 * 9 * _d; float L = src.x; float u = src.y; float v = src.z; - float Y = (L + 16.f) * (1.f / 116.f); - Y = Y * Y * Y; + float Y1 = (L + 16.f) * (1.f / 116.f); + Y1 = Y1 * Y1 * Y1; + float Y0 = L * (1.f / 903.3f); + float Y = L <= 8.f ? Y0 : Y1; - float d = (1.f / 13.f) / L; - u = u * d + _un; - v = v * d + _vn; + u = (u + _un * L) * 3.f; + v = (v + _vn * L) * 4.f; float iv = 1.f / v; - float X = 2.25f * u * Y * iv; - float Z = (12 - 3 * u - 20 * v) * Y * 0.25f * iv; + iv = ::fmaxf(-0.25f, ::fminf(0.25f, iv)); + float X = 3.f * u * iv; + float Z = (12.f * 13.f * L - u) * iv - 5.f; - float B = 0.055648f * X - 0.204043f * Y + 1.057311f * Z; - float G = -0.969256f * X + 1.875991f * Y + 0.041556f * Z; - float R = 3.240479f * X - 1.537150f * Y - 0.498535f * Z; + float B = (0.055648f * X - 0.204043f + 1.057311f * Z) * Y; + float G = (-0.969256f * X + 1.875991f + 0.041556f * Z) * Y; + float R = (3.240479f * X - 1.537150f - 0.498535f * Z) * Y; R = ::fminf(::fmaxf(R, 0.f), 1.f); G = ::fminf(::fmaxf(G, 0.f), 1.f); From 1a81a97e9f988d16da047a7d9c971bef0c8eeb68 Mon Sep 17 00:00:00 2001 From: Hamdi Sahloul Date: Sat, 29 Sep 2018 19:34:44 +0900 Subject: [PATCH 10/19] Utilize the currently running Python executable especially if it matches the module being tested --- modules/ts/misc/run_suite.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/ts/misc/run_suite.py b/modules/ts/misc/run_suite.py index 2eaeae1c3f30..a3c4be754653 100644 --- a/modules/ts/misc/run_suite.py +++ b/modules/ts/misc/run_suite.py @@ -1,6 +1,7 @@ #!/usr/bin/env python import os import re +import sys from run_utils import Err, log, execute, getPlatformVersion, isColorEnabled, TempEnvDir from run_long import LONG_TESTS_DEBUG_VALGRIND, longTestFilter @@ -116,6 +117,8 @@ def runTest(self, module, path, logfile, workingDir, args=[]): return None, ret elif module in ['python2', 'python3']: executable = os.getenv('OPENCV_PYTHON_BINARY', None) + if executable is None or module == 'python{}'.format(sys.version_info[0]): + executable = sys.executable if executable is None: executable = path if not self.tryCommand([executable, '--version'], workingDir): From 1059735bfbc93cd8bf83bce6d8eb1c891d28a058 Mon Sep 17 00:00:00 2001 From: Hamdi Sahloul <42140441+cv3d@users.noreply.github.com> Date: Sun, 30 Sep 2018 02:03:54 +0900 Subject: [PATCH 11/19] Merge pull request #12667 from cv3d:fix/ts_report TS: fix Python v2/v3 compatibility (#12667) * TS: fix Python2.7 compatibility * TS: fix Python3 compatibility * py3: use integer division '/' => '//' instead of cast --- modules/ts/misc/report.py | 2 +- modules/ts/misc/summary.py | 2 +- modules/ts/misc/table_formatter.py | 8 ++++---- modules/ts/misc/testlog_parser.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/ts/misc/report.py b/modules/ts/misc/report.py index 5c962b774bc6..f0a87f2a12f8 100755 --- a/modules/ts/misc/report.py +++ b/modules/ts/misc/report.py @@ -66,7 +66,7 @@ tbl.newColumn(m, metrix_table[m][0], align = "center") needNewRow = True - for case in sorted(tests): + for case in sorted(tests, key=lambda x: str(x)): if needNewRow: tbl.newRow() if not options.showall: diff --git a/modules/ts/misc/summary.py b/modules/ts/misc/summary.py index f03b62b9bfc9..5549b6c6dc16 100755 --- a/modules/ts/misc/summary.py +++ b/modules/ts/misc/summary.py @@ -177,7 +177,7 @@ def addHeaderColumns(suffix, description, cssclass): prevGroupName = None needNewRow = True lastRow = None - for name in sorted(test_cases.iterkeys(), key=alphanum_keyselector): + for name in sorted(test_cases.keys(), key=alphanum_keyselector): cases = test_cases[name] if needNewRow: lastRow = tbl.newRow() diff --git a/modules/ts/misc/table_formatter.py b/modules/ts/misc/table_formatter.py index 6069dea3b48d..1c1fd7852e50 100755 --- a/modules/ts/misc/table_formatter.py +++ b/modules/ts/misc/table_formatter.py @@ -98,7 +98,7 @@ def newCell(self, col_name, text, value = None, **properties): def layoutTable(self): columns = self.columns.values() - columns.sort(key=lambda c: c.index) + columns = sorted(columns, key=lambda c: c.index) colspanned = [] rowspanned = [] @@ -206,7 +206,7 @@ def measureCell(self, cell): cell.width = len(max(cell.text, key = lambda line: len(line))) def reformatTextValue(self, value): - if sys.version_info > (3,): # PY3 fix + if sys.version_info >= (2,7): unicode = str if isinstance(value, str): vstr = value @@ -340,7 +340,7 @@ def consolePrintLine(self, cell, row, column, out): if align == "right": pattern = "%" + str(width) + "s" elif align == "center": - pattern = "%" + str((width - len(line)) / 2 + len(line)) + "s" + " " * (width - len(line) - (width - len(line)) / 2) + pattern = "%" + str((width - len(line)) // 2 + len(line)) + "s" + " " * (width - len(line) - (width - len(line)) // 2) else: pattern = "%-" + str(width) + "s" @@ -354,7 +354,7 @@ def evalLine(self, cell, rows, column): if valign == "bottom": return height - space if valign == "middle": - return (height - space + 1) / 2 + return (height - space + 1) // 2 return 0 def htmlPrintTable(self, out, embeedcss = False): diff --git a/modules/ts/misc/testlog_parser.py b/modules/ts/misc/testlog_parser.py index 5f4414059d6c..80c5a0bc5a91 100755 --- a/modules/ts/misc/testlog_parser.py +++ b/modules/ts/misc/testlog_parser.py @@ -202,7 +202,7 @@ def parseLogFile(filename): if attr_name.startswith('cv_') } - tests = map(TestInfo, log.getElementsByTagName("testcase")) + tests = list(map(TestInfo, log.getElementsByTagName("testcase"))) return TestRunInfo(properties, tests) From df4139d37350619ab25ef51a68bb60d4e325afe2 Mon Sep 17 00:00:00 2001 From: berak Date: Sun, 30 Sep 2018 15:22:26 +0200 Subject: [PATCH 12/19] document imread grayscale behaviour --- modules/imgcodecs/include/opencv2/imgcodecs.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp index 5839c58c909b..c5ffff97b248 100644 --- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp +++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp @@ -63,7 +63,7 @@ namespace cv //! Imread flags enum ImreadModes { IMREAD_UNCHANGED = -1, //!< If set, return the loaded image as is (with alpha channel, otherwise it gets cropped). - IMREAD_GRAYSCALE = 0, //!< If set, always convert image to the single channel grayscale image. + IMREAD_GRAYSCALE = 0, //!< If set, always convert image to the single channel grayscale image (codec internal conversion). IMREAD_COLOR = 1, //!< If set, always convert image to the 3 channel BGR color image. IMREAD_ANYDEPTH = 2, //!< If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit. IMREAD_ANYCOLOR = 4, //!< If set, the image is read in any possible color format. @@ -155,6 +155,8 @@ Currently, the following file formats are supported: - The function determines the type of an image by the content, not by the file extension. - In the case of color images, the decoded images will have the channels stored in **B G R** order. +- When using IMREAD_GRAYSCALE, the codec's internal grayscale conversion will be used, if available. + Results may differ to the output of cvtColor() - On Microsoft Windows\* OS and MacOSX\*, the codecs shipped with an OpenCV image (libjpeg, libpng, libtiff, and libjasper) are used by default. So, OpenCV can always read JPEGs, PNGs, and TIFFs. On MacOSX, there is also an option to use native MacOSX image readers. But beware From ac9ec55b37b2dd3b224144b4f20857a80719b750 Mon Sep 17 00:00:00 2001 From: Loic Devulder Date: Fri, 28 Sep 2018 15:33:18 +0200 Subject: [PATCH 13/19] 3rdparty/protobuf: fix compilation issue on s390 This commit fixes an issue while trying to compile on s390x architecture. This is simply a backport of a fixe already applied in official protobuf code: - https://github.com/protocolbuffers/protobuf/pull/3955 --- .../protobuf/stubs/atomicops_internals_generic_gcc.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/3rdparty/protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h b/3rdparty/protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h index 0b0b06ce6cf9..075c406abab9 100644 --- a/3rdparty/protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h +++ b/3rdparty/protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h @@ -146,6 +146,14 @@ inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { return __atomic_load_n(ptr, __ATOMIC_RELAXED); } +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + __atomic_compare_exchange_n(ptr, &old_value, new_value, false, + __ATOMIC_RELEASE, __ATOMIC_ACQUIRE); + return old_value; +} + #endif // defined(__LP64__) } // namespace internal From 255b20f6de47b65fb1feead09b9dbc908af35ad6 Mon Sep 17 00:00:00 2001 From: Loic Petit Date: Sun, 30 Sep 2018 22:24:02 +0200 Subject: [PATCH 14/19] Fix frame rate rounding in ffmpeg wrapper (#9023) --- modules/videoio/src/cap_ffmpeg_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp index ce337ea10f98..b6a180f63639 100644 --- a/modules/videoio/src/cap_ffmpeg_impl.hpp +++ b/modules/videoio/src/cap_ffmpeg_impl.hpp @@ -1541,7 +1541,7 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc, identically 1. */ frame_rate=(int)(fps+0.5); frame_rate_base=1; - while (fabs((double)frame_rate/frame_rate_base) - fps > 0.001){ + while (fabs(((double)frame_rate/frame_rate_base) - fps) > 0.001){ frame_rate_base*=10; frame_rate=(int)(fps*frame_rate_base + 0.5); } @@ -2374,7 +2374,7 @@ AVStream* OutputMediaStream_FFMPEG::addVideoStream(AVFormatContext *oc, CV_CODEC int frame_rate = static_cast(fps+0.5); int frame_rate_base = 1; - while (fabs(static_cast(frame_rate)/frame_rate_base) - fps > 0.001) + while (fabs((static_cast(frame_rate)/frame_rate_base) - fps) > 0.001) { frame_rate_base *= 10; frame_rate = static_cast(fps*frame_rate_base + 0.5); From 0f031b668052105d199a552736052d5125399213 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Sun, 30 Sep 2018 20:22:39 +0000 Subject: [PATCH 15/19] dnn(ocl4dnn): drop weights_buf - avoid memory access violation during "prefetch" stage --- modules/dnn/src/opencl/conv_layer_spatial.cl | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/modules/dnn/src/opencl/conv_layer_spatial.cl b/modules/dnn/src/opencl/conv_layer_spatial.cl index c60b8fcdbb2a..37aceee983c1 100644 --- a/modules/dnn/src/opencl/conv_layer_spatial.cl +++ b/modules/dnn/src/opencl/conv_layer_spatial.cl @@ -280,15 +280,6 @@ convolve_simd( in_addr += INPUT_PITCH; - Dtype weight_buf[WEIGHT_PREF]; - int w_idx=0; - - for (int i = 0; i < WEIGHT_PREF; i++) - { - weight_buf[i] = weights[weight_addr]; - weight_addr += SIMD_SIZE; - } - #define BLOCK_IN(n, c) intel_sub_group_shuffle(in_buf[n], (c)) int kr = 0; // kr = Kernel Row @@ -297,20 +288,18 @@ convolve_simd( int kc = 0; // kc = Kernel Column LOOP(KERNEL_WIDTH, kc, { + Dtype weight_value = weights[weight_addr]; + weight_addr += SIMD_SIZE; for (int br=0; br < OUT_BLOCK_HEIGHT; br++) { for(int bc=0; bc < OUT_BLOCK_WIDTH; bc++) { Dtype input = BLOCK_IN((br * STRIDE_Y + kr * DILATION_Y), bc * STRIDE_X + kc * DILATION_X); - out[br * OUT_BLOCK_WIDTH + bc] = mad(weight_buf[w_idx % WEIGHT_PREF], input, out[br * OUT_BLOCK_WIDTH + bc]); + out[br * OUT_BLOCK_WIDTH + bc] = mad(weight_value, input, out[br * OUT_BLOCK_WIDTH + bc]); } } - weight_buf[w_idx % WEIGHT_PREF] = weights[weight_addr]; - weight_addr += SIMD_SIZE; - ++w_idx; }); }); - weight_addr -= WEIGHT_PREF * SIMD_SIZE; } fm = fm % ALIGNED_NUM_FILTERS; From 28e55dc5f379c866e3cdba1414501c516ae53265 Mon Sep 17 00:00:00 2001 From: Antonio Borondo Date: Mon, 1 Oct 2018 13:23:13 +0100 Subject: [PATCH 16/19] Fix documentation of cv::cuda::compare --- modules/cudaarithm/include/opencv2/cudaarithm.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cudaarithm/include/opencv2/cudaarithm.hpp b/modules/cudaarithm/include/opencv2/cudaarithm.hpp index d040bb11f0d9..a1c4fa8ed845 100644 --- a/modules/cudaarithm/include/opencv2/cudaarithm.hpp +++ b/modules/cudaarithm/include/opencv2/cudaarithm.hpp @@ -208,7 +208,7 @@ CV_EXPORTS void pow(InputArray src, double power, OutputArray dst, Stream& strea @param src1 First source matrix or scalar. @param src2 Second source matrix or scalar. -@param dst Destination matrix that has the same size and type as the input array(s). +@param dst Destination matrix that has the same size as the input array(s) and type CV_8U. @param cmpop Flag specifying the relation between the elements to be checked: - **CMP_EQ:** a(.) == b(.) - **CMP_GT:** a(.) \> b(.) From 15632c6305b5545ee85bcc39017724956f2921ad Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Thu, 27 Sep 2018 15:52:42 +0300 Subject: [PATCH 17/19] Added support for multi-path configuration parameter (env) --- .../core/utils/configuration.private.hpp | 6 + modules/core/src/system.cpp | 117 +++++++++++++----- 2 files changed, 93 insertions(+), 30 deletions(-) diff --git a/modules/core/include/opencv2/core/utils/configuration.private.hpp b/modules/core/include/opencv2/core/utils/configuration.private.hpp index fa1b045178fc..b35f35e9d49b 100644 --- a/modules/core/include/opencv2/core/utils/configuration.private.hpp +++ b/modules/core/include/opencv2/core/utils/configuration.private.hpp @@ -5,11 +5,17 @@ #ifndef OPENCV_CONFIGURATION_PRIVATE_HPP #define OPENCV_CONFIGURATION_PRIVATE_HPP +#include "opencv2/core/cvstd.hpp" +#include +#include + namespace cv { namespace utils { +typedef std::vector Paths; CV_EXPORTS bool getConfigurationParameterBool(const char* name, bool defaultValue); CV_EXPORTS size_t getConfigurationParameterSizeT(const char* name, size_t defaultValue); CV_EXPORTS cv::String getConfigurationParameterString(const char* name, const char* defaultValue); +CV_EXPORTS Paths getConfigurationParameterPaths(const char* name, const Paths &defaultValue = Paths()); }} // namespace diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index f1de60fd9a98..ac1dc05d2d6b 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -43,6 +43,7 @@ #include "precomp.hpp" #include +#include #include #include @@ -1657,18 +1658,26 @@ static TLSData& getThreadIDTLS() } // namespace int utils::getThreadID() { return getThreadIDTLS().get()->id; } -bool utils::getConfigurationParameterBool(const char* name, bool defaultValue) + +class ParseError { -#ifdef NO_GETENV - const char* envValue = NULL; -#else - const char* envValue = getenv(name); -#endif - if (envValue == NULL) + std::string bad_value; +public: + ParseError(const std::string bad_value_) :bad_value(bad_value_) {} + std::string toString(const std::string ¶m) const { - return defaultValue; + std::ostringstream out; + out << "Invalid value for parameter " << param << ": " << bad_value; + return out.str(); } - cv::String value = envValue; +}; + +template +T parseOption(const std::string &); + +template<> +inline bool parseOption(const std::string & value) +{ if (value == "1" || value == "True" || value == "true" || value == "TRUE") { return true; @@ -1677,22 +1686,12 @@ bool utils::getConfigurationParameterBool(const char* name, bool defaultValue) { return false; } - CV_Error(cv::Error::StsBadArg, cv::format("Invalid value for %s parameter: %s", name, value.c_str())); + throw ParseError(value); } - -size_t utils::getConfigurationParameterSizeT(const char* name, size_t defaultValue) +template<> +inline size_t parseOption(const std::string &value) { -#ifdef NO_GETENV - const char* envValue = NULL; -#else - const char* envValue = getenv(name); -#endif - if (envValue == NULL) - { - return defaultValue; - } - cv::String value = envValue; size_t pos = 0; for (; pos < value.size(); pos++) { @@ -1708,22 +1707,80 @@ size_t utils::getConfigurationParameterSizeT(const char* name, size_t defaultVal return v * 1024 * 1024; else if (suffixStr == "KB" || suffixStr == "Kb" || suffixStr == "kb") return v * 1024; - CV_Error(cv::Error::StsBadArg, cv::format("Invalid value for %s parameter: %s", name, value.c_str())); + throw ParseError(value); } -cv::String utils::getConfigurationParameterString(const char* name, const char* defaultValue) +template<> +inline cv::String parseOption(const std::string &value) +{ + return value; +} + +template<> +inline utils::Paths parseOption(const std::string &value) +{ + utils::Paths result; +#ifdef _WIN32 + const char sep = ';'; +#else + const char sep = ':'; +#endif + size_t start_pos = 0; + while (start_pos != std::string::npos) + { + const size_t pos = value.find(sep, start_pos); + const std::string one_piece(value, start_pos, pos == std::string::npos ? pos : pos - start_pos); + if (!one_piece.empty()) + result.push_back(one_piece); + start_pos = pos == std::string::npos ? pos : pos + 1; + } + return result; +} + +static inline const char * envRead(const char * name) { #ifdef NO_GETENV - const char* envValue = NULL; + CV_UNUSED(name); + return NULL; #else - const char* envValue = getenv(name); + return getenv(name); #endif - if (envValue == NULL) +} + +template +inline T read(const std::string & k, const T & defaultValue) +{ + try { - return defaultValue; + const char * res = envRead(k.c_str()); + if (res) + return parseOption(std::string(res)); } - cv::String value = envValue; - return value; + catch (const ParseError &err) + { + CV_Error(cv::Error::StsBadArg, err.toString(k)); + } + return defaultValue; +} + +bool utils::getConfigurationParameterBool(const char* name, bool defaultValue) +{ + return read(name, defaultValue); +} + +size_t utils::getConfigurationParameterSizeT(const char* name, size_t defaultValue) +{ + return read(name, defaultValue); +} + +cv::String utils::getConfigurationParameterString(const char* name, const char* defaultValue) +{ + return read(name, defaultValue); +} + +utils::Paths utils::getConfigurationParameterPaths(const char* name, const utils::Paths &defaultValue) +{ + return read(name, defaultValue); } From 94201b7cf93b21b85402ea3b22193f70b7b59948 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Fri, 21 Sep 2018 15:04:18 +0000 Subject: [PATCH 18/19] ocl: OPENCV_OPENCL_BUILD_EXTRA_OPTIONS parameter --- modules/core/src/ocl.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp index a73ddbb0bb6e..0e98c0865987 100644 --- a/modules/core/src/ocl.cpp +++ b/modules/core/src/ocl.cpp @@ -238,6 +238,20 @@ static const bool CV_OPENCL_DISABLE_BUFFER_RECT_OPERATIONS = utils::getConfigura #endif ); +static const String getBuildExtraOptions() +{ + static String param_buildExtraOptions; + static bool initialized = false; + if (!initialized) + { + param_buildExtraOptions = utils::getConfigurationParameterString("OPENCV_OPENCL_BUILD_EXTRA_OPTIONS", ""); + initialized = true; + if (!param_buildExtraOptions.empty()) + CV_LOG_WARNING(NULL, "OpenCL: using extra build options: '" << param_buildExtraOptions << "'"); + } + return param_buildExtraOptions; +} + #endif // HAVE_OPENCL struct UMat2D @@ -3522,6 +3536,9 @@ struct Program::Impl buildflags = joinBuildOptions(buildflags, " -D AMD_DEVICE"); else if (device.isIntel()) buildflags = joinBuildOptions(buildflags, " -D INTEL_DEVICE"); + const String param_buildExtraOptions = getBuildExtraOptions(); + if (!param_buildExtraOptions.empty()) + buildflags = joinBuildOptions(buildflags, param_buildExtraOptions); } compile(ctx, src_, errmsg); } From ee0c985491fe1d7af2d40eb626638aae67f46e64 Mon Sep 17 00:00:00 2001 From: Suleyman TURKMEN Date: Mon, 1 Oct 2018 22:22:37 +0300 Subject: [PATCH 19/19] Merge pull request #12649 from sturkmen72:patch-9 Update hog.cpp (#12649) --- modules/objdetect/src/hog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/objdetect/src/hog.cpp b/modules/objdetect/src/hog.cpp index cce5d27ac3ff..b7030fdd17bb 100644 --- a/modules/objdetect/src/hog.cpp +++ b/modules/objdetect/src/hog.cpp @@ -138,6 +138,8 @@ void HOGDescriptor::setSVMDetector(InputArray _svmDetector) bool HOGDescriptor::read(FileNode& obj) { + CV_Assert(!obj["winSize"].empty()); + if( !obj.isMap() ) return false; FileNodeIterator it = obj["winSize"].begin();