From 6b849906209629f02de10bf7fc0d1fbe26f85b71 Mon Sep 17 00:00:00 2001 From: Vitaly Tuzov Date: Fri, 21 Sep 2018 16:21:40 +0300 Subject: [PATCH 01/23] integral() implementation updated to utilize wide universal intrinsics --- modules/imgproc/src/sumpixels.cpp | 143 +++++++++++++++++++++--------- 1 file changed, 102 insertions(+), 41 deletions(-) diff --git a/modules/imgproc/src/sumpixels.cpp b/modules/imgproc/src/sumpixels.cpp index c09e085285..3c49aaf773 100755 --- a/modules/imgproc/src/sumpixels.cpp +++ b/modules/imgproc/src/sumpixels.cpp @@ -43,6 +43,8 @@ #include "precomp.hpp" #include "opencl_kernels_imgproc.hpp" +#include "opencv2/core/hal/intrin.hpp" + namespace cv { @@ -60,15 +62,12 @@ struct Integral_SIMD } }; -#if CV_SSE2 +#if CV_SIMD && CV_SIMD_WIDTH <= 64 template <> struct Integral_SIMD { - Integral_SIMD() - { - haveSSE2 = checkHardwareSupport(CV_CPU_SSE2); - } + Integral_SIMD() {} bool operator()(const uchar * src, size_t _srcstep, int * sum, size_t _sumstep, @@ -76,15 +75,12 @@ struct Integral_SIMD int * tilted, size_t, int width, int height, int cn) const { - if (sqsum || tilted || cn != 1 || !haveSSE2) + if (sqsum || tilted || cn != 1) return false; // the first iteration memset(sum, 0, (width + 1) * sizeof(int)); - __m128i v_zero = _mm_setzero_si128(), prev = v_zero; - int j = 0; - // the others for (int i = 0; i < height; ++i) { @@ -94,48 +90,113 @@ struct Integral_SIMD sum_row[-1] = 0; - prev = v_zero; - j = 0; - - for ( ; j + 7 < width; j += 8) + v_int32 prev = vx_setzero_s32(); + int j = 0; + for ( ; j + v_uint16::nlanes <= width; j += v_uint16::nlanes) { - __m128i vsuml = _mm_loadu_si128((const __m128i *)(prev_sum_row + j)); - __m128i vsumh = _mm_loadu_si128((const __m128i *)(prev_sum_row + j + 4)); - - __m128i el8shr0 = _mm_loadl_epi64((const __m128i *)(src_row + j)); - __m128i el8shr1 = _mm_slli_si128(el8shr0, 1); - __m128i el8shr2 = _mm_slli_si128(el8shr0, 2); - __m128i el8shr3 = _mm_slli_si128(el8shr0, 3); - - vsuml = _mm_add_epi32(vsuml, prev); - vsumh = _mm_add_epi32(vsumh, prev); - - __m128i el8shr12 = _mm_add_epi16(_mm_unpacklo_epi8(el8shr1, v_zero), - _mm_unpacklo_epi8(el8shr2, v_zero)); - __m128i el8shr03 = _mm_add_epi16(_mm_unpacklo_epi8(el8shr0, v_zero), - _mm_unpacklo_epi8(el8shr3, v_zero)); - __m128i el8 = _mm_add_epi16(el8shr12, el8shr03); - - __m128i el4h = _mm_add_epi16(_mm_unpackhi_epi16(el8, v_zero), - _mm_unpacklo_epi16(el8, v_zero)); - - vsuml = _mm_add_epi32(vsuml, _mm_unpacklo_epi16(el8, v_zero)); - vsumh = _mm_add_epi32(vsumh, el4h); - - _mm_storeu_si128((__m128i *)(sum_row + j), vsuml); - _mm_storeu_si128((__m128i *)(sum_row + j + 4), vsumh); - - prev = _mm_add_epi32(prev, _mm_shuffle_epi32(el4h, _MM_SHUFFLE(3, 3, 3, 3))); + v_int16 el8 = v_reinterpret_as_s16(vx_load_expand(src_row + j)); + v_int32 el4l, el4h; +#if CV_AVX2 + __m256i vsum = _mm256_add_epi16(el8.val, _mm256_slli_si256(el8.val, 2)); + vsum = _mm256_add_epi16(vsum, _mm256_slli_si256(vsum, 4)); + vsum = _mm256_add_epi16(vsum, _mm256_slli_si256(vsum, 8)); + __m256i shmask = _mm256_set1_epi32(7); + el4l.val = _mm256_add_epi32(_mm256_cvtepi16_epi32(_v256_extract_low(vsum)), prev.val); + el4h.val = _mm256_add_epi32(_mm256_cvtepi16_epi32(_v256_extract_high(vsum)), _mm256_permutevar8x32_epi32(el4l.val, shmask)); + prev.val = _mm256_permutevar8x32_epi32(el4h.val, shmask); +#else + el8 += v_rotate_left<1>(el8); + el8 += v_rotate_left<2>(el8); +#if CV_SIMD_WIDTH == 32 + el8 += v_rotate_left<4>(el8); +#if CV_SIMD_WIDTH == 64 + el8 += v_rotate_left<8>(el8); +#endif +#endif + v_expand(el8, el4l, el4h); + el4l += prev; + el4h += el4l; + prev = vx_setall_s32(v_rotate_right(el4h).get0()); +#endif + v_store(sum_row + j , el4l + vx_load(prev_sum_row + j )); + v_store(sum_row + j + v_int32::nlanes, el4h + vx_load(prev_sum_row + j + v_int32::nlanes)); } for (int v = sum_row[j - 1] - prev_sum_row[j - 1]; j < width; ++j) sum_row[j] = (v += src_row[j]) + prev_sum_row[j]; } + vx_cleanup(); return true; } +}; - bool haveSSE2; +template <> +struct Integral_SIMD +{ + Integral_SIMD() {} + + bool operator()(const uchar * src, size_t _srcstep, + float * sum, size_t _sumstep, + double * sqsum, size_t, + float * tilted, size_t, + int width, int height, int cn) const + { + if (sqsum || tilted || cn != 1) + return false; + + // the first iteration + memset(sum, 0, (width + 1) * sizeof(int)); + + // the others + for (int i = 0; i < height; ++i) + { + const uchar * src_row = src + _srcstep * i; + float * prev_sum_row = (float *)((uchar *)sum + _sumstep * i) + 1; + float * sum_row = (float *)((uchar *)sum + _sumstep * (i + 1)) + 1; + + sum_row[-1] = 0; + + v_float32 prev = vx_setzero_f32(); + int j = 0; + for (; j + v_uint16::nlanes <= width; j += v_uint16::nlanes) + { + v_int16 el8 = v_reinterpret_as_s16(vx_load_expand(src_row + j)); + v_float32 el4l, el4h; +#if CV_AVX2 + __m256i vsum = _mm256_add_epi16(el8.val, _mm256_slli_si256(el8.val, 2)); + vsum = _mm256_add_epi16(vsum, _mm256_slli_si256(vsum, 4)); + vsum = _mm256_add_epi16(vsum, _mm256_slli_si256(vsum, 8)); + __m256i shmask = _mm256_set1_epi32(7); + el4l.val = _mm256_add_ps(_mm256_cvtepi32_ps(_mm256_cvtepi16_epi32(_v256_extract_low(vsum))), prev.val); + el4h.val = _mm256_add_ps(_mm256_cvtepi32_ps(_mm256_cvtepi16_epi32(_v256_extract_high(vsum))), _mm256_permutevar8x32_ps(el4l.val, shmask)); + prev.val = _mm256_permutevar8x32_ps(el4h.val, shmask); +#else + el8 += v_rotate_left<1>(el8); + el8 += v_rotate_left<2>(el8); +#if CV_SIMD_WIDTH == 32 + el8 += v_rotate_left<4>(el8); +#if CV_SIMD_WIDTH == 64 + el8 += v_rotate_left<8>(el8); +#endif +#endif + v_int32 el4li, el4hi; + v_expand(el8, el4li, el4hi); + el4l = v_cvt_f32(el4li) + prev; + el4h = v_cvt_f32(el4hi) + el4l; + prev = vx_setall_f32(v_rotate_right(el4h).get0()); +#endif + v_store(sum_row + j , el4l + vx_load(prev_sum_row + j )); + v_store(sum_row + j + v_float32::nlanes, el4h + vx_load(prev_sum_row + j + v_float32::nlanes)); + } + + for (float v = sum_row[j - 1] - prev_sum_row[j - 1]; j < width; ++j) + sum_row[j] = (v += src_row[j]) + prev_sum_row[j]; + } + vx_cleanup(); + + return true; + } }; #endif From 283348afc33cebecfec4c69e1a420ec0d01bb6ff Mon Sep 17 00:00:00 2001 From: Vitaly Tuzov Date: Tue, 18 Sep 2018 12:22:34 +0300 Subject: [PATCH 02/23] SSE2 code in invert() replaced with universal intrinsics --- modules/core/src/lapack.cpp | 100 +++++++++++++----------------------- 1 file changed, 36 insertions(+), 64 deletions(-) diff --git a/modules/core/src/lapack.cpp b/modules/core/src/lapack.cpp index d8ceaf6abb..3fe2d77083 100644 --- a/modules/core/src/lapack.cpp +++ b/modules/core/src/lapack.cpp @@ -910,37 +910,23 @@ double cv::invert( InputArray _src, OutputArray _dst, int method ) { result = true; d = 1./d; - - #if CV_SSE2 - if(USE_SSE2) - { - __m128 zero = _mm_setzero_ps(); - __m128 t0 = _mm_loadl_pi(zero, (const __m64*)srcdata); //t0 = sf(0,0) sf(0,1) - __m128 t1 = _mm_loadh_pi(zero, (const __m64*)(srcdata+srcstep)); //t1 = sf(1,0) sf(1,1) - __m128 s0 = _mm_or_ps(t0, t1); - __m128 det =_mm_set1_ps((float)d); - s0 = _mm_mul_ps(s0, det); - static const uchar CV_DECL_ALIGNED(16) inv[16] = {0,0,0,0,0,0,0,0x80,0,0,0,0x80,0,0,0,0}; - __m128 pattern = _mm_load_ps((const float*)inv); - s0 = _mm_xor_ps(s0, pattern);//==-1*s0 - s0 = _mm_shuffle_ps(s0, s0, _MM_SHUFFLE(0,2,1,3)); - _mm_storel_pi((__m64*)dstdata, s0); - _mm_storeh_pi((__m64*)((float*)(dstdata+dststep)), s0); - } - else - #endif - { - double t0, t1; - t0 = Sf(0,0)*d; - t1 = Sf(1,1)*d; - Df(1,1) = (float)t0; - Df(0,0) = (float)t1; - t0 = -Sf(0,1)*d; - t1 = -Sf(1,0)*d; - Df(0,1) = (float)t0; - Df(1,0) = (float)t1; - } - + #if CV_SIMD128 + static const float CV_DECL_ALIGNED(16) inv[4] = { 0.f,-0.f,-0.f,0.f }; + v_float32x4 s0 = (v_load_halves((const float*)srcdata, (const float*)(srcdata + srcstep)) * v_setall_f32((float)d)) ^ v_load((const float *)inv);//0123//3120 + s0 = v_extract<3>(s0, v_combine_low(v_rotate_right<1>(s0), s0)); + v_store_low((float*)dstdata, s0); + v_store_high((float*)(dstdata + dststep), s0); + #else + double t0, t1; + t0 = Sf(0,0)*d; + t1 = Sf(1,1)*d; + Df(1,1) = (float)t0; + Df(0,0) = (float)t1; + t0 = -Sf(0,1)*d; + t1 = -Sf(1,0)*d; + Df(0,1) = (float)t0; + Df(1,0) = (float)t1; + #endif } } else @@ -950,39 +936,25 @@ double cv::invert( InputArray _src, OutputArray _dst, int method ) { result = true; d = 1./d; - #if CV_SSE2 - if(USE_SSE2) - { - __m128d s0 = _mm_loadu_pd((const double*)srcdata); //s0 = sf(0,0) sf(0,1) - __m128d s1 = _mm_loadu_pd ((const double*)(srcdata+srcstep));//s1 = sf(1,0) sf(1,1) - __m128d sm = _mm_unpacklo_pd(s0, _mm_load_sd((const double*)(srcdata+srcstep)+1)); //sm = sf(0,0) sf(1,1) - main diagonal - __m128d ss = _mm_shuffle_pd(s0, s1, _MM_SHUFFLE2(0,1)); //ss = sf(0,1) sf(1,0) - secondary diagonal - __m128d det = _mm_load1_pd((const double*)&d); - sm = _mm_mul_pd(sm, det); - - static const uchar CV_DECL_ALIGNED(16) inv[8] = {0,0,0,0,0,0,0,0x80}; - __m128d pattern = _mm_load1_pd((double*)inv); - ss = _mm_mul_pd(ss, det); - ss = _mm_xor_pd(ss, pattern);//==-1*ss - - s0 = _mm_shuffle_pd(sm, ss, _MM_SHUFFLE2(0,1)); - s1 = _mm_shuffle_pd(ss, sm, _MM_SHUFFLE2(0,1)); - _mm_storeu_pd((double*)dstdata, s0); - _mm_storeu_pd((double*)(dstdata+dststep), s1); - } - else - #endif - { - double t0, t1; - t0 = Sd(0,0)*d; - t1 = Sd(1,1)*d; - Dd(1,1) = t0; - Dd(0,0) = t1; - t0 = -Sd(0,1)*d; - t1 = -Sd(1,0)*d; - Dd(0,1) = t0; - Dd(1,0) = t1; - } + #if CV_SIMD128_64F + v_float64x2 det = v_setall_f64(d); + v_float64x2 s0 = v_load((const double*)srcdata) * det; + v_float64x2 s1 = v_load((const double*)(srcdata+srcstep)) * det; + v_float64x2 sm = v_extract<1>(s1, s0);//30 + v_float64x2 ss = v_extract<1>(s0, s1) ^ v_setall_f64(-0.);//12 + v_store((double*)dstdata, v_combine_low(sm, ss));//31 + v_store((double*)(dstdata + dststep), v_combine_high(ss, sm));//20 + #else + double t0, t1; + t0 = Sd(0,0)*d; + t1 = Sd(1,1)*d; + Dd(1,1) = t0; + Dd(0,0) = t1; + t0 = -Sd(0,1)*d; + t1 = -Sd(1,0)*d; + Dd(0,1) = t0; + Dd(1,0) = t1; + #endif } } } From fa8684b5c8267f1c0c89f6279b9b0ff87500480c Mon Sep 17 00:00:00 2001 From: Tomoaki Teshima Date: Wed, 3 Oct 2018 00:59:08 +0900 Subject: [PATCH 03/23] fix test failure of cudafilters Median_Accuracy * avoid race condition --- modules/cudafilters/src/cuda/median_filter.cu | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/modules/cudafilters/src/cuda/median_filter.cu b/modules/cudafilters/src/cuda/median_filter.cu index fe26c7be0e..cbc53f4b4f 100644 --- a/modules/cudafilters/src/cuda/median_filter.cu +++ b/modules/cudafilters/src/cuda/median_filter.cu @@ -127,14 +127,14 @@ namespace cv { namespace cuda { namespace device Hscan[tx]=H[tx]; } __syncthreads(); - if(tx<8){ - if(tx>=1 ) - Hscan[tx]+=Hscan[tx-1]; - if(tx>=2) - Hscan[tx]+=Hscan[tx-2]; - if(tx>=4) - Hscan[tx]+=Hscan[tx-4]; - } + if (1 <= tx && tx < 8 ) + Hscan[tx]+=Hscan[tx-1]; + __syncthreads(); + if (2 <= tx && tx < 8 ) + Hscan[tx]+=Hscan[tx-2]; + __syncthreads(); + if (4 <= tx && tx < 8 ) + Hscan[tx]+=Hscan[tx-4]; __syncthreads(); if(tx<7){ @@ -158,18 +158,20 @@ namespace cv { namespace cuda { namespace device Hscan[tx]=H[tx]; } __syncthreads(); - if(tx<32){ - if(tx>=1) - Hscan[tx]+=Hscan[tx-1]; - if(tx>=2) - Hscan[tx]+=Hscan[tx-2]; - if(tx>=4) - Hscan[tx]+=Hscan[tx-4]; - if(tx>=8) - Hscan[tx]+=Hscan[tx-8]; - if(tx>=16) - Hscan[tx]+=Hscan[tx-16]; - } + if ( 1 <= tx && tx < 32 ) + Hscan[tx]+=Hscan[tx-1]; + __syncthreads(); + if ( 2 <= tx && tx < 32 ) + Hscan[tx]+=Hscan[tx-2]; + __syncthreads(); + if ( 4 <= tx && tx < 32 ) + Hscan[tx]+=Hscan[tx-4]; + __syncthreads(); + if ( 8 <= tx && tx < 32 ) + Hscan[tx]+=Hscan[tx-8]; + __syncthreads(); + if ( 16 <= tx && tx < 32 ) + Hscan[tx]+=Hscan[tx-16]; __syncthreads(); if(tx<31){ if(Hscan[tx+1] > medPos && Hscan[tx] < medPos){ From 042c486b68bdacbb2680ddec46a247fb6645a54b Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Sat, 29 Sep 2018 19:43:01 +0200 Subject: [PATCH 04/23] Obtain fourcc when `AVStream` is network stream The `codec_tag` is only available when opening a file from disk. If `AVStream` is a network stream then `fourcc` must be obtained using `codec_id`. I have tested the following scenarios: 1) Open a `.mp4` file and verify that `codec_tag` is returned (old behavior) 2) Open a `rtsp` stream and verify that `codec_fourcc` is returned (Tested with a MJPEG, H264 and H265 stream) --- modules/videoio/src/cap_ffmpeg_impl.hpp | 59 ++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp index ce337ea10f..22cea63009 100644 --- a/modules/videoio/src/cap_ffmpeg_impl.hpp +++ b/modules/videoio/src/cap_ffmpeg_impl.hpp @@ -48,6 +48,7 @@ #include #include +#define OPENCV_FOURCC(c1, c2, c3, c4) (((c1) & 255) + (((c2) & 255) << 8) + (((c3) & 255) << 16) + (((c4) & 255) << 24)) #define CALC_FFMPEG_VERSION(a,b,c) ( a<<16 | b<<8 | c ) #if defined _MSC_VER && _MSC_VER >= 1200 @@ -350,6 +351,41 @@ struct AVInterruptCallbackMetadata int timeout; }; +// https://github.com/opencv/opencv/pull/12693#issuecomment-426236731 +static +inline const char* _opencv_avcodec_get_name(AVCodecID id) +{ +#if LIBAVCODEC_VERSION_MICRO >= 100 \ + && LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(53, 47, 100) + return avcodec_get_name(id); +#else + const AVCodecDescriptor *cd; + AVCodec *codec; + + if (id == AV_CODEC_ID_NONE) + { + return "none"; + } + cd = avcodec_descriptor_get(id); + if (cd) + { + return cd->name; + } + codec = avcodec_find_decoder(id); + if (codec) + { + return codec->name; + } + codec = avcodec_find_encoder(id); + if (codec) + { + return codec->name; + } + + return "unknown_codec"; +#endif +} + static inline void _opencv_ffmpeg_free(void** ptr) { @@ -1121,6 +1157,10 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const { if( !video_st ) return 0; + double codec_tag = 0; + AVCodecID codec_id = AV_CODEC_ID_NONE; + const char* codec_fourcc = NULL; + switch( property_id ) { case CV_FFMPEG_CAP_PROP_POS_MSEC: @@ -1139,10 +1179,25 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const return get_fps(); case CV_FFMPEG_CAP_PROP_FOURCC: #if LIBAVFORMAT_BUILD > 4628 - return (double)video_st->codec->codec_tag; + codec_id = video_st->codec->codec_id; + codec_tag = (double) video_st->codec->codec_tag; #else - return (double)video_st->codec.codec_tag; + codec_id = video_st->codec.codec_id; + codec_tag = (double)video_st->codec.codec_tag; #endif + + if(codec_tag || codec_id == AV_CODEC_ID_NONE) + { + return codec_tag; + } + + codec_fourcc = _opencv_avcodec_get_name(codec_id); + if(!codec_fourcc || strlen(codec_fourcc) < 4 || strcmp(codec_fourcc, "unknown_codec") == 0) + { + return codec_tag; + } + + return (double) OPENCV_FOURCC(codec_fourcc[0], codec_fourcc[1], codec_fourcc[2], codec_fourcc[3]); case CV_FFMPEG_CAP_PROP_SAR_NUM: return _opencv_ffmpeg_get_sample_aspect_ratio(ic->streams[video_stream]).num; case CV_FFMPEG_CAP_PROP_SAR_DEN: From eec468fa13b82721e48c371b131bf04404a8d2a9 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Tue, 2 Oct 2018 21:10:52 +0000 Subject: [PATCH 05/23] dnn(ocl4dnn): calculate activation expression once - to avoid multiple conditional calls via sub_group() functions --- modules/dnn/src/opencl/conv_layer_spatial.cl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/dnn/src/opencl/conv_layer_spatial.cl b/modules/dnn/src/opencl/conv_layer_spatial.cl index 37aceee983..5d4d6f3add 100644 --- a/modules/dnn/src/opencl/conv_layer_spatial.cl +++ b/modules/dnn/src/opencl/conv_layer_spatial.cl @@ -69,10 +69,16 @@ #endif #ifdef FUSED_CONV_ELTWISE -#define ACTIVATION_FUNCTION(_dst_, _offset_, _data_, _channel_) do { (_dst_)[(_offset_)] = ACTIVATION_RELU_FUNCTION(eltwise_data[(_offset_)] + (_data_), _channel_);} while(0) +#define ACTIVATION_FUNCTION(_dst_, _offset_, _data_, _channel_) do { \ + const Dtype _x_ = eltwise_data[(_offset_)] + (_data_); \ + (_dst_)[(_offset_)] = ACTIVATION_RELU_FUNCTION(_x_, _channel_); \ +} while(0) #define ELTWISE_DATA_ARG __global Dtype* eltwise_data, #else -#define ACTIVATION_FUNCTION(_dst_, _offset_, _data_, _channel_) do { (_dst_)[(_offset_)] = ACTIVATION_RELU_FUNCTION(_data_, _channel_);} while(0) +#define ACTIVATION_FUNCTION(_dst_, _offset_, _data_, _channel_) do { \ + const Dtype _x_ = (_data_); \ + (_dst_)[(_offset_)] = ACTIVATION_RELU_FUNCTION(_x_, _channel_); \ +} while(0) #define ELTWISE_DATA_ARG #endif From ffaf58349c124e9a98e954970623414751938e1b Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 2 Oct 2018 14:30:52 -0700 Subject: [PATCH 06/23] Fix CMake for clang-cl Avoids passing -Wall, which will enable literally every warning in Clang. Avoids passing -ffunction-sections etc to clang-cl, which each generate warnings. --- cmake/OpenCVCompilerOptions.cmake | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmake/OpenCVCompilerOptions.cmake b/cmake/OpenCVCompilerOptions.cmake index 082debf195..22c33806d1 100644 --- a/cmake/OpenCVCompilerOptions.cmake +++ b/cmake/OpenCVCompilerOptions.cmake @@ -86,7 +86,11 @@ endif() if(CV_GCC OR CV_CLANG) # High level of warnings. add_extra_compiler_option(-W) - add_extra_compiler_option(-Wall) + if (NOT MSVC) + # clang-cl interprets -Wall as MSVC would: -Weverything, which is more than + # we want. + add_extra_compiler_option(-Wall) + endif() add_extra_compiler_option(-Werror=return-type) add_extra_compiler_option(-Werror=non-virtual-dtor) add_extra_compiler_option(-Werror=address) @@ -173,7 +177,7 @@ if(CV_GCC OR CV_CLANG) string(REPLACE "-ffunction-sections" "" ${flags} "${${flags}}") string(REPLACE "-fdata-sections" "" ${flags} "${${flags}}") endforeach() - elseif(NOT ((IOS OR ANDROID) AND NOT BUILD_SHARED_LIBS)) + elseif(NOT ((IOS OR ANDROID) AND NOT BUILD_SHARED_LIBS) AND NOT MSVC) # Remove unreferenced functions: function level linking add_extra_compiler_option(-ffunction-sections) add_extra_compiler_option(-fdata-sections) @@ -266,6 +270,7 @@ endif() # set default visibility to hidden if((CV_GCC OR CV_CLANG) + AND NOT MSVC AND NOT OPENCV_SKIP_VISIBILITY_HIDDEN AND NOT " ${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_CXX_FLAGS}" MATCHES " -fvisibility") add_extra_compiler_option(-fvisibility=hidden) From 0ffc186680753febc7b5b70688dd795f2b6ed518 Mon Sep 17 00:00:00 2001 From: Apoorv Goel <35146783+UnderscoreAsterisk@users.noreply.github.com> Date: Wed, 3 Oct 2018 18:20:04 +0530 Subject: [PATCH 07/23] Merge pull request #12731 from UnderscoreAsterisk:fix-12012 * fix #12012 * Replace CV_StsBadFlag with Error::StsBadFlag --- modules/calib3d/src/calibration.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/calib3d/src/calibration.cpp b/modules/calib3d/src/calibration.cpp index 460914a741..112e4c9b89 100644 --- a/modules/calib3d/src/calibration.cpp +++ b/modules/calib3d/src/calibration.cpp @@ -3540,6 +3540,9 @@ double cv::stereoCalibrate( InputArrayOfArrays _objectPoints, OutputArray _Emat, OutputArray _Fmat, int flags, TermCriteria criteria) { + if (flags & CALIB_USE_EXTRINSIC_GUESS) + CV_Error(Error::StsBadFlag, "stereoCalibrate does not support CALIB_USE_EXTRINSIC_GUESS."); + Mat Rmat, Tmat; double ret = stereoCalibrate(_objectPoints, _imagePoints1, _imagePoints2, _cameraMatrix1, _distCoeffs1, _cameraMatrix2, _distCoeffs2, imageSize, Rmat, Tmat, _Emat, _Fmat, From 7294ae0f17282d52f5734d4cd45482f6c40b4b28 Mon Sep 17 00:00:00 2001 From: Tomoaki Teshima Date: Thu, 4 Oct 2018 08:35:34 +0900 Subject: [PATCH 08/23] fix test failure of StereoBeliefPropagation * if the src has odd number of height, access error happens * it could happen on width, too * check both dst and src range in both width and height --- modules/cudastereo/src/cuda/stereobp.cu | 23 ++++++++++++++--------- modules/cudastereo/src/stereobp.cpp | 6 +++--- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/modules/cudastereo/src/cuda/stereobp.cu b/modules/cudastereo/src/cuda/stereobp.cu index f8ecdaf508..a4e7d2daba 100644 --- a/modules/cudastereo/src/cuda/stereobp.cu +++ b/modules/cudastereo/src/cuda/stereobp.cu @@ -255,7 +255,7 @@ namespace cv { namespace cuda { namespace device /////////////////////////////////////////////////////////////// template - __global__ void data_step_down(int dst_cols, int dst_rows, int src_rows, const PtrStep src, PtrStep dst) + __global__ void data_step_down(int dst_cols, int dst_rows, int src_cols, int src_rows, const PtrStep src, PtrStep dst) { const int x = blockIdx.x * blockDim.x + threadIdx.x; const int y = blockIdx.y * blockDim.y + threadIdx.y; @@ -264,10 +264,15 @@ namespace cv { namespace cuda { namespace device { for (int d = 0; d < cndisp; ++d) { - float dst_reg = src.ptr(d * src_rows + (2*y+0))[(2*x+0)]; - dst_reg += src.ptr(d * src_rows + (2*y+1))[(2*x+0)]; - dst_reg += src.ptr(d * src_rows + (2*y+0))[(2*x+1)]; - dst_reg += src.ptr(d * src_rows + (2*y+1))[(2*x+1)]; + // check the index of src + const int x0 = 2 * x; + const int x1 = ::min(x0 + 1, src_cols - 1); + const int y0 = 2 * y; + const int y1 = ::min(y0 + 1, src_rows - 1); + float dst_reg = src.ptr(d * src_rows + y0)[x0]; + dst_reg += src.ptr(d * src_rows + y1)[x0]; + dst_reg += src.ptr(d * src_rows + y0)[x1]; + dst_reg += src.ptr(d * src_rows + y1)[x1]; dst.ptr(d * dst_rows + y)[x] = saturate_cast(dst_reg); } @@ -275,7 +280,7 @@ namespace cv { namespace cuda { namespace device } template - void data_step_down_gpu(int dst_cols, int dst_rows, int src_rows, const PtrStepSzb& src, const PtrStepSzb& dst, cudaStream_t stream) + void data_step_down_gpu(int dst_cols, int dst_rows, int src_cols, int src_rows, const PtrStepSzb& src, const PtrStepSzb& dst, cudaStream_t stream) { dim3 threads(32, 8, 1); dim3 grid(1, 1, 1); @@ -283,15 +288,15 @@ namespace cv { namespace cuda { namespace device grid.x = divUp(dst_cols, threads.x); grid.y = divUp(dst_rows, threads.y); - data_step_down<<>>(dst_cols, dst_rows, src_rows, (PtrStepSz)src, (PtrStepSz)dst); + data_step_down<<>>(dst_cols, dst_rows, src_cols, src_rows, (PtrStepSz)src, (PtrStepSz)dst); cudaSafeCall( cudaGetLastError() ); if (stream == 0) cudaSafeCall( cudaDeviceSynchronize() ); } - template void data_step_down_gpu(int dst_cols, int dst_rows, int src_rows, const PtrStepSzb& src, const PtrStepSzb& dst, cudaStream_t stream); - template void data_step_down_gpu(int dst_cols, int dst_rows, int src_rows, const PtrStepSzb& src, const PtrStepSzb& dst, cudaStream_t stream); + template void data_step_down_gpu(int dst_cols, int dst_rows, int src_cols, int src_rows, const PtrStepSzb& src, const PtrStepSzb& dst, cudaStream_t stream); + template void data_step_down_gpu(int dst_cols, int dst_rows, int src_cols, int src_rows, const PtrStepSzb& src, const PtrStepSzb& dst, cudaStream_t stream); /////////////////////////////////////////////////////////////// /////////////////// level up messages //////////////////////// diff --git a/modules/cudastereo/src/stereobp.cpp b/modules/cudastereo/src/stereobp.cpp index 953674b904..2c39d3e240 100644 --- a/modules/cudastereo/src/stereobp.cpp +++ b/modules/cudastereo/src/stereobp.cpp @@ -61,7 +61,7 @@ namespace cv { namespace cuda { namespace device template void comp_data_gpu(const PtrStepSzb& left, const PtrStepSzb& right, const PtrStepSzb& data, cudaStream_t stream); template - void data_step_down_gpu(int dst_cols, int dst_rows, int src_rows, const PtrStepSzb& src, const PtrStepSzb& dst, cudaStream_t stream); + void data_step_down_gpu(int dst_cols, int dst_rows, int src_cols, int src_rows, const PtrStepSzb& src, const PtrStepSzb& dst, cudaStream_t stream); template void level_up_messages_gpu(int dst_idx, int dst_cols, int dst_rows, int src_rows, PtrStepSzb* mus, PtrStepSzb* mds, PtrStepSzb* mls, PtrStepSzb* mrs, cudaStream_t stream); template @@ -283,7 +283,7 @@ namespace { using namespace cv::cuda::device::stereobp; - typedef void (*data_step_down_t)(int dst_cols, int dst_rows, int src_rows, const PtrStepSzb& src, const PtrStepSzb& dst, cudaStream_t stream); + typedef void (*data_step_down_t)(int dst_cols, int dst_rows, int src_cols, int src_rows, const PtrStepSzb& src, const PtrStepSzb& dst, cudaStream_t stream); static const data_step_down_t data_step_down_callers[2] = { data_step_down_gpu, data_step_down_gpu @@ -318,7 +318,7 @@ namespace datas_[i].create(rows_all_[i] * ndisp_, cols_all_[i], msg_type_); - data_step_down_callers[funcIdx](cols_all_[i], rows_all_[i], rows_all_[i-1], datas_[i-1], datas_[i], stream); + data_step_down_callers[funcIdx](cols_all_[i], rows_all_[i], cols_all_[i-1], rows_all_[i-1], datas_[i-1], datas_[i], stream); } PtrStepSzb mus[] = {u_, u2_}; From 60c26f8f1ec31c3b10f026ce40779c7b412a7667 Mon Sep 17 00:00:00 2001 From: Georgy Mironov Date: Thu, 4 Oct 2018 13:48:40 +0300 Subject: [PATCH 09/23] Fix install with external protobuf --- cmake/OpenCVFindProtobuf.cmake | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmake/OpenCVFindProtobuf.cmake b/cmake/OpenCVFindProtobuf.cmake index 289fa60641..98e1ce2406 100644 --- a/cmake/OpenCVFindProtobuf.cmake +++ b/cmake/OpenCVFindProtobuf.cmake @@ -44,8 +44,10 @@ else() if(Protobuf_FOUND) if(TARGET protobuf::libprotobuf) - add_library(libprotobuf INTERFACE) - target_link_libraries(libprotobuf INTERFACE protobuf::libprotobuf) + add_library(libprotobuf INTERFACE IMPORTED) + set_target_properties(libprotobuf PROPERTIES + INTERFACE_LINK_LIBRARIES protobuf::libprotobuf + ) else() add_library(libprotobuf UNKNOWN IMPORTED) set_target_properties(libprotobuf PROPERTIES From 0926a84a45031d4e024f1378f3a09f12a348c2ad Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 4 Oct 2018 14:43:43 +0300 Subject: [PATCH 10/23] cmake: define CV_ErrorNoReturn under CV_STATIC_ANALYSIS to avoid build break without `__OPENCV_BUILD` --- modules/core/include/opencv2/core/base.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/core/include/opencv2/core/base.hpp b/modules/core/include/opencv2/core/base.hpp index 389fa65705..98683a2023 100644 --- a/modules/core/include/opencv2/core/base.hpp +++ b/modules/core/include/opencv2/core/base.hpp @@ -415,6 +415,8 @@ CV_INLINE CV_NORETURN void errorNoReturn(int _code, const String& _err, const ch #define CV_Error(...) do { abort(); } while (0) #define CV_Error_( code, args ) do { cv::format args; abort(); } while (0) #define CV_Assert( expr ) do { if (!(expr)) abort(); } while (0) +#define CV_ErrorNoReturn CV_Error +#define CV_ErrorNoReturn_ CV_Error_ #else // CV_STATIC_ANALYSIS From da5e0ef4612814e0445205b4536e849bb7293f10 Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Thu, 4 Oct 2018 14:26:32 +0300 Subject: [PATCH 11/23] ocl::KernelArg::Local(): added size argument --- modules/core/include/opencv2/core/ocl.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/core/include/opencv2/core/ocl.hpp b/modules/core/include/opencv2/core/ocl.hpp index 5e6b247f8c..95f0fcdd66 100644 --- a/modules/core/include/opencv2/core/ocl.hpp +++ b/modules/core/include/opencv2/core/ocl.hpp @@ -352,7 +352,8 @@ public: KernelArg(int _flags, UMat* _m, int wscale=1, int iwscale=1, const void* _obj=0, size_t _sz=0); KernelArg(); - static KernelArg Local() { return KernelArg(LOCAL, 0); } + static KernelArg Local(size_t localMemSize) + { return KernelArg(LOCAL, 0, 1, 1, 0, localMemSize); } static KernelArg PtrWriteOnly(const UMat& m) { return KernelArg(PTR_ONLY+WRITE_ONLY, (UMat*)&m); } static KernelArg PtrReadOnly(const UMat& m) From 630a94b8b7ac987bc97f38df0d0a087d85eb92af Mon Sep 17 00:00:00 2001 From: Anush Elangovan Date: Thu, 4 Oct 2018 10:48:14 -0700 Subject: [PATCH 12/23] _tzcnt_u32() is undefined in clang-cl so use alternate impl _tzcnt_u32() is not exported by clang-cl intrin.h so check for clang-cl and enable an alterate for _tzcnt_u32() Some discussions: http://lists.llvm.org/pipermail/cfe-dev/2016-October/051329.html https://bugs.llvm.org/show_bug.cgi?id=30506 TEST=Build with clang-cl --- modules/core/include/opencv2/core/hal/intrin.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/core/include/opencv2/core/hal/intrin.hpp b/modules/core/include/opencv2/core/hal/intrin.hpp index a321627081..6ab4ccb36c 100644 --- a/modules/core/include/opencv2/core/hal/intrin.hpp +++ b/modules/core/include/opencv2/core/hal/intrin.hpp @@ -368,6 +368,9 @@ inline unsigned int trailingZeros32(unsigned int value) { unsigned long index = 0; _BitScanForward(&index, value); return (unsigned int)index; +#elif defined(__clang__) + // clang-cl doesn't export _tzcnt_u32 for non BMI systems + return value ? __builtin_ctz(value) : 32; #else return _tzcnt_u32(value); #endif From 9d02d42afe6f362d1f9ce39a85075fb6829c2122 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Fri, 5 Oct 2018 15:10:58 +0300 Subject: [PATCH 13/23] dnn(ocl4dnn): don't use getUMat() especially in CPU only processing --- modules/dnn/src/dnn.cpp | 4 +-- modules/dnn/src/layers/batch_norm_layer.cpp | 4 +-- modules/dnn/src/layers/convolution_layer.cpp | 6 +++-- modules/dnn/src/layers/elementwise_layers.cpp | 6 ++++- .../dnn/src/layers/fully_connected_layer.cpp | 16 ++++++------ modules/dnn/src/layers/mvn_layer.cpp | 25 ++++++++++++++++--- modules/dnn/src/layers/region_layer.cpp | 7 +++++- 7 files changed, 48 insertions(+), 20 deletions(-) diff --git a/modules/dnn/src/dnn.cpp b/modules/dnn/src/dnn.cpp index 8e5f478b00..a3d1efbc8b 100644 --- a/modules/dnn/src/dnn.cpp +++ b/modules/dnn/src/dnn.cpp @@ -2518,7 +2518,7 @@ void Net::forward(OutputArrayOfArrays outputBlobs, const String& outputName) if (outputBlobs.isUMat()) { - outputBlobs.assign(impl->getBlob(layerName).getUMat(ACCESS_RW)); + impl->getBlob(layerName).copyTo(outputBlobs); } else if (outputBlobs.isMat()) { @@ -2566,7 +2566,7 @@ void Net::forward(OutputArrayOfArrays outputBlobs, const String& outputName) { outputvec.resize(ld.outputBlobs.size()); for (int i = 0; i < outputvec.size(); ++i) - outputvec[i] = ld.outputBlobs[i].getUMat(ACCESS_RW); + ld.outputBlobs[i].copyTo(outputvec[i]); } } } diff --git a/modules/dnn/src/layers/batch_norm_layer.cpp b/modules/dnn/src/layers/batch_norm_layer.cpp index c0e8159532..f0fa5f21a5 100644 --- a/modules/dnn/src/layers/batch_norm_layer.cpp +++ b/modules/dnn/src/layers/batch_norm_layer.cpp @@ -172,8 +172,8 @@ public: if (umat_weight.empty()) { - umat_weight = weights_.getUMat(ACCESS_READ); - umat_bias = bias_.getUMat(ACCESS_READ); + weights_.copyTo(umat_weight); + bias_.copyTo(umat_bias); } UMat &inpBlob = inputs[0]; diff --git a/modules/dnn/src/layers/convolution_layer.cpp b/modules/dnn/src/layers/convolution_layer.cpp index 38d56180c7..0f0d3d41e1 100644 --- a/modules/dnn/src/layers/convolution_layer.cpp +++ b/modules/dnn/src/layers/convolution_layer.cpp @@ -1452,8 +1452,10 @@ public: if (umat_weights.empty()) { transpose(blobs[0].reshape(1, inpCn), umat_weights); - umat_biases = hasBias() ? blobs[1].reshape(1, outCn).getUMat(ACCESS_READ) : - UMat::zeros(outCn, 1, CV_32F); + if (hasBias()) + blobs[1].reshape(1, outCn).copyTo(umat_biases); + else + umat_biases = UMat::zeros(outCn, 1, CV_32F); } String buildopt = format("-DT=%s ", ocl::typeToStr(inputs[0].type())); diff --git a/modules/dnn/src/layers/elementwise_layers.cpp b/modules/dnn/src/layers/elementwise_layers.cpp index c042f5fc55..536c0ff50d 100644 --- a/modules/dnn/src/layers/elementwise_layers.cpp +++ b/modules/dnn/src/layers/elementwise_layers.cpp @@ -969,11 +969,12 @@ struct ChannelsPReLUFunctor { typedef ChannelsPReLULayer Layer; Mat scale; +#ifdef HAVE_OPENCL UMat scale_umat; +#endif explicit ChannelsPReLUFunctor(const Mat& scale_=Mat()) : scale(scale_) { - scale_umat = scale.getUMat(ACCESS_READ); } bool supportBackend(int backendId, int) @@ -1021,6 +1022,9 @@ struct ChannelsPReLUFunctor #ifdef HAVE_OPENCL bool applyOCL(InputArrayOfArrays inps, OutputArrayOfArrays outs, OutputArrayOfArrays internals) { + if (scale_umat.empty()) + scale.copyTo(scale_umat); + std::vector inputs; std::vector outputs; diff --git a/modules/dnn/src/layers/fully_connected_layer.cpp b/modules/dnn/src/layers/fully_connected_layer.cpp index 930ce2a4ce..f36813ff18 100644 --- a/modules/dnn/src/layers/fully_connected_layer.cpp +++ b/modules/dnn/src/layers/fully_connected_layer.cpp @@ -96,12 +96,6 @@ public: biasMat = blobs[1] = blobs[1].reshape(1, 1); else biasMat = Mat::zeros(1, numOutput, weightsMat.type()); - -#ifdef HAVE_OPENCL - size_t n = blobs.size(); - umat_blobs.resize(n); - for (int i = 0; i < n; i++) umat_blobs[i] = blobs[i].getUMat(ACCESS_READ); -#endif } bool getMemoryShapes(const std::vector &inputs, @@ -276,6 +270,8 @@ public: virtual void finalize(InputArrayOfArrays, OutputArrayOfArrays) CV_OVERRIDE { innerProductOp.release(); + umat_blobs.clear(); + half_blobs.clear(); } bool forward_ocl(InputArrayOfArrays inps, OutputArrayOfArrays outs, InputArrayOfArrays internals) @@ -288,13 +284,17 @@ public: outs.getUMatVector(outputs); int axisCan = clamp(axis, inputs[0].dims); - int numOutput = umat_blobs[0].size[0]; - int innerSize = umat_blobs[0].size[1]; + int numOutput = blobs[0].size[0]; + int innerSize = blobs[0].size[1]; int outerSize = total(shape(inputs[0]), 0, axisCan); bool ret = true; if (innerProductOp.empty()) { + size_t n = blobs.size(); + umat_blobs.resize(n); + for (int i = 0; i < n; i++) blobs[i].copyTo(umat_blobs[i]); + OCL4DNNInnerProductConfig config; config.num_output = numOutput; config.bias_term = bias; diff --git a/modules/dnn/src/layers/mvn_layer.cpp b/modules/dnn/src/layers/mvn_layer.cpp index 2edbffb90f..a32cbecee9 100644 --- a/modules/dnn/src/layers/mvn_layer.cpp +++ b/modules/dnn/src/layers/mvn_layer.cpp @@ -71,6 +71,9 @@ public: } Mat scale, shift; +#ifdef HAVE_OPENCL + UMat umat_scale, umat_shift; +#endif bool fuse_batch_norm; Ptr activ_relu; @@ -105,6 +108,10 @@ public: for( i = 0; i < splitDim; i++ ) newRows *= inputs[0].size[i]; zeroDev = inputs[0].total() == newRows; +#ifdef HAVE_OPENCL + umat_scale.release(); + umat_shift.release(); +#endif } virtual bool supportBackend(int backendId) CV_OVERRIDE @@ -118,8 +125,13 @@ public: #ifdef HAVE_OPENCL bool fast_forward_ocl(std::vector &inputs, std::vector &outputs) { - UMat bnorm_weight = scale.empty() ? UMat() : scale.getUMat(ACCESS_READ); - UMat bnorm_bias = shift.empty() ? UMat() : shift.getUMat(ACCESS_READ); + if (umat_scale.empty() && !scale.empty()) + scale.copyTo(umat_scale); + if (umat_shift.empty() && !shift.empty()) + shift.copyTo(umat_shift); + UMat& bnorm_weight = umat_scale; + UMat& bnorm_bias = umat_shift; + bool use_half = (inputs[0].depth() == CV_16S); String opts = format(" -DT=%s -DT4=%s -Dconvert_T=%s", use_half ? "half" : "float", use_half ? "half4" : "float4", use_half ? "convert_half4" : "convert_float4"); @@ -177,6 +189,13 @@ public: bool forward_ocl(InputArrayOfArrays inputs_, OutputArrayOfArrays outputs_, OutputArrayOfArrays internals_) { + if (umat_scale.empty() && !scale.empty()) + scale.copyTo(umat_scale); + if (umat_shift.empty() && !shift.empty()) + shift.copyTo(umat_shift); + UMat& bnorm_weight = umat_scale; + UMat& bnorm_bias = umat_shift; + std::vector inputs; std::vector outputs; @@ -192,8 +211,6 @@ public: if (inputs[0].depth() == CV_16S) return false; - UMat bnorm_weight = scale.empty() ? UMat() : scale.getUMat(ACCESS_READ); - UMat bnorm_bias = shift.empty() ? UMat() : shift.getUMat(ACCESS_READ); String opts = format(" -DT=float -DT4=float4 -Dconvert_T=convert_float4"); for (size_t inpIdx = 0; inpIdx < inputs.size(); inpIdx++) diff --git a/modules/dnn/src/layers/region_layer.cpp b/modules/dnn/src/layers/region_layer.cpp index f721d409a9..cfe61c1f65 100644 --- a/modules/dnn/src/layers/region_layer.cpp +++ b/modules/dnn/src/layers/region_layer.cpp @@ -60,6 +60,9 @@ public: int coords, classes, anchors, classfix; float thresh, nmsThreshold; bool useSoftmax, useLogistic; +#ifdef HAVE_OPENCL + UMat blob_umat; +#endif RegionLayerImpl(const LayerParams& params) { @@ -123,6 +126,9 @@ public: #ifdef HAVE_OPENCL bool forward_ocl(InputArrayOfArrays inps, OutputArrayOfArrays outs, OutputArrayOfArrays internals) { + if (blob_umat.empty()) + blobs[0].copyTo(blob_umat); + std::vector inputs; std::vector outputs; @@ -135,7 +141,6 @@ public: CV_Assert(inputs.size() >= 1); int const cell_size = classes + coords + 1; - UMat blob_umat = blobs[0].getUMat(ACCESS_READ); for (size_t ii = 0; ii < outputs.size(); ii++) { From 634dd656d5777d03b25c05a0fbe7dbca02880a74 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Fri, 5 Oct 2018 17:06:50 +0300 Subject: [PATCH 14/23] dnn: don't use Mat expressions with async UMat functions --- modules/dnn/src/dnn.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/modules/dnn/src/dnn.cpp b/modules/dnn/src/dnn.cpp index 8e5f478b00..3a6de1df03 100644 --- a/modules/dnn/src/dnn.cpp +++ b/modules/dnn/src/dnn.cpp @@ -483,6 +483,7 @@ struct DataLayer : public Layer } #ifdef HAVE_OPENCL + std::vector tmp_expressions; bool forward_ocl(InputArrayOfArrays, OutputArrayOfArrays outputs_, OutputArrayOfArrays internals_) { // Supported modes: @@ -493,8 +494,11 @@ struct DataLayer : public Layer std::vector outputs; outputs_.getUMatVector(outputs); + tmp_expressions.clear(); for (int i = 0; i < inputsData.size(); ++i) { + Mat inputData = inputsData[i]; + double scale = scaleFactors[i]; Scalar& mean = means[i]; @@ -508,7 +512,10 @@ struct DataLayer : public Layer if (outputs_.depth() == CV_16S) { if (singleMean) - convertFp16(scale * (inputsData[i] - mean[0]), outputs[i]); + { + tmp_expressions.push_back(Mat(scale * (inputsData[i] - mean[0]))); + convertFp16(tmp_expressions.back(), outputs[i]); + } else { for (int n = 0; n < inputsData[i].size[0]; ++n) @@ -521,7 +528,8 @@ struct DataLayer : public Layer plane[1] = Range(c, c + 1); UMat out = outputs[i](plane).reshape(1, inp.dims, inp.size); - convertFp16(scale * (inp - mean[c]), out); + tmp_expressions.push_back(scale * (inp - mean[c])); + convertFp16(tmp_expressions.back(), out); } } } @@ -529,7 +537,9 @@ struct DataLayer : public Layer { CV_Assert(outputs_.depth() == CV_32F); if (singleMean) + { inputsData[i].convertTo(outputs[i], CV_32F, scale, -mean[0] * scale); + } else { for (int n = 0; n < inputsData[i].size[0]; ++n) From 09ef4c9cff9c6907623640bb632f03ae044336cb Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Fri, 5 Oct 2018 16:38:44 +0300 Subject: [PATCH 15/23] FFmpeg: correct licenses install location --- 3rdparty/ffmpeg/ffmpeg-download.ps1.in | 2 +- 3rdparty/ffmpeg/ffmpeg.cmake | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/3rdparty/ffmpeg/ffmpeg-download.ps1.in b/3rdparty/ffmpeg/ffmpeg-download.ps1.in index 589aa143e8..e92ef45a9b 100644 --- a/3rdparty/ffmpeg/ffmpeg-download.ps1.in +++ b/3rdparty/ffmpeg/ffmpeg-download.ps1.in @@ -4,7 +4,7 @@ $output = "$PSScriptRoot\@OPENCV_BIN_INSTALL_PATH@\opencv_ffmpeg@OPENCV_DLLVERSI Write-Output ("=" * 120) try { - Get-content -Path "$PSScriptRoot\etc\licenses\ffmpeg-readme.txt" -ErrorAction 'Stop' + Get-content -Path "$PSScriptRoot\@OPENCV_LICENSES_INSTALL_PATH@\ffmpeg-readme.txt" -ErrorAction 'Stop' } catch { Write-Output "Refer to OpenCV FFmpeg wrapper readme notes about library usage / licensing details." } diff --git a/3rdparty/ffmpeg/ffmpeg.cmake b/3rdparty/ffmpeg/ffmpeg.cmake index cfa8ff4027..c8ac9d5e53 100644 --- a/3rdparty/ffmpeg/ffmpeg.cmake +++ b/3rdparty/ffmpeg/ffmpeg.cmake @@ -40,3 +40,5 @@ if(OPENCV_INSTALL_FFMPEG_DOWNLOAD_SCRIPT) configure_file("${CMAKE_CURRENT_LIST_DIR}/ffmpeg-download.ps1.in" "${CMAKE_BINARY_DIR}/win-install/ffmpeg-download.ps1" @ONLY) install(FILES "${CMAKE_BINARY_DIR}/win-install/ffmpeg-download.ps1" DESTINATION "." COMPONENT libs) endif() + +ocv_install_3rdparty_licenses(ffmpeg license.txt readme.txt) From 18bf91a08b5032fac9403cb84ab88b30180e0e83 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Fri, 5 Oct 2018 18:23:05 +0300 Subject: [PATCH 16/23] core: update allocSingleton implementation, valgrind suppression --- modules/core/include/opencv2/core/private.hpp | 10 +++++++--- modules/core/src/system.cpp | 2 ++ platforms/scripts/valgrind.supp | 7 +++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/modules/core/include/opencv2/core/private.hpp b/modules/core/include/opencv2/core/private.hpp index ef09d254ca..869b34d8a7 100644 --- a/modules/core/include/opencv2/core/private.hpp +++ b/modules/core/include/opencv2/core/private.hpp @@ -142,9 +142,13 @@ namespace cv CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int unroll_to = 0); //! Allocate all memory buffers which will not be freed, ease filtering memcheck issues -template -T* allocSingleton(size_t count) { return static_cast(fastMalloc(sizeof(T) * count)); } -} +CV_EXPORTS void* allocSingletonBuffer(size_t size); + +//! Allocate all memory buffers which will not be freed, ease filtering memcheck issues +template static inline +T* allocSingleton(size_t count = 1) { return static_cast(allocSingletonBuffer(sizeof(T) * count)); } + +} // namespace #if 1 // TODO: Remove in OpenCV 4.x diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index ac1dc05d2d..eb987f87a2 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -70,6 +70,8 @@ static bool param_dumpErrors = utils::getConfigurationParameterBool("OPENCV_DUMP #endif ); +void* allocSingletonBuffer(size_t size) { return fastMalloc(size); } + } // namespace cv #ifndef CV_ERROR_SET_TERMINATE_HANDLER // build config option diff --git a/platforms/scripts/valgrind.supp b/platforms/scripts/valgrind.supp index f61851c591..074c2013c5 100644 --- a/platforms/scripts/valgrind.supp +++ b/platforms/scripts/valgrind.supp @@ -12,6 +12,13 @@ fun:_ZN2cv22getInitializationMutexEv } +{ + OpenCV-SingletonBuffer + Memcheck:Leak + ... + fun:_ZN2cv20allocSingletonBufferEm +} + { OpenCV-getStdAllocator Memcheck:Leak From 2faa4cd9337b8325d9052be48fbc1a856969d607 Mon Sep 17 00:00:00 2001 From: Hamdi Sahloul Date: Mon, 8 Oct 2018 02:51:45 +0900 Subject: [PATCH 17/23] TS/CUDA: Show device ID in case of multiple devices --- modules/ts/src/cuda_test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/ts/src/cuda_test.cpp b/modules/ts/src/cuda_test.cpp index 307e1296a2..39658c403a 100644 --- a/modules/ts/src/cuda_test.cpp +++ b/modules/ts/src/cuda_test.cpp @@ -559,4 +559,6 @@ namespace cvtest void cv::cuda::PrintTo(const DeviceInfo& info, std::ostream* os) { (*os) << info.name(); + if (info.deviceID()) + (*os) << " [ID: " << info.deviceID() << "]"; } From 7649e537b778dc9f7a7e36639a6e9dbae9534f21 Mon Sep 17 00:00:00 2001 From: Dmitry Kurtaev Date: Sun, 7 Oct 2018 22:55:38 +0300 Subject: [PATCH 18/23] Fix JavaScript bindings for features2d module --- modules/js/src/core_bindings.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/js/src/core_bindings.cpp b/modules/js/src/core_bindings.cpp index e8f0ee7f85..60679bb96f 100644 --- a/modules/js/src/core_bindings.cpp +++ b/modules/js/src/core_bindings.cpp @@ -327,6 +327,7 @@ EMSCRIPTEN_BINDINGS(binding_utils) register_vector("PointVector"); register_vector("MatVector"); register_vector("RectVector"); + register_vector("KeyPointVector"); emscripten::class_("Mat") .constructor<>() @@ -472,6 +473,14 @@ EMSCRIPTEN_BINDINGS(binding_utils) function("rotatedRectBoundingRect", select_overload(&binding_utils::rotatedRectBoundingRect)); function("rotatedRectBoundingRect2f", select_overload(&binding_utils::rotatedRectBoundingRect2f)); + emscripten::value_object("KeyPoint") + .field("angle", &cv::KeyPoint::angle) + .field("class_id", &cv::KeyPoint::class_id) + .field("octave", &cv::KeyPoint::octave) + .field("pt", &cv::KeyPoint::pt) + .field("response", &cv::KeyPoint::response) + .field("size", &cv::KeyPoint::size); + emscripten::value_array> ("Scalar") .element(index<0>()) .element(index<1>()) From 913c4151bf4d2e4202200a72e53f0b2317bd419f Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Mon, 8 Oct 2018 17:45:50 +0300 Subject: [PATCH 19/23] Merge pull request #12725 from alalek:cmake_python_win32 * cmake: don't ignore Python from PATH environment variable - this breaks selection between 32/64-bit Python - this breaks Anaconda/Conda environments - it is not the CMake default behavior, expected by many projects * cmake: add Python version check, fallback path on CMake 3.12+ * cmake: drop Python 2.6, allow version selection for Python 3.x --- cmake/OpenCVDetectPython.cmake | 48 ++++++++++++++++++++++++++------ cmake/OpenCVMinDepVersions.cmake | 2 +- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/cmake/OpenCVDetectPython.cmake b/cmake/OpenCVDetectPython.cmake index 3a880215d2..140fb6283c 100644 --- a/cmake/OpenCVDetectPython.cmake +++ b/cmake/OpenCVDetectPython.cmake @@ -38,7 +38,7 @@ if(NOT ${found}) set(PYTHON_EXECUTABLE "${${executable}}") endif() - if(WIN32 AND NOT ${executable}) + if(WIN32 AND NOT ${executable} AND OPENCV_PYTHON_PREFER_WIN32_REGISTRY) # deprecated # search for executable with the same bitness as resulting binaries # standard FindPythonInterp always prefers executable from system path # this is really important because we are using the interpreter for numpy search and for choosing the install location @@ -53,16 +53,47 @@ if(NOT ${found}) endforeach() endif() - string(REGEX MATCH "^[0-9]+" _preferred_version_major "${preferred_version}") - - find_host_package(PythonInterp "${preferred_version}") - if(NOT PYTHONINTERP_FOUND) + if(preferred_version) + set(__python_package_version "${preferred_version} EXACT") + find_host_package(PythonInterp "${preferred_version}" EXACT) + if(NOT PYTHONINTERP_FOUND) + message(STATUS "Python is not found: ${preferred_version} EXACT") + endif() + else() + set(__python_package_version "${min_version}") find_host_package(PythonInterp "${min_version}") endif() + string(REGEX MATCH "^[0-9]+" _python_version_major "${min_version}") + if(PYTHONINTERP_FOUND) # Check if python major version is correct - if("${_preferred_version_major}" STREQUAL "" OR "${_preferred_version_major}" STREQUAL "${PYTHON_VERSION_MAJOR}") + if(NOT "${_python_version_major}" STREQUAL "${PYTHON_VERSION_MAJOR}" + AND NOT DEFINED ${executable} + ) + if(NOT OPENCV_SKIP_PYTHON_WARNING) + message(WARNING "CMake's 'find_host_package(PythonInterp ${__python_package_version})' founds wrong Python version:\n" + "PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}\n" + "PYTHON_VERSION_STRING=${PYTHON_VERSION_STRING}\n" + "Consider specify '${executable}' variable via CMake command line or environment variables\n") + endif() + ocv_clear_vars(PYTHONINTERP_FOUND PYTHON_EXECUTABLE PYTHON_VERSION_STRING PYTHON_VERSION_MAJOR PYTHON_VERSION_MINOR PYTHON_VERSION_PATCH) + if(NOT CMAKE_VERSION VERSION_LESS "3.12") + if(_python_version_major STREQUAL "2") + set(__PYTHON_PREFIX Python2) + else() + set(__PYTHON_PREFIX Python3) + endif() + find_host_package(${__PYTHON_PREFIX} "${preferred_version}" COMPONENTS Interpreter) + if(${__PYTHON_PREFIX}_EXECUTABLE) + set(PYTHON_EXECUTABLE "${${__PYTHON_PREFIX}_EXECUTABLE}") + find_host_package(PythonInterp "${preferred_version}") # Populate other variables + endif() + else() + message(STATUS "Consider using CMake 3.12+ for better Python support") + endif() + endif() + if(PYTHONINTERP_FOUND AND "${_python_version_major}" STREQUAL "${PYTHON_VERSION_MAJOR}") # Copy outputs set(_found ${PYTHONINTERP_FOUND}) set(_executable ${PYTHON_EXECUTABLE}) @@ -235,7 +266,7 @@ if(OPENCV_PYTHON_SKIP_DETECTION) return() endif() -find_python(2.7 "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR +find_python("" "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR PYTHON2INTERP_FOUND PYTHON2_EXECUTABLE PYTHON2_VERSION_STRING PYTHON2_VERSION_MAJOR PYTHON2_VERSION_MINOR PYTHON2LIBS_FOUND PYTHON2LIBS_VERSION_STRING PYTHON2_LIBRARIES PYTHON2_LIBRARY @@ -243,7 +274,8 @@ find_python(2.7 "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR PYTHON2_INCLUDE_DIR PYTHON2_INCLUDE_DIR2 PYTHON2_PACKAGES_PATH PYTHON2_NUMPY_INCLUDE_DIRS PYTHON2_NUMPY_VERSION) -find_python(3.4 "${MIN_VER_PYTHON3}" PYTHON3_LIBRARY PYTHON3_INCLUDE_DIR +option(OPENCV_PYTHON3_VERSION "Python3 version" "") +find_python("${OPENCV_PYTHON3_VERSION}" "${MIN_VER_PYTHON3}" PYTHON3_LIBRARY PYTHON3_INCLUDE_DIR PYTHON3INTERP_FOUND PYTHON3_EXECUTABLE PYTHON3_VERSION_STRING PYTHON3_VERSION_MAJOR PYTHON3_VERSION_MINOR PYTHON3LIBS_FOUND PYTHON3LIBS_VERSION_STRING PYTHON3_LIBRARIES PYTHON3_LIBRARY diff --git a/cmake/OpenCVMinDepVersions.cmake b/cmake/OpenCVMinDepVersions.cmake index d2c5b7c27f..a7e2477956 100644 --- a/cmake/OpenCVMinDepVersions.cmake +++ b/cmake/OpenCVMinDepVersions.cmake @@ -1,6 +1,6 @@ set(MIN_VER_CMAKE 2.8.12.2) set(MIN_VER_CUDA 6.5) -set(MIN_VER_PYTHON2 2.6) +set(MIN_VER_PYTHON2 2.7) set(MIN_VER_PYTHON3 3.2) set(MIN_VER_ZLIB 1.2.3) set(MIN_VER_GTK 2.18.0) From 50811e04f200fddf59ef92909bb22c8d66632707 Mon Sep 17 00:00:00 2001 From: Lubov Batanina Date: Mon, 8 Oct 2018 22:18:41 +0300 Subject: [PATCH 20/23] Merge pull request #12596 from l-bat:l-bat/shufflenet_onnx * Add Shufflenet support in ONNX * Add test for transpose layer --- modules/dnn/src/layers/permute_layer.cpp | 2 -- modules/dnn/src/onnx/onnx_importer.cpp | 5 +++++ modules/dnn/test/test_onnx_importer.cpp | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/modules/dnn/src/layers/permute_layer.cpp b/modules/dnn/src/layers/permute_layer.cpp index ac294a9a10..8d14d9ca95 100644 --- a/modules/dnn/src/layers/permute_layer.cpp +++ b/modules/dnn/src/layers/permute_layer.cpp @@ -132,8 +132,6 @@ public: for (size_t i = 0; i < inputs.size(); i++) { - CV_Assert(inputs[i].size() == 4); - CV_Assert(inputs[i][2] == shapeBefore[2] && inputs[i][3] == shapeBefore[3]); CV_Assert(total(inputs[i]) == total(shapeAfter)); outputs.push_back(shapeAfter); } diff --git a/modules/dnn/src/onnx/onnx_importer.cpp b/modules/dnn/src/onnx/onnx_importer.cpp index a9daa198df..3c50566449 100644 --- a/modules/dnn/src/onnx/onnx_importer.cpp +++ b/modules/dnn/src/onnx/onnx_importer.cpp @@ -486,6 +486,11 @@ void ONNXImporter::populateNet(Net dstNet) layerParams.set("num_output", layerParams.blobs[0].size[0]); layerParams.set("bias_term", node_proto.input_size() == 3); } + else if (layer_type == "Transpose") + { + layerParams.type = "Permute"; + replaceLayerParam(layerParams, "perm", "order"); + } else if (layer_type == "Unsqueeze") { CV_Assert(node_proto.input_size() == 1); diff --git a/modules/dnn/test/test_onnx_importer.cpp b/modules/dnn/test/test_onnx_importer.cpp index 9415bea754..52e867a499 100644 --- a/modules/dnn/test/test_onnx_importer.cpp +++ b/modules/dnn/test/test_onnx_importer.cpp @@ -108,6 +108,14 @@ TEST_P(Test_ONNX_layers, BatchNormalization) testONNXModels("batch_norm"); } +TEST_P(Test_ONNX_layers, Transpose) +{ + if (backend == DNN_BACKEND_INFERENCE_ENGINE && + (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_OPENCL || target == DNN_TARGET_MYRIAD)) + throw SkipTestException(""); + testONNXModels("transpose"); +} + TEST_P(Test_ONNX_layers, Multiplication) { if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16 || @@ -351,6 +359,14 @@ TEST_P(Test_ONNX_nets, Inception_v1) testONNXModels("inception_v1", pb); } +TEST_P(Test_ONNX_nets, Shufflenet) +{ + if (backend == DNN_BACKEND_INFERENCE_ENGINE && + (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_OPENCL || target == DNN_TARGET_MYRIAD)) + throw SkipTestException(""); + testONNXModels("shufflenet", pb); +} + INSTANTIATE_TEST_CASE_P(/**/, Test_ONNX_nets, dnnBackendsAndTargets()); }} // namespace From b8aa0cddab9306aaf8c262016dec9f4976ac1568 Mon Sep 17 00:00:00 2001 From: Apoorv Goel <35146783+UnderscoreAsterisk@users.noreply.github.com> Date: Tue, 9 Oct 2018 18:19:17 +0530 Subject: [PATCH 21/23] Merge pull request #12777 from UnderscoreAsterisk:document-cvtColorTwoPlane * Add documentation for cvtColorTwoPlane * Change brief and add links --- modules/imgproc/include/opencv2/imgproc.hpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/modules/imgproc/include/opencv2/imgproc.hpp b/modules/imgproc/include/opencv2/imgproc.hpp index bfffe1ec84..d489c02673 100644 --- a/modules/imgproc/include/opencv2/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc.hpp @@ -3636,6 +3636,24 @@ channels is derived automatically from src and code. */ CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 ); +/** @brief Converts an image from one color space to another where the source image is +stored in two planes. + +This function only supports YUV420 to RGB conversion as of now. + +@param src1: 8-bit image (#CV_8U) of the Y plane. +@param src2: image containing interleaved U/V plane. +@param dst: output image. +@param code: Specifies the type of conversion. It can take any of the following values: +- #COLOR_YUV2BGR_NV12 +- #COLOR_YUV2RGB_NV12 +- #COLOR_YUV2BGRA_NV12 +- #COLOR_YUV2RGBA_NV12 +- #COLOR_YUV2BGR_NV21 +- #COLOR_YUV2RGB_NV21 +- #COLOR_YUV2BGRA_NV21 +- #COLOR_YUV2RGBA_NV21 +*/ CV_EXPORTS_W void cvtColorTwoPlane( InputArray src1, InputArray src2, OutputArray dst, int code ); //! @} imgproc_misc From c4d434fd6f42edd955429990354191200897204d Mon Sep 17 00:00:00 2001 From: Hamdi Sahloul <42140441+cv3d@users.noreply.github.com> Date: Tue, 9 Oct 2018 23:39:39 +0900 Subject: [PATCH 22/23] CUDA/BgSegm: fix the threshold of MOG2.Update test when detectShadow=true (#12762) --- modules/cudabgsegm/test/test_bgsegm.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/modules/cudabgsegm/test/test_bgsegm.cpp b/modules/cudabgsegm/test/test_bgsegm.cpp index ce7c22808b..c0c319ff42 100644 --- a/modules/cudabgsegm/test/test_bgsegm.cpp +++ b/modules/cudabgsegm/test/test_bgsegm.cpp @@ -110,14 +110,7 @@ CUDA_TEST_P(MOG2, Update) mog2_gold->apply(frame, foreground_gold); - if (detectShadow) - { - ASSERT_MAT_SIMILAR(foreground_gold, foreground, 1e-2); - } - else - { - ASSERT_MAT_NEAR(foreground_gold, foreground, 0); - } + ASSERT_MAT_SIMILAR(foreground_gold, foreground, detectShadow ? 13e-3 : 18e-8); } } From 421fdc0e94c33e81f775e85202fd8a853cb6abbb Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Tue, 9 Oct 2018 19:01:29 +0300 Subject: [PATCH 23/23] Merge pull request #12636 from alalek:winpack_samples_cpp_build_script * samples: add winpack "drap & drop" build script * samples: add search for MSVS 2017 Enterprise --- samples/CMakeLists.example.in | 42 +++++++ samples/_winpack_build_sample.cmd | 180 ++++++++++++++++++++++++++++++ 2 files changed, 222 insertions(+) create mode 100644 samples/CMakeLists.example.in create mode 100644 samples/_winpack_build_sample.cmd diff --git a/samples/CMakeLists.example.in b/samples/CMakeLists.example.in new file mode 100644 index 0000000000..1769d4d9cf --- /dev/null +++ b/samples/CMakeLists.example.in @@ -0,0 +1,42 @@ +# cmake needs this line +cmake_minimum_required(VERSION 3.1) + +if(NOT DEFINED EXAMPLE_NAME) + message(FATAL_ERROR "Invalid build script: missing EXAMPLE_NAME") +endif() +if(NOT DEFINED EXAMPLE_FILE) + message(FATAL_ERROR "Invalid build script: missing EXAMPLE_FILE") +endif() + +file(TO_CMAKE_PATH "${EXAMPLE_FILE}" EXAMPLE_FILE) +message(STATUS "Project: ${EXAMPLE_NAME}") +message(STATUS "File : ${EXAMPLE_FILE}") + +# Enable C++11 +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED TRUE) + + +# Define project name +project(${EXAMPLE_NAME}) + +# Find OpenCV, you may need to set OpenCV_DIR variable +# to the absolute path to the directory containing OpenCVConfig.cmake file +# via the command line or GUI +find_package(OpenCV REQUIRED) + +# If the package has been found, several variables will +# be set, you can find the full list with descriptions +# in the OpenCVConfig.cmake file. +# Print some message showing some of them +message(STATUS "OpenCV library status:") +message(STATUS " config: ${OpenCV_DIR}") +message(STATUS " version: ${OpenCV_VERSION}") +message(STATUS " libraries: ${OpenCV_LIBS}") +message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}") + +# Declare the executable target built from your sources +add_executable(${EXAMPLE_NAME} "${EXAMPLE_FILE}") + +# Link your application with OpenCV libraries +target_link_libraries(${EXAMPLE_NAME} ${OpenCV_LIBS}) diff --git a/samples/_winpack_build_sample.cmd b/samples/_winpack_build_sample.cmd new file mode 100644 index 0000000000..c671d140fa --- /dev/null +++ b/samples/_winpack_build_sample.cmd @@ -0,0 +1,180 @@ +:: Usage: +:: - Drag & drop .cpp file on this file from Windows explorer +:: - Run from cmd/powershell: +:: - > _winpack_build_sample.cmd cpp\opencv_version.cpp +:: Requires: +:: - CMake +:: - MSVS 2015/2017 +:: (tools are searched on default paths or environment should be pre-configured) +@echo off +setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION + +set SCRIPTDIR=%~dp0 +if NOT exist "%SCRIPTDIR%\..\..\build" ( + set "MSG=OpenCV Winpack installation is required" + goto die +) + +if [%1]==[] ( + set "MSG=Sample path is required" + goto die +) +if exist %1\* ( + set "MSG=Only .cpp samples are allowed (not a directory): %1" + goto die +) +if NOT "%~x1" == ".cpp" ( + set "MSG=Only .cpp samples are allowed: %~x1" + goto die +) +set SRC_FILENAME=%~dpnx1 +echo SRC_FILENAME=!SRC_FILENAME! +call :dirname "!SRC_FILENAME!" SRC_DIR +echo SRC_DIR=!SRC_DIR! +set "SRC_NAME=%~n1" +echo SRC_NAME=!SRC_NAME! +echo ================================================================================ + +:: Path to FFMPEG binary files +set "PATH=!PATH!;!SCRIPTDIR!\..\..\build\bin\" + +:: Detect CMake +cmake --version >NUL 2>NUL +if !ERRORLEVEL! EQU 0 ( + set CMAKE_FOUND=1 +) else ( + if exist "C:\Program Files\CMake\bin" ( + set "PATH=!PATH!;C:\Program Files\CMake\bin" + cmake --version >NUL 2>NUL + if !ERRORLEVEL! EQU 0 ( + set CMAKE_FOUND=1 + ) + ) +) +if NOT DEFINED CMAKE_FOUND ( + set "MSG=CMake is required to build OpenCV samples. Download it from here: https://cmake.org/download/ and install into 'C:\Program Files\CMake'" + goto die +) else ( + echo CMake is detected +) + +:: Detect compiler +cl /? >NUL 2>NUL NUL 2>NUL