From d3ac1bc314136d0654fad24a9ee5b01c29e9f5af Mon Sep 17 00:00:00 2001
From: Pierre-Emmanuel Viel
Date: Fri, 20 Dec 2013 01:00:55 +0100
Subject: [PATCH 01/22] When a cluster is empty for KMeans, it's better to give
it the point from another cluster j that is the furthest one from center j.
---
modules/flann/include/opencv2/flann/kmeans_index.h | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/modules/flann/include/opencv2/flann/kmeans_index.h b/modules/flann/include/opencv2/flann/kmeans_index.h
index 3fea956a74..489ed80565 100644
--- a/modules/flann/include/opencv2/flann/kmeans_index.h
+++ b/modules/flann/include/opencv2/flann/kmeans_index.h
@@ -759,10 +759,13 @@ private:
for (int k=0; k
Date: Wed, 5 Mar 2014 11:25:27 +0400
Subject: [PATCH 02/22] Implicit CUDA and OpenCL control for module definition
added.
Feature allows to exclude CUDA or OpenCL optimizations at all even CUDA is used
on build. Exclusion of CUDA or OpenCL cut unwanted dependencies.
---
cmake/OpenCVModule.cmake | 66 +++++++++++++++++--------
modules/nonfree/CMakeLists.txt | 2 +-
modules/superres/src/cuda/btv_l1_gpu.cu | 2 +-
modules/ts/CMakeLists.txt | 2 +-
4 files changed, 49 insertions(+), 23 deletions(-)
diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake
index 03818018d9..c9c351113c 100644
--- a/cmake/OpenCVModule.cmake
+++ b/cmake/OpenCVModule.cmake
@@ -479,39 +479,49 @@ endmacro()
# finds and sets headers and sources for the standard OpenCV module
# Usage:
# ocv_glob_module_sources()
-macro(ocv_glob_module_sources)
+macro(ocv_glob_module_sources EXCLUDE_CUDA EXCLUDE_OPENCL)
file(GLOB_RECURSE lib_srcs "src/*.cpp")
file(GLOB_RECURSE lib_int_hdrs "src/*.hpp" "src/*.h")
file(GLOB lib_hdrs "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h")
file(GLOB lib_hdrs_detail "include/opencv2/${name}/detail/*.hpp" "include/opencv2/${name}/detail/*.h")
- file(GLOB lib_cuda_srcs "src/cuda/*.cu")
- set(cuda_objs "")
- set(lib_cuda_hdrs "")
- if(HAVE_CUDA)
- ocv_include_directories(${CUDA_INCLUDE_DIRS})
- file(GLOB lib_cuda_hdrs "src/cuda/*.hpp")
+ if (NOT ${EXCLUDE_CUDA})
+ file(GLOB lib_cuda_srcs "src/cuda/*.cu")
+ set(cuda_objs "")
+ set(lib_cuda_hdrs "")
+ if(HAVE_CUDA)
+ ocv_include_directories(${CUDA_INCLUDE_DIRS})
+ file(GLOB lib_cuda_hdrs "src/cuda/*.hpp")
- ocv_cuda_compile(cuda_objs ${lib_cuda_srcs} ${lib_cuda_hdrs})
- source_group("Src\\Cuda" FILES ${lib_cuda_srcs} ${lib_cuda_hdrs})
+ ocv_cuda_compile(cuda_objs ${lib_cuda_srcs} ${lib_cuda_hdrs})
+ source_group("Src\\Cuda" FILES ${lib_cuda_srcs} ${lib_cuda_hdrs})
+ endif()
+ else()
+ set(cuda_objs "")
+ set(lib_cuda_srcs "")
+ set(lib_cuda_hdrs "")
endif()
source_group("Src" FILES ${lib_srcs} ${lib_int_hdrs})
- file(GLOB cl_kernels "src/opencl/*.cl")
- if(HAVE_opencv_ocl AND cl_kernels)
- ocv_include_directories(${OPENCL_INCLUDE_DIRS})
- add_custom_command(
- OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp"
- COMMAND ${CMAKE_COMMAND} -DCL_DIR="${CMAKE_CURRENT_SOURCE_DIR}/src/opencl" -DOUTPUT="${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" -P "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake"
- DEPENDS ${cl_kernels} "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake")
- source_group("OpenCL" FILES ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp")
- list(APPEND lib_srcs ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp")
+ if (NOT ${EXCLUDE_OPENCL})
+ file(GLOB cl_kernels "src/opencl/*.cl")
+ if(HAVE_opencv_ocl AND cl_kernels)
+ ocv_include_directories(${OPENCL_INCLUDE_DIRS})
+ add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp"
+ COMMAND ${CMAKE_COMMAND} -DCL_DIR="${CMAKE_CURRENT_SOURCE_DIR}/src/opencl" -DOUTPUT="${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" -P "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake"
+ DEPENDS ${cl_kernels} "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake")
+ source_group("OpenCL" FILES ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp")
+ list(APPEND lib_srcs ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp")
+ endif()
endif()
source_group("Include" FILES ${lib_hdrs})
source_group("Include\\detail" FILES ${lib_hdrs_detail})
+ message(":${EXCLUDE_CUDA}: ${lib_cuda_srcs}")
+
ocv_set_module_sources(${ARGN} HEADERS ${lib_hdrs} ${lib_hdrs_detail}
SOURCES ${lib_srcs} ${lib_int_hdrs} ${cuda_objs} ${lib_cuda_srcs} ${lib_cuda_hdrs})
endmacro()
@@ -614,9 +624,25 @@ endmacro()
# Usage:
# ocv_define_module(module_name [INTERNAL] [REQUIRED] [] [OPTIONAL ])
macro(ocv_define_module module_name)
- ocv_add_module(${module_name} ${ARGN})
+ set(_tmp_argn ${ARGN})
+ set(exclude_cuda 0)
+ set(exclude_opencl 0)
+ set(argv0 ${ARGV1})
+ set(argv1 ${ARGV2})
+ set(argv2 ${ARGV3})
+ foreach(i RANGE 0 2)
+ if("${argv${i}}" STREQUAL "EXCLUDE_CUDA")
+ set(exclude_cuda 1)
+ list(REMOVE_AT _tmp_argn ${i})
+ elseif ("${argv${i}}" STREQUAL "EXCLUDE_OPENCL")
+ set(exclude_opencl 1)
+ list(REMOVE_AT _tmp_argn ${i})
+ endif()
+ endforeach()
+
+ ocv_add_module(${module_name} ${_tmp_argn})
ocv_module_include_directories()
- ocv_glob_module_sources()
+ ocv_glob_module_sources(${exclude_cuda} ${exclude_opencl})
ocv_create_module()
ocv_add_precompiled_headers(${the_module})
diff --git a/modules/nonfree/CMakeLists.txt b/modules/nonfree/CMakeLists.txt
index b43273bc80..571614be0d 100644
--- a/modules/nonfree/CMakeLists.txt
+++ b/modules/nonfree/CMakeLists.txt
@@ -6,7 +6,7 @@ set(the_description "Functionality with possible limitations on the use")
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wshadow)
if(ENABLE_DYNAMIC_CUDA)
add_definitions(-DDYNAMIC_CUDA_SUPPORT)
- ocv_define_module(nonfree opencv_imgproc opencv_features2d opencv_calib3d OPTIONAL opencv_ocl)
+ ocv_define_module(nonfree EXCLUDE_CUDA opencv_imgproc opencv_features2d opencv_calib3d OPTIONAL opencv_ocl)
else()
ocv_define_module(nonfree opencv_imgproc opencv_features2d opencv_calib3d OPTIONAL opencv_gpu opencv_ocl)
endif()
diff --git a/modules/superres/src/cuda/btv_l1_gpu.cu b/modules/superres/src/cuda/btv_l1_gpu.cu
index b4d96190ae..4b0ebdc592 100644
--- a/modules/superres/src/cuda/btv_l1_gpu.cu
+++ b/modules/superres/src/cuda/btv_l1_gpu.cu
@@ -42,7 +42,7 @@
#include "opencv2/opencv_modules.hpp"
-#ifdef HAVE_OPENCV_GPU
+#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
#include "opencv2/gpu/device/common.hpp"
#include "opencv2/gpu/device/transform.hpp"
diff --git a/modules/ts/CMakeLists.txt b/modules/ts/CMakeLists.txt
index bb56da2d98..dcd3e1563b 100644
--- a/modules/ts/CMakeLists.txt
+++ b/modules/ts/CMakeLists.txt
@@ -11,7 +11,7 @@ ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef)
ocv_add_module(ts opencv_core opencv_features2d)
-ocv_glob_module_sources()
+ocv_glob_module_sources(0 0)
ocv_module_include_directories()
ocv_create_module()
From 0eaeff06418223c89f86fc2fdcf48fbc90f4c4cb Mon Sep 17 00:00:00 2001
From: kurodash
Date: Fri, 7 Mar 2014 19:02:37 +0900
Subject: [PATCH 03/22] fix: use "cvAlloc" wrapper function for malloc.
---
modules/core/src/persistence.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp
index 7759f708b6..4a6e0c9ec5 100644
--- a/modules/core/src/persistence.cpp
+++ b/modules/core/src/persistence.cpp
@@ -4855,7 +4855,7 @@ cvRegisterType( const CvTypeInfo* _info )
"Type name should contain only letters, digits, - and _" );
}
- info = (CvTypeInfo*)malloc( sizeof(*info) + len + 1 );
+ info = (CvTypeInfo*)cvAlloc( sizeof(*info) + len + 1 );
*info = *_info;
info->type_name = (char*)(info + 1);
@@ -4893,7 +4893,7 @@ cvUnregisterType( const char* type_name )
if( !CvType::first || !CvType::last )
CvType::first = CvType::last = 0;
- free( info );
+ cvFree( info );
}
}
From a87607e3ef6d30a2ccd8bd3b516fde4647dce16d Mon Sep 17 00:00:00 2001
From: Firat Kalaycilar
Date: Wed, 12 Mar 2014 16:14:59 +0200
Subject: [PATCH 04/22] Fixed an issue with weight assignment causing the
resulting GMM weights to be unsorted in BackgroundSubtractorMOG2
---
modules/video/src/bgfg_gaussmix2.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/modules/video/src/bgfg_gaussmix2.cpp b/modules/video/src/bgfg_gaussmix2.cpp
index 6bbb960482..b14bc8e1e2 100644
--- a/modules/video/src/bgfg_gaussmix2.cpp
+++ b/modules/video/src/bgfg_gaussmix2.cpp
@@ -319,7 +319,7 @@ struct MOG2Invoker : ParallelLoopBody
for( int mode = 0; mode < nmodes; mode++, mean_m += nchannels )
{
float weight = alpha1*gmm[mode].weight + prune;//need only weight if fit is found
-
+ int swap_count = 0;
////
//fit not found yet
if( !fitsPDF )
@@ -384,6 +384,7 @@ struct MOG2Invoker : ParallelLoopBody
if( weight < gmm[i-1].weight )
break;
+ swap_count++;
//swap one up
std::swap(gmm[i], gmm[i-1]);
for( int c = 0; c < nchannels; c++ )
@@ -401,7 +402,7 @@ struct MOG2Invoker : ParallelLoopBody
nmodes--;
}
- gmm[mode].weight = weight;//update weight by the calculated value
+ gmm[mode-swap_count].weight = weight;//update weight by the calculated value
totalWeight += weight;
}
//go through all modes
From f9484bae8ab748132e753b8c217c5ded36a5c9dd Mon Sep 17 00:00:00 2001
From: kuroda sho
Date: Fri, 14 Mar 2014 17:02:20 +0900
Subject: [PATCH 05/22] fix: use "cvAlloc" wrapper function for malloc.
---
modules/core/src/persistence.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp
index 4a6e0c9ec5..6847eec34d 100644
--- a/modules/core/src/persistence.cpp
+++ b/modules/core/src/persistence.cpp
@@ -4893,7 +4893,7 @@ cvUnregisterType( const char* type_name )
if( !CvType::first || !CvType::last )
CvType::first = CvType::last = 0;
- cvFree( info );
+ cvFree( &info );
}
}
From 5f94a205d14180d5fd9c0b451add6da35a2b3f9f Mon Sep 17 00:00:00 2001
From: berak
Date: Thu, 13 Mar 2014 08:39:15 +0100
Subject: [PATCH 06/22] fixed h / s ranges in histogram_calculation tutorial
literalinclude
literalinclude, dropped :lines:
---
.../histogram_comparison.rst | 90 ++-----------------
.../Histograms_Matching/compareHist_Demo.cpp | 6 +-
2 files changed, 9 insertions(+), 87 deletions(-)
diff --git a/doc/tutorials/imgproc/histograms/histogram_comparison/histogram_comparison.rst b/doc/tutorials/imgproc/histograms/histogram_comparison/histogram_comparison.rst
index 1a5c59de07..f5f636d08b 100644
--- a/doc/tutorials/imgproc/histograms/histogram_comparison/histogram_comparison.rst
+++ b/doc/tutorials/imgproc/histograms/histogram_comparison/histogram_comparison.rst
@@ -84,88 +84,10 @@ Code
* **Code at glance:**
-.. code-block:: cpp
+.. literalinclude:: ../../../../../samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp
+ :language: cpp
+ :tab-width: 4
- #include "opencv2/highgui/highgui.hpp"
- #include "opencv2/imgproc/imgproc.hpp"
- #include
- #include
-
- using namespace std;
- using namespace cv;
-
- /** @function main */
- int main( int argc, char** argv )
- {
- Mat src_base, hsv_base;
- Mat src_test1, hsv_test1;
- Mat src_test2, hsv_test2;
- Mat hsv_half_down;
-
- /// Load three images with different environment settings
- if( argc < 4 )
- { printf("** Error. Usage: ./compareHist_Demo \n");
- return -1;
- }
-
- src_base = imread( argv[1], 1 );
- src_test1 = imread( argv[2], 1 );
- src_test2 = imread( argv[3], 1 );
-
- /// Convert to HSV
- cvtColor( src_base, hsv_base, CV_BGR2HSV );
- cvtColor( src_test1, hsv_test1, CV_BGR2HSV );
- cvtColor( src_test2, hsv_test2, CV_BGR2HSV );
-
- hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) );
-
- /// Using 30 bins for hue and 32 for saturation
- int h_bins = 50; int s_bins = 60;
- int histSize[] = { h_bins, s_bins };
-
- // hue varies from 0 to 256, saturation from 0 to 180
- float h_ranges[] = { 0, 256 };
- float s_ranges[] = { 0, 180 };
-
- const float* ranges[] = { h_ranges, s_ranges };
-
- // Use the o-th and 1-st channels
- int channels[] = { 0, 1 };
-
- /// Histograms
- MatND hist_base;
- MatND hist_half_down;
- MatND hist_test1;
- MatND hist_test2;
-
- /// Calculate the histograms for the HSV images
- calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false );
- normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() );
-
- calcHist( &hsv_half_down, 1, channels, Mat(), hist_half_down, 2, histSize, ranges, true, false );
- normalize( hist_half_down, hist_half_down, 0, 1, NORM_MINMAX, -1, Mat() );
-
- calcHist( &hsv_test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false );
- normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() );
-
- calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false );
- normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() );
-
- /// Apply the histogram comparison methods
- for( int i = 0; i < 4; i++ )
- { int compare_method = i;
- double base_base = compareHist( hist_base, hist_base, compare_method );
- double base_half = compareHist( hist_base, hist_half_down, compare_method );
- double base_test1 = compareHist( hist_base, hist_test1, compare_method );
- double base_test2 = compareHist( hist_base, hist_test2, compare_method );
-
- printf( " Method [%d] Perfect, Base-Half, Base-Test(1), Base-Test(2) : %f, %f, %f, %f \n", i, base_base, base_half , base_test1, base_test2 );
- }
-
- printf( "Done \n" );
-
- return 0;
- }
Explanation
@@ -211,11 +133,11 @@ Explanation
.. code-block:: cpp
- int h_bins = 50; int s_bins = 32;
+ int h_bins = 50; int s_bins = 60;
int histSize[] = { h_bins, s_bins };
- float h_ranges[] = { 0, 256 };
- float s_ranges[] = { 0, 180 };
+ float h_ranges[] = { 0, 180 };
+ float s_ranges[] = { 0, 256 };
const float* ranges[] = { h_ranges, s_ranges };
diff --git a/samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp b/samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp
index f4dd4e5e4e..424a38e93a 100644
--- a/samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp
+++ b/samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp
@@ -40,13 +40,13 @@ int main( int argc, char** argv )
hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) );
- /// Using 30 bins for hue and 32 for saturation
+ /// Using 50 bins for hue and 60 for saturation
int h_bins = 50; int s_bins = 60;
int histSize[] = { h_bins, s_bins };
- // hue varies from 0 to 256, saturation from 0 to 180
- float s_ranges[] = { 0, 256 };
+ // hue varies from 0 to 179, saturation from 0 to 255
float h_ranges[] = { 0, 180 };
+ float s_ranges[] = { 0, 256 };
const float* ranges[] = { h_ranges, s_ranges };
From 6b8de222d770174fc1fb31b1b64da8995e8a8ebf Mon Sep 17 00:00:00 2001
From: Alexander Smorkalov
Date: Wed, 5 Mar 2014 09:57:16 +0400
Subject: [PATCH 07/22] OpenCV_MODULES_SUFFIX variable added to
OpenCVConfig.cmake to enable custom module configurations.
---
cmake/templates/OpenCVConfig.cmake.in | 28 +++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/cmake/templates/OpenCVConfig.cmake.in b/cmake/templates/OpenCVConfig.cmake.in
index 6db61d2112..3222048282 100644
--- a/cmake/templates/OpenCVConfig.cmake.in
+++ b/cmake/templates/OpenCVConfig.cmake.in
@@ -18,8 +18,8 @@
# This file will define the following variables:
# - OpenCV_LIBS : The list of all imported targets for OpenCV modules.
# - OpenCV_INCLUDE_DIRS : The OpenCV include directories.
-# - OpenCV_COMPUTE_CAPABILITIES : The version of compute capability
-# - OpenCV_ANDROID_NATIVE_API_LEVEL : Minimum required level of Android API
+# - OpenCV_COMPUTE_CAPABILITIES : The version of compute capability.
+# - OpenCV_ANDROID_NATIVE_API_LEVEL : Minimum required level of Android API.
# - OpenCV_VERSION : The version of this OpenCV build: "@OPENCV_VERSION@"
# - OpenCV_VERSION_MAJOR : Major version part of OpenCV_VERSION: "@OPENCV_VERSION_MAJOR@"
# - OpenCV_VERSION_MINOR : Minor version part of OpenCV_VERSION: "@OPENCV_VERSION_MINOR@"
@@ -27,22 +27,26 @@
# - OpenCV_VERSION_TWEAK : Tweak version part of OpenCV_VERSION: "@OPENCV_VERSION_TWEAK@"
#
# Advanced variables:
-# - OpenCV_SHARED
-# - OpenCV_CONFIG_PATH
-# - OpenCV_INSTALL_PATH (not set on Windows)
-# - OpenCV_LIB_COMPONENTS
-# - OpenCV_USE_MANGLED_PATHS
-# - OpenCV_HAVE_ANDROID_CAMERA
+# - OpenCV_SHARED : Use OpenCV as shared library
+# - OpenCV_CONFIG_PATH : Path to this OpenCVConfig.cmake
+# - OpenCV_INSTALL_PATH : OpenCV location (not set on Windows)
+# - OpenCV_LIB_COMPONENTS : Present OpenCV modules list
+# - OpenCV_USE_MANGLED_PATHS : Mangled OpenCV path flag
+# - OpenCV_MODULES_SUFFIX : The suffix for OpenCVModules-XXX.cmake file
+# - OpenCV_HAVE_ANDROID_CAMERA : Presence of Android native camera wrappers
#
# ===================================================================================
-set(modules_file_suffix "")
-if(ANDROID)
- string(REPLACE - _ modules_file_suffix "_${ANDROID_NDK_ABI_NAME}")
+if(NOT DEFINED OpenCV_MODULES_SUFFIX)
+ if(ANDROID)
+ string(REPLACE - _ OpenCV_MODULES_SUFFIX "_${ANDROID_NDK_ABI_NAME}")
+ else()
+ set(OpenCV_MODULES_SUFFIX "")
+ endif()
endif()
if(NOT TARGET opencv_core)
- include(${CMAKE_CURRENT_LIST_DIR}/OpenCVModules${modules_file_suffix}.cmake)
+ include(${CMAKE_CURRENT_LIST_DIR}/OpenCVModules${OpenCV_MODULES_SUFFIX}.cmake)
endif()
# TODO All things below should be reviewed. What is about of moving this code into related modules (special vars/hooks/files)
From 0c02e5de254d32e8f00bde4047f12624e77a7ef5 Mon Sep 17 00:00:00 2001
From: Anatoly Baksheev
Date: Mon, 17 Mar 2014 17:02:49 +0400
Subject: [PATCH 08/22] minor doc fix
---
modules/viz/doc/widget.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/viz/doc/widget.rst b/modules/viz/doc/widget.rst
index 7c1fc45751..0601ba1b72 100644
--- a/modules/viz/doc/widget.rst
+++ b/modules/viz/doc/widget.rst
@@ -1049,7 +1049,7 @@ viz::WWidgetMerger::WWidgetMerger
---------------------------------------
Constructs a WWidgetMerger.
-.. ocv:WWidgetMerger:: WWidgetMerger()
+.. ocv:function:: WWidgetMerger()
viz::WWidgetMerger::addCloud
-------------------------------
From 3940b6163b8370312d2a7fe66c96d43ab6d12efd Mon Sep 17 00:00:00 2001
From: Ilya Lavrenov
Date: Mon, 17 Mar 2014 18:52:28 +0400
Subject: [PATCH 09/22] remove intel guard since the code is 2 times faster on
AMD too
---
modules/ocl/perf/perf_filters.cpp | 6 +++---
modules/ocl/src/filtering.cpp | 6 +++---
modules/ocl/src/opencl/filtering_sep_filter_singlepass.cl | 2 ++
3 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/modules/ocl/perf/perf_filters.cpp b/modules/ocl/perf/perf_filters.cpp
index b3ffc51b30..c542d647cf 100644
--- a/modules/ocl/perf/perf_filters.cpp
+++ b/modules/ocl/perf/perf_filters.cpp
@@ -262,13 +262,13 @@ OCL_PERF_TEST_P(SobelFixture, Sobel,
oclDst.download(dst);
- SANITY_CHECK(dst);
+ SANITY_CHECK(dst, 1e-3);
}
else if (RUN_PLAIN_IMPL)
{
TEST_CYCLE() cv::Sobel(src, dst, -1, dx, dy);
- SANITY_CHECK(dst);
+ SANITY_CHECK(dst, 1e-3);
}
else
OCL_PERF_ELSE
@@ -326,7 +326,7 @@ OCL_PERF_TEST_P(GaussianBlurFixture, GaussianBlur,
Mat src(srcSize, type), dst(srcSize, type);
declare.in(src, WARMUP_RNG).out(dst);
- const double eps = src.depth() == CV_8U ? 1 + DBL_EPSILON : 3e-4;
+ const double eps = src.depth() == CV_8U ? 1 + DBL_EPSILON : 5e-4;
if (RUN_OCL_IMPL)
{
diff --git a/modules/ocl/src/filtering.cpp b/modules/ocl/src/filtering.cpp
index 35aa226de6..77052ffbf3 100644
--- a/modules/ocl/src/filtering.cpp
+++ b/modules/ocl/src/filtering.cpp
@@ -774,12 +774,12 @@ static void sepFilter2D_SinglePass(const oclMat &src, oclMat &dst,
option += " -D KERNEL_MATRIX_X=";
for(int i=0; i( &row_kernel.at(i) ) );
+ option += cv::format("DIG(0x%x)", *reinterpret_cast( &row_kernel.at(i) ) );
option += "0x0";
option += " -D KERNEL_MATRIX_Y=";
for(int i=0; i( &col_kernel.at(i) ) );
+ option += cv::format("DIG(0x%x)", *reinterpret_cast( &col_kernel.at(i) ) );
option += "0x0";
switch(src.type())
@@ -1410,7 +1410,7 @@ Ptr cv::ocl::createSeparableLinearFilter_GPU(int srcType, int
//if image size is non-degenerate and large enough
//and if filter support is reasonable to satisfy larger local memory requirements,
//then we can use single pass routine to avoid extra runtime calls overhead
- if( clCxt && clCxt->supportsFeature(FEATURE_CL_INTEL_DEVICE) &&
+ if( clCxt &&
rowKernel.rows <= 21 && columnKernel.rows <= 21 &&
(rowKernel.rows & 1) == 1 && (columnKernel.rows & 1) == 1 &&
imgSize.width > optimizedSepFilterLocalSize + (rowKernel.rows>>1) &&
diff --git a/modules/ocl/src/opencl/filtering_sep_filter_singlepass.cl b/modules/ocl/src/opencl/filtering_sep_filter_singlepass.cl
index c6555bff0f..c5f490284e 100644
--- a/modules/ocl/src/opencl/filtering_sep_filter_singlepass.cl
+++ b/modules/ocl/src/opencl/filtering_sep_filter_singlepass.cl
@@ -84,6 +84,8 @@
#define DST(_x,_y) (((global DSTTYPE*)(Dst+DstOffset+(_y)*DstPitch))[_x])
+#define DIG(a) a,
+
//horizontal and vertical filter kernels
//should be defined on host during compile time to avoid overhead
__constant uint mat_kernelX[] = {KERNEL_MATRIX_X};
From 16869225ffb6029cea0f694b8ee9ffab2eb835bd Mon Sep 17 00:00:00 2001
From: RJ2
Date: Tue, 18 Mar 2014 08:01:18 +0100
Subject: [PATCH 10/22] It's will be better
---
doc/tutorials/core/adding_images/adding_images.rst | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/doc/tutorials/core/adding_images/adding_images.rst b/doc/tutorials/core/adding_images/adding_images.rst
index e3135693de..601dbc07ef 100644
--- a/doc/tutorials/core/adding_images/adding_images.rst
+++ b/doc/tutorials/core/adding_images/adding_images.rst
@@ -6,12 +6,12 @@ Adding (blending) two images using OpenCV
Goal
=====
-In this tutorial you will learn how to:
+In this tutorial you will learn:
.. container:: enumeratevisibleitemswithsquare
- * What is *linear blending* and why it is useful.
- * Add two images using :add_weighted:`addWeighted <>`
+ * what is *linear blending* and why it is useful;
+ * how to add two images using :add_weighted:`addWeighted <>`
Theory
=======
From 0470bb0e2958ae9725465fe6ab2767f19c5009fa Mon Sep 17 00:00:00 2001
From: RJ2
Date: Tue, 18 Mar 2014 08:59:53 +0100
Subject: [PATCH 11/22] I have changed one sentence in tutorial, making it more
understandable
---
doc/tutorials/core/how_to_scan_images/how_to_scan_images.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/tutorials/core/how_to_scan_images/how_to_scan_images.rst b/doc/tutorials/core/how_to_scan_images/how_to_scan_images.rst
index ef0f8640ca..b6a18fee88 100644
--- a/doc/tutorials/core/how_to_scan_images/how_to_scan_images.rst
+++ b/doc/tutorials/core/how_to_scan_images/how_to_scan_images.rst
@@ -18,7 +18,7 @@ We'll seek answers for the following questions:
Our test case
=============
-Let us consider a simple color reduction method. Using the unsigned char C and C++ type for matrix item storing a channel of pixel may have up to 256 different values. For a three channel image this can allow the formation of way too many colors (16 million to be exact). Working with so many color shades may give a heavy blow to our algorithm performance. However, sometimes it is enough to work with a lot less of them to get the same final result.
+Let us consider a simple color reduction method. By using the unsigned char C and C++ type for matrix item storing, a channel of pixel may have up to 256 different values. For a three channel image this can allow the formation of way too many colors (16 million to be exact). Working with so many color shades may give a heavy blow to our algorithm performance. However, sometimes it is enough to work with a lot less of them to get the same final result.
In this cases it's common that we make a *color space reduction*. This means that we divide the color space current value with a new input value to end up with fewer colors. For instance every value between zero and nine takes the new value zero, every value between ten and nineteen the value ten and so on.
From b4e4f13f9efdfe2d1f0909d78556d8c865d5f371 Mon Sep 17 00:00:00 2001
From: Alexander Smorkalov
Date: Wed, 5 Mar 2014 12:31:04 +0400
Subject: [PATCH 12/22] Superres module enabled for Android. GPU samples build
fixed for Android.
---
cmake/OpenCVModule.cmake | 66 +++++++++-----------
modules/superres/CMakeLists.txt | 9 ++-
modules/superres/src/btv_l1_gpu.cpp | 2 +-
modules/superres/src/frame_source.cpp | 2 +-
modules/superres/src/input_array_utility.cpp | 2 +-
modules/superres/src/optical_flow.cpp | 2 +-
modules/superres/src/precomp.hpp | 2 +-
modules/ts/CMakeLists.txt | 2 +-
samples/gpu/CMakeLists.txt | 2 +-
samples/gpu/brox_optical_flow.cpp | 1 +
samples/gpu/opticalflow_nvidia_api.cpp | 1 +
samples/gpu/super_resolution.cpp | 2 +
12 files changed, 49 insertions(+), 44 deletions(-)
diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake
index c9c351113c..e11f5e671f 100644
--- a/cmake/OpenCVModule.cmake
+++ b/cmake/OpenCVModule.cmake
@@ -27,7 +27,8 @@
# The verbose template for OpenCV module:
#
# ocv_add_module(modname )
-# ocv_glob_module_sources() or glob them manually and ocv_set_module_sources(...)
+# ocv_glob_module_sources(([EXCLUDE_CUDA] )
+# or glob them manually and ocv_set_module_sources(...)
# ocv_module_include_directories()
# ocv_create_module()
#
@@ -478,14 +479,20 @@ endmacro()
# finds and sets headers and sources for the standard OpenCV module
# Usage:
-# ocv_glob_module_sources()
-macro(ocv_glob_module_sources EXCLUDE_CUDA EXCLUDE_OPENCL)
+# ocv_glob_module_sources([EXCLUDE_CUDA] )
+macro(ocv_glob_module_sources)
+ set(_argn ${ARGN})
+ list(FIND _argn "EXCLUDE_CUDA" exclude_cuda)
+ if(NOT exclude_cuda EQUAL -1)
+ list(REMOVE_AT _argn ${exclude_cuda})
+ endif()
+
file(GLOB_RECURSE lib_srcs "src/*.cpp")
file(GLOB_RECURSE lib_int_hdrs "src/*.hpp" "src/*.h")
file(GLOB lib_hdrs "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h")
file(GLOB lib_hdrs_detail "include/opencv2/${name}/detail/*.hpp" "include/opencv2/${name}/detail/*.h")
- if (NOT ${EXCLUDE_CUDA})
+ if (exclude_cuda EQUAL -1)
file(GLOB lib_cuda_srcs "src/cuda/*.cu")
set(cuda_objs "")
set(lib_cuda_hdrs "")
@@ -504,26 +511,22 @@ macro(ocv_glob_module_sources EXCLUDE_CUDA EXCLUDE_OPENCL)
source_group("Src" FILES ${lib_srcs} ${lib_int_hdrs})
- if (NOT ${EXCLUDE_OPENCL})
- file(GLOB cl_kernels "src/opencl/*.cl")
- if(HAVE_opencv_ocl AND cl_kernels)
- ocv_include_directories(${OPENCL_INCLUDE_DIRS})
- add_custom_command(
- OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp"
- COMMAND ${CMAKE_COMMAND} -DCL_DIR="${CMAKE_CURRENT_SOURCE_DIR}/src/opencl" -DOUTPUT="${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" -P "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake"
- DEPENDS ${cl_kernels} "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake")
- source_group("OpenCL" FILES ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp")
- list(APPEND lib_srcs ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp")
- endif()
+ file(GLOB cl_kernels "src/opencl/*.cl")
+ if(HAVE_opencv_ocl AND cl_kernels)
+ ocv_include_directories(${OPENCL_INCLUDE_DIRS})
+ add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp"
+ COMMAND ${CMAKE_COMMAND} -DCL_DIR="${CMAKE_CURRENT_SOURCE_DIR}/src/opencl" -DOUTPUT="${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" -P "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake"
+ DEPENDS ${cl_kernels} "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake")
+ source_group("OpenCL" FILES ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp")
+ list(APPEND lib_srcs ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp")
endif()
source_group("Include" FILES ${lib_hdrs})
source_group("Include\\detail" FILES ${lib_hdrs_detail})
- message(":${EXCLUDE_CUDA}: ${lib_cuda_srcs}")
-
- ocv_set_module_sources(${ARGN} HEADERS ${lib_hdrs} ${lib_hdrs_detail}
- SOURCES ${lib_srcs} ${lib_int_hdrs} ${cuda_objs} ${lib_cuda_srcs} ${lib_cuda_hdrs})
+ ocv_set_module_sources(${_argn} HEADERS ${lib_hdrs} ${lib_hdrs_detail}
+ SOURCES ${lib_srcs} ${lib_int_hdrs} ${cuda_objs} ${lib_cuda_srcs} ${lib_cuda_hdrs})
endmacro()
# creates OpenCV module in current folder
@@ -622,27 +625,20 @@ endmacro()
# short command for adding simple OpenCV module
# see ocv_add_module for argument details
# Usage:
-# ocv_define_module(module_name [INTERNAL] [REQUIRED] [] [OPTIONAL ])
+# ocv_define_module(module_name [INTERNAL] [EXCLUDE_CUDA] [REQUIRED] [] [OPTIONAL ])
macro(ocv_define_module module_name)
- set(_tmp_argn ${ARGN})
- set(exclude_cuda 0)
- set(exclude_opencl 0)
- set(argv0 ${ARGV1})
- set(argv1 ${ARGV2})
- set(argv2 ${ARGV3})
- foreach(i RANGE 0 2)
- if("${argv${i}}" STREQUAL "EXCLUDE_CUDA")
- set(exclude_cuda 1)
- list(REMOVE_AT _tmp_argn ${i})
- elseif ("${argv${i}}" STREQUAL "EXCLUDE_OPENCL")
- set(exclude_opencl 1)
- list(REMOVE_AT _tmp_argn ${i})
+ set(_argn ${ARGN})
+ set(exclude_cuda "")
+ foreach(arg ${_argn})
+ if("${arg}" STREQUAL "EXCLUDE_CUDA")
+ set(exclude_cuda "${arg}")
+ list(REMOVE_ITEM _argn ${arg})
endif()
endforeach()
- ocv_add_module(${module_name} ${_tmp_argn})
+ ocv_add_module(${module_name} ${_argn})
ocv_module_include_directories()
- ocv_glob_module_sources(${exclude_cuda} ${exclude_opencl})
+ ocv_glob_module_sources(${exclude_cuda})
ocv_create_module()
ocv_add_precompiled_headers(${the_module})
diff --git a/modules/superres/CMakeLists.txt b/modules/superres/CMakeLists.txt
index 82c61cccb4..8e3d7b2f2d 100644
--- a/modules/superres/CMakeLists.txt
+++ b/modules/superres/CMakeLists.txt
@@ -1,7 +1,12 @@
-if(ANDROID OR IOS)
+if(IOS)
ocv_module_disable(superres)
endif()
set(the_description "Super Resolution")
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 -Wundef -Wshadow)
-ocv_define_module(superres opencv_imgproc opencv_video OPTIONAL opencv_gpu opencv_highgui opencv_ocl ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
+if(ENABLE_DYNAMIC_CUDA)
+ add_definitions(-DDYNAMIC_CUDA_SUPPORT)
+ ocv_define_module(superres EXCLUDE_CUDA opencv_imgproc opencv_video OPTIONAL opencv_highgui opencv_ocl)
+else()
+ ocv_define_module(superres opencv_imgproc opencv_video OPTIONAL opencv_gpu opencv_highgui opencv_ocl ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
+endif()
diff --git a/modules/superres/src/btv_l1_gpu.cpp b/modules/superres/src/btv_l1_gpu.cpp
index b93bcfd577..2f40fa3771 100644
--- a/modules/superres/src/btv_l1_gpu.cpp
+++ b/modules/superres/src/btv_l1_gpu.cpp
@@ -51,7 +51,7 @@ using namespace cv::gpu;
using namespace cv::superres;
using namespace cv::superres::detail;
-#if !defined(HAVE_CUDA) || !defined(HAVE_OPENCV_GPU)
+#if !defined(HAVE_CUDA) || !defined(HAVE_OPENCV_GPU) || defined(DYNAMIC_CUDA_SUPPORT)
Ptr cv::superres::createSuperResolution_BTVL1_GPU()
{
diff --git a/modules/superres/src/frame_source.cpp b/modules/superres/src/frame_source.cpp
index 20e45d9518..5f59a98b80 100644
--- a/modules/superres/src/frame_source.cpp
+++ b/modules/superres/src/frame_source.cpp
@@ -200,7 +200,7 @@ Ptr cv::superres::createFrameSource_Camera(int deviceId)
//////////////////////////////////////////////////////
// VideoFrameSource_GPU
-#ifndef HAVE_OPENCV_GPU
+#if !defined(HAVE_OPENCV_GPU) || defined(DYNAMIC_CUDA_SUPPORT)
Ptr cv::superres::createFrameSource_Video_GPU(const string& fileName)
{
diff --git a/modules/superres/src/input_array_utility.cpp b/modules/superres/src/input_array_utility.cpp
index 075cf95144..10fc1c96ed 100644
--- a/modules/superres/src/input_array_utility.cpp
+++ b/modules/superres/src/input_array_utility.cpp
@@ -207,7 +207,7 @@ namespace
switch (src.kind())
{
case _InputArray::GPU_MAT:
- #ifdef HAVE_OPENCV_GPU
+ #if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
gpu::cvtColor(src.getGpuMat(), dst.getGpuMatRef(), code, cn);
#else
CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
diff --git a/modules/superres/src/optical_flow.cpp b/modules/superres/src/optical_flow.cpp
index e1e8a10275..617f83a5e1 100644
--- a/modules/superres/src/optical_flow.cpp
+++ b/modules/superres/src/optical_flow.cpp
@@ -344,7 +344,7 @@ Ptr cv::superres::createOptFlow_DualTVL1()
///////////////////////////////////////////////////////////////////
// GpuOpticalFlow
-#ifndef HAVE_OPENCV_GPU
+#if !defined(HAVE_OPENCV_GPU) || defined(DYNAMIC_CUDA_SUPPORT)
Ptr cv::superres::createOptFlow_Farneback_GPU()
{
diff --git a/modules/superres/src/precomp.hpp b/modules/superres/src/precomp.hpp
index 4cf49411b6..65fc7c8502 100644
--- a/modules/superres/src/precomp.hpp
+++ b/modules/superres/src/precomp.hpp
@@ -56,7 +56,7 @@
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/tracking.hpp"
-#ifdef HAVE_OPENCV_GPU
+#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT)
#include "opencv2/gpu/gpu.hpp"
#ifdef HAVE_CUDA
#include "opencv2/gpu/stream_accessor.hpp"
diff --git a/modules/ts/CMakeLists.txt b/modules/ts/CMakeLists.txt
index dcd3e1563b..bb56da2d98 100644
--- a/modules/ts/CMakeLists.txt
+++ b/modules/ts/CMakeLists.txt
@@ -11,7 +11,7 @@ ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef)
ocv_add_module(ts opencv_core opencv_features2d)
-ocv_glob_module_sources(0 0)
+ocv_glob_module_sources()
ocv_module_include_directories()
ocv_create_module()
diff --git a/samples/gpu/CMakeLists.txt b/samples/gpu/CMakeLists.txt
index 8fa539473b..d25c3a6b5d 100644
--- a/samples/gpu/CMakeLists.txt
+++ b/samples/gpu/CMakeLists.txt
@@ -41,7 +41,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_GPU_SAMPLES_REQUIRED_DEPS})
- if(HAVE_CUDA)
+ if(HAVE_CUDA AND NOT ANDROID)
target_link_libraries(${the_target} ${CUDA_CUDA_LIBRARY})
endif()
diff --git a/samples/gpu/brox_optical_flow.cpp b/samples/gpu/brox_optical_flow.cpp
index 722e19f02f..7cd5089b41 100644
--- a/samples/gpu/brox_optical_flow.cpp
+++ b/samples/gpu/brox_optical_flow.cpp
@@ -1,6 +1,7 @@
#include
#include
#include
+#include
#include "cvconfig.h"
#include "opencv2/core/core.hpp"
diff --git a/samples/gpu/opticalflow_nvidia_api.cpp b/samples/gpu/opticalflow_nvidia_api.cpp
index 05a37ef69d..31ee569788 100644
--- a/samples/gpu/opticalflow_nvidia_api.cpp
+++ b/samples/gpu/opticalflow_nvidia_api.cpp
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
#include "cvconfig.h"
#include
diff --git a/samples/gpu/super_resolution.cpp b/samples/gpu/super_resolution.cpp
index 6efd24144c..85cb6cff1c 100644
--- a/samples/gpu/super_resolution.cpp
+++ b/samples/gpu/super_resolution.cpp
@@ -1,6 +1,8 @@
#include
#include
#include
+#include
+
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
From 0a16d93e1d2b8c23df77c769589cfc7982c68af1 Mon Sep 17 00:00:00 2001
From: Firat Kalaycilar
Date: Tue, 18 Mar 2014 17:26:24 +0200
Subject: [PATCH 13/22] Fixed an issue with weight assignment causing the
resulting GMM weights to be unsorted in the CUDA and OCL versions of
BackgroundSubtractorMOG2
---
modules/gpu/src/cuda/bgfg_mog.cu | 5 +++--
modules/ocl/src/opencl/bgfg_mog.cl | 5 +++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/modules/gpu/src/cuda/bgfg_mog.cu b/modules/gpu/src/cuda/bgfg_mog.cu
index 89ad5ff0b5..055c9e041e 100644
--- a/modules/gpu/src/cuda/bgfg_mog.cu
+++ b/modules/gpu/src/cuda/bgfg_mog.cu
@@ -489,7 +489,7 @@ namespace cv { namespace gpu { namespace device
{
//need only weight if fit is found
float weight = alpha1 * gmm_weight(mode * frame.rows + y, x) + prune;
-
+ int swap_count = 0;
//fit not found yet
if (!fitsPDF)
{
@@ -540,6 +540,7 @@ namespace cv { namespace gpu { namespace device
if (weight < gmm_weight((i - 1) * frame.rows + y, x))
break;
+ swap_count++;
//swap one up
swap(gmm_weight, x, y, i - 1, frame.rows);
swap(gmm_variance, x, y, i - 1, frame.rows);
@@ -557,7 +558,7 @@ namespace cv { namespace gpu { namespace device
nmodes--;
}
- gmm_weight(mode * frame.rows + y, x) = weight; //update weight by the calculated value
+ gmm_weight((mode - swap_count) * frame.rows + y, x) = weight; //update weight by the calculated value
totalWeight += weight;
}
diff --git a/modules/ocl/src/opencl/bgfg_mog.cl b/modules/ocl/src/opencl/bgfg_mog.cl
index 6a95316f0f..a7479b929c 100644
--- a/modules/ocl/src/opencl/bgfg_mog.cl
+++ b/modules/ocl/src/opencl/bgfg_mog.cl
@@ -376,7 +376,7 @@ __kernel void mog2_kernel(__global T_FRAME * frame, __global int* fgmask, __glob
for (int mode = 0; mode < nmodes; ++mode)
{
float _weight = alpha1 * weight[(mode * frame_row + y) * weight_step + x] + prune;
-
+ int swap_count = 0;
if (!fitsPDF)
{
float var = variance[(mode * frame_row + y) * var_step + x];
@@ -404,6 +404,7 @@ __kernel void mog2_kernel(__global T_FRAME * frame, __global int* fgmask, __glob
{
if (_weight < weight[((i - 1) * frame_row + y) * weight_step + x])
break;
+ swap_count++;
swap(weight, x, y, i - 1, frame_row, weight_step);
swap(variance, x, y, i - 1, frame_row, var_step);
#if defined (CN1)
@@ -421,7 +422,7 @@ __kernel void mog2_kernel(__global T_FRAME * frame, __global int* fgmask, __glob
nmodes--;
}
- weight[(mode * frame_row + y) * weight_step + x] = _weight; //update weight by the calculated value
+ weight[((mode - swap_count) * frame_row + y) * weight_step + x] = _weight; //update weight by the calculated value
totalWeight += _weight;
}
From 284b2fc1e735886c569685333d558f624ce58719 Mon Sep 17 00:00:00 2001
From: Alexander Smorkalov
Date: Fri, 28 Feb 2014 18:18:20 +0400
Subject: [PATCH 14/22] Cut path to CUDA libraries to prevent generation of
OpenCVModules.cmake with abs path.
---
CMakeLists.txt | 11 ---------
cmake/OpenCVDetectAndroidSDK.cmake | 6 ++---
cmake/OpenCVDetectCUDA.cmake | 39 ++++++++++++++++++++++++++++++
3 files changed, 42 insertions(+), 14 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fb49497412..747d207e36 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -467,7 +467,6 @@ include(cmake/OpenCVFindLibsGUI.cmake)
include(cmake/OpenCVFindLibsVideo.cmake)
include(cmake/OpenCVFindLibsPerf.cmake)
-
# ----------------------------------------------------------------------------
# Detect other 3rd-party libraries/tools
# ----------------------------------------------------------------------------
@@ -513,16 +512,6 @@ if(NOT HAVE_CUDA)
set(ENABLE_DYNAMIC_CUDA OFF)
endif()
-if(HAVE_CUDA AND NOT ENABLE_DYNAMIC_CUDA)
- set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
- if(HAVE_CUBLAS)
- set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cublas_LIBRARY})
- endif()
- if(HAVE_CUFFT)
- set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cufft_LIBRARY})
- endif()
-endif()
-
# ----------------------------------------------------------------------------
# Solution folders:
# ----------------------------------------------------------------------------
diff --git a/cmake/OpenCVDetectAndroidSDK.cmake b/cmake/OpenCVDetectAndroidSDK.cmake
index af7427194e..273758967c 100644
--- a/cmake/OpenCVDetectAndroidSDK.cmake
+++ b/cmake/OpenCVDetectAndroidSDK.cmake
@@ -326,12 +326,12 @@ macro(add_android_project target path)
# copy all needed CUDA libs to project if EMBED_CUDA flag is present
if(android_proj_EMBED_CUDA)
- set(android_proj_culibs ${CUDA_npp_LIBRARY} ${CUDA_LIBRARIES})
+ set(android_proj_culibs ${CUDA_npp_LIBRARY_ABS} ${CUDA_LIBRARIES_ABS})
if(HAVE_CUFFT)
- list(INSERT android_proj_culibs 0 ${CUDA_cufft_LIBRARY})
+ list(INSERT android_proj_culibs 0 ${CUDA_cufft_LIBRARY_ABS})
endif()
if(HAVE_CUBLAS)
- list(INSERT android_proj_culibs 0 ${CUDA_cublas_LIBRARY})
+ list(INSERT android_proj_culibs 0 ${CUDA_cublas_LIBRARY_ABS})
endif()
foreach(lib ${android_proj_culibs})
get_filename_component(f "${lib}" NAME)
diff --git a/cmake/OpenCVDetectCUDA.cmake b/cmake/OpenCVDetectCUDA.cmake
index 56b142970e..24fbb03ce3 100644
--- a/cmake/OpenCVDetectCUDA.cmake
+++ b/cmake/OpenCVDetectCUDA.cmake
@@ -219,3 +219,42 @@ else()
unset(CUDA_ARCH_BIN CACHE)
unset(CUDA_ARCH_PTX CACHE)
endif()
+
+if(HAVE_CUDA)
+ set(CUDA_LIBS_PATH "")
+ foreach(p ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
+ get_filename_component(_tmp ${p} PATH)
+ list(APPEND CUDA_LIBS_PATH ${_tmp})
+ endforeach()
+
+ if(HAVE_CUBLAS)
+ foreach(p ${CUDA_cublas_LIBRARY})
+ get_filename_component(_tmp ${p} PATH)
+ list(APPEND CUDA_LIBS_PATH ${_tmp})
+ endforeach()
+ endif()
+
+ if(HAVE_CUFFT)
+ foreach(p ${CUDA_cufft_LIBRARY})
+ get_filename_component(_tmp ${p} PATH)
+ list(APPEND CUDA_LIBS_PATH ${_tmp})
+ endforeach()
+ endif()
+
+ list(REMOVE_DUPLICATES CUDA_LIBS_PATH)
+ link_directories(${CUDA_LIBS_PATH})
+
+ set(CUDA_LIBRARIES_ABS ${CUDA_LIBRARIES})
+ ocv_convert_to_lib_name(CUDA_LIBRARIES ${CUDA_LIBRARIES})
+ set(CUDA_npp_LIBRARY_ABS ${CUDA_npp_LIBRARY})
+ ocv_convert_to_lib_name(CUDA_npp_LIBRARY ${CUDA_npp_LIBRARY})
+ if(HAVE_CUBLAS)
+ set(CUDA_cublas_LIBRARY_ABS ${CUDA_cublas_LIBRARY})
+ ocv_convert_to_lib_name(CUDA_cublas_LIBRARY ${CUDA_cublas_LIBRARY})
+ endif()
+
+ if(HAVE_CUFFT)
+ set(CUDA_cufft_LIBRARY_ABS ${CUDA_cufft_LIBRARY})
+ ocv_convert_to_lib_name(CUDA_cufft_LIBRARY ${CUDA_cufft_LIBRARY})
+ endif()
+endif()
\ No newline at end of file
From 640e180efe645c32863af549b7a856d91ef0276f Mon Sep 17 00:00:00 2001
From: Andrey Pavlenko
Date: Thu, 20 Mar 2014 22:22:55 +0400
Subject: [PATCH 15/22] switching to CV_HAAR_SCALE_IMAGE mode, enabling test
---
modules/ocl/perf/perf_haar.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/modules/ocl/perf/perf_haar.cpp b/modules/ocl/perf/perf_haar.cpp
index e70641d061..6b5100b6f2 100644
--- a/modules/ocl/perf/perf_haar.cpp
+++ b/modules/ocl/perf/perf_haar.cpp
@@ -92,12 +92,12 @@ PERF_TEST(HaarFixture, Haar)
typedef std::tr1::tuple Cascade_Image_MinSize_t;
typedef perf::TestBaseWithParam Cascade_Image_MinSize;
-OCL_PERF_TEST_P(Cascade_Image_MinSize, DISABLED_CascadeClassifier,
+OCL_PERF_TEST_P(Cascade_Image_MinSize, CascadeClassifier,
testing::Combine(testing::Values( string("cv/cascadeandhog/cascades/haarcascade_frontalface_alt.xml"),
string("cv/cascadeandhog/cascades/haarcascade_frontalface_alt2.xml") ),
- testing::Values(string("cv/shared/lena.png"),
- string("cv/cascadeandhog/images/bttf301.png")/*,
- string("cv/cascadeandhog/images/class57.png")*/ ),
+ testing::Values( string("cv/shared/lena.png"),
+ string("cv/cascadeandhog/images/bttf301.png"),
+ string("cv/cascadeandhog/images/class57.png") ),
testing::Values(30, 64, 90)))
{
const string cascasePath = get<0>(GetParam());
@@ -121,7 +121,7 @@ OCL_PERF_TEST_P(Cascade_Image_MinSize, DISABLED_CascadeClassifier,
faces.clear();
startTimer();
- cc.detectMultiScale(img, faces, 1.1, 3, 0, minSize);
+ cc.detectMultiScale(img, faces, 1.1, 3, CV_HAAR_SCALE_IMAGE, minSize);
stopTimer();
}
}
@@ -137,7 +137,7 @@ OCL_PERF_TEST_P(Cascade_Image_MinSize, DISABLED_CascadeClassifier,
ocl::finish();
startTimer();
- cc.detectMultiScale(uimg, faces, 1.1, 3, 0, minSize);
+ cc.detectMultiScale(uimg, faces, 1.1, 3, CV_HAAR_SCALE_IMAGE, minSize);
stopTimer();
}
}
From b0ad84cfa2f4ecb884de542c9706177f22dade6d Mon Sep 17 00:00:00 2001
From: Alexander Smorkalov
Date: Fri, 21 Mar 2014 12:48:38 +0400
Subject: [PATCH 16/22] Libraries filter update after abs path cut.
---
cmake/OpenCVGenAndroidMK.cmake | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/cmake/OpenCVGenAndroidMK.cmake b/cmake/OpenCVGenAndroidMK.cmake
index ee52fa6886..2622d2aaed 100644
--- a/cmake/OpenCVGenAndroidMK.cmake
+++ b/cmake/OpenCVGenAndroidMK.cmake
@@ -56,8 +56,11 @@ if(ANDROID)
# remove CUDA runtime and NPP from regular deps
# it can be added separately if needed.
- ocv_list_filterout(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "libcu")
- ocv_list_filterout(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "libnpp")
+ ocv_list_filterout(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "cusparse")
+ ocv_list_filterout(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "cufft")
+ ocv_list_filterout(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "cublas")
+ ocv_list_filterout(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "npp")
+ ocv_list_filterout(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "cudart")
if(HAVE_CUDA)
# CUDA runtime libraries and are required always
From 846266fde4c82fe392ccf122ef64ea30b6da4f01 Mon Sep 17 00:00:00 2001
From: Alexander Smorkalov
Date: Wed, 19 Feb 2014 16:20:40 +0400
Subject: [PATCH 17/22] Native camera fix for some deivices with Qualcomm SoC
like Samsung Galaxy S4.
---
.../armeabi-v7a/libnative_camera_r2.2.0.so | Bin 275932 -> 271836 bytes
.../armeabi-v7a/libnative_camera_r2.3.3.so | Bin 275932 -> 271836 bytes
.../armeabi-v7a/libnative_camera_r3.0.1.so | Bin 275932 -> 271836 bytes
.../armeabi-v7a/libnative_camera_r4.0.0.so | Bin 263644 -> 259548 bytes
.../armeabi-v7a/libnative_camera_r4.0.3.so | Bin 275932 -> 271836 bytes
.../armeabi-v7a/libnative_camera_r4.1.1.so | Bin 275932 -> 271836 bytes
.../armeabi-v7a/libnative_camera_r4.2.0.so | Bin 275932 -> 271836 bytes
.../armeabi-v7a/libnative_camera_r4.3.0.so | Bin 275932 -> 271836 bytes
.../armeabi-v7a/libnative_camera_r4.4.0.so | Bin 275932 -> 271836 bytes
.../lib/armeabi/libnative_camera_r2.2.0.so | Bin 288212 -> 284116 bytes
.../lib/armeabi/libnative_camera_r2.3.3.so | Bin 288212 -> 284116 bytes
.../lib/armeabi/libnative_camera_r3.0.1.so | Bin 284124 -> 280028 bytes
.../lib/armeabi/libnative_camera_r4.0.0.so | Bin 271832 -> 267736 bytes
.../lib/armeabi/libnative_camera_r4.0.3.so | Bin 284120 -> 280024 bytes
.../lib/armeabi/libnative_camera_r4.1.1.so | Bin 288216 -> 284120 bytes
.../lib/armeabi/libnative_camera_r4.2.0.so | Bin 288216 -> 284120 bytes
.../lib/armeabi/libnative_camera_r4.3.0.so | Bin 288220 -> 284124 bytes
.../lib/armeabi/libnative_camera_r4.4.0.so | Bin 284124 -> 280028 bytes
3rdparty/lib/mips/libnative_camera_r4.0.3.so | Bin 546012 -> 545972 bytes
3rdparty/lib/mips/libnative_camera_r4.1.1.so | Bin 546104 -> 546008 bytes
3rdparty/lib/mips/libnative_camera_r4.2.0.so | Bin 546108 -> 546012 bytes
3rdparty/lib/mips/libnative_camera_r4.3.0.so | Bin 546104 -> 546008 bytes
3rdparty/lib/mips/libnative_camera_r4.4.0.so | Bin 550340 -> 550308 bytes
3rdparty/lib/x86/libnative_camera_r2.3.3.so | Bin 427444 -> 423348 bytes
3rdparty/lib/x86/libnative_camera_r3.0.1.so | Bin 427444 -> 423348 bytes
3rdparty/lib/x86/libnative_camera_r4.0.3.so | Bin 427444 -> 423348 bytes
3rdparty/lib/x86/libnative_camera_r4.1.1.so | Bin 431540 -> 427444 bytes
3rdparty/lib/x86/libnative_camera_r4.2.0.so | Bin 447940 -> 443844 bytes
3rdparty/lib/x86/libnative_camera_r4.3.0.so | Bin 447940 -> 443844 bytes
3rdparty/lib/x86/libnative_camera_r4.4.0.so | Bin 456132 -> 456132 bytes
.../camera_wrapper/CMakeLists.txt | 2 +-
.../camera_wrapper/camera_wrapper.cpp | 171 ++++++++++--------
.../src/java/android+NativeCameraView.java | 1 -
33 files changed, 101 insertions(+), 73 deletions(-)
diff --git a/3rdparty/lib/armeabi-v7a/libnative_camera_r2.2.0.so b/3rdparty/lib/armeabi-v7a/libnative_camera_r2.2.0.so
index 5b618a87459123ff5f70d6f0647ca5d1785140cb..9b8352e03fe48531bab41f5b28dccdc403c7898d 100755
GIT binary patch
delta 80209
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