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 0a949b42ed..2fb1315e61 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 02f412d994..9aa2d4e4e0 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 cf133024e4..9d20046df9 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 a482b49fcf..d040bb11f0 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 7fd97b1d24..94dff9e762 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 9b507e604e..90cb5652b0 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 2a6456f69b..f18f69edb3 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 1ba4f0da26..ee81ebe385 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -137,7 +137,11 @@ public: /** @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 2e9811ada2..caa8d6067e 100644 --- a/modules/js/src/embindgen.py +++ b/modules/js/src/embindgen.py @@ -126,7 +126,22 @@ video = {'': ['CamShift', 'calcOpticalFlowFarneback', 'calcOpticalFlowPyrLK', 'c '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 @@ class JSWrapperGenerator(object): [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 3ff69c05e5..3cdce4aa2b 100644 --- a/platforms/js/build_js.py +++ b/platforms/js/build_js.py @@ -131,7 +131,7 @@ class Builder: "-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 d624e08d90..f546c6af5d 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 88e826cf96..d22c68e415 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 class FpsMeter { 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 e4f91ea1bc..3362fe5faf 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 a456dfad48..f485e09e5b 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 2eaeae1c3f..a3c4be7546 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 @@ class TestSuite(object): 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 5c962b774b..f0a87f2a12 100755 --- a/modules/ts/misc/report.py +++ b/modules/ts/misc/report.py @@ -66,7 +66,7 @@ if __name__ == "__main__": 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 f03b62b9bf..5549b6c6dc 100755 --- a/modules/ts/misc/summary.py +++ b/modules/ts/misc/summary.py @@ -177,7 +177,7 @@ if __name__ == "__main__": 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 6069dea3b4..1c1fd7852e 100755 --- a/modules/ts/misc/table_formatter.py +++ b/modules/ts/misc/table_formatter.py @@ -98,7 +98,7 @@ class table(object): 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 @@ class table(object): 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 @@ class table(object): 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 @@ class table(object): 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 5f4414059d..80c5a0bc5a 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 5839c58c90..c5ffff97b2 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 0b0b06ce6c..075c406aba 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 ce337ea10f..b6a180f636 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 c60b8fcdbb..37aceee983 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 d040bb11f0..a1c4fa8ed8 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 fa1b045178..b35f35e9d4 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 f1de60fd9a..ac1dc05d2d 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 a73ddbb0bb..0e98c08659 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 cce5d27ac3..b7030fdd17 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();