From: Roman Donchenko Date: Mon, 19 Aug 2013 10:08:34 +0000 (+0400) Subject: Merge remote-tracking branch 'origin/2.4' into merge-2.4 X-Git-Tag: accepted/tizen/6.0/unified/20201030.111113~3801^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f76dd992994bbdff68bd6841ac7b5d2a2407f756;p=platform%2Fupstream%2Fopencv.git Merge remote-tracking branch 'origin/2.4' into merge-2.4 Conflicts: cmake/OpenCVModule.cmake doc/tutorials/calib3d/camera_calibration/camera_calibration.rst doc/tutorials/features2d/feature_detection/feature_detection.rst doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.rst doc/tutorials/features2d/feature_homography/feature_homography.rst modules/core/include/opencv2/core/operations.hpp modules/core/src/arithm.cpp modules/gpu/perf/perf_video.cpp modules/imgproc/include/opencv2/imgproc/imgproc.hpp modules/java/generator/gen_java.py modules/java/generator/src/cpp/VideoCapture.cpp modules/nonfree/src/opencl/surf.cl modules/ocl/include/opencv2/ocl/ocl.hpp modules/ocl/perf/perf_haar.cpp modules/ocl/perf/perf_precomp.hpp modules/ocl/src/color.cpp modules/ocl/src/filtering.cpp modules/ocl/test/test_color.cpp modules/ocl/test/test_objdetect.cpp modules/python/src2/cv2.cpp samples/gpu/CMakeLists.txt samples/gpu/super_resolution.cpp --- f76dd992994bbdff68bd6841ac7b5d2a2407f756 diff --cc cmake/OpenCVModule.cmake index e602955,44e43fc..816758d --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@@ -470,11 -470,16 +470,19 @@@ endmacro( # ocv_create_module() # ocv_create_module(SKIP_LINK) macro(ocv_create_module) + # The condition we ought to be testing here is whether ocv_add_precompiled_headers will + # be called at some point in the future. We can't look into the future, though, + # so this will have to do. + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/precomp.hpp") + get_native_precompiled_header(${the_module} precomp.hpp) + endif() + add_library(${the_module} ${OPENCV_MODULE_TYPE} ${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES} - "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp") + "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp" + ${${the_module}_pch}) + if(NOT the_module STREQUAL opencv_ts) + set_target_properties(${the_module} PROPERTIES COMPILE_DEFINITIONS OPENCV_NOSTL) + endif() if(NOT "${ARGN}" STREQUAL "SKIP_LINK") target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_MODULE_${the_module}_DEPS_EXT} ${OPENCV_LINKER_LIBS} ${IPP_LIBS} ${ARGN}) diff --cc doc/tutorials/calib3d/camera_calibration/camera_calibration.rst index 77723b2,0e2c764..4e80769 --- a/doc/tutorials/calib3d/camera_calibration/camera_calibration.rst +++ b/doc/tutorials/calib3d/camera_calibration/camera_calibration.rst @@@ -3,30 -3,30 +3,30 @@@ Camera calibration With OpenCV ****************************** - Cameras have been around for a long-long time. However, with the introduction of the cheap *pinhole* cameras in the late 20th century, they became a common occurrence in our everyday life. Unfortunately, this cheapness comes with its price: significant distortion. Luckily, these are constants and with a calibration and some remapping we can correct this. Furthermore, with calibration you may also determinate the relation between the camera's natural units (pixels) and the real world units (for example millimeters). -Cameras have been around for a long-long time. However, with the introduction of the cheap *pinhole* cameras in the late 20th century, they became a common occurrence in our everyday life. Unfortunately, this cheapness comes with its price: significant distortion. Luckily, these are constants and with a calibration and some remapping we can correct this. Furthermore, with calibration you may also determine the relation between the camera's natural units (pixels) and the real world units (for example millimeters). ++Cameras have been around for a long-long time. However, with the introduction of the cheap *pinhole* cameras in the late 20th century, they became a common occurrence in our everyday life. Unfortunately, this cheapness comes with its price: significant distortion. Luckily, these are constants and with a calibration and some remapping we can correct this. Furthermore, with calibration you may also determine the relation between the camera's natural units (pixels) and the real world units (for example millimeters). Theory ====== - For the distortion OpenCV takes into account the radial and tangential factors. For the radial one uses the following formula: + For the distortion OpenCV takes into account the radial and tangential factors. For the radial factor one uses the following formula: -.. math:: +.. math:: x_{corrected} = x( 1 + k_1 r^2 + k_2 r^4 + k_3 r^6) \\ y_{corrected} = y( 1 + k_1 r^2 + k_2 r^4 + k_3 r^6) - So for an old pixel point at :math:`(x,y)` coordinate in the input image, for a corrected output image its position will be :math:`(x_{corrected} y_{corrected})` . The presence of the radial distortion manifests in form of the "barrel" or "fish-eye" effect. + So for an old pixel point at :math:`(x,y)` coordinates in the input image, its position on the corrected output image will be :math:`(x_{corrected} y_{corrected})`. The presence of the radial distortion manifests in form of the "barrel" or "fish-eye" effect. - Tangential distortion occurs because the image taking lenses are not perfectly parallel to the imaging plane. Correcting this is made via the formulas: + Tangential distortion occurs because the image taking lenses are not perfectly parallel to the imaging plane. It can be corrected via the formulas: -.. math:: +.. math:: x_{corrected} = x + [ 2p_1xy + p_2(r^2+2x^2)] \\ y_{corrected} = y + [ p_1(r^2+ 2y^2)+ 2p_2xy] - So we have five distortion parameters, which in OpenCV are organized in a 5 column one row matrix: + So we have five distortion parameters which in OpenCV are presented as one row matrix with 5 columns: -.. math:: +.. math:: Distortion_{coefficients}=(k_1 \hspace{10pt} k_2 \hspace{10pt} p_1 \hspace{10pt} p_2 \hspace{10pt} k_3) @@@ -65,9 -65,9 +65,9 @@@ The sample application will Source code =========== - You may also find the source code in the :file:`samples/cpp/tutorial_code/calib3d/camera_calibration/` folder of the OpenCV source library or :download:`download it from here <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp>`. The program has a single argument. The name of its configuration file. If none given it will try to open the one named "default.xml". :download:`Here's a sample configuration file <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/in_VID5.xml>` in XML format. In the configuration file you may choose to use as input a camera, a video file or an image list. If you opt for the later one, you need to create a configuration file where you enumerate the images to use. Here's :download:`an example of this <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/VID5.xml>`. The important part to remember is that the images needs to be specified using the absolute path or the relative one from your applications working directory. You may find all this in the beforehand mentioned directory. + You may also find the source code in the :file:`samples/cpp/tutorial_code/calib3d/camera_calibration/` folder of the OpenCV source library or :download:`download it from here <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp>`. The program has a single argument: the name of its configuration file. If none is given then it will try to open the one named "default.xml". :download:`Here's a sample configuration file <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/in_VID5.xml>` in XML format. In the configuration file you may choose to use camera as an input, a video file or an image list. If you opt for the last one, you will need to create a configuration file where you enumerate the images to use. Here's :download:`an example of this <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/VID5.xml>`. The important part to remember is that the images need to be specified using the absolute path or the relative one from your application's working directory. You may find all this in the samples directory mentioned above. - The application starts up with reading the settings from the configuration file. Although, this is an important part of it, it has nothing to do with the subject of this tutorial: *camera calibration*. Therefore, I've chosen to do not post here the code part for that. The technical background on how to do this you can find in the :ref:`fileInputOutputXMLYAML` tutorial. -The application starts up with reading the settings from the configuration file. Although, this is an important part of it, it has nothing to do with the subject of this tutorial: *camera calibration*. Therefore, I've chosen not to post the code for that part here. Technical background on how to do this you can find in the :ref:`fileInputOutputXMLYAML` tutorial. ++The application starts up with reading the settings from the configuration file. Although, this is an important part of it, it has nothing to do with the subject of this tutorial: *camera calibration*. Therefore, I've chosen not to post the code for that part here. Technical background on how to do this you can find in the :ref:`fileInputOutputXMLYAML` tutorial. Explanation =========== @@@ -93,9 -93,9 +93,9 @@@ return -1; } - For this I've used simple OpenCV class input operation. After reading the file I've an additional post-process function that checks for the validity of the input. Only if all of them are good will be the *goodInput* variable true. + For this I've used simple OpenCV class input operation. After reading the file I've an additional post-processing function that checks validity of the input. Only if all inputs are good then *goodInput* variable will be true. - #. **Get next input, if it fails or we have enough of them calibrate**. After this we have a big loop where we do the following operations: get the next image from the image list, camera or video file. If this fails or we have enough images we run the calibration process. In case of image we step out of the loop and otherwise the remaining frames will be undistorted (if the option is set) via changing from *DETECTION* mode to *CALIBRATED* one. -#. **Get next input, if it fails or we have enough of them - calibrate**. After this we have a big loop where we do the following operations: get the next image from the image list, camera or video file. If this fails or we have enough images then we run the calibration process. In case of image we step out of the loop and otherwise the remaining frames will be undistorted (if the option is set) via changing from *DETECTION* mode to the *CALIBRATED* one. ++#. **Get next input, if it fails or we have enough of them - calibrate**. After this we have a big loop where we do the following operations: get the next image from the image list, camera or video file. If this fails or we have enough images then we run the calibration process. In case of image we step out of the loop and otherwise the remaining frames will be undistorted (if the option is set) via changing from *DETECTION* mode to the *CALIBRATED* one. .. code-block:: cpp @@@ -123,9 -123,9 +123,9 @@@ if( s.flipVertical ) flip( view, view, 0 ); } - For some cameras we may need to flip the input image. Here we do this too. + For some cameras we may need to flip the input image. Here we do this too. - #. **Find the pattern in the current input**. The formation of the equations I mentioned above consists of finding the major patterns in the input: in case of the chessboard this is their corners of the squares and for the circles, well, the circles itself. The position of these will form the result and is collected into the *pointBuf* vector. + #. **Find the pattern in the current input**. The formation of the equations I mentioned above aims to finding major patterns in the input: in case of the chessboard this are corners of the squares and for the circles, well, the circles themselves. The position of these will form the result which will be written into the *pointBuf* vector. .. code-block:: cpp @@@ -146,9 -146,9 +146,9 @@@ break; } - Depending on the type of the input pattern you use either the :calib3d:`findChessboardCorners ` or the :calib3d:`findCirclesGrid ` function. For both of them you pass on the current image, the size of the board and you'll get back the positions of the patterns. Furthermore, they return a boolean variable that states if in the input we could find or not the pattern (we only need to take into account images where this is true!). - Depending on the type of the input pattern you use either the :calib3d:`findChessboardCorners ` or the :calib3d:`findCirclesGrid ` function. For both of them you pass the current image and the size of the board and you'll get the positions of the patterns. Furthermore, they return a boolean variable which states if the pattern was found in the input (we only need to take into account those images where this is true!). ++ Depending on the type of the input pattern you use either the :calib3d:`findChessboardCorners ` or the :calib3d:`findCirclesGrid ` function. For both of them you pass the current image and the size of the board and you'll get the positions of the patterns. Furthermore, they return a boolean variable which states if the pattern was found in the input (we only need to take into account those images where this is true!). - Then again in case of cameras we only take camera images after an input delay time passed. This is in order to allow for the user to move the chessboard around and as getting different images. Same images mean same equations, and same equations at the calibration will form an ill-posed problem, so the calibration will fail. For square images the position of the corners are only approximate. We may improve this by calling the :feature2d:`cornerSubPix ` function. This way will get a better calibration result. After this we add a valid inputs result to the *imagePoints* vector to collect all of the equations into a single container. Finally, for visualization feedback purposes we will draw the found points on the input image with the :calib3d:`findChessboardCorners ` function. + Then again in case of cameras we only take camera images when an input delay time is passed. This is done in order to allow user moving the chessboard around and getting different images. Similar images result in similar equations, and similar equations at the calibration step will form an ill-posed problem, so the calibration will fail. For square images the positions of the corners are only approximate. We may improve this by calling the :feature2d:`cornerSubPix ` function. It will produce better calibration result. After this we add a valid inputs result to the *imagePoints* vector to collect all of the equations into a single container. Finally, for visualization feedback purposes we will draw the found points on the input image using :calib3d:`findChessboardCorners ` function. .. code-block:: cpp @@@ -256,9 -256,9 +256,9 @@@ The calibration and save ======================== - Because the calibration needs to be only once per camera it makes sense to save them after a successful calibration. This way later on you can just load these values into your program. Due to this we first make the calibration, and if it succeeds we save the result into an OpenCV style XML or YAML file, depending on the extension you give in the configuration file. + Because the calibration needs to be done only once per camera, it makes sense to save it after a successful calibration. This way later on you can just load these values into your program. Due to this we first make the calibration, and if it succeeds we save the result into an OpenCV style XML or YAML file, depending on the extension you give in the configuration file. -Therefore in the first function we just split up these two processes. Because we want to save many of the calibration variables we'll create these variables here and pass on both of them to the calibration and saving function. Again, I'll not show the saving part as that has little in common with the calibration. Explore the source file in order to find out how and what: +Therefore in the first function we just split up these two processes. Because we want to save many of the calibration variables we'll create these variables here and pass on both of them to the calibration and saving function. Again, I'll not show the saving part as that has little in common with the calibration. Explore the source file in order to find out how and what: .. code-block:: cpp @@@ -316,13 -316,13 +316,13 @@@ We do the calibration with the help of vector > objectPoints(1); calcBoardCornerPositions(s.boardSize, s.squareSize, objectPoints[0], s.calibrationPattern); - objectPoints.resize(imagePoints.size(),objectPoints[0]); + objectPoints.resize(imagePoints.size(),objectPoints[0]); - + The image points. This is a vector of *Point2f* vector that for each input image contains where the important points (corners for chessboard, and center of circles for the circle patterns) were found. We already collected this from what the :calib3d:`findChessboardCorners ` or the :calib3d:`findCirclesGrid ` function returned. We just need to pass it on. + + The image points. This is a vector of *Point2f* vector which for each input image contains coordinates of the important points (corners for chessboard and centers of the circles for the circle pattern). We have already collected this from :calib3d:`findChessboardCorners ` or :calib3d:`findCirclesGrid ` function. We just need to pass it on. - + The size of the image acquired from the camera, video file or the images. + + The size of the image acquired from the camera, video file or the images. - + The camera matrix. If we used the fix aspect ratio option we need to set the :math:`f_x` to zero: + + The camera matrix. If we used the fixed aspect ratio option we need to set the :math:`f_x` to zero: .. code-block:: cpp @@@ -345,9 -345,9 +345,9 @@@ double rms = calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs, s.flag|CV_CALIB_FIX_K4|CV_CALIB_FIX_K5); - + The function returns the average re-projection error. This number gives a good estimation of just how exact is the found parameters. This should be as close to zero as possible. Given the intrinsic, distortion, rotation and translation matrices we may calculate the error for one view by using the :calib3d:`projectPoints ` to first transform the object point to image point. Then we calculate the absolute norm between what we got with our transformation and the corner/circle finding algorithm. To find the average error we calculate the arithmetical mean of the errors calculate for all the calibration images. + + The function returns the average re-projection error. This number gives a good estimation of precision of the found parameters. This should be as close to zero as possible. Given the intrinsic, distortion, rotation and translation matrices we may calculate the error for one view by using the :calib3d:`projectPoints ` to first transform the object point to image point. Then we calculate the absolute norm between what we got with our transformation and the corner/circle finding algorithm. To find the average error we calculate the arithmetical mean of the errors calculated for all the calibration images. - .. code-block:: cpp + .. code-block:: cpp double computeReprojectionErrors( const vector >& objectPoints, const vector >& imagePoints, @@@ -396,9 -396,9 +396,9 @@@ Let there be :download:`this input ches - Then specified the :file:`images/CameraCalibraation/VID5/VID5.XML` as input in the configuration file. Here's a chessboard pattern found during the runtime of the application: + Then passed :file:`images/CameraCalibration/VID5/VID5.XML` as an input in the configuration file. Here's a chessboard pattern found during the runtime of the application: -.. image:: images/fileListImage.jpg +.. image:: images/fileListImage.jpg :alt: A found chessboard :align: center @@@ -433,9 -433,9 +433,9 @@@ In both cases in the specified output X -4.1802327176423804e-001 5.0715244063187526e-001 0. 0. -5.7843597214487474e-001 - Add these values as constants to your program, call the :imgproc_geometric:`initUndistortRectifyMap ` and the :imgproc_geometric:`remap ` function to remove distortion and enjoy distortion free inputs with cheap and low quality cameras. + Add these values as constants to your program, call the :imgproc_geometric:`initUndistortRectifyMap ` and the :imgproc_geometric:`remap ` function to remove distortion and enjoy distortion free inputs for cheap and low quality cameras. -You may observe a runtime instance of this on the `YouTube here `_. +You may observe a runtime instance of this on the `YouTube here `_. .. raw:: html diff --cc doc/tutorials/features2d/feature_detection/feature_detection.rst index 1c9ca7c,1051fe5..02da6d0 --- a/doc/tutorials/features2d/feature_detection/feature_detection.rst +++ b/doc/tutorials/features2d/feature_detection/feature_detection.rst @@@ -28,9 -28,10 +28,10 @@@ This tutorial code's is shown lines bel #include #include - #include "opencv2/core/core.hpp" - #include "opencv2/features2d/features2d.hpp" - #include "opencv2/highgui/highgui.hpp" - #include "opencv2/nonfree/nonfree.hpp" + #include "opencv2/core.hpp" + #include "opencv2/features2d.hpp" + #include "opencv2/highgui.hpp" ++ #include "opencv2/nonfree.hpp" using namespace cv; @@@ -94,4 -95,4 +95,3 @@@ Resul .. image:: images/Feature_Detection_Result_b.jpg :align: center :height: 200pt -- diff --cc doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.rst index 4b3ffbc,3bf757f..9839c89 --- a/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.rst +++ b/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.rst @@@ -25,9 -25,10 +25,10 @@@ This tutorial code's is shown lines bel #include #include - #include "opencv2/core/core.hpp" - #include "opencv2/features2d/features2d.hpp" - #include "opencv2/highgui/highgui.hpp" - #include "opencv2/nonfree/nonfree.hpp" + #include "opencv2/core.hpp" + #include "opencv2/features2d.hpp" + #include "opencv2/highgui.hpp" ++ #include "opencv2/nonfree.hpp" using namespace cv; diff --cc doc/tutorials/features2d/feature_homography/feature_homography.rst index 0d78229,eb06083..3040ed7 --- a/doc/tutorials/features2d/feature_homography/feature_homography.rst +++ b/doc/tutorials/features2d/feature_homography/feature_homography.rst @@@ -26,10 -26,11 +26,11 @@@ This tutorial code's is shown lines bel #include #include - #include "opencv2/core/core.hpp" - #include "opencv2/features2d/features2d.hpp" - #include "opencv2/highgui/highgui.hpp" - #include "opencv2/calib3d/calib3d.hpp" - #include "opencv2/nonfree/nonfree.hpp" + #include "opencv2/core.hpp" + #include "opencv2/features2d.hpp" + #include "opencv2/highgui.hpp" + #include "opencv2/calib3d.hpp" ++ #include "opencv2/nonfree.hpp" using namespace cv; @@@ -145,4 -146,4 +146,3 @@@ Resul .. image:: images/Feature_Homography_Result.jpg :align: center :height: 200pt -- diff --cc modules/core/include/opencv2/core/persistence.hpp index e81401c,0000000..1b2bbf6 mode 100644,000000..100644 --- a/modules/core/include/opencv2/core/persistence.hpp +++ b/modules/core/include/opencv2/core/persistence.hpp @@@ -1,817 -1,0 +1,870 @@@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_CORE_PERSISTENCE_HPP__ +#define __OPENCV_CORE_PERSISTENCE_HPP__ + +#ifndef __cplusplus +# error persistence.hpp header must be compiled as C++ +#endif + +// black-box structures used by FileStorage +typedef struct CvFileStorage CvFileStorage; +typedef struct CvFileNode CvFileNode; + +#include "opencv2/core/types.hpp" +#include "opencv2/core/mat.hpp" + +namespace cv { + +////////////////////////// XML & YAML I/O ////////////////////////// + +class CV_EXPORTS FileNode; +class CV_EXPORTS FileNodeIterator; + +/*! + XML/YAML File Storage Class. + + The class describes an object associated with XML or YAML file. + It can be used to store data to such a file or read and decode the data. + + The storage is organized as a tree of nested sequences (or lists) and mappings. + Sequence is a heterogenious array, which elements are accessed by indices or sequentially using an iterator. + Mapping is analogue of std::map or C structure, which elements are accessed by names. + The most top level structure is a mapping. + Leaves of the file storage tree are integers, floating-point numbers and text strings. + + For example, the following code: + + \code + // open file storage for writing. Type of the file is determined from the extension + FileStorage fs("test.yml", FileStorage::WRITE); + fs << "test_int" << 5 << "test_real" << 3.1 << "test_string" << "ABCDEFGH"; + fs << "test_mat" << Mat::eye(3,3,CV_32F); + + fs << "test_list" << "[" << 0.0000000000001 << 2 << CV_PI << -3435345 << "2-502 2-029 3egegeg" << + "{:" << "month" << 12 << "day" << 31 << "year" << 1969 << "}" << "]"; + fs << "test_map" << "{" << "x" << 1 << "y" << 2 << "width" << 100 << "height" << 200 << "lbp" << "[:"; + + const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1}; + fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0]))); + + fs << "]" << "}"; + \endcode + + will produce the following file: + + \verbatim + %YAML:1.0 + test_int: 5 + test_real: 3.1000000000000001e+00 + test_string: ABCDEFGH + test_mat: !!opencv-matrix + rows: 3 + cols: 3 + dt: f + data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1. ] + test_list: + - 1.0000000000000000e-13 + - 2 + - 3.1415926535897931e+00 + - -3435345 + - "2-502 2-029 3egegeg" + - { month:12, day:31, year:1969 } + test_map: + x: 1 + y: 2 + width: 100 + height: 200 + lbp: [ 0, 1, 1, 0, 1, 1, 0, 1 ] + \endverbatim + + and to read the file above, the following code can be used: + + \code + // open file storage for reading. + // Type of the file is determined from the content, not the extension + FileStorage fs("test.yml", FileStorage::READ); + int test_int = (int)fs["test_int"]; + double test_real = (double)fs["test_real"]; + String test_string = (String)fs["test_string"]; + + Mat M; + fs["test_mat"] >> M; + + FileNode tl = fs["test_list"]; + CV_Assert(tl.type() == FileNode::SEQ && tl.size() == 6); + double tl0 = (double)tl[0]; + int tl1 = (int)tl[1]; + double tl2 = (double)tl[2]; + int tl3 = (int)tl[3]; + String tl4 = (String)tl[4]; + CV_Assert(tl[5].type() == FileNode::MAP && tl[5].size() == 3); + + int month = (int)tl[5]["month"]; + int day = (int)tl[5]["day"]; + int year = (int)tl[5]["year"]; + + FileNode tm = fs["test_map"]; + + int x = (int)tm["x"]; + int y = (int)tm["y"]; + int width = (int)tm["width"]; + int height = (int)tm["height"]; + + int lbp_val = 0; + FileNodeIterator it = tm["lbp"].begin(); + + for(int k = 0; k < 8; k++, ++it) + lbp_val |= ((int)*it) << k; + \endcode +*/ +class CV_EXPORTS_W FileStorage +{ +public: + //! file storage mode + enum + { + READ = 0, //! read mode + WRITE = 1, //! write mode + APPEND = 2, //! append mode + MEMORY = 4, + FORMAT_MASK = (7<<3), + FORMAT_AUTO = 0, + FORMAT_XML = (1<<3), + FORMAT_YAML = (2<<3) + }; + enum + { + UNDEFINED = 0, + VALUE_EXPECTED = 1, + NAME_EXPECTED = 2, + INSIDE_MAP = 4 + }; + //! the default constructor + CV_WRAP FileStorage(); + //! the full constructor that opens file storage for reading or writing + CV_WRAP FileStorage(const String& source, int flags, const String& encoding=String()); + //! the constructor that takes pointer to the C FileStorage structure + FileStorage(CvFileStorage* fs); + //! the destructor. calls release() + virtual ~FileStorage(); + + //! opens file storage for reading or writing. The previous storage is closed with release() + CV_WRAP virtual bool open(const String& filename, int flags, const String& encoding=String()); + //! returns true if the object is associated with currently opened file. + CV_WRAP virtual bool isOpened() const; + //! closes the file and releases all the memory buffers + CV_WRAP virtual void release(); + //! closes the file, releases all the memory buffers and returns the text string + CV_WRAP virtual String releaseAndGetString(); + + //! returns the first element of the top-level mapping + CV_WRAP FileNode getFirstTopLevelNode() const; + //! returns the top-level mapping. YAML supports multiple streams + CV_WRAP FileNode root(int streamidx=0) const; + //! returns the specified element of the top-level mapping + FileNode operator[](const String& nodename) const; + //! returns the specified element of the top-level mapping + CV_WRAP FileNode operator[](const char* nodename) const; + + //! returns pointer to the underlying C FileStorage structure + CvFileStorage* operator *() { return fs; } + //! returns pointer to the underlying C FileStorage structure + const CvFileStorage* operator *() const { return fs; } + //! writes one or more numbers of the specified format to the currently written structure + void writeRaw( const String& fmt, const uchar* vec, size_t len ); + //! writes the registered C structure (CvMat, CvMatND, CvSeq). See cvWrite() + void writeObj( const String& name, const void* obj ); + + //! returns the normalized object name for the specified file name + static String getDefaultObjectName(const String& filename); + + Ptr fs; //!< the underlying C FileStorage structure + String elname; //!< the currently written element + std::vector structs; //!< the stack of written structures + int state; //!< the writer state +}; + +template<> CV_EXPORTS void Ptr::delete_obj(); + +/*! + File Storage Node class + + The node is used to store each and every element of the file storage opened for reading - + from the primitive objects, such as numbers and text strings, to the complex nodes: + sequences, mappings and the registered objects. + + Note that file nodes are only used for navigating file storages opened for reading. + When a file storage is opened for writing, no data is stored in memory after it is written. +*/ +class CV_EXPORTS_W_SIMPLE FileNode +{ +public: + //! type of the file storage node + enum + { + NONE = 0, //!< empty node + INT = 1, //!< an integer + REAL = 2, //!< floating-point number + FLOAT = REAL, //!< synonym or REAL + STR = 3, //!< text string in UTF-8 encoding + STRING = STR, //!< synonym for STR + REF = 4, //!< integer of size size_t. Typically used for storing complex dynamic structures where some elements reference the others + SEQ = 5, //!< sequence + MAP = 6, //!< mapping + TYPE_MASK = 7, + FLOW = 8, //!< compact representation of a sequence or mapping. Used only by YAML writer + USER = 16, //!< a registered object (e.g. a matrix) + EMPTY = 32, //!< empty structure (sequence or mapping) + NAMED = 64 //!< the node has a name (i.e. it is element of a mapping) + }; + //! the default constructor + CV_WRAP FileNode(); + //! the full constructor wrapping CvFileNode structure. + FileNode(const CvFileStorage* fs, const CvFileNode* node); + //! the copy constructor + FileNode(const FileNode& node); + //! returns element of a mapping node + FileNode operator[](const String& nodename) const; + //! returns element of a mapping node + CV_WRAP FileNode operator[](const char* nodename) const; + //! returns element of a sequence node + CV_WRAP FileNode operator[](int i) const; + //! returns type of the node + CV_WRAP int type() const; + + //! returns true if the node is empty + CV_WRAP bool empty() const; + //! returns true if the node is a "none" object + CV_WRAP bool isNone() const; + //! returns true if the node is a sequence + CV_WRAP bool isSeq() const; + //! returns true if the node is a mapping + CV_WRAP bool isMap() const; + //! returns true if the node is an integer + CV_WRAP bool isInt() const; + //! returns true if the node is a floating-point number + CV_WRAP bool isReal() const; + //! returns true if the node is a text string + CV_WRAP bool isString() const; + //! returns true if the node has a name + CV_WRAP bool isNamed() const; + //! returns the node name or an empty string if the node is nameless + CV_WRAP String name() const; + //! returns the number of elements in the node, if it is a sequence or mapping, or 1 otherwise. + CV_WRAP size_t size() const; + //! returns the node content as an integer. If the node stores floating-point number, it is rounded. + operator int() const; + //! returns the node content as float + operator float() const; + //! returns the node content as double + operator double() const; + //! returns the node content as text string + operator String() const; +#ifndef OPENCV_NOSTL + operator std::string() const; +#endif + + //! returns pointer to the underlying file node + CvFileNode* operator *(); + //! returns pointer to the underlying file node + const CvFileNode* operator* () const; + + //! returns iterator pointing to the first node element + FileNodeIterator begin() const; + //! returns iterator pointing to the element following the last node element + FileNodeIterator end() const; + + //! reads node elements to the buffer with the specified format + void readRaw( const String& fmt, uchar* vec, size_t len ) const; + //! reads the registered object and returns pointer to it + void* readObj() const; + + // do not use wrapper pointer classes for better efficiency + const CvFileStorage* fs; + const CvFileNode* node; +}; + + +/*! + File Node Iterator + + The class is used for iterating sequences (usually) and mappings. + */ +class CV_EXPORTS FileNodeIterator +{ +public: + //! the default constructor + FileNodeIterator(); + //! the full constructor set to the ofs-th element of the node + FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0); + //! the copy constructor + FileNodeIterator(const FileNodeIterator& it); + //! returns the currently observed element + FileNode operator *() const; + //! accesses the currently observed element methods + FileNode operator ->() const; + + //! moves iterator to the next node + FileNodeIterator& operator ++ (); + //! moves iterator to the next node + FileNodeIterator operator ++ (int); + //! moves iterator to the previous node + FileNodeIterator& operator -- (); + //! moves iterator to the previous node + FileNodeIterator operator -- (int); + //! moves iterator forward by the specified offset (possibly negative) + FileNodeIterator& operator += (int ofs); + //! moves iterator backward by the specified offset (possibly negative) + FileNodeIterator& operator -= (int ofs); + + //! reads the next maxCount elements (or less, if the sequence/mapping last element occurs earlier) to the buffer with the specified format + FileNodeIterator& readRaw( const String& fmt, uchar* vec, + size_t maxCount=(size_t)INT_MAX ); + + struct SeqReader + { + int header_size; + void* seq; /* sequence, beign read; CvSeq */ + void* block; /* current block; CvSeqBlock */ + schar* ptr; /* pointer to element be read next */ + schar* block_min; /* pointer to the beginning of block */ + schar* block_max; /* pointer to the end of block */ + int delta_index;/* = seq->first->start_index */ + schar* prev_elem; /* pointer to previous element */ + }; + + const CvFileStorage* fs; + const CvFileNode* container; + SeqReader reader; + size_t remaining; +}; + + + +/////////////////// XML & YAML I/O implementation ////////////////// + +CV_EXPORTS void write( FileStorage& fs, const String& name, int value ); +CV_EXPORTS void write( FileStorage& fs, const String& name, float value ); +CV_EXPORTS void write( FileStorage& fs, const String& name, double value ); +CV_EXPORTS void write( FileStorage& fs, const String& name, const String& value ); +CV_EXPORTS void write( FileStorage& fs, const String& name, const Mat& value ); +CV_EXPORTS void write( FileStorage& fs, const String& name, const SparseMat& value ); +CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector& value); + +CV_EXPORTS void writeScalar( FileStorage& fs, int value ); +CV_EXPORTS void writeScalar( FileStorage& fs, float value ); +CV_EXPORTS void writeScalar( FileStorage& fs, double value ); +CV_EXPORTS void writeScalar( FileStorage& fs, const String& value ); + +CV_EXPORTS void read(const FileNode& node, int& value, int default_value); +CV_EXPORTS void read(const FileNode& node, float& value, float default_value); +CV_EXPORTS void read(const FileNode& node, double& value, double default_value); +CV_EXPORTS void read(const FileNode& node, String& value, const String& default_value); +CV_EXPORTS void read(const FileNode& node, Mat& mat, const Mat& default_mat = Mat() ); +CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat = SparseMat() ); +CV_EXPORTS void read(const FileNode& node, std::vector& keypoints); + ++template static inline void read(const FileNode& node, Point_<_Tp>& value, const Point_<_Tp>& default_value) ++{ ++ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; ++ value = temp.size() != 2 ? default_value : Point_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1])); ++} ++ ++template static inline void read(const FileNode& node, Point3_<_Tp>& value, const Point3_<_Tp>& default_value) ++{ ++ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; ++ value = temp.size() != 3 ? default_value : Point3_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]), ++ saturate_cast<_Tp>(temp[2])); ++} ++ ++template static inline void read(const FileNode& node, Size_<_Tp>& value, const Size_<_Tp>& default_value) ++{ ++ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; ++ value = temp.size() != 2 ? default_value : Size_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1])); ++} ++ ++template static inline void read(const FileNode& node, Complex<_Tp>& value, const Complex<_Tp>& default_value) ++{ ++ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; ++ value = temp.size() != 2 ? default_value : Complex<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1])); ++} ++ ++template static inline void read(const FileNode& node, Rect_<_Tp>& value, const Rect_<_Tp>& default_value) ++{ ++ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; ++ value = temp.size() != 4 ? default_value : Rect_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]), ++ saturate_cast<_Tp>(temp[2]), saturate_cast<_Tp>(temp[3])); ++} ++ ++template static inline void read(const FileNode& node, Vec<_Tp, cn>& value, const Vec<_Tp, cn>& default_value) ++{ ++ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; ++ value = temp.size() != cn ? default_value : Vec<_Tp, cn>(&temp[0]); ++} ++ ++template static inline void read(const FileNode& node, Scalar_<_Tp>& value, const Scalar_<_Tp>& default_value) ++{ ++ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; ++ value = temp.size() != 4 ? default_value : Scalar_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]), ++ saturate_cast<_Tp>(temp[2]), saturate_cast<_Tp>(temp[3])); ++} ++ ++static inline void read(const FileNode& node, Range& value, const Range& default_value) ++{ ++ Point2i temp(value.start, value.end); const Point2i default_temp = Point2i(default_value.start, default_value.end); ++ read(node, temp, default_temp); ++ value.start = temp.x; value.end = temp.y; ++} ++ ++ +CV_EXPORTS FileStorage& operator << (FileStorage& fs, const String& str); + + +namespace internal +{ + class CV_EXPORTS WriteStructContext + { + public: + WriteStructContext(FileStorage& _fs, const String& name, int flags, const String& typeName = String()); + ~WriteStructContext(); + private: + FileStorage* fs; + }; + + template class VecWriterProxy + { + public: + VecWriterProxy( FileStorage* _fs ) : fs(_fs) {} + void operator()(const std::vector<_Tp>& vec) const + { + size_t count = vec.size(); + for (size_t i = 0; i < count; i++) + write(*fs, vec[i]); + } + private: + FileStorage* fs; + }; + + template class VecWriterProxy<_Tp, 1> + { + public: + VecWriterProxy( FileStorage* _fs ) : fs(_fs) {} + void operator()(const std::vector<_Tp>& vec) const + { + int _fmt = DataType<_Tp>::fmt; + char fmt[] = { (char)((_fmt >> 8) + '1'), (char)_fmt, '\0' }; + fs->writeRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, vec.size() * sizeof(_Tp)); + } + private: + FileStorage* fs; + }; + + template class VecReaderProxy + { + public: + VecReaderProxy( FileNodeIterator* _it ) : it(_it) {} + void operator()(std::vector<_Tp>& vec, size_t count) const + { + count = std::min(count, it->remaining); + vec.resize(count); + for (size_t i = 0; i < count; i++, ++(*it)) + read(**it, vec[i], _Tp()); + } + private: + FileNodeIterator* it; + }; + + template class VecReaderProxy<_Tp, 1> + { + public: + VecReaderProxy( FileNodeIterator* _it ) : it(_it) {} + void operator()(std::vector<_Tp>& vec, size_t count) const + { + size_t remaining = it->remaining; + size_t cn = DataType<_Tp>::channels; + int _fmt = DataType<_Tp>::fmt; + char fmt[] = { (char)((_fmt >> 8)+'1'), (char)_fmt, '\0' }; + size_t remaining1 = remaining / cn; + count = count < remaining1 ? count : remaining1; + vec.resize(count); + it->readRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, count*sizeof(_Tp)); + } + private: + FileNodeIterator* it; + }; + +} // internal + + + +template static inline +void write(FileStorage& fs, const _Tp& value) +{ + write(fs, String(), value); +} + +template<> inline +void write( FileStorage& fs, const int& value ) +{ + writeScalar(fs, value); +} + +template<> inline +void write( FileStorage& fs, const float& value ) +{ + writeScalar(fs, value); +} + +template<> inline +void write( FileStorage& fs, const double& value ) +{ + writeScalar(fs, value); +} + +template<> inline +void write( FileStorage& fs, const String& value ) +{ + writeScalar(fs, value); +} + +template static inline +void write(FileStorage& fs, const Point_<_Tp>& pt ) +{ + write(fs, pt.x); + write(fs, pt.y); +} + +template static inline +void write(FileStorage& fs, const Point3_<_Tp>& pt ) +{ + write(fs, pt.x); + write(fs, pt.y); + write(fs, pt.z); +} + +template static inline +void write(FileStorage& fs, const Size_<_Tp>& sz ) +{ + write(fs, sz.width); + write(fs, sz.height); +} + +template static inline +void write(FileStorage& fs, const Complex<_Tp>& c ) +{ + write(fs, c.re); + write(fs, c.im); +} + +template static inline +void write(FileStorage& fs, const Rect_<_Tp>& r ) +{ + write(fs, r.x); + write(fs, r.y); + write(fs, r.width); + write(fs, r.height); +} + +template static inline +void write(FileStorage& fs, const Vec<_Tp, cn>& v ) +{ + for(int i = 0; i < cn; i++) + write(fs, v.val[i]); +} + +template static inline +void write(FileStorage& fs, const Scalar_<_Tp>& s ) +{ + write(fs, s.val[0]); + write(fs, s.val[1]); + write(fs, s.val[2]); + write(fs, s.val[3]); +} + +static inline +void write(FileStorage& fs, const Range& r ) +{ + write(fs, r.start); + write(fs, r.end); +} + +template static inline +void write( FileStorage& fs, const std::vector<_Tp>& vec ) +{ + internal::VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs); + w(vec); +} + + +template static inline +void write(FileStorage& fs, const String& name, const Point_<_Tp>& pt ) +{ + internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, pt); +} + +template static inline +void write(FileStorage& fs, const String& name, const Point3_<_Tp>& pt ) +{ + internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, pt); +} + +template static inline +void write(FileStorage& fs, const String& name, const Size_<_Tp>& sz ) +{ + internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, sz); +} + +template static inline +void write(FileStorage& fs, const String& name, const Complex<_Tp>& c ) +{ + internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, c); +} + +template static inline +void write(FileStorage& fs, const String& name, const Rect_<_Tp>& r ) +{ + internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, r); +} + +template static inline +void write(FileStorage& fs, const String& name, const Vec<_Tp, cn>& v ) +{ + internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, v); +} + +template static inline +void write(FileStorage& fs, const String& name, const Scalar_<_Tp>& s ) +{ + internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, s); +} + +static inline +void write(FileStorage& fs, const String& name, const Range& r ) +{ + internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, r); +} + +template static inline +void write( FileStorage& fs, const String& name, const std::vector<_Tp>& vec ) +{ + internal::WriteStructContext ws(fs, name, FileNode::SEQ+(DataType<_Tp>::fmt != 0 ? FileNode::FLOW : 0)); + write(fs, vec); +} + + +static inline +void read(const FileNode& node, bool& value, bool default_value) +{ + int temp; + read(node, temp, (int)default_value); + value = temp != 0; +} + +static inline +void read(const FileNode& node, uchar& value, uchar default_value) +{ + int temp; + read(node, temp, (int)default_value); + value = saturate_cast(temp); +} + +static inline +void read(const FileNode& node, schar& value, schar default_value) +{ + int temp; + read(node, temp, (int)default_value); + value = saturate_cast(temp); +} + +static inline +void read(const FileNode& node, ushort& value, ushort default_value) +{ + int temp; + read(node, temp, (int)default_value); + value = saturate_cast(temp); +} + +static inline +void read(const FileNode& node, short& value, short default_value) +{ + int temp; + read(node, temp, (int)default_value); + value = saturate_cast(temp); +} + +template static inline +void read( FileNodeIterator& it, std::vector<_Tp>& vec, size_t maxCount = (size_t)INT_MAX ) +{ + internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it); + r(vec, maxCount); +} + +template static inline +void read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>& default_value = std::vector<_Tp>() ) +{ + if(!node.node) + vec = default_value; + else + { + FileNodeIterator it = node.begin(); + read( it, vec ); + } +} + + +template static inline +FileStorage& operator << (FileStorage& fs, const _Tp& value) +{ + if( !fs.isOpened() ) + return fs; + if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP ) + CV_Error( Error::StsError, "No element name has been given" ); + write( fs, fs.elname, value ); + if( fs.state & FileStorage::INSIDE_MAP ) + fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP; + return fs; +} + +static inline +FileStorage& operator << (FileStorage& fs, const char* str) +{ + return (fs << String(str)); +} + +static inline +FileStorage& operator << (FileStorage& fs, char* value) +{ + return (fs << String(value)); +} + +template static inline +FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value) +{ + read( *it, value, _Tp()); + return ++it; +} + +template static inline +FileNodeIterator& operator >> (FileNodeIterator& it, std::vector<_Tp>& vec) +{ + internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it); + r(vec, (size_t)INT_MAX); + return it; +} + +template static inline +void operator >> (const FileNode& n, _Tp& value) +{ + read( n, value, _Tp()); +} + +template static inline +void operator >> (const FileNode& n, std::vector<_Tp>& vec) +{ + FileNodeIterator it = n.begin(); + it >> vec; +} + + +static inline +bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2) +{ + return it1.fs == it2.fs && it1.container == it2.container && + it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining; +} + +static inline +bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2) +{ + return !(it1 == it2); +} + +static inline +ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2) +{ + return it2.remaining - it1.remaining; +} + +static inline +bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2) +{ + return it1.remaining > it2.remaining; +} + +inline FileNode FileStorage::getFirstTopLevelNode() const { FileNode r = root(); FileNodeIterator it = r.begin(); return it != r.end() ? *it : FileNode(); } +inline FileNode::FileNode() : fs(0), node(0) {} +inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node) : fs(_fs), node(_node) {} +inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {} +inline bool FileNode::empty() const { return node == 0; } +inline bool FileNode::isNone() const { return type() == NONE; } +inline bool FileNode::isSeq() const { return type() == SEQ; } +inline bool FileNode::isMap() const { return type() == MAP; } +inline bool FileNode::isInt() const { return type() == INT; } +inline bool FileNode::isReal() const { return type() == REAL; } +inline bool FileNode::isString() const { return type() == STR; } +inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; } +inline const CvFileNode* FileNode::operator* () const { return node; } +inline FileNode::operator int() const { int value; read(*this, value, 0); return value; } +inline FileNode::operator float() const { float value; read(*this, value, 0.f); return value; } +inline FileNode::operator double() const { double value; read(*this, value, 0.); return value; } +inline FileNode::operator String() const { String value; read(*this, value, value); return value; } +inline FileNodeIterator FileNode::begin() const { return FileNodeIterator(fs, node); } +inline FileNodeIterator FileNode::end() const { return FileNodeIterator(fs, node, size()); } +inline void FileNode::readRaw( const String& fmt, uchar* vec, size_t len ) const { begin().readRaw( fmt, vec, len ); } +inline FileNode FileNodeIterator::operator *() const { return FileNode(fs, (const CvFileNode*)reader.ptr); } +inline FileNode FileNodeIterator::operator ->() const { return FileNode(fs, (const CvFileNode*)reader.ptr); } +inline String::String(const FileNode& fn): cstr_(0), len_(0) { read(fn, *this, *this); } + +} // cv + +#endif // __OPENCV_CORE_PERSISTENCE_HPP__ diff --cc modules/core/src/arithm.cpp index 98b67aa,9939040..7ad7b09 --- a/modules/core/src/arithm.cpp +++ b/modules/core/src/arithm.cpp @@@ -1194,9 -1204,20 +1204,9 @@@ void cv::max(const Mat& src1, const Mat void cv::min(const Mat& src1, const Mat& src2, Mat& dst) { OutputArray _dst(dst); - binary_op(src1, src2, _dst, noArray(), minTab, false ); + binary_op(src1, src2, _dst, noArray(), getMinTab(), false ); } -void cv::max(const Mat& src1, double src2, Mat& dst) -{ - OutputArray _dst(dst); - binary_op(src1, src2, _dst, noArray(), getMaxTab(), false ); -} - -void cv::min(const Mat& src1, double src2, Mat& dst) -{ - OutputArray _dst(dst); - binary_op(src1, src2, _dst, noArray(), getMinTab(), false ); -} /****************************************************************************************\ * add/subtract * diff --cc modules/core/src/convert.cpp index f5d6e99,288eb1d..97bd5dd --- a/modules/core/src/convert.cpp +++ b/modules/core/src/convert.cpp @@@ -1043,8 -1015,50 +1021,50 @@@ BinaryFunc getConvertFunc(int sdepth, i return cvtTab[CV_MAT_DEPTH(ddepth)][CV_MAT_DEPTH(sdepth)]; } -BinaryFunc getConvertScaleFunc(int sdepth, int ddepth) +static BinaryFunc getConvertScaleFunc(int sdepth, int ddepth) { + static BinaryFunc cvtScaleTab[][8] = + { + { + (BinaryFunc)GET_OPTIMIZED(cvtScale8u), (BinaryFunc)GET_OPTIMIZED(cvtScale8s8u), (BinaryFunc)GET_OPTIMIZED(cvtScale16u8u), + (BinaryFunc)GET_OPTIMIZED(cvtScale16s8u), (BinaryFunc)GET_OPTIMIZED(cvtScale32s8u), (BinaryFunc)GET_OPTIMIZED(cvtScale32f8u), + (BinaryFunc)cvtScale64f8u, 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvtScale8u8s), (BinaryFunc)GET_OPTIMIZED(cvtScale8s), (BinaryFunc)GET_OPTIMIZED(cvtScale16u8s), + (BinaryFunc)GET_OPTIMIZED(cvtScale16s8s), (BinaryFunc)GET_OPTIMIZED(cvtScale32s8s), (BinaryFunc)GET_OPTIMIZED(cvtScale32f8s), + (BinaryFunc)cvtScale64f8s, 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvtScale8u16u), (BinaryFunc)GET_OPTIMIZED(cvtScale8s16u), (BinaryFunc)GET_OPTIMIZED(cvtScale16u), + (BinaryFunc)GET_OPTIMIZED(cvtScale16s16u), (BinaryFunc)GET_OPTIMIZED(cvtScale32s16u), (BinaryFunc)GET_OPTIMIZED(cvtScale32f16u), + (BinaryFunc)cvtScale64f16u, 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvtScale8u16s), (BinaryFunc)GET_OPTIMIZED(cvtScale8s16s), (BinaryFunc)GET_OPTIMIZED(cvtScale16u16s), + (BinaryFunc)GET_OPTIMIZED(cvtScale16s), (BinaryFunc)GET_OPTIMIZED(cvtScale32s16s), (BinaryFunc)GET_OPTIMIZED(cvtScale32f16s), + (BinaryFunc)cvtScale64f16s, 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvtScale8u32s), (BinaryFunc)GET_OPTIMIZED(cvtScale8s32s), (BinaryFunc)GET_OPTIMIZED(cvtScale16u32s), + (BinaryFunc)GET_OPTIMIZED(cvtScale16s32s), (BinaryFunc)GET_OPTIMIZED(cvtScale32s), (BinaryFunc)GET_OPTIMIZED(cvtScale32f32s), + (BinaryFunc)cvtScale64f32s, 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvtScale8u32f), (BinaryFunc)GET_OPTIMIZED(cvtScale8s32f), (BinaryFunc)GET_OPTIMIZED(cvtScale16u32f), + (BinaryFunc)GET_OPTIMIZED(cvtScale16s32f), (BinaryFunc)GET_OPTIMIZED(cvtScale32s32f), (BinaryFunc)GET_OPTIMIZED(cvtScale32f), + (BinaryFunc)cvtScale64f32f, 0 + }, + { + (BinaryFunc)cvtScale8u64f, (BinaryFunc)cvtScale8s64f, (BinaryFunc)cvtScale16u64f, + (BinaryFunc)cvtScale16s64f, (BinaryFunc)cvtScale32s64f, (BinaryFunc)cvtScale32f64f, + (BinaryFunc)cvtScale64f, 0 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0 + } + }; + return cvtScaleTab[CV_MAT_DEPTH(ddepth)][CV_MAT_DEPTH(sdepth)]; } diff --cc modules/gpubgsegm/perf/perf_bgsegm.cpp index d442169,0000000..6f864fd mode 100644,000000..100644 --- a/modules/gpubgsegm/perf/perf_bgsegm.cpp +++ b/modules/gpubgsegm/perf/perf_bgsegm.cpp @@@ -1,556 -1,0 +1,557 @@@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "perf_precomp.hpp" + +#ifdef HAVE_OPENCV_LEGACY +# include "opencv2/legacy.hpp" +#endif + +#ifdef HAVE_OPENCV_GPUIMGPROC +# include "opencv2/gpuimgproc.hpp" +#endif + +using namespace std; +using namespace testing; +using namespace perf; + +#if defined(HAVE_XINE) || \ + defined(HAVE_GSTREAMER) || \ + defined(HAVE_QUICKTIME) || \ ++ defined(HAVE_QTKIT) || \ + defined(HAVE_AVFOUNDATION) || \ + defined(HAVE_FFMPEG) || \ + defined(WIN32) /* assume that we have ffmpeg */ + +# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 +#else +# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 +#endif + +////////////////////////////////////////////////////// +// FGDStatModel + +#if BUILD_WITH_VIDEO_INPUT_SUPPORT + +#ifdef HAVE_OPENCV_LEGACY + +namespace cv +{ + template<> void Ptr::delete_obj() + { + cvReleaseBGStatModel(&obj); + } +} + +#endif + +DEF_PARAM_TEST_1(Video, string); + +PERF_TEST_P(Video, FGDStatModel, + Values(string("gpu/video/768x576.avi"))) +{ + declare.time(60); + + const string inputFile = perf::TestBase::getDataPath(GetParam()); + + cv::VideoCapture cap(inputFile); + ASSERT_TRUE(cap.isOpened()); + + cv::Mat frame; + cap >> frame; + ASSERT_FALSE(frame.empty()); + + if (PERF_RUN_GPU()) + { + cv::gpu::GpuMat d_frame(frame), foreground; + + cv::Ptr d_fgd = cv::gpu::createBackgroundSubtractorFGD(); + d_fgd->apply(d_frame, foreground); + + for (int i = 0; i < 10; ++i) + { + cap >> frame; + ASSERT_FALSE(frame.empty()); + + d_frame.upload(frame); + + startTimer(); next(); + d_fgd->apply(d_frame, foreground); + stopTimer(); + } + + GPU_SANITY_CHECK(foreground, 1e-2, ERROR_RELATIVE); + +#ifdef HAVE_OPENCV_GPUIMGPROC + cv::gpu::GpuMat background3, background; + d_fgd->getBackgroundImage(background3); + cv::gpu::cvtColor(background3, background, cv::COLOR_BGR2BGRA); + GPU_SANITY_CHECK(background, 1e-2, ERROR_RELATIVE); +#endif + } + else + { +#ifdef HAVE_OPENCV_LEGACY + IplImage ipl_frame = frame; + cv::Ptr model(cvCreateFGDStatModel(&ipl_frame)); + + for (int i = 0; i < 10; ++i) + { + cap >> frame; + ASSERT_FALSE(frame.empty()); + + ipl_frame = frame; + + startTimer(); next(); + cvUpdateBGStatModel(&ipl_frame, model); + stopTimer(); + } + + const cv::Mat background = cv::cvarrToMat(model->background); + const cv::Mat foreground = cv::cvarrToMat(model->foreground); + + CPU_SANITY_CHECK(background); + CPU_SANITY_CHECK(foreground); +#else + FAIL_NO_CPU(); +#endif + } +} + +#endif + +////////////////////////////////////////////////////// +// MOG + +#if BUILD_WITH_VIDEO_INPUT_SUPPORT + +DEF_PARAM_TEST(Video_Cn_LearningRate, string, MatCn, double); + +PERF_TEST_P(Video_Cn_LearningRate, MOG, + Combine(Values("gpu/video/768x576.avi", "gpu/video/1920x1080.avi"), + GPU_CHANNELS_1_3_4, + Values(0.0, 0.01))) +{ + const string inputFile = perf::TestBase::getDataPath(GET_PARAM(0)); + const int cn = GET_PARAM(1); + const float learningRate = static_cast(GET_PARAM(2)); + + cv::VideoCapture cap(inputFile); + ASSERT_TRUE(cap.isOpened()); + + cv::Mat frame; + + cap >> frame; + ASSERT_FALSE(frame.empty()); + + if (cn != 3) + { + cv::Mat temp; + if (cn == 1) + cv::cvtColor(frame, temp, cv::COLOR_BGR2GRAY); + else + cv::cvtColor(frame, temp, cv::COLOR_BGR2BGRA); + cv::swap(temp, frame); + } + + if (PERF_RUN_GPU()) + { + cv::Ptr d_mog = cv::gpu::createBackgroundSubtractorMOG(); + + cv::gpu::GpuMat d_frame(frame); + cv::gpu::GpuMat foreground; + + d_mog->apply(d_frame, foreground, learningRate); + + for (int i = 0; i < 10; ++i) + { + cap >> frame; + ASSERT_FALSE(frame.empty()); + + if (cn != 3) + { + cv::Mat temp; + if (cn == 1) + cv::cvtColor(frame, temp, cv::COLOR_BGR2GRAY); + else + cv::cvtColor(frame, temp, cv::COLOR_BGR2BGRA); + cv::swap(temp, frame); + } + + d_frame.upload(frame); + + startTimer(); next(); + d_mog->apply(d_frame, foreground, learningRate); + stopTimer(); + } + + GPU_SANITY_CHECK(foreground); + } + else + { + cv::Ptr mog = cv::createBackgroundSubtractorMOG(); + cv::Mat foreground; + + mog->apply(frame, foreground, learningRate); + + for (int i = 0; i < 10; ++i) + { + cap >> frame; + ASSERT_FALSE(frame.empty()); + + if (cn != 3) + { + cv::Mat temp; + if (cn == 1) + cv::cvtColor(frame, temp, cv::COLOR_BGR2GRAY); + else + cv::cvtColor(frame, temp, cv::COLOR_BGR2BGRA); + cv::swap(temp, frame); + } + + startTimer(); next(); + mog->apply(frame, foreground, learningRate); + stopTimer(); + } + + CPU_SANITY_CHECK(foreground); + } +} + +#endif + +////////////////////////////////////////////////////// +// MOG2 + +#if BUILD_WITH_VIDEO_INPUT_SUPPORT + +DEF_PARAM_TEST(Video_Cn, string, int); + +PERF_TEST_P(Video_Cn, MOG2, + Combine(Values("gpu/video/768x576.avi", "gpu/video/1920x1080.avi"), + GPU_CHANNELS_1_3_4)) +{ + const string inputFile = perf::TestBase::getDataPath(GET_PARAM(0)); + const int cn = GET_PARAM(1); + + cv::VideoCapture cap(inputFile); + ASSERT_TRUE(cap.isOpened()); + + cv::Mat frame; + + cap >> frame; + ASSERT_FALSE(frame.empty()); + + if (cn != 3) + { + cv::Mat temp; + if (cn == 1) + cv::cvtColor(frame, temp, cv::COLOR_BGR2GRAY); + else + cv::cvtColor(frame, temp, cv::COLOR_BGR2BGRA); + cv::swap(temp, frame); + } + + if (PERF_RUN_GPU()) + { + cv::Ptr d_mog2 = cv::gpu::createBackgroundSubtractorMOG2(); + d_mog2->setDetectShadows(false); + + cv::gpu::GpuMat d_frame(frame); + cv::gpu::GpuMat foreground; + + d_mog2->apply(d_frame, foreground); + + for (int i = 0; i < 10; ++i) + { + cap >> frame; + ASSERT_FALSE(frame.empty()); + + if (cn != 3) + { + cv::Mat temp; + if (cn == 1) + cv::cvtColor(frame, temp, cv::COLOR_BGR2GRAY); + else + cv::cvtColor(frame, temp, cv::COLOR_BGR2BGRA); + cv::swap(temp, frame); + } + + d_frame.upload(frame); + + startTimer(); next(); + d_mog2->apply(d_frame, foreground); + stopTimer(); + } + + GPU_SANITY_CHECK(foreground); + } + else + { + cv::Ptr mog2 = cv::createBackgroundSubtractorMOG2(); + mog2->setDetectShadows(false); + + cv::Mat foreground; + + mog2->apply(frame, foreground); + + for (int i = 0; i < 10; ++i) + { + cap >> frame; + ASSERT_FALSE(frame.empty()); + + if (cn != 3) + { + cv::Mat temp; + if (cn == 1) + cv::cvtColor(frame, temp, cv::COLOR_BGR2GRAY); + else + cv::cvtColor(frame, temp, cv::COLOR_BGR2BGRA); + cv::swap(temp, frame); + } + + startTimer(); next(); + mog2->apply(frame, foreground); + stopTimer(); + } + + CPU_SANITY_CHECK(foreground); + } +} + +#endif + +////////////////////////////////////////////////////// +// MOG2GetBackgroundImage + +#if BUILD_WITH_VIDEO_INPUT_SUPPORT + +PERF_TEST_P(Video_Cn, MOG2GetBackgroundImage, + Combine(Values("gpu/video/768x576.avi", "gpu/video/1920x1080.avi"), + GPU_CHANNELS_1_3_4)) +{ + const string inputFile = perf::TestBase::getDataPath(GET_PARAM(0)); + const int cn = GET_PARAM(1); + + cv::VideoCapture cap(inputFile); + ASSERT_TRUE(cap.isOpened()); + + cv::Mat frame; + + if (PERF_RUN_GPU()) + { + cv::Ptr d_mog2 = cv::gpu::createBackgroundSubtractorMOG2(); + + cv::gpu::GpuMat d_frame; + cv::gpu::GpuMat d_foreground; + + for (int i = 0; i < 10; ++i) + { + cap >> frame; + ASSERT_FALSE(frame.empty()); + + if (cn != 3) + { + cv::Mat temp; + if (cn == 1) + cv::cvtColor(frame, temp, cv::COLOR_BGR2GRAY); + else + cv::cvtColor(frame, temp, cv::COLOR_BGR2BGRA); + cv::swap(temp, frame); + } + + d_frame.upload(frame); + + d_mog2->apply(d_frame, d_foreground); + } + + cv::gpu::GpuMat background; + + TEST_CYCLE() d_mog2->getBackgroundImage(background); + + GPU_SANITY_CHECK(background, 1); + } + else + { + cv::Ptr mog2 = cv::createBackgroundSubtractorMOG2(); + cv::Mat foreground; + + for (int i = 0; i < 10; ++i) + { + cap >> frame; + ASSERT_FALSE(frame.empty()); + + if (cn != 3) + { + cv::Mat temp; + if (cn == 1) + cv::cvtColor(frame, temp, cv::COLOR_BGR2GRAY); + else + cv::cvtColor(frame, temp, cv::COLOR_BGR2BGRA); + cv::swap(temp, frame); + } + + mog2->apply(frame, foreground); + } + + cv::Mat background; + + TEST_CYCLE() mog2->getBackgroundImage(background); + + CPU_SANITY_CHECK(background); + } +} + +#endif + +////////////////////////////////////////////////////// +// GMG + +#if BUILD_WITH_VIDEO_INPUT_SUPPORT + +DEF_PARAM_TEST(Video_Cn_MaxFeatures, string, MatCn, int); + +PERF_TEST_P(Video_Cn_MaxFeatures, GMG, + Combine(Values(string("gpu/video/768x576.avi")), + GPU_CHANNELS_1_3_4, + Values(20, 40, 60))) +{ + const std::string inputFile = perf::TestBase::getDataPath(GET_PARAM(0)); + const int cn = GET_PARAM(1); + const int maxFeatures = GET_PARAM(2); + + cv::VideoCapture cap(inputFile); + ASSERT_TRUE(cap.isOpened()); + + cv::Mat frame; + cap >> frame; + ASSERT_FALSE(frame.empty()); + + if (cn != 3) + { + cv::Mat temp; + if (cn == 1) + cv::cvtColor(frame, temp, cv::COLOR_BGR2GRAY); + else + cv::cvtColor(frame, temp, cv::COLOR_BGR2BGRA); + cv::swap(temp, frame); + } + + if (PERF_RUN_GPU()) + { + cv::gpu::GpuMat d_frame(frame); + cv::gpu::GpuMat foreground; + + cv::Ptr d_gmg = cv::gpu::createBackgroundSubtractorGMG(); + d_gmg->setMaxFeatures(maxFeatures); + + d_gmg->apply(d_frame, foreground); + + for (int i = 0; i < 150; ++i) + { + cap >> frame; + if (frame.empty()) + { + cap.release(); + cap.open(inputFile); + cap >> frame; + } + + if (cn != 3) + { + cv::Mat temp; + if (cn == 1) + cv::cvtColor(frame, temp, cv::COLOR_BGR2GRAY); + else + cv::cvtColor(frame, temp, cv::COLOR_BGR2BGRA); + cv::swap(temp, frame); + } + + d_frame.upload(frame); + + startTimer(); next(); + d_gmg->apply(d_frame, foreground); + stopTimer(); + } + + GPU_SANITY_CHECK(foreground); + } + else + { + cv::Mat foreground; + cv::Mat zeros(frame.size(), CV_8UC1, cv::Scalar::all(0)); + + cv::Ptr gmg = cv::createBackgroundSubtractorGMG(); + gmg->setMaxFeatures(maxFeatures); + + gmg->apply(frame, foreground); + + for (int i = 0; i < 150; ++i) + { + cap >> frame; + if (frame.empty()) + { + cap.release(); + cap.open(inputFile); + cap >> frame; + } + + if (cn != 3) + { + cv::Mat temp; + if (cn == 1) + cv::cvtColor(frame, temp, cv::COLOR_BGR2GRAY); + else + cv::cvtColor(frame, temp, cv::COLOR_BGR2BGRA); + cv::swap(temp, frame); + } + + startTimer(); next(); + gmg->apply(frame, foreground); + stopTimer(); + } + + CPU_SANITY_CHECK(foreground); + } +} + +#endif diff --cc modules/gpubgsegm/test/test_bgsegm.cpp index e8fc68d,0000000..3b5526b mode 100644,000000..100644 --- a/modules/gpubgsegm/test/test_bgsegm.cpp +++ b/modules/gpubgsegm/test/test_bgsegm.cpp @@@ -1,390 -1,0 +1,391 @@@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +#ifdef HAVE_OPENCV_LEGACY +# include "opencv2/legacy.hpp" +#endif + +#ifdef HAVE_CUDA + +using namespace cvtest; + +#if defined(HAVE_XINE) || \ + defined(HAVE_GSTREAMER) || \ + defined(HAVE_QUICKTIME) || \ ++ defined(HAVE_QTKIT) || \ + defined(HAVE_AVFOUNDATION) || \ + defined(HAVE_FFMPEG) || \ + defined(WIN32) /* assume that we have ffmpeg */ + +# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 +#else +# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 +#endif + +////////////////////////////////////////////////////// +// FGDStatModel + +#if BUILD_WITH_VIDEO_INPUT_SUPPORT && defined(HAVE_OPENCV_LEGACY) + +namespace cv +{ + template<> void Ptr::delete_obj() + { + cvReleaseBGStatModel(&obj); + } +} + +PARAM_TEST_CASE(FGDStatModel, cv::gpu::DeviceInfo, std::string) +{ + cv::gpu::DeviceInfo devInfo; + std::string inputFile; + + virtual void SetUp() + { + devInfo = GET_PARAM(0); + cv::gpu::setDevice(devInfo.deviceID()); + + inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "video/" + GET_PARAM(1); + } +}; + +GPU_TEST_P(FGDStatModel, Update) +{ + cv::VideoCapture cap(inputFile); + ASSERT_TRUE(cap.isOpened()); + + cv::Mat frame; + cap >> frame; + ASSERT_FALSE(frame.empty()); + + IplImage ipl_frame = frame; + cv::Ptr model(cvCreateFGDStatModel(&ipl_frame)); + + cv::gpu::GpuMat d_frame(frame); + cv::Ptr d_fgd = cv::gpu::createBackgroundSubtractorFGD(); + cv::gpu::GpuMat d_foreground, d_background; + std::vector< std::vector > foreground_regions; + d_fgd->apply(d_frame, d_foreground); + + for (int i = 0; i < 5; ++i) + { + cap >> frame; + ASSERT_FALSE(frame.empty()); + + ipl_frame = frame; + int gold_count = cvUpdateBGStatModel(&ipl_frame, model); + + d_frame.upload(frame); + d_fgd->apply(d_frame, d_foreground); + d_fgd->getBackgroundImage(d_background); + d_fgd->getForegroundRegions(foreground_regions); + int count = (int) foreground_regions.size(); + + cv::Mat gold_background = cv::cvarrToMat(model->background); + cv::Mat gold_foreground = cv::cvarrToMat(model->foreground); + + ASSERT_MAT_NEAR(gold_background, d_background, 1.0); + ASSERT_MAT_NEAR(gold_foreground, d_foreground, 0.0); + ASSERT_EQ(gold_count, count); + } +} + +INSTANTIATE_TEST_CASE_P(GPU_BgSegm, FGDStatModel, testing::Combine( + ALL_DEVICES, + testing::Values(std::string("768x576.avi")))); + +#endif + +////////////////////////////////////////////////////// +// MOG + +#if BUILD_WITH_VIDEO_INPUT_SUPPORT + +namespace +{ + IMPLEMENT_PARAM_CLASS(UseGray, bool) + IMPLEMENT_PARAM_CLASS(LearningRate, double) +} + +PARAM_TEST_CASE(MOG, cv::gpu::DeviceInfo, std::string, UseGray, LearningRate, UseRoi) +{ + cv::gpu::DeviceInfo devInfo; + std::string inputFile; + bool useGray; + double learningRate; + bool useRoi; + + virtual void SetUp() + { + devInfo = GET_PARAM(0); + cv::gpu::setDevice(devInfo.deviceID()); + + inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "video/" + GET_PARAM(1); + + useGray = GET_PARAM(2); + + learningRate = GET_PARAM(3); + + useRoi = GET_PARAM(4); + } +}; + +GPU_TEST_P(MOG, Update) +{ + cv::VideoCapture cap(inputFile); + ASSERT_TRUE(cap.isOpened()); + + cv::Mat frame; + cap >> frame; + ASSERT_FALSE(frame.empty()); + + cv::Ptr mog = cv::gpu::createBackgroundSubtractorMOG(); + cv::gpu::GpuMat foreground = createMat(frame.size(), CV_8UC1, useRoi); + + cv::Ptr mog_gold = cv::createBackgroundSubtractorMOG(); + cv::Mat foreground_gold; + + for (int i = 0; i < 10; ++i) + { + cap >> frame; + ASSERT_FALSE(frame.empty()); + + if (useGray) + { + cv::Mat temp; + cv::cvtColor(frame, temp, cv::COLOR_BGR2GRAY); + cv::swap(temp, frame); + } + + mog->apply(loadMat(frame, useRoi), foreground, learningRate); + + mog_gold->apply(frame, foreground_gold, learningRate); + + ASSERT_MAT_NEAR(foreground_gold, foreground, 0.0); + } +} + +INSTANTIATE_TEST_CASE_P(GPU_BgSegm, MOG, testing::Combine( + ALL_DEVICES, + testing::Values(std::string("768x576.avi")), + testing::Values(UseGray(true), UseGray(false)), + testing::Values(LearningRate(0.0), LearningRate(0.01)), + WHOLE_SUBMAT)); + +#endif + +////////////////////////////////////////////////////// +// MOG2 + +#if BUILD_WITH_VIDEO_INPUT_SUPPORT + +namespace +{ + IMPLEMENT_PARAM_CLASS(DetectShadow, bool) +} + +PARAM_TEST_CASE(MOG2, cv::gpu::DeviceInfo, std::string, UseGray, DetectShadow, UseRoi) +{ + cv::gpu::DeviceInfo devInfo; + std::string inputFile; + bool useGray; + bool detectShadow; + bool useRoi; + + virtual void SetUp() + { + devInfo = GET_PARAM(0); + cv::gpu::setDevice(devInfo.deviceID()); + + inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "video/" + GET_PARAM(1); + useGray = GET_PARAM(2); + detectShadow = GET_PARAM(3); + useRoi = GET_PARAM(4); + } +}; + +GPU_TEST_P(MOG2, Update) +{ + cv::VideoCapture cap(inputFile); + ASSERT_TRUE(cap.isOpened()); + + cv::Mat frame; + cap >> frame; + ASSERT_FALSE(frame.empty()); + + cv::Ptr mog2 = cv::gpu::createBackgroundSubtractorMOG2(); + mog2->setDetectShadows(detectShadow); + cv::gpu::GpuMat foreground = createMat(frame.size(), CV_8UC1, useRoi); + + cv::Ptr mog2_gold = cv::createBackgroundSubtractorMOG2(); + mog2_gold->setDetectShadows(detectShadow); + cv::Mat foreground_gold; + + for (int i = 0; i < 10; ++i) + { + cap >> frame; + ASSERT_FALSE(frame.empty()); + + if (useGray) + { + cv::Mat temp; + cv::cvtColor(frame, temp, cv::COLOR_BGR2GRAY); + cv::swap(temp, frame); + } + + mog2->apply(loadMat(frame, useRoi), foreground); + + mog2_gold->apply(frame, foreground_gold); + + if (detectShadow) + { + ASSERT_MAT_SIMILAR(foreground_gold, foreground, 1e-2); + } + else + { + ASSERT_MAT_NEAR(foreground_gold, foreground, 0); + } + } +} + +GPU_TEST_P(MOG2, getBackgroundImage) +{ + if (useGray) + return; + + cv::VideoCapture cap(inputFile); + ASSERT_TRUE(cap.isOpened()); + + cv::Mat frame; + + cv::Ptr mog2 = cv::gpu::createBackgroundSubtractorMOG2(); + mog2->setDetectShadows(detectShadow); + cv::gpu::GpuMat foreground; + + cv::Ptr mog2_gold = cv::createBackgroundSubtractorMOG2(); + mog2_gold->setDetectShadows(detectShadow); + cv::Mat foreground_gold; + + for (int i = 0; i < 10; ++i) + { + cap >> frame; + ASSERT_FALSE(frame.empty()); + + mog2->apply(loadMat(frame, useRoi), foreground); + + mog2_gold->apply(frame, foreground_gold); + } + + cv::gpu::GpuMat background = createMat(frame.size(), frame.type(), useRoi); + mog2->getBackgroundImage(background); + + cv::Mat background_gold; + mog2_gold->getBackgroundImage(background_gold); + + ASSERT_MAT_NEAR(background_gold, background, 0); +} + +INSTANTIATE_TEST_CASE_P(GPU_BgSegm, MOG2, testing::Combine( + ALL_DEVICES, + testing::Values(std::string("768x576.avi")), + testing::Values(UseGray(true), UseGray(false)), + testing::Values(DetectShadow(true), DetectShadow(false)), + WHOLE_SUBMAT)); + +#endif + +////////////////////////////////////////////////////// +// GMG + +PARAM_TEST_CASE(GMG, cv::gpu::DeviceInfo, cv::Size, MatDepth, Channels, UseRoi) +{ +}; + +GPU_TEST_P(GMG, Accuracy) +{ + const cv::gpu::DeviceInfo devInfo = GET_PARAM(0); + cv::gpu::setDevice(devInfo.deviceID()); + const cv::Size size = GET_PARAM(1); + const int depth = GET_PARAM(2); + const int channels = GET_PARAM(3); + const bool useRoi = GET_PARAM(4); + + const int type = CV_MAKE_TYPE(depth, channels); + + const cv::Mat zeros(size, CV_8UC1, cv::Scalar::all(0)); + const cv::Mat fullfg(size, CV_8UC1, cv::Scalar::all(255)); + + cv::Mat frame = randomMat(size, type, 0, 100); + cv::gpu::GpuMat d_frame = loadMat(frame, useRoi); + + cv::Ptr gmg = cv::gpu::createBackgroundSubtractorGMG(); + gmg->setNumFrames(5); + gmg->setSmoothingRadius(0); + + cv::gpu::GpuMat d_fgmask = createMat(size, CV_8UC1, useRoi); + + for (int i = 0; i < gmg->getNumFrames(); ++i) + { + gmg->apply(d_frame, d_fgmask); + + // fgmask should be entirely background during training + ASSERT_MAT_NEAR(zeros, d_fgmask, 0); + } + + frame = randomMat(size, type, 160, 255); + d_frame = loadMat(frame, useRoi); + gmg->apply(d_frame, d_fgmask); + + // now fgmask should be entirely foreground + ASSERT_MAT_NEAR(fullfg, d_fgmask, 0); +} + +INSTANTIATE_TEST_CASE_P(GPU_BgSegm, GMG, testing::Combine( + ALL_DEVICES, + DIFFERENT_SIZES, + testing::Values(MatType(CV_8U), MatType(CV_16U), MatType(CV_32F)), + testing::Values(Channels(1), Channels(3), Channels(4)), + WHOLE_SUBMAT)); + +#endif // HAVE_CUDA diff --cc modules/gpucodec/perf/perf_video.cpp index f389605,0000000..c4ab227 mode 100644,000000..100644 --- a/modules/gpucodec/perf/perf_video.cpp +++ b/modules/gpucodec/perf/perf_video.cpp @@@ -1,161 -1,0 +1,162 @@@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "perf_precomp.hpp" +#include "opencv2/highgui/highgui_c.h" + +using namespace std; +using namespace testing; +using namespace perf; + +#if defined(HAVE_XINE) || \ + defined(HAVE_GSTREAMER) || \ + defined(HAVE_QUICKTIME) || \ ++ defined(HAVE_QTKIT) || \ + defined(HAVE_AVFOUNDATION) || \ + defined(HAVE_FFMPEG) || \ + defined(WIN32) /* assume that we have ffmpeg */ + +# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 +#else +# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 +#endif + +DEF_PARAM_TEST_1(FileName, string); + +////////////////////////////////////////////////////// +// VideoReader + +#if defined(HAVE_NVCUVID) && BUILD_WITH_VIDEO_INPUT_SUPPORT + +PERF_TEST_P(FileName, VideoReader, Values("gpu/video/768x576.avi", "gpu/video/1920x1080.avi")) +{ + declare.time(20); + + const string inputFile = perf::TestBase::getDataPath(GetParam()); + + if (PERF_RUN_GPU()) + { + cv::Ptr d_reader = cv::gpucodec::createVideoReader(inputFile); + + cv::gpu::GpuMat frame; + + TEST_CYCLE_N(10) d_reader->nextFrame(frame); + + GPU_SANITY_CHECK(frame); + } + else + { + cv::VideoCapture reader(inputFile); + ASSERT_TRUE( reader.isOpened() ); + + cv::Mat frame; + + TEST_CYCLE_N(10) reader >> frame; + + CPU_SANITY_CHECK(frame); + } +} + +#endif + +////////////////////////////////////////////////////// +// VideoWriter + +#if defined(HAVE_NVCUVID) && defined(WIN32) + +PERF_TEST_P(FileName, VideoWriter, Values("gpu/video/768x576.avi", "gpu/video/1920x1080.avi")) +{ + declare.time(30); + + const string inputFile = perf::TestBase::getDataPath(GetParam()); + const string outputFile = cv::tempfile(".avi"); + + const double FPS = 25.0; + + cv::VideoCapture reader(inputFile); + ASSERT_TRUE( reader.isOpened() ); + + cv::Mat frame; + + if (PERF_RUN_GPU()) + { + cv::Ptr d_writer; + + cv::gpu::GpuMat d_frame; + + for (int i = 0; i < 10; ++i) + { + reader >> frame; + ASSERT_FALSE(frame.empty()); + + d_frame.upload(frame); + + if (d_writer.empty()) + d_writer = cv::gpucodec::createVideoWriter(outputFile, frame.size(), FPS); + + startTimer(); next(); + d_writer->write(d_frame); + stopTimer(); + } + } + else + { + cv::VideoWriter writer; + + for (int i = 0; i < 10; ++i) + { + reader >> frame; + ASSERT_FALSE(frame.empty()); + + if (!writer.isOpened()) + writer.open(outputFile, CV_FOURCC('X', 'V', 'I', 'D'), FPS, frame.size()); + + startTimer(); next(); + writer.write(frame); + stopTimer(); + } + } + + SANITY_CHECK(frame); +} + +#endif diff --cc modules/highgui/src/cap_qtkit.mm index d44b763,258d637..02afb9b --- a/modules/highgui/src/cap_qtkit.mm +++ b/modules/highgui/src/cap_qtkit.mm @@@ -1,35 -1,47 +1,47 @@@ - /* - * CvCapture.mm - * - * Created by Nicholas Butko on 11/3/09. - * Copyright 2009. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ + /*M/////////////////////////////////////////////////////////////////////////////////////// + // + // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. + // + // By downloading, copying, installing or using the software you agree to this license. + // If you do not agree to this license, do not download, install, + // copy or use the software. + // + // + // License Agreement + // For Open Source Computer Vision Library + // + // Copyright (C) 2013, OpenCV Foundation, all rights reserved. + // Third party copyrights are property of their respective owners. + // + // Redistribution and use in source and binary forms, with or without modification, + // are permitted provided that the following conditions are met: + // + // * Redistribution's of source code must retain the above copyright notice, + // this list of conditions and the following disclaimer. + // + // * Redistribution's in binary form must reproduce the above copyright notice, + // this list of conditions and the following disclaimer in the documentation + // and/or other materials provided with the distribution. + // + // * The name of the copyright holders may not be used to endorse or promote products + // derived from this software without specific prior written permission. + // + // This software is provided by the copyright holders and contributors "as is" and + // any express or implied warranties, including, but not limited to, the implied + // warranties of merchantability and fitness for a particular purpose are disclaimed. + // In no event shall the contributor be liable for any direct, + // indirect, incidental, special, exemplary, or consequential damages + // (including, but not limited to, procurement of substitute goods or services; + // loss of use, data, or profits; or business interruption) however caused + // and on any theory of liability, whether in contract, strict liability, + // or tort (including negligence or otherwise) arising in any way out of + // the use of this software, even if advised of the possibility of such damage. + // + //M*//////////////////////////////////////////////////////////////////////////////////////// + #include "precomp.hpp" -#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/imgproc.hpp" #include #import diff --cc modules/imgproc/include/opencv2/imgproc.hpp index c2a488a,0000000..24d9f44 mode 100644,000000..100644 --- a/modules/imgproc/include/opencv2/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc.hpp @@@ -1,1494 -1,0 +1,1494 @@@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_IMGPROC_HPP__ +#define __OPENCV_IMGPROC_HPP__ + +#include "opencv2/core.hpp" + +/*! \namespace cv + Namespace where all the C++ OpenCV functionality resides + */ +namespace cv +{ + +//! type of the kernel +enum { KERNEL_GENERAL = 0, // the kernel is generic. No any type of symmetry or other properties. + KERNEL_SYMMETRICAL = 1, // kernel[i] == kernel[ksize-i-1] , and the anchor is at the center + KERNEL_ASYMMETRICAL = 2, // kernel[i] == -kernel[ksize-i-1] , and the anchor is at the center + KERNEL_SMOOTH = 4, // all the kernel elements are non-negative and summed to 1 + KERNEL_INTEGER = 8 // all the kernel coefficients are integer numbers + }; + +//! type of morphological operation +enum { MORPH_ERODE = 0, + MORPH_DILATE = 1, + MORPH_OPEN = 2, + MORPH_CLOSE = 3, + MORPH_GRADIENT = 4, + MORPH_TOPHAT = 5, + MORPH_BLACKHAT = 6 + }; + +//! shape of the structuring element +enum { MORPH_RECT = 0, + MORPH_CROSS = 1, + MORPH_ELLIPSE = 2 + }; + +//! interpolation algorithm +enum { INTER_NEAREST = 0, //!< nearest neighbor interpolation + INTER_LINEAR = 1, //!< bilinear interpolation + INTER_CUBIC = 2, //!< bicubic interpolation + INTER_AREA = 3, //!< area-based (or super) interpolation + INTER_LANCZOS4 = 4, //!< Lanczos interpolation over 8x8 neighborhood + + INTER_MAX = 7, //!< mask for interpolation codes + WARP_INVERSE_MAP = 16 + }; + +enum { INTER_BITS = 5, + INTER_BITS2 = INTER_BITS * 2, + INTER_TAB_SIZE = 1 << INTER_BITS, + INTER_TAB_SIZE2 = INTER_TAB_SIZE * INTER_TAB_SIZE + }; + +//! Distance types for Distance Transform and M-estimators +enum { DIST_USER = -1, // User defined distance + DIST_L1 = 1, // distance = |x1-x2| + |y1-y2| + DIST_L2 = 2, // the simple euclidean distance + DIST_C = 3, // distance = max(|x1-x2|,|y1-y2|) + DIST_L12 = 4, // L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1)) + DIST_FAIR = 5, // distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998 + DIST_WELSCH = 6, // distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846 + DIST_HUBER = 7 // distance = |x| threshold ? max_value : 0 + THRESH_BINARY_INV = 1, // value = value > threshold ? 0 : max_value + THRESH_TRUNC = 2, // value = value > threshold ? threshold : value + THRESH_TOZERO = 3, // value = value > threshold ? value : 0 + THRESH_TOZERO_INV = 4, // value = value > threshold ? 0 : value + THRESH_MASK = 7, + THRESH_OTSU = 8 // use Otsu algorithm to choose the optimal threshold value + }; + +//! adaptive threshold algorithm +enum { ADAPTIVE_THRESH_MEAN_C = 0, + ADAPTIVE_THRESH_GAUSSIAN_C = 1 + }; + +enum { PROJ_SPHERICAL_ORTHO = 0, + PROJ_SPHERICAL_EQRECT = 1 + }; + +//! class of the pixel in GrabCut algorithm +enum { GC_BGD = 0, //!< background + GC_FGD = 1, //!< foreground + GC_PR_BGD = 2, //!< most probably background + GC_PR_FGD = 3 //!< most probably foreground + }; + +//! GrabCut algorithm flags +enum { GC_INIT_WITH_RECT = 0, + GC_INIT_WITH_MASK = 1, + GC_EVAL = 2 +}; + +//! distanceTransform algorithm flags +enum { DIST_LABEL_CCOMP = 0, + DIST_LABEL_PIXEL = 1 + }; + +//! floodfill algorithm flags +enum { FLOODFILL_FIXED_RANGE = 1 << 16, + FLOODFILL_MASK_ONLY = 1 << 17 + }; + +//! type of the template matching operation +enum { TM_SQDIFF = 0, + TM_SQDIFF_NORMED = 1, + TM_CCORR = 2, + TM_CCORR_NORMED = 3, + TM_CCOEFF = 4, + TM_CCOEFF_NORMED = 5 + }; + +//! connected components algorithm output formats +enum { CC_STAT_LEFT = 0, + CC_STAT_TOP = 1, + CC_STAT_WIDTH = 2, + CC_STAT_HEIGHT = 3, + CC_STAT_AREA = 4, + CC_STAT_MAX = 5 + }; + +//! mode of the contour retrieval algorithm +enum { RETR_EXTERNAL = 0, //!< retrieve only the most external (top-level) contours + RETR_LIST = 1, //!< retrieve all the contours without any hierarchical information + RETR_CCOMP = 2, //!< retrieve the connected components (that can possibly be nested) + RETR_TREE = 3, //!< retrieve all the contours and the whole hierarchy + RETR_FLOODFILL = 4 + }; + +//! the contour approximation algorithm +enum { CHAIN_APPROX_NONE = 1, + CHAIN_APPROX_SIMPLE = 2, + CHAIN_APPROX_TC89_L1 = 3, + CHAIN_APPROX_TC89_KCOS = 4 + }; + +//! Variants of a Hough transform +enum { HOUGH_STANDARD = 0, + HOUGH_PROBABILISTIC = 1, + HOUGH_MULTI_SCALE = 2, + HOUGH_GRADIENT = 3 + }; + +//! Variants of Line Segment Detector +enum { LSD_REFINE_NONE = 0, + LSD_REFINE_STD = 1, + LSD_REFINE_ADV = 2 + }; + +//! Histogram comparison methods +enum { HISTCMP_CORREL = 0, + HISTCMP_CHISQR = 1, + HISTCMP_INTERSECT = 2, + HISTCMP_BHATTACHARYYA = 3, + HISTCMP_HELLINGER = HISTCMP_BHATTACHARYYA + }; + +//! the color conversion code +enum { COLOR_BGR2BGRA = 0, + COLOR_RGB2RGBA = COLOR_BGR2BGRA, + + COLOR_BGRA2BGR = 1, + COLOR_RGBA2RGB = COLOR_BGRA2BGR, + + COLOR_BGR2RGBA = 2, + COLOR_RGB2BGRA = COLOR_BGR2RGBA, + + COLOR_RGBA2BGR = 3, + COLOR_BGRA2RGB = COLOR_RGBA2BGR, + + COLOR_BGR2RGB = 4, + COLOR_RGB2BGR = COLOR_BGR2RGB, + + COLOR_BGRA2RGBA = 5, + COLOR_RGBA2BGRA = COLOR_BGRA2RGBA, + + COLOR_BGR2GRAY = 6, + COLOR_RGB2GRAY = 7, + COLOR_GRAY2BGR = 8, + COLOR_GRAY2RGB = COLOR_GRAY2BGR, + COLOR_GRAY2BGRA = 9, + COLOR_GRAY2RGBA = COLOR_GRAY2BGRA, + COLOR_BGRA2GRAY = 10, + COLOR_RGBA2GRAY = 11, + + COLOR_BGR2BGR565 = 12, + COLOR_RGB2BGR565 = 13, + COLOR_BGR5652BGR = 14, + COLOR_BGR5652RGB = 15, + COLOR_BGRA2BGR565 = 16, + COLOR_RGBA2BGR565 = 17, + COLOR_BGR5652BGRA = 18, + COLOR_BGR5652RGBA = 19, + + COLOR_GRAY2BGR565 = 20, + COLOR_BGR5652GRAY = 21, + + COLOR_BGR2BGR555 = 22, + COLOR_RGB2BGR555 = 23, + COLOR_BGR5552BGR = 24, + COLOR_BGR5552RGB = 25, + COLOR_BGRA2BGR555 = 26, + COLOR_RGBA2BGR555 = 27, + COLOR_BGR5552BGRA = 28, + COLOR_BGR5552RGBA = 29, + + COLOR_GRAY2BGR555 = 30, + COLOR_BGR5552GRAY = 31, + + COLOR_BGR2XYZ = 32, + COLOR_RGB2XYZ = 33, + COLOR_XYZ2BGR = 34, + COLOR_XYZ2RGB = 35, + + COLOR_BGR2YCrCb = 36, + COLOR_RGB2YCrCb = 37, + COLOR_YCrCb2BGR = 38, + COLOR_YCrCb2RGB = 39, + + COLOR_BGR2HSV = 40, + COLOR_RGB2HSV = 41, + + COLOR_BGR2Lab = 44, + COLOR_RGB2Lab = 45, + + COLOR_BGR2Luv = 50, + COLOR_RGB2Luv = 51, + COLOR_BGR2HLS = 52, + COLOR_RGB2HLS = 53, + + COLOR_HSV2BGR = 54, + COLOR_HSV2RGB = 55, + + COLOR_Lab2BGR = 56, + COLOR_Lab2RGB = 57, + COLOR_Luv2BGR = 58, + COLOR_Luv2RGB = 59, + COLOR_HLS2BGR = 60, + COLOR_HLS2RGB = 61, + + COLOR_BGR2HSV_FULL = 66, + COLOR_RGB2HSV_FULL = 67, + COLOR_BGR2HLS_FULL = 68, + COLOR_RGB2HLS_FULL = 69, + + COLOR_HSV2BGR_FULL = 70, + COLOR_HSV2RGB_FULL = 71, + COLOR_HLS2BGR_FULL = 72, + COLOR_HLS2RGB_FULL = 73, + + COLOR_LBGR2Lab = 74, + COLOR_LRGB2Lab = 75, + COLOR_LBGR2Luv = 76, + COLOR_LRGB2Luv = 77, + + COLOR_Lab2LBGR = 78, + COLOR_Lab2LRGB = 79, + COLOR_Luv2LBGR = 80, + COLOR_Luv2LRGB = 81, + + COLOR_BGR2YUV = 82, + COLOR_RGB2YUV = 83, + COLOR_YUV2BGR = 84, + COLOR_YUV2RGB = 85, + + // YUV 4:2:0 family to RGB + COLOR_YUV2RGB_NV12 = 90, + COLOR_YUV2BGR_NV12 = 91, + COLOR_YUV2RGB_NV21 = 92, + COLOR_YUV2BGR_NV21 = 93, + COLOR_YUV420sp2RGB = COLOR_YUV2RGB_NV21, + COLOR_YUV420sp2BGR = COLOR_YUV2BGR_NV21, + + COLOR_YUV2RGBA_NV12 = 94, + COLOR_YUV2BGRA_NV12 = 95, + COLOR_YUV2RGBA_NV21 = 96, + COLOR_YUV2BGRA_NV21 = 97, + COLOR_YUV420sp2RGBA = COLOR_YUV2RGBA_NV21, + COLOR_YUV420sp2BGRA = COLOR_YUV2BGRA_NV21, + + COLOR_YUV2RGB_YV12 = 98, + COLOR_YUV2BGR_YV12 = 99, + COLOR_YUV2RGB_IYUV = 100, + COLOR_YUV2BGR_IYUV = 101, + COLOR_YUV2RGB_I420 = COLOR_YUV2RGB_IYUV, + COLOR_YUV2BGR_I420 = COLOR_YUV2BGR_IYUV, + COLOR_YUV420p2RGB = COLOR_YUV2RGB_YV12, + COLOR_YUV420p2BGR = COLOR_YUV2BGR_YV12, + + COLOR_YUV2RGBA_YV12 = 102, + COLOR_YUV2BGRA_YV12 = 103, + COLOR_YUV2RGBA_IYUV = 104, + COLOR_YUV2BGRA_IYUV = 105, + COLOR_YUV2RGBA_I420 = COLOR_YUV2RGBA_IYUV, + COLOR_YUV2BGRA_I420 = COLOR_YUV2BGRA_IYUV, + COLOR_YUV420p2RGBA = COLOR_YUV2RGBA_YV12, + COLOR_YUV420p2BGRA = COLOR_YUV2BGRA_YV12, + + COLOR_YUV2GRAY_420 = 106, + COLOR_YUV2GRAY_NV21 = COLOR_YUV2GRAY_420, + COLOR_YUV2GRAY_NV12 = COLOR_YUV2GRAY_420, + COLOR_YUV2GRAY_YV12 = COLOR_YUV2GRAY_420, + COLOR_YUV2GRAY_IYUV = COLOR_YUV2GRAY_420, + COLOR_YUV2GRAY_I420 = COLOR_YUV2GRAY_420, + COLOR_YUV420sp2GRAY = COLOR_YUV2GRAY_420, + COLOR_YUV420p2GRAY = COLOR_YUV2GRAY_420, + + // YUV 4:2:2 family to RGB + COLOR_YUV2RGB_UYVY = 107, + COLOR_YUV2BGR_UYVY = 108, + //COLOR_YUV2RGB_VYUY = 109, + //COLOR_YUV2BGR_VYUY = 110, + COLOR_YUV2RGB_Y422 = COLOR_YUV2RGB_UYVY, + COLOR_YUV2BGR_Y422 = COLOR_YUV2BGR_UYVY, + COLOR_YUV2RGB_UYNV = COLOR_YUV2RGB_UYVY, + COLOR_YUV2BGR_UYNV = COLOR_YUV2BGR_UYVY, + + COLOR_YUV2RGBA_UYVY = 111, + COLOR_YUV2BGRA_UYVY = 112, + //COLOR_YUV2RGBA_VYUY = 113, + //COLOR_YUV2BGRA_VYUY = 114, + COLOR_YUV2RGBA_Y422 = COLOR_YUV2RGBA_UYVY, + COLOR_YUV2BGRA_Y422 = COLOR_YUV2BGRA_UYVY, + COLOR_YUV2RGBA_UYNV = COLOR_YUV2RGBA_UYVY, + COLOR_YUV2BGRA_UYNV = COLOR_YUV2BGRA_UYVY, + + COLOR_YUV2RGB_YUY2 = 115, + COLOR_YUV2BGR_YUY2 = 116, + COLOR_YUV2RGB_YVYU = 117, + COLOR_YUV2BGR_YVYU = 118, + COLOR_YUV2RGB_YUYV = COLOR_YUV2RGB_YUY2, + COLOR_YUV2BGR_YUYV = COLOR_YUV2BGR_YUY2, + COLOR_YUV2RGB_YUNV = COLOR_YUV2RGB_YUY2, + COLOR_YUV2BGR_YUNV = COLOR_YUV2BGR_YUY2, + + COLOR_YUV2RGBA_YUY2 = 119, + COLOR_YUV2BGRA_YUY2 = 120, + COLOR_YUV2RGBA_YVYU = 121, + COLOR_YUV2BGRA_YVYU = 122, + COLOR_YUV2RGBA_YUYV = COLOR_YUV2RGBA_YUY2, + COLOR_YUV2BGRA_YUYV = COLOR_YUV2BGRA_YUY2, + COLOR_YUV2RGBA_YUNV = COLOR_YUV2RGBA_YUY2, + COLOR_YUV2BGRA_YUNV = COLOR_YUV2BGRA_YUY2, + + COLOR_YUV2GRAY_UYVY = 123, + COLOR_YUV2GRAY_YUY2 = 124, + //CV_YUV2GRAY_VYUY = CV_YUV2GRAY_UYVY, + COLOR_YUV2GRAY_Y422 = COLOR_YUV2GRAY_UYVY, + COLOR_YUV2GRAY_UYNV = COLOR_YUV2GRAY_UYVY, + COLOR_YUV2GRAY_YVYU = COLOR_YUV2GRAY_YUY2, + COLOR_YUV2GRAY_YUYV = COLOR_YUV2GRAY_YUY2, + COLOR_YUV2GRAY_YUNV = COLOR_YUV2GRAY_YUY2, + + // alpha premultiplication + COLOR_RGBA2mRGBA = 125, + COLOR_mRGBA2RGBA = 126, + + // RGB to YUV 4:2:0 family + COLOR_RGB2YUV_I420 = 127, + COLOR_BGR2YUV_I420 = 128, + COLOR_RGB2YUV_IYUV = COLOR_RGB2YUV_I420, + COLOR_BGR2YUV_IYUV = COLOR_BGR2YUV_I420, + + COLOR_RGBA2YUV_I420 = 129, + COLOR_BGRA2YUV_I420 = 130, + COLOR_RGBA2YUV_IYUV = COLOR_RGBA2YUV_I420, + COLOR_BGRA2YUV_IYUV = COLOR_BGRA2YUV_I420, + COLOR_RGB2YUV_YV12 = 131, + COLOR_BGR2YUV_YV12 = 132, + COLOR_RGBA2YUV_YV12 = 133, + COLOR_BGRA2YUV_YV12 = 134, + + // Demosaicing + COLOR_BayerBG2BGR = 46, + COLOR_BayerGB2BGR = 47, + COLOR_BayerRG2BGR = 48, + COLOR_BayerGR2BGR = 49, + + COLOR_BayerBG2RGB = COLOR_BayerRG2BGR, + COLOR_BayerGB2RGB = COLOR_BayerGR2BGR, + COLOR_BayerRG2RGB = COLOR_BayerBG2BGR, + COLOR_BayerGR2RGB = COLOR_BayerGB2BGR, + + COLOR_BayerBG2GRAY = 86, + COLOR_BayerGB2GRAY = 87, + COLOR_BayerRG2GRAY = 88, + COLOR_BayerGR2GRAY = 89, + + // Demosaicing using Variable Number of Gradients + COLOR_BayerBG2BGR_VNG = 62, + COLOR_BayerGB2BGR_VNG = 63, + COLOR_BayerRG2BGR_VNG = 64, + COLOR_BayerGR2BGR_VNG = 65, + + COLOR_BayerBG2RGB_VNG = COLOR_BayerRG2BGR_VNG, + COLOR_BayerGB2RGB_VNG = COLOR_BayerGR2BGR_VNG, + COLOR_BayerRG2RGB_VNG = COLOR_BayerBG2BGR_VNG, + COLOR_BayerGR2RGB_VNG = COLOR_BayerGB2BGR_VNG, + + // Edge-Aware Demosaicing + COLOR_BayerBG2BGR_EA = 135, + COLOR_BayerGB2BGR_EA = 136, + COLOR_BayerRG2BGR_EA = 137, + COLOR_BayerGR2BGR_EA = 138, + + COLOR_BayerBG2RGB_EA = COLOR_BayerRG2BGR_EA, + COLOR_BayerGB2RGB_EA = COLOR_BayerGR2BGR_EA, + COLOR_BayerRG2RGB_EA = COLOR_BayerBG2BGR_EA, + COLOR_BayerGR2RGB_EA = COLOR_BayerGB2BGR_EA, + + + COLOR_COLORCVT_MAX = 139 +}; + + + +/*! + The Base Class for 1D or Row-wise Filters + + This is the base class for linear or non-linear filters that process 1D data. + In particular, such filters are used for the "horizontal" filtering parts in separable filters. + + Several functions in OpenCV return Ptr for the specific types of filters, + and those pointers can be used directly or within cv::FilterEngine. +*/ +class CV_EXPORTS BaseRowFilter +{ +public: + //! the default constructor + BaseRowFilter(); + //! the destructor + virtual ~BaseRowFilter(); + //! the filtering operator. Must be overrided in the derived classes. The horizontal border interpolation is done outside of the class. + virtual void operator()(const uchar* src, uchar* dst, int width, int cn) = 0; + + int ksize; + int anchor; +}; + + +/*! + The Base Class for Column-wise Filters + + This is the base class for linear or non-linear filters that process columns of 2D arrays. + Such filters are used for the "vertical" filtering parts in separable filters. + + Several functions in OpenCV return Ptr for the specific types of filters, + and those pointers can be used directly or within cv::FilterEngine. + + Unlike cv::BaseRowFilter, cv::BaseColumnFilter may have some context information, + i.e. box filter keeps the sliding sum of elements. To reset the state BaseColumnFilter::reset() + must be called (e.g. the method is called by cv::FilterEngine) + */ +class CV_EXPORTS BaseColumnFilter +{ +public: + //! the default constructor + BaseColumnFilter(); + //! the destructor + virtual ~BaseColumnFilter(); + //! the filtering operator. Must be overrided in the derived classes. The vertical border interpolation is done outside of the class. + virtual void operator()(const uchar** src, uchar* dst, int dststep, int dstcount, int width) = 0; + //! resets the internal buffers, if any + virtual void reset(); + + int ksize; + int anchor; +}; + + +/*! + The Base Class for Non-Separable 2D Filters. + + This is the base class for linear or non-linear 2D filters. + + Several functions in OpenCV return Ptr for the specific types of filters, + and those pointers can be used directly or within cv::FilterEngine. + + Similar to cv::BaseColumnFilter, the class may have some context information, + that should be reset using BaseFilter::reset() method before processing the new array. +*/ +class CV_EXPORTS BaseFilter +{ +public: + //! the default constructor + BaseFilter(); + //! the destructor + virtual ~BaseFilter(); + //! the filtering operator. The horizontal and the vertical border interpolation is done outside of the class. + virtual void operator()(const uchar** src, uchar* dst, int dststep, int dstcount, int width, int cn) = 0; + //! resets the internal buffers, if any + virtual void reset(); + + Size ksize; + Point anchor; +}; + + +/*! + The Main Class for Image Filtering. + + The class can be used to apply an arbitrary filtering operation to an image. + It contains all the necessary intermediate buffers, it computes extrapolated values + of the "virtual" pixels outside of the image etc. + Pointers to the initialized cv::FilterEngine instances + are returned by various OpenCV functions, such as cv::createSeparableLinearFilter(), + cv::createLinearFilter(), cv::createGaussianFilter(), cv::createDerivFilter(), + cv::createBoxFilter() and cv::createMorphologyFilter(). + + Using the class you can process large images by parts and build complex pipelines + that include filtering as some of the stages. If all you need is to apply some pre-defined + filtering operation, you may use cv::filter2D(), cv::erode(), cv::dilate() etc. + functions that create FilterEngine internally. + + Here is the example on how to use the class to implement Laplacian operator, which is the sum of + second-order derivatives. More complex variant for different types is implemented in cv::Laplacian(). + + \code + void laplace_f(const Mat& src, Mat& dst) + { + CV_Assert( src.type() == CV_32F ); + // make sure the destination array has the proper size and type + dst.create(src.size(), src.type()); + + // get the derivative and smooth kernels for d2I/dx2. + // for d2I/dy2 we could use the same kernels, just swapped + Mat kd, ks; + getSobelKernels( kd, ks, 2, 0, ksize, false, ktype ); + + // let's process 10 source rows at once + int DELTA = std::min(10, src.rows); + Ptr Fxx = createSeparableLinearFilter(src.type(), + dst.type(), kd, ks, Point(-1,-1), 0, borderType, borderType, Scalar() ); + Ptr Fyy = createSeparableLinearFilter(src.type(), + dst.type(), ks, kd, Point(-1,-1), 0, borderType, borderType, Scalar() ); + + int y = Fxx->start(src), dsty = 0, dy = 0; + Fyy->start(src); + const uchar* sptr = src.data + y*src.step; + + // allocate the buffers for the spatial image derivatives; + // the buffers need to have more than DELTA rows, because at the + // last iteration the output may take max(kd.rows-1,ks.rows-1) + // rows more than the input. + Mat Ixx( DELTA + kd.rows - 1, src.cols, dst.type() ); + Mat Iyy( DELTA + kd.rows - 1, src.cols, dst.type() ); + + // inside the loop we always pass DELTA rows to the filter + // (note that the "proceed" method takes care of possibe overflow, since + // it was given the actual image height in the "start" method) + // on output we can get: + // * < DELTA rows (the initial buffer accumulation stage) + // * = DELTA rows (settled state in the middle) + // * > DELTA rows (then the input image is over, but we generate + // "virtual" rows using the border mode and filter them) + // this variable number of output rows is dy. + // dsty is the current output row. + // sptr is the pointer to the first input row in the portion to process + for( ; dsty < dst.rows; sptr += DELTA*src.step, dsty += dy ) + { + Fxx->proceed( sptr, (int)src.step, DELTA, Ixx.data, (int)Ixx.step ); + dy = Fyy->proceed( sptr, (int)src.step, DELTA, d2y.data, (int)Iyy.step ); + if( dy > 0 ) + { + Mat dstripe = dst.rowRange(dsty, dsty + dy); + add(Ixx.rowRange(0, dy), Iyy.rowRange(0, dy), dstripe); + } + } + } + \endcode +*/ +class CV_EXPORTS FilterEngine +{ +public: + //! the default constructor + FilterEngine(); + //! the full constructor. Either _filter2D or both _rowFilter and _columnFilter must be non-empty. + FilterEngine(const Ptr& _filter2D, + const Ptr& _rowFilter, + const Ptr& _columnFilter, + int srcType, int dstType, int bufType, + int _rowBorderType = BORDER_REPLICATE, + int _columnBorderType = -1, + const Scalar& _borderValue = Scalar()); + //! the destructor + virtual ~FilterEngine(); + //! reinitializes the engine. The previously assigned filters are released. + void init(const Ptr& _filter2D, + const Ptr& _rowFilter, + const Ptr& _columnFilter, + int srcType, int dstType, int bufType, + int _rowBorderType = BORDER_REPLICATE, + int _columnBorderType = -1, + const Scalar& _borderValue = Scalar()); + //! starts filtering of the specified ROI of an image of size wholeSize. + virtual int start(Size wholeSize, Rect roi, int maxBufRows = -1); + //! starts filtering of the specified ROI of the specified image. + virtual int start(const Mat& src, const Rect& srcRoi = Rect(0,0,-1,-1), + bool isolated = false, int maxBufRows = -1); + //! processes the next srcCount rows of the image. + virtual int proceed(const uchar* src, int srcStep, int srcCount, + uchar* dst, int dstStep); + //! applies filter to the specified ROI of the image. if srcRoi=(0,0,-1,-1), the whole image is filtered. + virtual void apply( const Mat& src, Mat& dst, + const Rect& srcRoi = Rect(0,0,-1,-1), + Point dstOfs = Point(0,0), + bool isolated = false); + //! returns true if the filter is separable + bool isSeparable() const { return (const BaseFilter*)filter2D == 0; } + //! returns the number + int remainingInputRows() const; + int remainingOutputRows() const; + + int srcType; + int dstType; + int bufType; + Size ksize; + Point anchor; + int maxWidth; + Size wholeSize; + Rect roi; + int dx1; + int dx2; + int rowBorderType; + int columnBorderType; + std::vector borderTab; + int borderElemSize; + std::vector ringBuf; + std::vector srcRow; + std::vector constBorderValue; + std::vector constBorderRow; + int bufStep; + int startY; + int startY0; + int endY; + int rowCount; + int dstY; + std::vector rows; + + Ptr filter2D; + Ptr rowFilter; + Ptr columnFilter; +}; + + +//! finds arbitrary template in the grayscale image using Generalized Hough Transform +class CV_EXPORTS GeneralizedHough : public Algorithm +{ +public: + //! set template to search + virtual void setTemplate(InputArray templ, Point templCenter = Point(-1, -1)) = 0; + virtual void setTemplate(InputArray edges, InputArray dx, InputArray dy, Point templCenter = Point(-1, -1)) = 0; + + //! find template on image + virtual void detect(InputArray image, OutputArray positions, OutputArray votes = noArray()) = 0; + virtual void detect(InputArray edges, InputArray dx, InputArray dy, OutputArray positions, OutputArray votes = noArray()) = 0; + + //! Canny low threshold. + virtual void setCannyLowThresh(int cannyLowThresh) = 0; + virtual int getCannyLowThresh() const = 0; + + //! Canny high threshold. + virtual void setCannyHighThresh(int cannyHighThresh) = 0; + virtual int getCannyHighThresh() const = 0; + + //! Minimum distance between the centers of the detected objects. + virtual void setMinDist(double minDist) = 0; + virtual double getMinDist() const = 0; + + //! Inverse ratio of the accumulator resolution to the image resolution. + virtual void setDp(double dp) = 0; + virtual double getDp() const = 0; + + //! Maximal size of inner buffers. + virtual void setMaxBufferSize(int maxBufferSize) = 0; + virtual int getMaxBufferSize() const = 0; +}; + +//! Ballard, D.H. (1981). Generalizing the Hough transform to detect arbitrary shapes. Pattern Recognition 13 (2): 111-122. +//! Detects position only without traslation and rotation +class CV_EXPORTS GeneralizedHoughBallard : public GeneralizedHough +{ +public: + //! R-Table levels. + virtual void setLevels(int levels) = 0; + virtual int getLevels() const = 0; + + //! The accumulator threshold for the template centers at the detection stage. The smaller it is, the more false positions may be detected. + virtual void setVotesThreshold(int votesThreshold) = 0; + virtual int getVotesThreshold() const = 0; +}; + +//! Guil, N., González-Linares, J.M. and Zapata, E.L. (1999). Bidimensional shape detection using an invariant approach. Pattern Recognition 32 (6): 1025-1038. +//! Detects position, traslation and rotation +class CV_EXPORTS GeneralizedHoughGuil : public GeneralizedHough +{ +public: + //! Angle difference in degrees between two points in feature. + virtual void setXi(double xi) = 0; + virtual double getXi() const = 0; + + //! Feature table levels. + virtual void setLevels(int levels) = 0; + virtual int getLevels() const = 0; + + //! Maximal difference between angles that treated as equal. + virtual void setAngleEpsilon(double angleEpsilon) = 0; + virtual double getAngleEpsilon() const = 0; + + //! Minimal rotation angle to detect in degrees. + virtual void setMinAngle(double minAngle) = 0; + virtual double getMinAngle() const = 0; + + //! Maximal rotation angle to detect in degrees. + virtual void setMaxAngle(double maxAngle) = 0; + virtual double getMaxAngle() const = 0; + + //! Angle step in degrees. + virtual void setAngleStep(double angleStep) = 0; + virtual double getAngleStep() const = 0; + + //! Angle votes threshold. + virtual void setAngleThresh(int angleThresh) = 0; + virtual int getAngleThresh() const = 0; + + //! Minimal scale to detect. + virtual void setMinScale(double minScale) = 0; + virtual double getMinScale() const = 0; + + //! Maximal scale to detect. + virtual void setMaxScale(double maxScale) = 0; + virtual double getMaxScale() const = 0; + + //! Scale step. + virtual void setScaleStep(double scaleStep) = 0; + virtual double getScaleStep() const = 0; + + //! Scale votes threshold. + virtual void setScaleThresh(int scaleThresh) = 0; + virtual int getScaleThresh() const = 0; + + //! Position votes threshold. + virtual void setPosThresh(int posThresh) = 0; + virtual int getPosThresh() const = 0; +}; + + - class CV_EXPORTS CLAHE : public Algorithm ++class CV_EXPORTS_W CLAHE : public Algorithm +{ +public: - virtual void apply(InputArray src, OutputArray dst) = 0; ++ CV_WRAP virtual void apply(InputArray src, OutputArray dst) = 0; + - virtual void setClipLimit(double clipLimit) = 0; - virtual double getClipLimit() const = 0; ++ CV_WRAP virtual void setClipLimit(double clipLimit) = 0; ++ CV_WRAP virtual double getClipLimit() const = 0; + - virtual void setTilesGridSize(Size tileGridSize) = 0; - virtual Size getTilesGridSize() const = 0; ++ CV_WRAP virtual void setTilesGridSize(Size tileGridSize) = 0; ++ CV_WRAP virtual Size getTilesGridSize() const = 0; + - virtual void collectGarbage() = 0; ++ CV_WRAP virtual void collectGarbage() = 0; +}; + + +class CV_EXPORTS_W Subdiv2D +{ +public: + enum { PTLOC_ERROR = -2, + PTLOC_OUTSIDE_RECT = -1, + PTLOC_INSIDE = 0, + PTLOC_VERTEX = 1, + PTLOC_ON_EDGE = 2 + }; + + enum { NEXT_AROUND_ORG = 0x00, + NEXT_AROUND_DST = 0x22, + PREV_AROUND_ORG = 0x11, + PREV_AROUND_DST = 0x33, + NEXT_AROUND_LEFT = 0x13, + NEXT_AROUND_RIGHT = 0x31, + PREV_AROUND_LEFT = 0x20, + PREV_AROUND_RIGHT = 0x02 + }; + + CV_WRAP Subdiv2D(); + CV_WRAP Subdiv2D(Rect rect); + CV_WRAP void initDelaunay(Rect rect); + + CV_WRAP int insert(Point2f pt); + CV_WRAP void insert(const std::vector& ptvec); + CV_WRAP int locate(Point2f pt, CV_OUT int& edge, CV_OUT int& vertex); + + CV_WRAP int findNearest(Point2f pt, CV_OUT Point2f* nearestPt = 0); + CV_WRAP void getEdgeList(CV_OUT std::vector& edgeList) const; + CV_WRAP void getTriangleList(CV_OUT std::vector& triangleList) const; + CV_WRAP void getVoronoiFacetList(const std::vector& idx, CV_OUT std::vector >& facetList, + CV_OUT std::vector& facetCenters); + + CV_WRAP Point2f getVertex(int vertex, CV_OUT int* firstEdge = 0) const; + + CV_WRAP int getEdge( int edge, int nextEdgeType ) const; + CV_WRAP int nextEdge(int edge) const; + CV_WRAP int rotateEdge(int edge, int rotate) const; + CV_WRAP int symEdge(int edge) const; + CV_WRAP int edgeOrg(int edge, CV_OUT Point2f* orgpt = 0) const; + CV_WRAP int edgeDst(int edge, CV_OUT Point2f* dstpt = 0) const; + +protected: + int newEdge(); + void deleteEdge(int edge); + int newPoint(Point2f pt, bool isvirtual, int firstEdge = 0); + void deletePoint(int vtx); + void setEdgePoints( int edge, int orgPt, int dstPt ); + void splice( int edgeA, int edgeB ); + int connectEdges( int edgeA, int edgeB ); + void swapEdges( int edge ); + int isRightOf(Point2f pt, int edge) const; + void calcVoronoi(); + void clearVoronoi(); + void checkSubdiv() const; + + struct CV_EXPORTS Vertex + { + Vertex(); + Vertex(Point2f pt, bool _isvirtual, int _firstEdge=0); + bool isvirtual() const; + bool isfree() const; + + int firstEdge; + int type; + Point2f pt; + }; + + struct CV_EXPORTS QuadEdge + { + QuadEdge(); + QuadEdge(int edgeidx); + bool isfree() const; + + int next[4]; + int pt[4]; + }; + + std::vector vtx; + std::vector qedges; + int freeQEdge; + int freePoint; + bool validGeometry; + + int recentEdge; + Point2f topLeft; + Point2f bottomRight; +}; + +class LineSegmentDetector : public Algorithm +{ +public: +/** + * Detect lines in the input image with the specified ROI. + * + * @param _image A grayscale(CV_8UC1) input image. + * If only a roi needs to be selected, use + * lsd_ptr->detect(image(roi), ..., lines); + * lines += Scalar(roi.x, roi.y, roi.x, roi.y); + * @param _lines Return: A vector of Vec4i elements specifying the beginning and ending point of a line. + * Where Vec4i is (x1, y1, x2, y2), point 1 is the start, point 2 - end. + * Returned lines are strictly oriented depending on the gradient. + * @param _roi Return: ROI of the image, where lines are to be found. If specified, the returning + * lines coordinates are image wise. + * @param width Return: Vector of widths of the regions, where the lines are found. E.g. Width of line. + * @param prec Return: Vector of precisions with which the lines are found. + * @param nfa Return: Vector containing number of false alarms in the line region, with precision of 10%. + * The bigger the value, logarithmically better the detection. + * * -1 corresponds to 10 mean false alarms + * * 0 corresponds to 1 mean false alarm + * * 1 corresponds to 0.1 mean false alarms + * This vector will be calculated _only_ when the objects type is REFINE_ADV + */ + virtual void detect(InputArray _image, OutputArray _lines, + OutputArray width = noArray(), OutputArray prec = noArray(), + OutputArray nfa = noArray()) = 0; + +/** + * Draw lines on the given canvas. + * + * @param image The image, where lines will be drawn. + * Should have the size of the image, where the lines were found + * @param lines The lines that need to be drawn + */ + virtual void drawSegments(InputOutputArray image, InputArray lines) = 0; + +/** + * Draw both vectors on the image canvas. Uses blue for lines 1 and red for lines 2. + * + * @param image The image, where lines will be drawn. + * Should have the size of the image, where the lines were found + * @param lines1 The first lines that need to be drawn. Color - Blue. + * @param lines2 The second lines that need to be drawn. Color - Red. + * @return The number of mismatching pixels between lines1 and lines2. + */ + virtual int compareSegments(const Size& size, InputArray lines1, InputArray lines2, Mat* image = 0) = 0; + + virtual ~LineSegmentDetector() {}; +}; + +//! Returns a pointer to a LineSegmentDetector class. +CV_EXPORTS Ptr createLineSegmentDetectorPtr( + int _refine = LSD_REFINE_STD, double _scale = 0.8, + double _sigma_scale = 0.6, double _quant = 2.0, double _ang_th = 22.5, + double _log_eps = 0, double _density_th = 0.7, int _n_bins = 1024); + +//! returns type (one of KERNEL_*) of 1D or 2D kernel specified by its coefficients. +CV_EXPORTS int getKernelType(InputArray kernel, Point anchor); + +//! returns the primitive row filter with the specified kernel +CV_EXPORTS Ptr getLinearRowFilter(int srcType, int bufType, + InputArray kernel, int anchor, + int symmetryType); + +//! returns the primitive column filter with the specified kernel +CV_EXPORTS Ptr getLinearColumnFilter(int bufType, int dstType, + InputArray kernel, int anchor, + int symmetryType, double delta = 0, + int bits = 0); + +//! returns 2D filter with the specified kernel +CV_EXPORTS Ptr getLinearFilter(int srcType, int dstType, + InputArray kernel, + Point anchor = Point(-1,-1), + double delta = 0, int bits = 0); + +//! returns the separable linear filter engine +CV_EXPORTS Ptr createSeparableLinearFilter(int srcType, int dstType, + InputArray rowKernel, InputArray columnKernel, + Point anchor = Point(-1,-1), double delta = 0, + int rowBorderType = BORDER_DEFAULT, + int columnBorderType = -1, + const Scalar& borderValue = Scalar()); + +//! returns the non-separable linear filter engine +CV_EXPORTS Ptr createLinearFilter(int srcType, int dstType, + InputArray kernel, Point _anchor = Point(-1,-1), + double delta = 0, int rowBorderType = BORDER_DEFAULT, + int columnBorderType = -1, const Scalar& borderValue = Scalar()); + +//! returns the Gaussian kernel with the specified parameters +CV_EXPORTS_W Mat getGaussianKernel( int ksize, double sigma, int ktype = CV_64F ); + +//! returns the Gaussian filter engine +CV_EXPORTS Ptr createGaussianFilter( int type, Size ksize, + double sigma1, double sigma2 = 0, + int borderType = BORDER_DEFAULT); + +//! initializes kernels of the generalized Sobel operator +CV_EXPORTS_W void getDerivKernels( OutputArray kx, OutputArray ky, + int dx, int dy, int ksize, + bool normalize = false, int ktype = CV_32F ); + +//! returns filter engine for the generalized Sobel operator +CV_EXPORTS Ptr createDerivFilter( int srcType, int dstType, + int dx, int dy, int ksize, + int borderType = BORDER_DEFAULT ); + +//! returns horizontal 1D box filter +CV_EXPORTS Ptr getRowSumFilter(int srcType, int sumType, + int ksize, int anchor = -1); + +//! returns vertical 1D box filter +CV_EXPORTS Ptr getColumnSumFilter( int sumType, int dstType, + int ksize, int anchor = -1, + double scale = 1); +//! returns box filter engine +CV_EXPORTS Ptr createBoxFilter( int srcType, int dstType, Size ksize, + Point anchor = Point(-1,-1), + bool normalize = true, + int borderType = BORDER_DEFAULT); + +//! returns the Gabor kernel with the specified parameters +CV_EXPORTS_W Mat getGaborKernel( Size ksize, double sigma, double theta, double lambd, + double gamma, double psi = CV_PI*0.5, int ktype = CV_64F ); + +//! returns horizontal 1D morphological filter +CV_EXPORTS Ptr getMorphologyRowFilter(int op, int type, int ksize, int anchor = -1); + +//! returns vertical 1D morphological filter +CV_EXPORTS Ptr getMorphologyColumnFilter(int op, int type, int ksize, int anchor = -1); + +//! returns 2D morphological filter +CV_EXPORTS Ptr getMorphologyFilter(int op, int type, InputArray kernel, + Point anchor = Point(-1,-1)); + +//! returns "magic" border value for erosion and dilation. It is automatically transformed to Scalar::all(-DBL_MAX) for dilation. +static inline Scalar morphologyDefaultBorderValue() { return Scalar::all(DBL_MAX); } + +//! returns morphological filter engine. Only MORPH_ERODE and MORPH_DILATE are supported. +CV_EXPORTS Ptr createMorphologyFilter(int op, int type, InputArray kernel, + Point anchor = Point(-1,-1), int rowBorderType = BORDER_CONSTANT, + int columnBorderType = -1, const Scalar& borderValue = morphologyDefaultBorderValue()); + +//! returns structuring element of the specified shape and size +CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1)); + +//! smooths the image using median filter. +CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize ); + +//! smooths the image using Gaussian filter. +CV_EXPORTS_W void GaussianBlur( InputArray src, OutputArray dst, Size ksize, + double sigmaX, double sigmaY = 0, + int borderType = BORDER_DEFAULT ); + +//! smooths the image using bilateral filter +CV_EXPORTS_W void bilateralFilter( InputArray src, OutputArray dst, int d, + double sigmaColor, double sigmaSpace, + int borderType = BORDER_DEFAULT ); + +//! smooths the image using the box filter. Each pixel is processed in O(1) time +CV_EXPORTS_W void boxFilter( InputArray src, OutputArray dst, int ddepth, + Size ksize, Point anchor = Point(-1,-1), + bool normalize = true, + int borderType = BORDER_DEFAULT ); + +//! a synonym for normalized box filter +CV_EXPORTS_W void blur( InputArray src, OutputArray dst, + Size ksize, Point anchor = Point(-1,-1), + int borderType = BORDER_DEFAULT ); + +//! applies non-separable 2D linear filter to the image +CV_EXPORTS_W void filter2D( InputArray src, OutputArray dst, int ddepth, + InputArray kernel, Point anchor = Point(-1,-1), + double delta = 0, int borderType = BORDER_DEFAULT ); + +//! applies separable 2D linear filter to the image +CV_EXPORTS_W void sepFilter2D( InputArray src, OutputArray dst, int ddepth, + InputArray kernelX, InputArray kernelY, + Point anchor = Point(-1,-1), + double delta = 0, int borderType = BORDER_DEFAULT ); + +//! applies generalized Sobel operator to the image +CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth, + int dx, int dy, int ksize = 3, + double scale = 1, double delta = 0, + int borderType = BORDER_DEFAULT ); + +//! applies the vertical or horizontal Scharr operator to the image +CV_EXPORTS_W void Scharr( InputArray src, OutputArray dst, int ddepth, + int dx, int dy, double scale = 1, double delta = 0, + int borderType = BORDER_DEFAULT ); + +//! applies Laplacian operator to the image +CV_EXPORTS_W void Laplacian( InputArray src, OutputArray dst, int ddepth, + int ksize = 1, double scale = 1, double delta = 0, + int borderType = BORDER_DEFAULT ); + +//! applies Canny edge detector and produces the edge map. +CV_EXPORTS_W void Canny( InputArray image, OutputArray edges, + double threshold1, double threshold2, + int apertureSize = 3, bool L2gradient = false ); + +//! computes minimum eigen value of 2x2 derivative covariation matrix at each pixel - the cornerness criteria +CV_EXPORTS_W void cornerMinEigenVal( InputArray src, OutputArray dst, + int blockSize, int ksize = 3, + int borderType = BORDER_DEFAULT ); + +//! computes Harris cornerness criteria at each image pixel +CV_EXPORTS_W void cornerHarris( InputArray src, OutputArray dst, int blockSize, + int ksize, double k, + int borderType = BORDER_DEFAULT ); + +//! computes both eigenvalues and the eigenvectors of 2x2 derivative covariation matrix at each pixel. The output is stored as 6-channel matrix. +CV_EXPORTS_W void cornerEigenValsAndVecs( InputArray src, OutputArray dst, + int blockSize, int ksize, + int borderType = BORDER_DEFAULT ); + +//! computes another complex cornerness criteria at each pixel +CV_EXPORTS_W void preCornerDetect( InputArray src, OutputArray dst, int ksize, + int borderType = BORDER_DEFAULT ); + +//! adjusts the corner locations with sub-pixel accuracy to maximize the certain cornerness criteria +CV_EXPORTS_W void cornerSubPix( InputArray image, InputOutputArray corners, + Size winSize, Size zeroZone, + TermCriteria criteria ); + +//! finds the strong enough corners where the cornerMinEigenVal() or cornerHarris() report the local maxima +CV_EXPORTS_W void goodFeaturesToTrack( InputArray image, OutputArray corners, + int maxCorners, double qualityLevel, double minDistance, + InputArray mask = noArray(), int blockSize = 3, + bool useHarrisDetector = false, double k = 0.04 ); + +//! finds lines in the black-n-white image using the standard or pyramid Hough transform +CV_EXPORTS_W void HoughLines( InputArray image, OutputArray lines, + double rho, double theta, int threshold, + double srn = 0, double stn = 0 ); + +//! finds line segments in the black-n-white image using probabalistic Hough transform +CV_EXPORTS_W void HoughLinesP( InputArray image, OutputArray lines, + double rho, double theta, int threshold, + double minLineLength = 0, double maxLineGap = 0 ); + +//! finds circles in the grayscale image using 2+1 gradient Hough transform +CV_EXPORTS_W void HoughCircles( InputArray image, OutputArray circles, + int method, double dp, double minDist, + double param1 = 100, double param2 = 100, + int minRadius = 0, int maxRadius = 0 ); + +//! erodes the image (applies the local minimum operator) +CV_EXPORTS_W void erode( InputArray src, OutputArray dst, InputArray kernel, + Point anchor = Point(-1,-1), int iterations = 1, + int borderType = BORDER_CONSTANT, + const Scalar& borderValue = morphologyDefaultBorderValue() ); + +//! dilates the image (applies the local maximum operator) +CV_EXPORTS_W void dilate( InputArray src, OutputArray dst, InputArray kernel, + Point anchor = Point(-1,-1), int iterations = 1, + int borderType = BORDER_CONSTANT, + const Scalar& borderValue = morphologyDefaultBorderValue() ); + +//! applies an advanced morphological operation to the image +CV_EXPORTS_W void morphologyEx( InputArray src, OutputArray dst, + int op, InputArray kernel, + Point anchor = Point(-1,-1), int iterations = 1, + int borderType = BORDER_CONSTANT, + const Scalar& borderValue = morphologyDefaultBorderValue() ); + +//! resizes the image +CV_EXPORTS_W void resize( InputArray src, OutputArray dst, + Size dsize, double fx = 0, double fy = 0, + int interpolation = INTER_LINEAR ); + +//! warps the image using affine transformation +CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst, + InputArray M, Size dsize, + int flags = INTER_LINEAR, + int borderMode = BORDER_CONSTANT, + const Scalar& borderValue = Scalar()); + +//! warps the image using perspective transformation +CV_EXPORTS_W void warpPerspective( InputArray src, OutputArray dst, + InputArray M, Size dsize, + int flags = INTER_LINEAR, + int borderMode = BORDER_CONSTANT, + const Scalar& borderValue = Scalar()); + +//! warps the image using the precomputed maps. The maps are stored in either floating-point or integer fixed-point format +CV_EXPORTS_W void remap( InputArray src, OutputArray dst, + InputArray map1, InputArray map2, + int interpolation, int borderMode = BORDER_CONSTANT, + const Scalar& borderValue = Scalar()); + +//! converts maps for remap from floating-point to fixed-point format or backwards +CV_EXPORTS_W void convertMaps( InputArray map1, InputArray map2, + OutputArray dstmap1, OutputArray dstmap2, + int dstmap1type, bool nninterpolation = false ); + +//! returns 2x3 affine transformation matrix for the planar rotation. +CV_EXPORTS_W Mat getRotationMatrix2D( Point2f center, double angle, double scale ); + +//! returns 3x3 perspective transformation for the corresponding 4 point pairs. +CV_EXPORTS Mat getPerspectiveTransform( const Point2f src[], const Point2f dst[] ); + +//! returns 2x3 affine transformation for the corresponding 3 point pairs. +CV_EXPORTS Mat getAffineTransform( const Point2f src[], const Point2f dst[] ); + +//! computes 2x3 affine transformation matrix that is inverse to the specified 2x3 affine transformation. +CV_EXPORTS_W void invertAffineTransform( InputArray M, OutputArray iM ); + +CV_EXPORTS_W Mat getPerspectiveTransform( InputArray src, InputArray dst ); + +CV_EXPORTS_W Mat getAffineTransform( InputArray src, InputArray dst ); + +//! extracts rectangle from the image at sub-pixel location +CV_EXPORTS_W void getRectSubPix( InputArray image, Size patchSize, + Point2f center, OutputArray patch, int patchType = -1 ); + +//! computes the integral image +CV_EXPORTS_W void integral( InputArray src, OutputArray sum, int sdepth = -1 ); + +//! computes the integral image and integral for the squared image +CV_EXPORTS_AS(integral2) void integral( InputArray src, OutputArray sum, + OutputArray sqsum, int sdepth = -1 ); + +//! computes the integral image, integral for the squared image and the tilted integral image +CV_EXPORTS_AS(integral3) void integral( InputArray src, OutputArray sum, + OutputArray sqsum, OutputArray tilted, + int sdepth = -1 ); + +//! adds image to the accumulator (dst += src). Unlike cv::add, dst and src can have different types. +CV_EXPORTS_W void accumulate( InputArray src, InputOutputArray dst, + InputArray mask = noArray() ); + +//! adds squared src image to the accumulator (dst += src*src). +CV_EXPORTS_W void accumulateSquare( InputArray src, InputOutputArray dst, + InputArray mask = noArray() ); +//! adds product of the 2 images to the accumulator (dst += src1*src2). +CV_EXPORTS_W void accumulateProduct( InputArray src1, InputArray src2, + InputOutputArray dst, InputArray mask=noArray() ); + +//! updates the running average (dst = dst*(1-alpha) + src*alpha) +CV_EXPORTS_W void accumulateWeighted( InputArray src, InputOutputArray dst, + double alpha, InputArray mask = noArray() ); + +CV_EXPORTS_W Point2d phaseCorrelate(InputArray src1, InputArray src2, + InputArray window = noArray(), CV_OUT double* response = 0); + +CV_EXPORTS_W void createHanningWindow(OutputArray dst, Size winSize, int type); + +//! applies fixed threshold to the image +CV_EXPORTS_W double threshold( InputArray src, OutputArray dst, + double thresh, double maxval, int type ); + + +//! applies variable (adaptive) threshold to the image +CV_EXPORTS_W void adaptiveThreshold( InputArray src, OutputArray dst, + double maxValue, int adaptiveMethod, + int thresholdType, int blockSize, double C ); + +//! smooths and downsamples the image +CV_EXPORTS_W void pyrDown( InputArray src, OutputArray dst, + const Size& dstsize = Size(), int borderType = BORDER_DEFAULT ); + +//! upsamples and smoothes the image +CV_EXPORTS_W void pyrUp( InputArray src, OutputArray dst, + const Size& dstsize = Size(), int borderType = BORDER_DEFAULT ); + +//! builds the gaussian pyramid using pyrDown() as a basic operation +CV_EXPORTS void buildPyramid( InputArray src, OutputArrayOfArrays dst, + int maxlevel, int borderType = BORDER_DEFAULT ); + +//! corrects lens distortion for the given camera matrix and distortion coefficients +CV_EXPORTS_W void undistort( InputArray src, OutputArray dst, + InputArray cameraMatrix, + InputArray distCoeffs, + InputArray newCameraMatrix = noArray() ); + +//! initializes maps for cv::remap() to correct lens distortion and optionally rectify the image +CV_EXPORTS_W void initUndistortRectifyMap( InputArray cameraMatrix, InputArray distCoeffs, + InputArray R, InputArray newCameraMatrix, + Size size, int m1type, OutputArray map1, OutputArray map2 ); + +//! initializes maps for cv::remap() for wide-angle +CV_EXPORTS_W float initWideAngleProjMap( InputArray cameraMatrix, InputArray distCoeffs, + Size imageSize, int destImageWidth, + int m1type, OutputArray map1, OutputArray map2, + int projType = PROJ_SPHERICAL_EQRECT, double alpha = 0); + +//! returns the default new camera matrix (by default it is the same as cameraMatrix unless centerPricipalPoint=true) +CV_EXPORTS_W Mat getDefaultNewCameraMatrix( InputArray cameraMatrix, Size imgsize = Size(), + bool centerPrincipalPoint = false ); + +//! returns points' coordinates after lens distortion correction +CV_EXPORTS_W void undistortPoints( InputArray src, OutputArray dst, + InputArray cameraMatrix, InputArray distCoeffs, + InputArray R = noArray(), InputArray P = noArray()); + +//! computes the joint dense histogram for a set of images. +CV_EXPORTS void calcHist( const Mat* images, int nimages, + const int* channels, InputArray mask, + OutputArray hist, int dims, const int* histSize, + const float** ranges, bool uniform = true, bool accumulate = false ); + +//! computes the joint sparse histogram for a set of images. +CV_EXPORTS void calcHist( const Mat* images, int nimages, + const int* channels, InputArray mask, + SparseMat& hist, int dims, + const int* histSize, const float** ranges, + bool uniform = true, bool accumulate = false ); + +CV_EXPORTS_W void calcHist( InputArrayOfArrays images, + const std::vector& channels, + InputArray mask, OutputArray hist, + const std::vector& histSize, + const std::vector& ranges, + bool accumulate = false ); + +//! computes back projection for the set of images +CV_EXPORTS void calcBackProject( const Mat* images, int nimages, + const int* channels, InputArray hist, + OutputArray backProject, const float** ranges, + double scale = 1, bool uniform = true ); + +//! computes back projection for the set of images +CV_EXPORTS void calcBackProject( const Mat* images, int nimages, + const int* channels, const SparseMat& hist, + OutputArray backProject, const float** ranges, + double scale = 1, bool uniform = true ); + +CV_EXPORTS_W void calcBackProject( InputArrayOfArrays images, const std::vector& channels, + InputArray hist, OutputArray dst, + const std::vector& ranges, + double scale ); + +//! compares two histograms stored in dense arrays +CV_EXPORTS_W double compareHist( InputArray H1, InputArray H2, int method ); + +//! compares two histograms stored in sparse arrays +CV_EXPORTS double compareHist( const SparseMat& H1, const SparseMat& H2, int method ); + +//! normalizes the grayscale image brightness and contrast by normalizing its histogram +CV_EXPORTS_W void equalizeHist( InputArray src, OutputArray dst ); + +CV_EXPORTS float EMD( InputArray signature1, InputArray signature2, + int distType, InputArray cost=noArray(), + float* lowerBound = 0, OutputArray flow = noArray() ); + +//! segments the image using watershed algorithm +CV_EXPORTS_W void watershed( InputArray image, InputOutputArray markers ); + +//! filters image using meanshift algorithm +CV_EXPORTS_W void pyrMeanShiftFiltering( InputArray src, OutputArray dst, + double sp, double sr, int maxLevel = 1, + TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5,1) ); + +//! segments the image using GrabCut algorithm +CV_EXPORTS_W void grabCut( InputArray img, InputOutputArray mask, Rect rect, + InputOutputArray bgdModel, InputOutputArray fgdModel, + int iterCount, int mode = GC_EVAL ); + + +//! builds the discrete Voronoi diagram +CV_EXPORTS_AS(distanceTransformWithLabels) void distanceTransform( InputArray src, OutputArray dst, + OutputArray labels, int distanceType, int maskSize, + int labelType = DIST_LABEL_CCOMP ); + +//! computes the distance transform map +CV_EXPORTS_W void distanceTransform( InputArray src, OutputArray dst, + int distanceType, int maskSize ); + + +//! fills the semi-uniform image region starting from the specified seed point +CV_EXPORTS int floodFill( InputOutputArray image, + Point seedPoint, Scalar newVal, CV_OUT Rect* rect = 0, + Scalar loDiff = Scalar(), Scalar upDiff = Scalar(), + int flags = 4 ); + +//! fills the semi-uniform image region and/or the mask starting from the specified seed point +CV_EXPORTS_W int floodFill( InputOutputArray image, InputOutputArray mask, + Point seedPoint, Scalar newVal, CV_OUT Rect* rect=0, + Scalar loDiff = Scalar(), Scalar upDiff = Scalar(), + int flags = 4 ); + +//! converts image from one color space to another +CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 ); + +// main function for all demosaicing procceses +CV_EXPORTS_W void demosaicing(InputArray _src, OutputArray _dst, int code, int dcn = 0); + +//! computes moments of the rasterized shape or a vector of points +CV_EXPORTS_W Moments moments( InputArray array, bool binaryImage = false ); + +//! computes 7 Hu invariants from the moments +CV_EXPORTS void HuMoments( const Moments& moments, double hu[7] ); + +CV_EXPORTS_W void HuMoments( const Moments& m, OutputArray hu ); + +//! computes the proximity map for the raster template and the image where the template is searched for +CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ, + OutputArray result, int method ); + + +// computes the connected components labeled image of boolean image ``image`` +// with 4 or 8 way connectivity - returns N, the total +// number of labels [0, N-1] where 0 represents the background label. +// ltype specifies the output label image type, an important +// consideration based on the total number of labels or +// alternatively the total number of pixels in the source image. +CV_EXPORTS_W int connectedComponents(InputArray image, OutputArray labels, + int connectivity = 8, int ltype = CV_32S); + +CV_EXPORTS_W int connectedComponentsWithStats(InputArray image, OutputArray labels, + OutputArray stats, OutputArray centroids, + int connectivity = 8, int ltype = CV_32S); + + +//! retrieves contours and the hierarchical information from black-n-white image. +CV_EXPORTS_W void findContours( InputOutputArray image, OutputArrayOfArrays contours, + OutputArray hierarchy, int mode, + int method, Point offset = Point()); + +//! retrieves contours from black-n-white image. +CV_EXPORTS void findContours( InputOutputArray image, OutputArrayOfArrays contours, + int mode, int method, Point offset = Point()); + +//! approximates contour or a curve using Douglas-Peucker algorithm +CV_EXPORTS_W void approxPolyDP( InputArray curve, + OutputArray approxCurve, + double epsilon, bool closed ); + +//! computes the contour perimeter (closed=true) or a curve length +CV_EXPORTS_W double arcLength( InputArray curve, bool closed ); + +//! computes the bounding rectangle for a contour +CV_EXPORTS_W Rect boundingRect( InputArray points ); + +//! computes the contour area +CV_EXPORTS_W double contourArea( InputArray contour, bool oriented = false ); + +//! computes the minimal rotated rectangle for a set of points +CV_EXPORTS_W RotatedRect minAreaRect( InputArray points ); + +//! computes boxpoints +CV_EXPORTS_W void boxPoints(RotatedRect box, OutputArray points); + +//! computes the minimal enclosing circle for a set of points +CV_EXPORTS_W void minEnclosingCircle( InputArray points, + CV_OUT Point2f& center, CV_OUT float& radius ); + +//! matches two contours using one of the available algorithms +CV_EXPORTS_W double matchShapes( InputArray contour1, InputArray contour2, + int method, double parameter ); + +//! computes convex hull for a set of 2D points. +CV_EXPORTS_W void convexHull( InputArray points, OutputArray hull, + bool clockwise = false, bool returnPoints = true ); + +//! computes the contour convexity defects +CV_EXPORTS_W void convexityDefects( InputArray contour, InputArray convexhull, OutputArray convexityDefects ); + +//! returns true if the contour is convex. Does not support contours with self-intersection +CV_EXPORTS_W bool isContourConvex( InputArray contour ); + +//! finds intersection of two convex polygons +CV_EXPORTS_W float intersectConvexConvex( InputArray _p1, InputArray _p2, + OutputArray _p12, bool handleNested = true ); + +//! fits ellipse to the set of 2D points +CV_EXPORTS_W RotatedRect fitEllipse( InputArray points ); + +//! fits line to the set of 2D points using M-estimator algorithm +CV_EXPORTS_W void fitLine( InputArray points, OutputArray line, int distType, + double param, double reps, double aeps ); + +//! checks if the point is inside the contour. Optionally computes the signed distance from the point to the contour boundary +CV_EXPORTS_W double pointPolygonTest( InputArray contour, Point2f pt, bool measureDist ); + - CV_EXPORTS Ptr createCLAHE(double clipLimit = 40.0, Size tileGridSize = Size(8, 8)); ++CV_EXPORTS_W Ptr createCLAHE(double clipLimit = 40.0, Size tileGridSize = Size(8, 8)); + +//! Ballard, D.H. (1981). Generalizing the Hough transform to detect arbitrary shapes. Pattern Recognition 13 (2): 111-122. +//! Detects position only without traslation and rotation +CV_EXPORTS Ptr createGeneralizedHoughBallard(); + +//! Guil, N., González-Linares, J.M. and Zapata, E.L. (1999). Bidimensional shape detection using an invariant approach. Pattern Recognition 32 (6): 1025-1038. +//! Detects position, traslation and rotation +CV_EXPORTS Ptr createGeneralizedHoughGuil(); + +} // cv + +#endif diff --cc modules/java/generator/gen_java.py index ae8c3b4,254298d..cf92955 --- a/modules/java/generator/gen_java.py +++ b/modules/java/generator/gen_java.py @@@ -10,9 -10,9 +10,9 @@@ except class_ignore_list = ( #core - "FileNode", "FileStorage", "KDTree", + "FileNode", "FileStorage", "KDTree", "KeyPoint", "DMatch", #highgui - "VideoWriter", "VideoCapture", + "VideoWriter", ) const_ignore_list = ( @@@ -510,70 -512,98 +510,118 @@@ JNIEXPORT jdoubleArray JNICALL Java_org "resizeWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, }, # Highgui + 'VideoCapture' : + { + "getSupportedPreviewSizes" : + { + 'j_code' : + """ + public java.util.List getSupportedPreviewSizes() + { + String[] sizes_str = getSupportedPreviewSizes_0(nativeObj).split(","); + java.util.List sizes = new java.util.ArrayList(sizes_str.length); + + for (String str : sizes_str) { + String[] wh = str.split("x"); + sizes.add(new org.opencv.core.Size(Double.parseDouble(wh[0]), Double.parseDouble(wh[1]))); + } + + return sizes; + } + + """, + 'jn_code' : + """\n private static native String getSupportedPreviewSizes_0(long nativeObj);\n""", + 'cpp_code' : + """ + JNIEXPORT jstring JNICALL Java_org_opencv_highgui_VideoCapture_getSupportedPreviewSizes_10 + (JNIEnv *env, jclass, jlong self); + + JNIEXPORT jstring JNICALL Java_org_opencv_highgui_VideoCapture_getSupportedPreviewSizes_10 + (JNIEnv *env, jclass, jlong self) + { + static const char method_name[] = "highgui::VideoCapture_getSupportedPreviewSizes_10()"; + try { + LOGD(%s, method_name); + VideoCapture* me = (VideoCapture*) self; //TODO: check for NULL + union {double prop; const char* name;} u; - u.prop = me->get(CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING); ++ u.prop = me->get(CAP_PROP_ANDROID_PREVIEW_SIZES_STRING); + return env->NewStringUTF(u.name); + } catch(const std::exception &e) { + throwJavaException(env, &e, method_name); + } catch (...) { + throwJavaException(env, 0, method_name); + } + return env->NewStringUTF(""); + } + + """, + }, # getSupportedPreviewSizes + }, # VideoCapture } -# { class : { func : {arg_name : ctype} } } +# { class : { func : { arg_name : {"ctype" : ctype, "attrib" : [attrib]} } } } func_arg_fix = { '' : { - 'randu' : { 'low' : 'double', 'high' : 'double', }, - 'randn' : { 'mean' : 'double', 'stddev' : 'double', }, - 'inRange' : { 'lowerb' : 'Scalar', 'upperb' : 'Scalar', }, - 'goodFeaturesToTrack' : { 'corners' : 'vector_Point', }, - 'findFundamentalMat' : { 'points1' : 'vector_Point2f', 'points2' : 'vector_Point2f', }, - 'cornerSubPix' : { 'corners' : 'vector_Point2f', }, - 'minEnclosingCircle' : { 'points' : 'vector_Point2f', }, - 'findHomography' : { 'srcPoints' : 'vector_Point2f', 'dstPoints' : 'vector_Point2f', }, - 'solvePnP' : { 'objectPoints' : 'vector_Point3f', 'imagePoints' : 'vector_Point2f', - 'distCoeffs' : 'vector_double' }, - 'solvePnPRansac' : { 'objectPoints' : 'vector_Point3f', 'imagePoints' : 'vector_Point2f', - 'distCoeffs' : 'vector_double' }, - 'calcOpticalFlowPyrLK' : { 'prevPts' : 'vector_Point2f', 'nextPts' : 'vector_Point2f', - 'status' : 'vector_uchar', 'err' : 'vector_float', }, - 'fitEllipse' : { 'points' : 'vector_Point2f', }, - 'fillPoly' : { 'pts' : 'vector_vector_Point', }, - 'polylines' : { 'pts' : 'vector_vector_Point', }, - 'fillConvexPoly' : { 'points' : 'vector_Point', }, - 'boundingRect' : { 'points' : 'vector_Point', }, - 'approxPolyDP' : { 'curve' : 'vector_Point2f', 'approxCurve' : 'vector_Point2f', }, - 'arcLength' : { 'curve' : 'vector_Point2f', }, - 'pointPolygonTest' : { 'contour' : 'vector_Point2f', }, - 'minAreaRect' : { 'points' : 'vector_Point2f', }, - 'getAffineTransform' : { 'src' : 'vector_Point2f', 'dst' : 'vector_Point2f', }, - 'hconcat' : { 'src' : 'vector_Mat', }, - 'vconcat' : { 'src' : 'vector_Mat', }, - 'undistortPoints' : { 'src' : 'vector_Point2f', 'dst' : 'vector_Point2f' }, - 'checkRange' : {'pos' : '*'}, - 'meanStdDev' : {'mean' : 'vector_double', 'stddev' : 'vector_double'}, - 'drawContours' : {'contours' : 'vector_vector_Point'}, - 'findContours' : {'contours' : 'vector_vector_Point'}, - 'convexityDefects' : {'contour' : 'vector_Point', 'convexhull' : 'vector_int', 'convexityDefects' : 'vector_Vec4i'}, - 'isContourConvex' : { 'contour' : 'vector_Point', }, - 'convexHull' : {'points' : 'vector_Point', 'hull' : 'vector_int', 'returnPoints' : ''}, - 'projectPoints' : { 'objectPoints' : 'vector_Point3f', 'imagePoints' : 'vector_Point2f', - 'distCoeffs' : 'vector_double' }, - 'initCameraMatrix2D' : {'objectPoints' : 'vector_vector_Point3f', 'imagePoints' : 'vector_vector_Point2f', }, - 'findChessboardCorners' : { 'corners' : 'vector_Point2f' }, - 'drawChessboardCorners' : { 'corners' : 'vector_Point2f' }, + 'randu' : { 'low' : {"ctype" : 'double'}, + 'high' : {"ctype" : 'double'} }, + 'randn' : { 'mean' : {"ctype" : 'double'}, + 'stddev' : {"ctype" : 'double'} }, + 'inRange' : { 'lowerb' : {"ctype" : 'Scalar'}, + 'upperb' : {"ctype" : 'Scalar'} }, + 'goodFeaturesToTrack' : { 'corners' : {"ctype" : 'vector_Point'} }, + 'findFundamentalMat' : { 'points1' : {"ctype" : 'vector_Point2f'}, + 'points2' : {"ctype" : 'vector_Point2f'} }, + 'cornerSubPix' : { 'corners' : {"ctype" : 'vector_Point2f'} }, + 'minEnclosingCircle' : { 'points' : {"ctype" : 'vector_Point2f'} }, + 'findHomography' : { 'srcPoints' : {"ctype" : 'vector_Point2f'}, + 'dstPoints' : {"ctype" : 'vector_Point2f'} }, + 'solvePnP' : { 'objectPoints' : {"ctype" : 'vector_Point3f'}, + 'imagePoints' : {"ctype" : 'vector_Point2f'}, + 'distCoeffs' : {"ctype" : 'vector_double' } }, + 'solvePnPRansac' : { 'objectPoints' : {"ctype" : 'vector_Point3f'}, + 'imagePoints' : {"ctype" : 'vector_Point2f'}, + 'distCoeffs' : {"ctype" : 'vector_double' } }, + 'calcOpticalFlowPyrLK' : { 'prevPts' : {"ctype" : 'vector_Point2f'}, + 'nextPts' : {"ctype" : 'vector_Point2f'}, + 'status' : {"ctype" : 'vector_uchar'}, + 'err' : {"ctype" : 'vector_float'} }, + 'fitEllipse' : { 'points' : {"ctype" : 'vector_Point2f'} }, + 'fillPoly' : { 'pts' : {"ctype" : 'vector_vector_Point'} }, + 'polylines' : { 'pts' : {"ctype" : 'vector_vector_Point'} }, + 'fillConvexPoly' : { 'points' : {"ctype" : 'vector_Point'} }, + 'boundingRect' : { 'points' : {"ctype" : 'vector_Point'} }, + 'approxPolyDP' : { 'curve' : {"ctype" : 'vector_Point2f'}, + 'approxCurve' : {"ctype" : 'vector_Point2f'} }, + 'arcLength' : { 'curve' : {"ctype" : 'vector_Point2f'} }, + 'pointPolygonTest' : { 'contour' : {"ctype" : 'vector_Point2f'} }, + 'minAreaRect' : { 'points' : {"ctype" : 'vector_Point2f'} }, + 'getAffineTransform' : { 'src' : {"ctype" : 'vector_Point2f'}, + 'dst' : {"ctype" : 'vector_Point2f'} }, + 'hconcat' : { 'src' : {"ctype" : 'vector_Mat'} }, + 'vconcat' : { 'src' : {"ctype" : 'vector_Mat'} }, + 'undistortPoints' : { 'src' : {"ctype" : 'vector_Point2f'}, + 'dst' : {"ctype" : 'vector_Point2f'} }, + 'checkRange' : {'pos' : {"ctype" : '*'} }, + 'meanStdDev' : { 'mean' : {"ctype" : 'vector_double'}, + 'stddev' : {"ctype" : 'vector_double'} }, + 'drawContours' : {'contours' : {"ctype" : 'vector_vector_Point'} }, + 'findContours' : {'contours' : {"ctype" : 'vector_vector_Point'} }, + 'convexityDefects' : { 'contour' : {"ctype" : 'vector_Point'}, + 'convexhull' : {"ctype" : 'vector_int'}, + 'convexityDefects' : {"ctype" : 'vector_Vec4i'} }, + 'isContourConvex' : { 'contour' : {"ctype" : 'vector_Point'} }, + 'convexHull' : { 'points' : {"ctype" : 'vector_Point'}, + 'hull' : {"ctype" : 'vector_int'}, + 'returnPoints' : {"ctype" : ''} }, + 'projectPoints' : { 'objectPoints' : {"ctype" : 'vector_Point3f'}, + 'imagePoints' : {"ctype" : 'vector_Point2f'}, + 'distCoeffs' : {"ctype" : 'vector_double' } }, + 'initCameraMatrix2D' : { 'objectPoints' : {"ctype" : 'vector_vector_Point3f'}, + 'imagePoints' : {"ctype" : 'vector_vector_Point2f'} }, + 'findChessboardCorners' : { 'corners' : {"ctype" : 'vector_Point2f'} }, + 'drawChessboardCorners' : { 'corners' : {"ctype" : 'vector_Point2f'} }, + 'mixChannels' : { 'dst' : {"attrib" : []} }, }, # '', i.e. no class } # func_arg_fix @@@ -903,10 -931,13 +951,16 @@@ public class %(jc)s // This file is auto-generated, please don't edit! // - #define LOG_TAG "org.opencv.%(m)s" + #define LOG_TAG "org.opencv.$m" #include "common.h" - #include "opencv2/%(m)s.hpp" + + #include "opencv2/opencv_modules.hpp" + #ifdef HAVE_OPENCV_$M -#include "opencv2/$m/$m.hpp" ++ ++#include ++ ++#include "opencv2/$m.hpp" using namespace cv; @@@ -1442,4 -1485,4 +1515,3 @@@ if __name__ == "__main__" #print "Generating module '" + module + "' from headers:\n\t" + "\n\t".join(srcfiles) generator = JavaWrapperGenerator() generator.gen(srcfiles, module, dstdir) -- diff --cc modules/nonfree/src/opencl/surf.cl index 1975713,3dced5e..aace143 --- a/modules/nonfree/src/opencl/surf.cl +++ b/modules/nonfree/src/opencl/surf.cl @@@ -116,21 -114,24 +114,24 @@@ float icvCalcHaarPatternSum_2 F d = 0; - #pragma unroll - for (int k = 0; k < 2; ++k) - { - int dx1 = convert_int_rte(ratio * src[k][0]); - int dy1 = convert_int_rte(ratio * src[k][1]); - int dx2 = convert_int_rte(ratio * src[k][2]); - int dy2 = convert_int_rte(ratio * src[k][3]); - - F t = 0; - t += read_sumTex( sumTex, sampler, (int2)(x + dx1, y + dy1), rows, cols, elemPerRow ); - t -= read_sumTex( sumTex, sampler, (int2)(x + dx1, y + dy2), rows, cols, elemPerRow ); - t -= read_sumTex( sumTex, sampler, (int2)(x + dx2, y + dy1), rows, cols, elemPerRow ); - t += read_sumTex( sumTex, sampler, (int2)(x + dx2, y + dy2), rows, cols, elemPerRow ); - d += t * src[k][4] / ((dx2 - dx1) * (dy2 - dy1)); - } + int2 dx1 = convert_int2_rte(ratio * src[0]); + int2 dy1 = convert_int2_rte(ratio * src[1]); + int2 dx2 = convert_int2_rte(ratio * src[2]); + int2 dy2 = convert_int2_rte(ratio * src[3]); + + F t = 0; + t += read_sumTex( sumTex, sampler, (int2)(x + dx1.x, y + dy1.x), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.x, y + dy2.x), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.x, y + dy1.x), rows, cols, elemPerRow ); + t += read_sumTex( sumTex, sampler, (int2)(x + dx2.x, y + dy2.x), rows, cols, elemPerRow ); + d += t * src[4].x / ((dx2.x - dx1.x) * (dy2.x - dy1.x)); - ++ + t = 0; + t += read_sumTex( sumTex, sampler, (int2)(x + dx1.y, y + dy1.y), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.y, y + dy2.y), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.y, y + dy1.y), rows, cols, elemPerRow ); + t += read_sumTex( sumTex, sampler, (int2)(x + dx2.y, y + dy2.y), rows, cols, elemPerRow ); + d += t * src[4].y / ((dx2.y - dx1.y) * (dy2.y - dy1.y)); return (float)d; } @@@ -149,21 -150,31 +150,31 @@@ float icvCalcHaarPatternSum_3 F d = 0; - #pragma unroll - for (int k = 0; k < 3; ++k) - { - int dx1 = convert_int_rte(ratio * src[k][0]); - int dy1 = convert_int_rte(ratio * src[k][1]); - int dx2 = convert_int_rte(ratio * src[k][2]); - int dy2 = convert_int_rte(ratio * src[k][3]); - - F t = 0; - t += read_sumTex( sumTex, sampler, (int2)(x + dx1, y + dy1), rows, cols, elemPerRow ); - t -= read_sumTex( sumTex, sampler, (int2)(x + dx1, y + dy2), rows, cols, elemPerRow ); - t -= read_sumTex( sumTex, sampler, (int2)(x + dx2, y + dy1), rows, cols, elemPerRow ); - t += read_sumTex( sumTex, sampler, (int2)(x + dx2, y + dy2), rows, cols, elemPerRow ); - d += t * src[k][4] / ((dx2 - dx1) * (dy2 - dy1)); - } + int4 dx1 = convert_int4_rte(ratio * src[0]); + int4 dy1 = convert_int4_rte(ratio * src[1]); + int4 dx2 = convert_int4_rte(ratio * src[2]); + int4 dy2 = convert_int4_rte(ratio * src[3]); + + F t = 0; + t += read_sumTex( sumTex, sampler, (int2)(x + dx1.x, y + dy1.x), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.x, y + dy2.x), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.x, y + dy1.x), rows, cols, elemPerRow ); + t += read_sumTex( sumTex, sampler, (int2)(x + dx2.x, y + dy2.x), rows, cols, elemPerRow ); + d += t * src[4].x / ((dx2.x - dx1.x) * (dy2.x - dy1.x)); - ++ + t = 0; + t += read_sumTex( sumTex, sampler, (int2)(x + dx1.y, y + dy1.y), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.y, y + dy2.y), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.y, y + dy1.y), rows, cols, elemPerRow ); + t += read_sumTex( sumTex, sampler, (int2)(x + dx2.y, y + dy2.y), rows, cols, elemPerRow ); + d += t * src[4].y / ((dx2.y - dx1.y) * (dy2.y - dy1.y)); - ++ + t = 0; + t += read_sumTex( sumTex, sampler, (int2)(x + dx1.z, y + dy1.z), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.z, y + dy2.z), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.z, y + dy1.z), rows, cols, elemPerRow ); + t += read_sumTex( sumTex, sampler, (int2)(x + dx2.z, y + dy2.z), rows, cols, elemPerRow ); + d += t * src[4].z / ((dx2.z - dx1.z) * (dy2.z - dy1.z)); return (float)d; } @@@ -182,21 -193,38 +193,38 @@@ float icvCalcHaarPatternSum_4 F d = 0; - #pragma unroll - for (int k = 0; k < 4; ++k) - { - int dx1 = convert_int_rte(ratio * src[k][0]); - int dy1 = convert_int_rte(ratio * src[k][1]); - int dx2 = convert_int_rte(ratio * src[k][2]); - int dy2 = convert_int_rte(ratio * src[k][3]); - - F t = 0; - t += read_sumTex( sumTex, sampler, (int2)(x + dx1, y + dy1), rows, cols, elemPerRow ); - t -= read_sumTex( sumTex, sampler, (int2)(x + dx1, y + dy2), rows, cols, elemPerRow ); - t -= read_sumTex( sumTex, sampler, (int2)(x + dx2, y + dy1), rows, cols, elemPerRow ); - t += read_sumTex( sumTex, sampler, (int2)(x + dx2, y + dy2), rows, cols, elemPerRow ); - d += t * src[k][4] / ((dx2 - dx1) * (dy2 - dy1)); - } + int4 dx1 = convert_int4_rte(ratio * src[0]); + int4 dy1 = convert_int4_rte(ratio * src[1]); + int4 dx2 = convert_int4_rte(ratio * src[2]); + int4 dy2 = convert_int4_rte(ratio * src[3]); + + F t = 0; + t += read_sumTex( sumTex, sampler, (int2)(x + dx1.x, y + dy1.x), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.x, y + dy2.x), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.x, y + dy1.x), rows, cols, elemPerRow ); + t += read_sumTex( sumTex, sampler, (int2)(x + dx2.x, y + dy2.x), rows, cols, elemPerRow ); + d += t * src[4].x / ((dx2.x - dx1.x) * (dy2.x - dy1.x)); - ++ + t = 0; + t += read_sumTex( sumTex, sampler, (int2)(x + dx1.y, y + dy1.y), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.y, y + dy2.y), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.y, y + dy1.y), rows, cols, elemPerRow ); + t += read_sumTex( sumTex, sampler, (int2)(x + dx2.y, y + dy2.y), rows, cols, elemPerRow ); + d += t * src[4].y / ((dx2.y - dx1.y) * (dy2.y - dy1.y)); - ++ + t = 0; + t += read_sumTex( sumTex, sampler, (int2)(x + dx1.z, y + dy1.z), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.z, y + dy2.z), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.z, y + dy1.z), rows, cols, elemPerRow ); + t += read_sumTex( sumTex, sampler, (int2)(x + dx2.z, y + dy2.z), rows, cols, elemPerRow ); + d += t * src[4].z / ((dx2.z - dx1.z) * (dy2.z - dy1.z)); - ++ + t = 0; + t += read_sumTex( sumTex, sampler, (int2)(x + dx1.w, y + dy1.w), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.w, y + dy2.w), rows, cols, elemPerRow ); + t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.w, y + dy1.w), rows, cols, elemPerRow ); + t += read_sumTex( sumTex, sampler, (int2)(x + dx2.w, y + dy2.w), rows, cols, elemPerRow ); + d += t * src[4].w / ((dx2.w - dx1.w) * (dy2.w - dy1.w)); return (float)d; } @@@ -1203,8 -1230,8 +1230,8 @@@ void compute_descriptors64 } barrier(CLK_LOCAL_MEM_FENCE); - reduce_sum25(sdx, sdy, sdxabs, sdyabs, tid); + reduce_sum25(sdx, sdy, sdxabs, sdyabs, tid); - + barrier(CLK_LOCAL_MEM_FENCE); if (tid < 25) { diff --cc modules/ocl/include/opencv2/ocl.hpp index d4ce905,0000000..7aaafca mode 100644,000000..100644 --- a/modules/ocl/include/opencv2/ocl.hpp +++ b/modules/ocl/include/opencv2/ocl.hpp @@@ -1,1811 -1,0 +1,1811 @@@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved. +// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved. +// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other oclMaterials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_OCL_HPP__ +#define __OPENCV_OCL_HPP__ + +#include +#include + +#include "opencv2/core.hpp" +#include "opencv2/imgproc.hpp" +#include "opencv2/objdetect.hpp" + +namespace cv +{ + namespace ocl + { + enum + { + CVCL_DEVICE_TYPE_DEFAULT = (1 << 0), + CVCL_DEVICE_TYPE_CPU = (1 << 1), + CVCL_DEVICE_TYPE_GPU = (1 << 2), + CVCL_DEVICE_TYPE_ACCELERATOR = (1 << 3), + //CVCL_DEVICE_TYPE_CUSTOM = (1 << 4) + CVCL_DEVICE_TYPE_ALL = 0xFFFFFFFF + }; + + enum DevMemRW + { + DEVICE_MEM_R_W = 0, + DEVICE_MEM_R_ONLY, + DEVICE_MEM_W_ONLY + }; + + enum DevMemType + { + DEVICE_MEM_DEFAULT = 0, + DEVICE_MEM_AHP, //alloc host pointer + DEVICE_MEM_UHP, //use host pointer + DEVICE_MEM_CHP, //copy host pointer + DEVICE_MEM_PM //persistent memory + }; + + //Get the global device memory and read/write type + //return 1 if unified memory system supported, otherwise return 0 + CV_EXPORTS int getDevMemType(DevMemRW& rw_type, DevMemType& mem_type); + + //Set the global device memory and read/write type, + //the newly generated oclMat will all use this type + //return -1 if the target type is unsupported, otherwise return 0 + CV_EXPORTS int setDevMemType(DevMemRW rw_type = DEVICE_MEM_R_W, DevMemType mem_type = DEVICE_MEM_DEFAULT); + + //this class contains ocl runtime information + class CV_EXPORTS Info + { + public: + struct Impl; + Impl *impl; + + Info(); + Info(const Info &m); + ~Info(); + void release(); + Info &operator = (const Info &m); + std::vector DeviceName; + String PlatformName; + }; + //////////////////////////////// Initialization & Info //////////////////////// + //this function may be obsoleted + //CV_EXPORTS cl_device_id getDevice(); + //the function must be called before any other cv::ocl::functions, it initialize ocl runtime + //each Info relates to an OpenCL platform + //there is one or more devices in each platform, each one has a separate name + CV_EXPORTS int getDevice(std::vector &oclinfo, int devicetype = CVCL_DEVICE_TYPE_GPU); + + //set device you want to use, optional function after getDevice be called + //the devnum is the index of the selected device in DeviceName vector of INfo + CV_EXPORTS void setDevice(Info &oclinfo, int devnum = 0); + + //The two functions below enable other opencl program to use ocl module's cl_context and cl_command_queue + //returns cl_context * + CV_EXPORTS void* getoclContext(); + //returns cl_command_queue * + CV_EXPORTS void* getoclCommandQueue(); + + //explicit call clFinish. The global command queue will be used. + CV_EXPORTS void finish(); + + //this function enable ocl module to use customized cl_context and cl_command_queue + //getDevice also need to be called before this function + CV_EXPORTS void setDeviceEx(Info &oclinfo, void *ctx, void *qu, int devnum = 0); + + //returns true when global OpenCL context is initialized + CV_EXPORTS bool initialized(); + + //////////////////////////////// OpenCL context //////////////////////// + //This is a global singleton class used to represent a OpenCL context. + class CV_EXPORTS Context + { + protected: + Context(); + friend class std::auto_ptr; + friend bool initialized(); + private: + static std::auto_ptr clCxt; + static int val; + public: + ~Context(); + void release(); + Info::Impl* impl; + + static Context *getContext(); + static void setContext(Info &oclinfo); + + enum {CL_DOUBLE, CL_UNIFIED_MEM, CL_VER_1_2}; + bool supportsFeature(int ftype); + size_t computeUnits(); + size_t maxWorkGroupSize(); + void* oclContext(); + void* oclCommandQueue(); + }; + + //! Calls a kernel, by string. Pass globalThreads = NULL, and cleanUp = true, to finally clean-up without executing. + CV_EXPORTS double openCLExecuteKernelInterop(Context *clCxt , + const char **source, String kernelName, + size_t globalThreads[3], size_t localThreads[3], + std::vector< std::pair > &args, + int channels, int depth, const char *build_options, + bool finish = true, bool measureKernelTime = false, + bool cleanUp = true); + + //! Calls a kernel, by file. Pass globalThreads = NULL, and cleanUp = true, to finally clean-up without executing. + CV_EXPORTS double openCLExecuteKernelInterop(Context *clCxt , + const char **fileName, const int numFiles, String kernelName, + size_t globalThreads[3], size_t localThreads[3], + std::vector< std::pair > &args, + int channels, int depth, const char *build_options, + bool finish = true, bool measureKernelTime = false, + bool cleanUp = true); + + //! Enable or disable OpenCL program binary caching onto local disk + // After a program (*.cl files in opencl/ folder) is built at runtime, we allow the + // compiled OpenCL program to be cached to the path automatically as "path/*.clb" + // binary file, which will be reused when the OpenCV executable is started again. + // + // Caching mode is controlled by the following enums + // Notes + // 1. the feature is by default enabled when OpenCV is built in release mode. + // 2. the CACHE_DEBUG / CACHE_RELEASE flags only effectively work with MSVC compiler; + // for GNU compilers, the function always treats the build as release mode (enabled by default). + enum + { + CACHE_NONE = 0, // do not cache OpenCL binary + CACHE_DEBUG = 0x1 << 0, // cache OpenCL binary when built in debug mode (only work with MSVC) + CACHE_RELEASE = 0x1 << 1, // default behavior, only cache when built in release mode (only work with MSVC) + CACHE_ALL = CACHE_DEBUG | CACHE_RELEASE, // always cache opencl binary + CACHE_UPDATE = 0x1 << 2 // if the binary cache file with the same name is already on the disk, it will be updated. + }; + CV_EXPORTS void setBinaryDiskCache(int mode = CACHE_RELEASE, cv::String path = "./"); + + //! set where binary cache to be saved to + CV_EXPORTS void setBinpath(const char *path); + + class CV_EXPORTS oclMatExpr; + //////////////////////////////// oclMat //////////////////////////////// + class CV_EXPORTS oclMat + { + public: + //! default constructor + oclMat(); + //! constructs oclMatrix of the specified size and type (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.) + oclMat(int rows, int cols, int type); + oclMat(Size size, int type); + //! constucts oclMatrix and fills it with the specified value _s. + oclMat(int rows, int cols, int type, const Scalar &s); + oclMat(Size size, int type, const Scalar &s); + //! copy constructor + oclMat(const oclMat &m); + + //! constructor for oclMatrix headers pointing to user-allocated data + oclMat(int rows, int cols, int type, void *data, size_t step = Mat::AUTO_STEP); + oclMat(Size size, int type, void *data, size_t step = Mat::AUTO_STEP); + + //! creates a matrix header for a part of the bigger matrix + oclMat(const oclMat &m, const Range &rowRange, const Range &colRange); + oclMat(const oclMat &m, const Rect &roi); + + //! builds oclMat from Mat. Perfom blocking upload to device. + explicit oclMat (const Mat &m); + + //! destructor - calls release() + ~oclMat(); + + //! assignment operators + oclMat &operator = (const oclMat &m); + //! assignment operator. Perfom blocking upload to device. + oclMat &operator = (const Mat &m); + oclMat &operator = (const oclMatExpr& expr); + + //! pefroms blocking upload data to oclMat. + void upload(const cv::Mat &m); + + + //! downloads data from device to host memory. Blocking calls. + operator Mat() const; + void download(cv::Mat &m) const; + + //! convert to _InputArray + operator _InputArray(); + + //! convert to _OutputArray + operator _OutputArray(); + + //! returns a new oclMatrix header for the specified row + oclMat row(int y) const; + //! returns a new oclMatrix header for the specified column + oclMat col(int x) const; + //! ... for the specified row span + oclMat rowRange(int startrow, int endrow) const; + oclMat rowRange(const Range &r) const; + //! ... for the specified column span + oclMat colRange(int startcol, int endcol) const; + oclMat colRange(const Range &r) const; + + //! returns deep copy of the oclMatrix, i.e. the data is copied + oclMat clone() const; + //! copies the oclMatrix content to "m". + // It calls m.create(this->size(), this->type()). + // It supports any data type + void copyTo( oclMat &m ) const; + //! copies those oclMatrix elements to "m" that are marked with non-zero mask elements. + //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4 + void copyTo( oclMat &m, const oclMat &mask ) const; + //! converts oclMatrix to another datatype with optional scalng. See cvConvertScale. + //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4 + void convertTo( oclMat &m, int rtype, double alpha = 1, double beta = 0 ) const; + + void assignTo( oclMat &m, int type = -1 ) const; + + //! sets every oclMatrix element to s + //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4 + oclMat& operator = (const Scalar &s); + //! sets some of the oclMatrix elements to s, according to the mask + //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4 + oclMat& setTo(const Scalar &s, const oclMat &mask = oclMat()); + //! creates alternative oclMatrix header for the same data, with different + // number of channels and/or different number of rows. see cvReshape. + oclMat reshape(int cn, int rows = 0) const; + + //! allocates new oclMatrix data unless the oclMatrix already has specified size and type. + // previous data is unreferenced if needed. + void create(int rows, int cols, int type); + void create(Size size, int type); + + //! allocates new oclMatrix with specified device memory type. + void createEx(int rows, int cols, int type, + DevMemRW rw_type, DevMemType mem_type, void* hptr = 0); + void createEx(Size size, int type, DevMemRW rw_type, + DevMemType mem_type, void* hptr = 0); + + //! decreases reference counter; + // deallocate the data when reference counter reaches 0. + void release(); + + //! swaps with other smart pointer + void swap(oclMat &mat); + + //! locates oclMatrix header within a parent oclMatrix. See below + void locateROI( Size &wholeSize, Point &ofs ) const; + //! moves/resizes the current oclMatrix ROI inside the parent oclMatrix. + oclMat& adjustROI( int dtop, int dbottom, int dleft, int dright ); + //! extracts a rectangular sub-oclMatrix + // (this is a generalized form of row, rowRange etc.) + oclMat operator()( Range rowRange, Range colRange ) const; + oclMat operator()( const Rect &roi ) const; + + oclMat& operator+=( const oclMat& m ); + oclMat& operator-=( const oclMat& m ); + oclMat& operator*=( const oclMat& m ); + oclMat& operator/=( const oclMat& m ); + + //! returns true if the oclMatrix data is continuous + // (i.e. when there are no gaps between successive rows). + // similar to CV_IS_oclMat_CONT(cvoclMat->type) + bool isContinuous() const; + //! returns element size in bytes, + // similar to CV_ELEM_SIZE(cvMat->type) + size_t elemSize() const; + //! returns the size of element channel in bytes. + size_t elemSize1() const; + //! returns element type, similar to CV_MAT_TYPE(cvMat->type) + int type() const; + //! returns element type, i.e. 8UC3 returns 8UC4 because in ocl + //! 3 channels element actually use 4 channel space + int ocltype() const; + //! returns element type, similar to CV_MAT_DEPTH(cvMat->type) + int depth() const; + //! returns element type, similar to CV_MAT_CN(cvMat->type) + int channels() const; + //! returns element type, return 4 for 3 channels element, + //!becuase 3 channels element actually use 4 channel space + int oclchannels() const; + //! returns step/elemSize1() + size_t step1() const; + //! returns oclMatrix size: + // width == number of columns, height == number of rows + Size size() const; + //! returns true if oclMatrix data is NULL + bool empty() const; + + //! returns pointer to y-th row + uchar* ptr(int y = 0); + const uchar *ptr(int y = 0) const; + + //! template version of the above method + template _Tp *ptr(int y = 0); + template const _Tp *ptr(int y = 0) const; + + //! matrix transposition + oclMat t() const; + + /*! includes several bit-fields: + - the magic signature + - continuity flag + - depth + - number of channels + */ + int flags; + //! the number of rows and columns + int rows, cols; + //! a distance between successive rows in bytes; includes the gap if any + size_t step; + //! pointer to the data(OCL memory object) + uchar *data; + + //! pointer to the reference counter; + // when oclMatrix points to user-allocated data, the pointer is NULL + int *refcount; + + //! helper fields used in locateROI and adjustROI + //datastart and dataend are not used in current version + uchar *datastart; + uchar *dataend; + + //! OpenCL context associated with the oclMat object. + Context *clCxt; + //add offset for handle ROI, calculated in byte + int offset; + //add wholerows and wholecols for the whole matrix, datastart and dataend are no longer used + int wholerows; + int wholecols; + }; + + // convert InputArray/OutputArray to oclMat references + CV_EXPORTS oclMat& getOclMatRef(InputArray src); + CV_EXPORTS oclMat& getOclMatRef(OutputArray src); + + ///////////////////// mat split and merge ///////////////////////////////// + //! Compose a multi-channel array from several single-channel arrays + // Support all types + CV_EXPORTS void merge(const oclMat *src, size_t n, oclMat &dst); + CV_EXPORTS void merge(const std::vector &src, oclMat &dst); + + //! Divides multi-channel array into several single-channel arrays + // Support all types + CV_EXPORTS void split(const oclMat &src, oclMat *dst); + CV_EXPORTS void split(const oclMat &src, std::vector &dst); + + ////////////////////////////// Arithmetics /////////////////////////////////// + //#if defined DOUBLE_SUPPORT + //typedef double F; + //#else + //typedef float F; + //#endif + // CV_EXPORTS void addWeighted(const oclMat& a,F alpha, const oclMat& b,F beta,F gama, oclMat& c); + CV_EXPORTS void addWeighted(const oclMat &a, double alpha, const oclMat &b, double beta, double gama, oclMat &c); + //! adds one matrix to another (c = a + b) + // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4 + CV_EXPORTS void add(const oclMat &a, const oclMat &b, oclMat &c); + //! adds one matrix to another (c = a + b) + // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4 + CV_EXPORTS void add(const oclMat &a, const oclMat &b, oclMat &c, const oclMat &mask); + //! adds scalar to a matrix (c = a + s) + // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4 + CV_EXPORTS void add(const oclMat &a, const Scalar &sc, oclMat &c, const oclMat &mask = oclMat()); + //! subtracts one matrix from another (c = a - b) + // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4 + CV_EXPORTS void subtract(const oclMat &a, const oclMat &b, oclMat &c); + //! subtracts one matrix from another (c = a - b) + // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4 + CV_EXPORTS void subtract(const oclMat &a, const oclMat &b, oclMat &c, const oclMat &mask); + //! subtracts scalar from a matrix (c = a - s) + // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4 + CV_EXPORTS void subtract(const oclMat &a, const Scalar &sc, oclMat &c, const oclMat &mask = oclMat()); + //! subtracts scalar from a matrix (c = a - s) + // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4 + CV_EXPORTS void subtract(const Scalar &sc, const oclMat &a, oclMat &c, const oclMat &mask = oclMat()); + //! computes element-wise product of the two arrays (c = a * b) + // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4 + CV_EXPORTS void multiply(const oclMat &a, const oclMat &b, oclMat &c, double scale = 1); + //! multiplies matrix to a number (dst = scalar * src) + // supports CV_32FC1 only + CV_EXPORTS void multiply(double scalar, const oclMat &src, oclMat &dst); + //! computes element-wise quotient of the two arrays (c = a / b) + // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4 + CV_EXPORTS void divide(const oclMat &a, const oclMat &b, oclMat &c, double scale = 1); + //! computes element-wise quotient of the two arrays (c = a / b) + // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4 + CV_EXPORTS void divide(double scale, const oclMat &b, oclMat &c); + + //! compares elements of two arrays (c = a b) + // supports except CV_8SC1,CV_8SC2,CV8SC3,CV_8SC4 types + CV_EXPORTS void compare(const oclMat &a, const oclMat &b, oclMat &c, int cmpop); + + //! transposes the matrix + // supports CV_8UC1, 8UC4, 8SC4, 16UC2, 16SC2, 32SC1 and 32FC1.(the same as cuda) + CV_EXPORTS void transpose(const oclMat &src, oclMat &dst); + + //! computes element-wise absolute difference of two arrays (c = abs(a - b)) + // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4 + CV_EXPORTS void absdiff(const oclMat &a, const oclMat &b, oclMat &c); + //! computes element-wise absolute difference of array and scalar (c = abs(a - s)) + // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4 + CV_EXPORTS void absdiff(const oclMat &a, const Scalar &s, oclMat &c); + + //! computes mean value and standard deviation of all or selected array elements + // supports except CV_32F,CV_64F + CV_EXPORTS void meanStdDev(const oclMat &mtx, Scalar &mean, Scalar &stddev); + + //! computes norm of array + // supports NORM_INF, NORM_L1, NORM_L2 + // supports only CV_8UC1 type + CV_EXPORTS double norm(const oclMat &src1, int normType = NORM_L2); + + //! computes norm of the difference between two arrays + // supports NORM_INF, NORM_L1, NORM_L2 + // supports only CV_8UC1 type + CV_EXPORTS double norm(const oclMat &src1, const oclMat &src2, int normType = NORM_L2); + + //! reverses the order of the rows, columns or both in a matrix + // supports all types + CV_EXPORTS void flip(const oclMat &a, oclMat &b, int flipCode); + + //! computes sum of array elements + // disabled until fix crash + // support all types + CV_EXPORTS Scalar sum(const oclMat &m); + CV_EXPORTS Scalar absSum(const oclMat &m); + CV_EXPORTS Scalar sqrSum(const oclMat &m); + + //! finds global minimum and maximum array elements and returns their values + // support all C1 types + + CV_EXPORTS void minMax(const oclMat &src, double *minVal, double *maxVal = 0, const oclMat &mask = oclMat()); + CV_EXPORTS void minMax_buf(const oclMat &src, double *minVal, double *maxVal, const oclMat &mask, oclMat& buf); + + //! finds global minimum and maximum array elements and returns their values with locations + // support all C1 types + + CV_EXPORTS void minMaxLoc(const oclMat &src, double *minVal, double *maxVal = 0, Point *minLoc = 0, Point *maxLoc = 0, + const oclMat &mask = oclMat()); + + //! counts non-zero array elements + // support all types + CV_EXPORTS int countNonZero(const oclMat &src); + + //! transforms 8-bit unsigned integers using lookup table: dst(i)=lut(src(i)) + // destination array will have the depth type as lut and the same channels number as source + //It supports 8UC1 8UC4 only + CV_EXPORTS void LUT(const oclMat &src, const oclMat &lut, oclMat &dst); + + //! only 8UC1 and 256 bins is supported now + CV_EXPORTS void calcHist(const oclMat &mat_src, oclMat &mat_hist); + //! only 8UC1 and 256 bins is supported now + CV_EXPORTS void equalizeHist(const oclMat &mat_src, oclMat &mat_dst); + + //! only 8UC1 is supported now + CV_EXPORTS Ptr createCLAHE(double clipLimit = 40.0, Size tileGridSize = Size(8, 8)); + + //! bilateralFilter + // supports 8UC1 8UC4 + CV_EXPORTS void bilateralFilter(const oclMat& src, oclMat& dst, int d, double sigmaColor, double sigmaSpave, int borderType=BORDER_DEFAULT); + //! computes exponent of each matrix element (b = e**a) + // supports only CV_32FC1 type + CV_EXPORTS void exp(const oclMat &a, oclMat &b); + + //! computes natural logarithm of absolute value of each matrix element: b = log(abs(a)) + // supports only CV_32FC1 type + CV_EXPORTS void log(const oclMat &a, oclMat &b); + + //! computes magnitude of each (x(i), y(i)) vector + // supports only CV_32F CV_64F type + CV_EXPORTS void magnitude(const oclMat &x, const oclMat &y, oclMat &magnitude); + CV_EXPORTS void magnitudeSqr(const oclMat &x, const oclMat &y, oclMat &magnitude); + + CV_EXPORTS void magnitudeSqr(const oclMat &x, oclMat &magnitude); + + //! computes angle (angle(i)) of each (x(i), y(i)) vector + // supports only CV_32F CV_64F type + CV_EXPORTS void phase(const oclMat &x, const oclMat &y, oclMat &angle, bool angleInDegrees = false); + + //! the function raises every element of tne input array to p + //! support only CV_32F CV_64F type + CV_EXPORTS void pow(const oclMat &x, double p, oclMat &y); + + //! converts Cartesian coordinates to polar + // supports only CV_32F CV_64F type + CV_EXPORTS void cartToPolar(const oclMat &x, const oclMat &y, oclMat &magnitude, oclMat &angle, bool angleInDegrees = false); + + //! converts polar coordinates to Cartesian + // supports only CV_32F CV_64F type + CV_EXPORTS void polarToCart(const oclMat &magnitude, const oclMat &angle, oclMat &x, oclMat &y, bool angleInDegrees = false); + + //! perfroms per-elements bit-wise inversion + // supports all types + CV_EXPORTS void bitwise_not(const oclMat &src, oclMat &dst); + //! calculates per-element bit-wise disjunction of two arrays + // supports all types + CV_EXPORTS void bitwise_or(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat()); + CV_EXPORTS void bitwise_or(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat()); + //! calculates per-element bit-wise conjunction of two arrays + // supports all types + CV_EXPORTS void bitwise_and(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat()); + CV_EXPORTS void bitwise_and(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat()); + //! calculates per-element bit-wise "exclusive or" operation + // supports all types + CV_EXPORTS void bitwise_xor(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat()); + CV_EXPORTS void bitwise_xor(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat()); + + //! Logical operators + CV_EXPORTS oclMat operator ~ (const oclMat &); + CV_EXPORTS oclMat operator | (const oclMat &, const oclMat &); + CV_EXPORTS oclMat operator & (const oclMat &, const oclMat &); + CV_EXPORTS oclMat operator ^ (const oclMat &, const oclMat &); + + + //! Mathematics operators + CV_EXPORTS oclMatExpr operator + (const oclMat &src1, const oclMat &src2); + CV_EXPORTS oclMatExpr operator - (const oclMat &src1, const oclMat &src2); + CV_EXPORTS oclMatExpr operator * (const oclMat &src1, const oclMat &src2); + CV_EXPORTS oclMatExpr operator / (const oclMat &src1, const oclMat &src2); + + struct CV_EXPORTS ConvolveBuf + { + Size result_size; + Size block_size; + Size user_block_size; + Size dft_size; + + oclMat image_spect, templ_spect, result_spect; + oclMat image_block, templ_block, result_data; + + void create(Size image_size, Size templ_size); + static Size estimateBlockSize(Size result_size, Size templ_size); + }; + + //! computes convolution of two images, may use discrete Fourier transform + //! support only CV_32FC1 type + CV_EXPORTS void convolve(const oclMat &image, const oclMat &temp1, oclMat &result, bool ccorr = false); + CV_EXPORTS void convolve(const oclMat &image, const oclMat &temp1, oclMat &result, bool ccorr, ConvolveBuf& buf); + + //! Performs a per-element multiplication of two Fourier spectrums. + //! Only full (not packed) CV_32FC2 complex spectrums in the interleaved format are supported for now. + //! support only CV_32FC2 type + CV_EXPORTS void mulSpectrums(const oclMat &a, const oclMat &b, oclMat &c, int flags, float scale, bool conjB = false); + + CV_EXPORTS void cvtColor(const oclMat &src, oclMat &dst, int code , int dcn = 0); + + //////////////////////////////// Filter Engine //////////////////////////////// + + /*! + The Base Class for 1D or Row-wise Filters + + This is the base class for linear or non-linear filters that process 1D data. + In particular, such filters are used for the "horizontal" filtering parts in separable filters. + */ + class CV_EXPORTS BaseRowFilter_GPU + { + public: + BaseRowFilter_GPU(int ksize_, int anchor_, int bordertype_) : ksize(ksize_), anchor(anchor_), bordertype(bordertype_) {} + virtual ~BaseRowFilter_GPU() {} + virtual void operator()(const oclMat &src, oclMat &dst) = 0; + int ksize, anchor, bordertype; + }; + + /*! + The Base Class for Column-wise Filters + + This is the base class for linear or non-linear filters that process columns of 2D arrays. + Such filters are used for the "vertical" filtering parts in separable filters. + */ + class CV_EXPORTS BaseColumnFilter_GPU + { + public: + BaseColumnFilter_GPU(int ksize_, int anchor_, int bordertype_) : ksize(ksize_), anchor(anchor_), bordertype(bordertype_) {} + virtual ~BaseColumnFilter_GPU() {} + virtual void operator()(const oclMat &src, oclMat &dst) = 0; + int ksize, anchor, bordertype; + }; + + /*! + The Base Class for Non-Separable 2D Filters. + + This is the base class for linear or non-linear 2D filters. + */ + class CV_EXPORTS BaseFilter_GPU + { + public: + BaseFilter_GPU(const Size &ksize_, const Point &anchor_, const int &borderType_) + : ksize(ksize_), anchor(anchor_), borderType(borderType_) {} + virtual ~BaseFilter_GPU() {} + virtual void operator()(const oclMat &src, oclMat &dst) = 0; + Size ksize; + Point anchor; + int borderType; + }; + + /*! + The Base Class for Filter Engine. + + The class can be used to apply an arbitrary filtering operation to an image. + It contains all the necessary intermediate buffers. + */ + class CV_EXPORTS FilterEngine_GPU + { + public: + virtual ~FilterEngine_GPU() {} + + virtual void apply(const oclMat &src, oclMat &dst, Rect roi = Rect(0, 0, -1, -1)) = 0; + }; + + //! returns the non-separable filter engine with the specified filter + CV_EXPORTS Ptr createFilter2D_GPU(const Ptr filter2D); + + //! returns the primitive row filter with the specified kernel + CV_EXPORTS Ptr getLinearRowFilter_GPU(int srcType, int bufType, const Mat &rowKernel, + int anchor = -1, int bordertype = BORDER_DEFAULT); + + //! returns the primitive column filter with the specified kernel + CV_EXPORTS Ptr getLinearColumnFilter_GPU(int bufType, int dstType, const Mat &columnKernel, + int anchor = -1, int bordertype = BORDER_DEFAULT, double delta = 0.0); + + //! returns the separable linear filter engine + CV_EXPORTS Ptr createSeparableLinearFilter_GPU(int srcType, int dstType, const Mat &rowKernel, + const Mat &columnKernel, const Point &anchor = Point(-1, -1), double delta = 0.0, int bordertype = BORDER_DEFAULT); + + //! returns the separable filter engine with the specified filters + CV_EXPORTS Ptr createSeparableFilter_GPU(const Ptr &rowFilter, + const Ptr &columnFilter); + + //! returns the Gaussian filter engine + CV_EXPORTS Ptr createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2 = 0, int bordertype = BORDER_DEFAULT); + + //! returns filter engine for the generalized Sobel operator + CV_EXPORTS Ptr createDerivFilter_GPU( int srcType, int dstType, int dx, int dy, int ksize, int borderType = BORDER_DEFAULT ); + + //! applies Laplacian operator to the image + // supports only ksize = 1 and ksize = 3 8UC1 8UC4 32FC1 32FC4 data type + CV_EXPORTS void Laplacian(const oclMat &src, oclMat &dst, int ddepth, int ksize = 1, double scale = 1); + + //! returns 2D box filter + // supports CV_8UC1 and CV_8UC4 source type, dst type must be the same as source type + CV_EXPORTS Ptr getBoxFilter_GPU(int srcType, int dstType, + const Size &ksize, Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT); + + //! returns box filter engine + CV_EXPORTS Ptr createBoxFilter_GPU(int srcType, int dstType, const Size &ksize, + const Point &anchor = Point(-1, -1), int borderType = BORDER_DEFAULT); + + //! returns 2D filter with the specified kernel + // supports CV_8UC1 and CV_8UC4 types + CV_EXPORTS Ptr getLinearFilter_GPU(int srcType, int dstType, const Mat &kernel, const Size &ksize, - Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT); ++ const Point &anchor = Point(-1, -1), int borderType = BORDER_DEFAULT); + + //! returns the non-separable linear filter engine + CV_EXPORTS Ptr createLinearFilter_GPU(int srcType, int dstType, const Mat &kernel, + const Point &anchor = Point(-1, -1), int borderType = BORDER_DEFAULT); + + //! smooths the image using the normalized box filter + // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 + // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101,BORDER_WRAP + CV_EXPORTS void boxFilter(const oclMat &src, oclMat &dst, int ddepth, Size ksize, + Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT); + + //! returns 2D morphological filter + //! only MORPH_ERODE and MORPH_DILATE are supported + // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types + // kernel must have CV_8UC1 type, one rows and cols == ksize.width * ksize.height + CV_EXPORTS Ptr getMorphologyFilter_GPU(int op, int type, const Mat &kernel, const Size &ksize, + Point anchor = Point(-1, -1)); + + //! returns morphological filter engine. Only MORPH_ERODE and MORPH_DILATE are supported. + CV_EXPORTS Ptr createMorphologyFilter_GPU(int op, int type, const Mat &kernel, + const Point &anchor = Point(-1, -1), int iterations = 1); + + //! a synonym for normalized box filter + // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 + // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101 + static inline void blur(const oclMat &src, oclMat &dst, Size ksize, Point anchor = Point(-1, -1), + int borderType = BORDER_CONSTANT) + { + boxFilter(src, dst, -1, ksize, anchor, borderType); + } + + //! applies non-separable 2D linear filter to the image + // Note, at the moment this function only works when anchor point is in the kernel center + // and kernel size supported is either 3x3 or 5x5; otherwise the function will fail to output valid result + CV_EXPORTS void filter2D(const oclMat &src, oclMat &dst, int ddepth, const Mat &kernel, + Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT); + + //! applies separable 2D linear filter to the image + CV_EXPORTS void sepFilter2D(const oclMat &src, oclMat &dst, int ddepth, const Mat &kernelX, const Mat &kernelY, + Point anchor = Point(-1, -1), double delta = 0.0, int bordertype = BORDER_DEFAULT); + + //! applies generalized Sobel operator to the image + // dst.type must equalize src.type + // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 + // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101 + CV_EXPORTS void Sobel(const oclMat &src, oclMat &dst, int ddepth, int dx, int dy, int ksize = 3, double scale = 1, double delta = 0.0, int bordertype = BORDER_DEFAULT); + + //! applies the vertical or horizontal Scharr operator to the image + // dst.type must equalize src.type + // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 + // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101 + CV_EXPORTS void Scharr(const oclMat &src, oclMat &dst, int ddepth, int dx, int dy, double scale = 1, double delta = 0.0, int bordertype = BORDER_DEFAULT); + + //! smooths the image using Gaussian filter. + // dst.type must equalize src.type + // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 + // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101 + CV_EXPORTS void GaussianBlur(const oclMat &src, oclMat &dst, Size ksize, double sigma1, double sigma2 = 0, int bordertype = BORDER_DEFAULT); + + //! erodes the image (applies the local minimum operator) + // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 + CV_EXPORTS void erode( const oclMat &src, oclMat &dst, const Mat &kernel, Point anchor = Point(-1, -1), int iterations = 1, + + int borderType = BORDER_CONSTANT, const Scalar &borderValue = morphologyDefaultBorderValue()); + + + //! dilates the image (applies the local maximum operator) + // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 + CV_EXPORTS void dilate( const oclMat &src, oclMat &dst, const Mat &kernel, Point anchor = Point(-1, -1), int iterations = 1, + + int borderType = BORDER_CONSTANT, const Scalar &borderValue = morphologyDefaultBorderValue()); + + + //! applies an advanced morphological operation to the image + CV_EXPORTS void morphologyEx( const oclMat &src, oclMat &dst, int op, const Mat &kernel, Point anchor = Point(-1, -1), int iterations = 1, + + int borderType = BORDER_CONSTANT, const Scalar &borderValue = morphologyDefaultBorderValue()); + + + ////////////////////////////// Image processing ////////////////////////////// + //! Does mean shift filtering on GPU. + CV_EXPORTS void meanShiftFiltering(const oclMat &src, oclMat &dst, int sp, int sr, + TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 5, 1)); + + //! Does mean shift procedure on GPU. + CV_EXPORTS void meanShiftProc(const oclMat &src, oclMat &dstr, oclMat &dstsp, int sp, int sr, + TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 5, 1)); + + //! Does mean shift segmentation with elimiation of small regions. + CV_EXPORTS void meanShiftSegmentation(const oclMat &src, Mat &dst, int sp, int sr, int minsize, + TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 5, 1)); + + //! applies fixed threshold to the image. + // supports CV_8UC1 and CV_32FC1 data type + // supports threshold type: THRESH_BINARY, THRESH_BINARY_INV, THRESH_TRUNC, THRESH_TOZERO, THRESH_TOZERO_INV + CV_EXPORTS double threshold(const oclMat &src, oclMat &dst, double thresh, double maxVal, int type = THRESH_TRUNC); + + //! resizes the image + // Supports INTER_NEAREST, INTER_LINEAR + // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types + CV_EXPORTS void resize(const oclMat &src, oclMat &dst, Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR); + + //! Applies a generic geometrical transformation to an image. + + // Supports INTER_NEAREST, INTER_LINEAR. + + // Map1 supports CV_16SC2, CV_32FC2 types. + + // Src supports CV_8UC1, CV_8UC2, CV_8UC4. + + CV_EXPORTS void remap(const oclMat &src, oclMat &dst, oclMat &map1, oclMat &map2, int interpolation, int bordertype, const Scalar &value = Scalar()); + + //! copies 2D array to a larger destination array and pads borders with user-specifiable constant + // supports CV_8UC1, CV_8UC4, CV_32SC1 types + CV_EXPORTS void copyMakeBorder(const oclMat &src, oclMat &dst, int top, int bottom, int left, int right, int boardtype, const Scalar &value = Scalar()); + + //! Smoothes image using median filter + // The source 1- or 4-channel image. When m is 3 or 5, the image depth should be CV 8U or CV 32F. + CV_EXPORTS void medianFilter(const oclMat &src, oclMat &dst, int m); + + //! warps the image using affine transformation + // Supports INTER_NEAREST, INTER_LINEAR, INTER_CUBIC + // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types + CV_EXPORTS void warpAffine(const oclMat &src, oclMat &dst, const Mat &M, Size dsize, int flags = INTER_LINEAR); + + //! warps the image using perspective transformation + // Supports INTER_NEAREST, INTER_LINEAR, INTER_CUBIC + // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types + CV_EXPORTS void warpPerspective(const oclMat &src, oclMat &dst, const Mat &M, Size dsize, int flags = INTER_LINEAR); + + //! computes the integral image and integral for the squared image + // sum will have CV_32S type, sqsum - CV32F type + // supports only CV_8UC1 source type + CV_EXPORTS void integral(const oclMat &src, oclMat &sum, oclMat &sqsum); + CV_EXPORTS void integral(const oclMat &src, oclMat &sum); + CV_EXPORTS void cornerHarris(const oclMat &src, oclMat &dst, int blockSize, int ksize, double k, int bordertype = cv::BORDER_DEFAULT); + CV_EXPORTS void cornerHarris_dxdy(const oclMat &src, oclMat &dst, oclMat &Dx, oclMat &Dy, + int blockSize, int ksize, double k, int bordertype = cv::BORDER_DEFAULT); + CV_EXPORTS void cornerMinEigenVal(const oclMat &src, oclMat &dst, int blockSize, int ksize, int bordertype = cv::BORDER_DEFAULT); + CV_EXPORTS void cornerMinEigenVal_dxdy(const oclMat &src, oclMat &dst, oclMat &Dx, oclMat &Dy, + int blockSize, int ksize, int bordertype = cv::BORDER_DEFAULT); + + + /////////////////////////////////// ML /////////////////////////////////////////// + + //! Compute closest centers for each lines in source and lable it after center's index + // supports CV_32FC1/CV_32FC2/CV_32FC4 data type + CV_EXPORTS void distanceToCenters(oclMat &dists, oclMat &labels, const oclMat &src, const oclMat ¢ers); + + //!Does k-means procedure on GPU + // supports CV_32FC1/CV_32FC2/CV_32FC4 data type + CV_EXPORTS double kmeans(const oclMat &src, int K, oclMat &bestLabels, + TermCriteria criteria, int attemps, int flags, oclMat ¢ers); + + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////CascadeClassifier////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + class CV_EXPORTS OclCascadeClassifier : public cv::CascadeClassifier + { + public: + void detectMultiScale(oclMat &image, CV_OUT std::vector& faces, + double scaleFactor = 1.1, int minNeighbors = 3, int flags = 0, + Size minSize = Size(), Size maxSize = Size()); + }; + + /////////////////////////////// Pyramid ///////////////////////////////////// + CV_EXPORTS void pyrDown(const oclMat &src, oclMat &dst); + + //! upsamples the source image and then smoothes it + CV_EXPORTS void pyrUp(const oclMat &src, oclMat &dst); + + //! performs linear blending of two images + //! to avoid accuracy errors sum of weigths shouldn't be very close to zero + // supports only CV_8UC1 source type + CV_EXPORTS void blendLinear(const oclMat &img1, const oclMat &img2, const oclMat &weights1, const oclMat &weights2, oclMat &result); + + //! computes vertical sum, supports only CV_32FC1 images + CV_EXPORTS void columnSum(const oclMat &src, oclMat &sum); + + ///////////////////////////////////////// match_template ///////////////////////////////////////////////////////////// + struct CV_EXPORTS MatchTemplateBuf + { + Size user_block_size; + oclMat imagef, templf; + std::vector images; + std::vector image_sums; + std::vector image_sqsums; + }; + + //! computes the proximity map for the raster template and the image where the template is searched for + // Supports TM_SQDIFF, TM_SQDIFF_NORMED, TM_CCORR, TM_CCORR_NORMED, TM_CCOEFF, TM_CCOEFF_NORMED for type 8UC1 and 8UC4 + // Supports TM_SQDIFF, TM_CCORR for type 32FC1 and 32FC4 + CV_EXPORTS void matchTemplate(const oclMat &image, const oclMat &templ, oclMat &result, int method); + + //! computes the proximity map for the raster template and the image where the template is searched for + // Supports TM_SQDIFF, TM_SQDIFF_NORMED, TM_CCORR, TM_CCORR_NORMED, TM_CCOEFF, TM_CCOEFF_NORMED for type 8UC1 and 8UC4 + // Supports TM_SQDIFF, TM_CCORR for type 32FC1 and 32FC4 + CV_EXPORTS void matchTemplate(const oclMat &image, const oclMat &templ, oclMat &result, int method, MatchTemplateBuf &buf); + + + + ///////////////////////////////////////////// Canny ///////////////////////////////////////////// + struct CV_EXPORTS CannyBuf; + + //! compute edges of the input image using Canny operator + // Support CV_8UC1 only + CV_EXPORTS void Canny(const oclMat &image, oclMat &edges, double low_thresh, double high_thresh, int apperture_size = 3, bool L2gradient = false); + CV_EXPORTS void Canny(const oclMat &image, CannyBuf &buf, oclMat &edges, double low_thresh, double high_thresh, int apperture_size = 3, bool L2gradient = false); + CV_EXPORTS void Canny(const oclMat &dx, const oclMat &dy, oclMat &edges, double low_thresh, double high_thresh, bool L2gradient = false); + CV_EXPORTS void Canny(const oclMat &dx, const oclMat &dy, CannyBuf &buf, oclMat &edges, double low_thresh, double high_thresh, bool L2gradient = false); + + struct CV_EXPORTS CannyBuf + { + CannyBuf() : counter(NULL) {} + ~CannyBuf() + { + release(); + } + explicit CannyBuf(const Size &image_size, int apperture_size = 3) : counter(NULL) + { + create(image_size, apperture_size); + } + CannyBuf(const oclMat &dx_, const oclMat &dy_); + void create(const Size &image_size, int apperture_size = 3); + void release(); + + oclMat dx, dy; + oclMat dx_buf, dy_buf; + oclMat magBuf, mapBuf; + oclMat trackBuf1, trackBuf2; + void *counter; + Ptr filterDX, filterDY; + }; + + ///////////////////////////////////////// Hough Transform ///////////////////////////////////////// + //! HoughCircles + struct HoughCirclesBuf + { + oclMat edges; + oclMat accum; + oclMat srcPoints; + oclMat centers; + CannyBuf cannyBuf; + }; + + CV_EXPORTS void HoughCircles(const oclMat& src, oclMat& circles, int method, float dp, float minDist, int cannyThreshold, int votesThreshold, int minRadius, int maxRadius, int maxCircles = 4096); + CV_EXPORTS void HoughCircles(const oclMat& src, oclMat& circles, HoughCirclesBuf& buf, int method, float dp, float minDist, int cannyThreshold, int votesThreshold, int minRadius, int maxRadius, int maxCircles = 4096); + CV_EXPORTS void HoughCirclesDownload(const oclMat& d_circles, OutputArray h_circles); + + + ///////////////////////////////////////// clAmdFft related ///////////////////////////////////////// + //! Performs a forward or inverse discrete Fourier transform (1D or 2D) of floating point matrix. + //! Param dft_size is the size of DFT transform. + //! + //! For complex-to-real transform it is assumed that the source matrix is packed in CLFFT's format. + // support src type of CV32FC1, CV32FC2 + // support flags: DFT_INVERSE, DFT_REAL_OUTPUT, DFT_COMPLEX_OUTPUT, DFT_ROWS + // dft_size is the size of original input, which is used for transformation from complex to real. + // dft_size must be powers of 2, 3 and 5 + // real to complex dft requires at least v1.8 clAmdFft + // real to complex dft output is not the same with cpu version + // real to complex and complex to real does not support DFT_ROWS + CV_EXPORTS void dft(const oclMat &src, oclMat &dst, Size dft_size = Size(0, 0), int flags = 0); + + //! implements generalized matrix product algorithm GEMM from BLAS + // The functionality requires clAmdBlas library + // only support type CV_32FC1 + // flag GEMM_3_T is not supported + CV_EXPORTS void gemm(const oclMat &src1, const oclMat &src2, double alpha, + const oclMat &src3, double beta, oclMat &dst, int flags = 0); + + //////////////// HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector ////////////// + + struct CV_EXPORTS HOGDescriptor + + { + + enum { DEFAULT_WIN_SIGMA = -1 }; + + enum { DEFAULT_NLEVELS = 64 }; + + enum { DESCR_FORMAT_ROW_BY_ROW, DESCR_FORMAT_COL_BY_COL }; + + + + HOGDescriptor(Size win_size = Size(64, 128), Size block_size = Size(16, 16), + + Size block_stride = Size(8, 8), Size cell_size = Size(8, 8), + + int nbins = 9, double win_sigma = DEFAULT_WIN_SIGMA, + + double threshold_L2hys = 0.2, bool gamma_correction = true, + + int nlevels = DEFAULT_NLEVELS); + + + + size_t getDescriptorSize() const; + + size_t getBlockHistogramSize() const; + + + + void setSVMDetector(const std::vector &detector); + + + + static std::vector getDefaultPeopleDetector(); + + static std::vector getPeopleDetector48x96(); + + static std::vector getPeopleDetector64x128(); + + + + void detect(const oclMat &img, std::vector &found_locations, + + double hit_threshold = 0, Size win_stride = Size(), + + Size padding = Size()); + + + + void detectMultiScale(const oclMat &img, std::vector &found_locations, + + double hit_threshold = 0, Size win_stride = Size(), + + Size padding = Size(), double scale0 = 1.05, + + int group_threshold = 2); + + + + void getDescriptors(const oclMat &img, Size win_stride, + + oclMat &descriptors, + + int descr_format = DESCR_FORMAT_COL_BY_COL); + + + + Size win_size; + + Size block_size; + + Size block_stride; + + Size cell_size; + + int nbins; + + double win_sigma; + + double threshold_L2hys; + + bool gamma_correction; + + int nlevels; + + + + protected: + + // initialize buffers; only need to do once in case of multiscale detection + + void init_buffer(const oclMat &img, Size win_stride); + + + + void computeBlockHistograms(const oclMat &img); + + void computeGradient(const oclMat &img, oclMat &grad, oclMat &qangle); + + + + double getWinSigma() const; + + bool checkDetectorSize() const; + + + + static int numPartsWithin(int size, int part_size, int stride); + + static Size numPartsWithin(Size size, Size part_size, Size stride); + + + + // Coefficients of the separating plane + + float free_coef; + + oclMat detector; + + + + // Results of the last classification step + + oclMat labels; + + Mat labels_host; + + + + // Results of the last histogram evaluation step + + oclMat block_hists; + + + + // Gradients conputation results + + oclMat grad, qangle; + + + + // scaled image + + oclMat image_scale; + + + + // effect size of input image (might be different from original size after scaling) + + Size effect_size; + + }; + + + ////////////////////////feature2d_ocl///////////////// + /****************************************************************************************\ + * Distance * + \****************************************************************************************/ + template + struct CV_EXPORTS Accumulator + { + typedef T Type; + }; + template<> struct Accumulator + { + typedef float Type; + }; + template<> struct Accumulator + { + typedef float Type; + }; + template<> struct Accumulator + { + typedef float Type; + }; + template<> struct Accumulator + { + typedef float Type; + }; + + /* + * Manhattan distance (city block distance) functor + */ + template + struct CV_EXPORTS L1 + { + enum { normType = NORM_L1 }; + typedef T ValueType; + typedef typename Accumulator::Type ResultType; + + ResultType operator()( const T *a, const T *b, int size ) const + { + return normL1(a, b, size); + } + }; + + /* + * Euclidean distance functor + */ + template + struct CV_EXPORTS L2 + { + enum { normType = NORM_L2 }; + typedef T ValueType; + typedef typename Accumulator::Type ResultType; + + ResultType operator()( const T *a, const T *b, int size ) const + { + return (ResultType)std::sqrt((double)normL2Sqr(a, b, size)); + } + }; + + /* + * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor + * bit count of A exclusive XOR'ed with B + */ + struct CV_EXPORTS Hamming + { + enum { normType = NORM_HAMMING }; + typedef unsigned char ValueType; + typedef int ResultType; + + /** this will count the bits in a ^ b + */ + ResultType operator()( const unsigned char *a, const unsigned char *b, int size ) const + { + return normHamming(a, b, size); + } + }; + + ////////////////////////////////// BruteForceMatcher ////////////////////////////////// + + class CV_EXPORTS BruteForceMatcher_OCL_base + { + public: + enum DistType {L1Dist = 0, L2Dist, HammingDist}; + explicit BruteForceMatcher_OCL_base(DistType distType = L2Dist); + + // Add descriptors to train descriptor collection + void add(const std::vector &descCollection); + + // Get train descriptors collection + const std::vector &getTrainDescriptors() const; + + // Clear train descriptors collection + void clear(); + + // Return true if there are not train descriptors in collection + bool empty() const; + + // Return true if the matcher supports mask in match methods + bool isMaskSupported() const; + + // Find one best match for each query descriptor + void matchSingle(const oclMat &query, const oclMat &train, + oclMat &trainIdx, oclMat &distance, + const oclMat &mask = oclMat()); + + // Download trainIdx and distance and convert it to CPU vector with DMatch + static void matchDownload(const oclMat &trainIdx, const oclMat &distance, std::vector &matches); + // Convert trainIdx and distance to vector with DMatch + static void matchConvert(const Mat &trainIdx, const Mat &distance, std::vector &matches); + + // Find one best match for each query descriptor + void match(const oclMat &query, const oclMat &train, std::vector &matches, const oclMat &mask = oclMat()); + + // Make gpu collection of trains and masks in suitable format for matchCollection function + void makeGpuCollection(oclMat &trainCollection, oclMat &maskCollection, const std::vector &masks = std::vector()); + + // Find one best match from train collection for each query descriptor + void matchCollection(const oclMat &query, const oclMat &trainCollection, + oclMat &trainIdx, oclMat &imgIdx, oclMat &distance, + const oclMat &masks = oclMat()); + + // Download trainIdx, imgIdx and distance and convert it to vector with DMatch + static void matchDownload(const oclMat &trainIdx, const oclMat &imgIdx, const oclMat &distance, std::vector &matches); + // Convert trainIdx, imgIdx and distance to vector with DMatch + static void matchConvert(const Mat &trainIdx, const Mat &imgIdx, const Mat &distance, std::vector &matches); + + // Find one best match from train collection for each query descriptor. + void match(const oclMat &query, std::vector &matches, const std::vector &masks = std::vector()); + + // Find k best matches for each query descriptor (in increasing order of distances) + void knnMatchSingle(const oclMat &query, const oclMat &train, + oclMat &trainIdx, oclMat &distance, oclMat &allDist, int k, + const oclMat &mask = oclMat()); + + // Download trainIdx and distance and convert it to vector with DMatch + // compactResult is used when mask is not empty. If compactResult is false matches + // vector will have the same size as queryDescriptors rows. If compactResult is true + // matches vector will not contain matches for fully masked out query descriptors. + static void knnMatchDownload(const oclMat &trainIdx, const oclMat &distance, + std::vector< std::vector > &matches, bool compactResult = false); + // Convert trainIdx and distance to vector with DMatch + static void knnMatchConvert(const Mat &trainIdx, const Mat &distance, + std::vector< std::vector > &matches, bool compactResult = false); + + // Find k best matches for each query descriptor (in increasing order of distances). + // compactResult is used when mask is not empty. If compactResult is false matches + // vector will have the same size as queryDescriptors rows. If compactResult is true + // matches vector will not contain matches for fully masked out query descriptors. + void knnMatch(const oclMat &query, const oclMat &train, + std::vector< std::vector > &matches, int k, const oclMat &mask = oclMat(), + bool compactResult = false); + + // Find k best matches from train collection for each query descriptor (in increasing order of distances) + void knnMatch2Collection(const oclMat &query, const oclMat &trainCollection, + oclMat &trainIdx, oclMat &imgIdx, oclMat &distance, + const oclMat &maskCollection = oclMat()); + + // Download trainIdx and distance and convert it to vector with DMatch + // compactResult is used when mask is not empty. If compactResult is false matches + // vector will have the same size as queryDescriptors rows. If compactResult is true + // matches vector will not contain matches for fully masked out query descriptors. + static void knnMatch2Download(const oclMat &trainIdx, const oclMat &imgIdx, const oclMat &distance, + std::vector< std::vector > &matches, bool compactResult = false); + // Convert trainIdx and distance to vector with DMatch + static void knnMatch2Convert(const Mat &trainIdx, const Mat &imgIdx, const Mat &distance, + std::vector< std::vector > &matches, bool compactResult = false); + + // Find k best matches for each query descriptor (in increasing order of distances). + // compactResult is used when mask is not empty. If compactResult is false matches + // vector will have the same size as queryDescriptors rows. If compactResult is true + // matches vector will not contain matches for fully masked out query descriptors. + void knnMatch(const oclMat &query, std::vector< std::vector > &matches, int k, + const std::vector &masks = std::vector(), bool compactResult = false); + + // Find best matches for each query descriptor which have distance less than maxDistance. + // nMatches.at(0, queryIdx) will contain matches count for queryIdx. + // carefully nMatches can be greater than trainIdx.cols - it means that matcher didn't find all matches, + // because it didn't have enough memory. + // If trainIdx is empty, then trainIdx and distance will be created with size nQuery x max((nTrain / 100), 10), + // otherwize user can pass own allocated trainIdx and distance with size nQuery x nMaxMatches + // Matches doesn't sorted. + void radiusMatchSingle(const oclMat &query, const oclMat &train, + oclMat &trainIdx, oclMat &distance, oclMat &nMatches, float maxDistance, + const oclMat &mask = oclMat()); + + // Download trainIdx, nMatches and distance and convert it to vector with DMatch. + // matches will be sorted in increasing order of distances. + // compactResult is used when mask is not empty. If compactResult is false matches + // vector will have the same size as queryDescriptors rows. If compactResult is true + // matches vector will not contain matches for fully masked out query descriptors. + static void radiusMatchDownload(const oclMat &trainIdx, const oclMat &distance, const oclMat &nMatches, + std::vector< std::vector > &matches, bool compactResult = false); + // Convert trainIdx, nMatches and distance to vector with DMatch. + static void radiusMatchConvert(const Mat &trainIdx, const Mat &distance, const Mat &nMatches, + std::vector< std::vector > &matches, bool compactResult = false); + + // Find best matches for each query descriptor which have distance less than maxDistance + // in increasing order of distances). + void radiusMatch(const oclMat &query, const oclMat &train, + std::vector< std::vector > &matches, float maxDistance, + const oclMat &mask = oclMat(), bool compactResult = false); + + // Find best matches for each query descriptor which have distance less than maxDistance. + // If trainIdx is empty, then trainIdx and distance will be created with size nQuery x max((nQuery / 100), 10), + // otherwize user can pass own allocated trainIdx and distance with size nQuery x nMaxMatches + // Matches doesn't sorted. + void radiusMatchCollection(const oclMat &query, oclMat &trainIdx, oclMat &imgIdx, oclMat &distance, oclMat &nMatches, float maxDistance, + const std::vector &masks = std::vector()); + + // Download trainIdx, imgIdx, nMatches and distance and convert it to vector with DMatch. + // matches will be sorted in increasing order of distances. + // compactResult is used when mask is not empty. If compactResult is false matches + // vector will have the same size as queryDescriptors rows. If compactResult is true + // matches vector will not contain matches for fully masked out query descriptors. + static void radiusMatchDownload(const oclMat &trainIdx, const oclMat &imgIdx, const oclMat &distance, const oclMat &nMatches, + std::vector< std::vector > &matches, bool compactResult = false); + // Convert trainIdx, nMatches and distance to vector with DMatch. + static void radiusMatchConvert(const Mat &trainIdx, const Mat &imgIdx, const Mat &distance, const Mat &nMatches, + std::vector< std::vector > &matches, bool compactResult = false); + + // Find best matches from train collection for each query descriptor which have distance less than + // maxDistance (in increasing order of distances). + void radiusMatch(const oclMat &query, std::vector< std::vector > &matches, float maxDistance, + const std::vector &masks = std::vector(), bool compactResult = false); + + DistType distType; + + private: + std::vector trainDescCollection; + }; + + template + class CV_EXPORTS BruteForceMatcher_OCL; + + template + class CV_EXPORTS BruteForceMatcher_OCL< L1 > : public BruteForceMatcher_OCL_base + { + public: + explicit BruteForceMatcher_OCL() : BruteForceMatcher_OCL_base(L1Dist) {} + explicit BruteForceMatcher_OCL(L1 /*d*/) : BruteForceMatcher_OCL_base(L1Dist) {} + }; + template + class CV_EXPORTS BruteForceMatcher_OCL< L2 > : public BruteForceMatcher_OCL_base + { + public: + explicit BruteForceMatcher_OCL() : BruteForceMatcher_OCL_base(L2Dist) {} + explicit BruteForceMatcher_OCL(L2 /*d*/) : BruteForceMatcher_OCL_base(L2Dist) {} + }; + template <> class CV_EXPORTS BruteForceMatcher_OCL< Hamming > : public BruteForceMatcher_OCL_base + { + public: + explicit BruteForceMatcher_OCL() : BruteForceMatcher_OCL_base(HammingDist) {} + explicit BruteForceMatcher_OCL(Hamming /*d*/) : BruteForceMatcher_OCL_base(HammingDist) {} + }; + + class CV_EXPORTS BFMatcher_OCL : public BruteForceMatcher_OCL_base + { + public: + explicit BFMatcher_OCL(int norm = NORM_L2) : BruteForceMatcher_OCL_base(norm == NORM_L1 ? L1Dist : norm == NORM_L2 ? L2Dist : HammingDist) {} + }; + + class CV_EXPORTS GoodFeaturesToTrackDetector_OCL + { + public: + explicit GoodFeaturesToTrackDetector_OCL(int maxCorners = 1000, double qualityLevel = 0.01, double minDistance = 0.0, + int blockSize = 3, bool useHarrisDetector = false, double harrisK = 0.04); + + //! return 1 rows matrix with CV_32FC2 type + void operator ()(const oclMat& image, oclMat& corners, const oclMat& mask = oclMat()); + //! download points of type Point2f to a vector. the vector's content will be erased + void downloadPoints(const oclMat &points, std::vector &points_v); + + int maxCorners; + double qualityLevel; + double minDistance; + + int blockSize; + bool useHarrisDetector; + double harrisK; + void releaseMemory() + { + Dx_.release(); + Dy_.release(); + eig_.release(); + minMaxbuf_.release(); + tmpCorners_.release(); + } + private: + oclMat Dx_; + oclMat Dy_; + oclMat eig_; + oclMat minMaxbuf_; + oclMat tmpCorners_; + }; + + inline GoodFeaturesToTrackDetector_OCL::GoodFeaturesToTrackDetector_OCL(int maxCorners_, double qualityLevel_, double minDistance_, + int blockSize_, bool useHarrisDetector_, double harrisK_) + { + maxCorners = maxCorners_; + qualityLevel = qualityLevel_; + minDistance = minDistance_; + blockSize = blockSize_; + useHarrisDetector = useHarrisDetector_; + harrisK = harrisK_; + } + + /////////////////////////////// PyrLKOpticalFlow ///////////////////////////////////// + + class CV_EXPORTS PyrLKOpticalFlow + { + public: + PyrLKOpticalFlow() + { + winSize = Size(21, 21); + maxLevel = 3; + iters = 30; + derivLambda = 0.5; + useInitialFlow = false; + minEigThreshold = 1e-4f; + getMinEigenVals = false; + isDeviceArch11_ = false; + } + + void sparse(const oclMat &prevImg, const oclMat &nextImg, const oclMat &prevPts, oclMat &nextPts, + oclMat &status, oclMat *err = 0); + + void dense(const oclMat &prevImg, const oclMat &nextImg, oclMat &u, oclMat &v, oclMat *err = 0); + + Size winSize; + int maxLevel; + int iters; + double derivLambda; + bool useInitialFlow; + float minEigThreshold; + bool getMinEigenVals; + + void releaseMemory() + { + dx_calcBuf_.release(); + dy_calcBuf_.release(); + + prevPyr_.clear(); + nextPyr_.clear(); + + dx_buf_.release(); + dy_buf_.release(); + } + + private: + void calcSharrDeriv(const oclMat &src, oclMat &dx, oclMat &dy); + + void buildImagePyramid(const oclMat &img0, std::vector &pyr, bool withBorder); + + oclMat dx_calcBuf_; + oclMat dy_calcBuf_; + + std::vector prevPyr_; + std::vector nextPyr_; + + oclMat dx_buf_; + oclMat dy_buf_; + + oclMat uPyr_[2]; + oclMat vPyr_[2]; + + bool isDeviceArch11_; + }; + + class CV_EXPORTS FarnebackOpticalFlow + { + public: + FarnebackOpticalFlow(); + + int numLevels; + double pyrScale; + bool fastPyramids; + int winSize; + int numIters; + int polyN; + double polySigma; + int flags; + + void operator ()(const oclMat &frame0, const oclMat &frame1, oclMat &flowx, oclMat &flowy); + + void releaseMemory(); + + private: + void prepareGaussian( + int n, double sigma, float *g, float *xg, float *xxg, + double &ig11, double &ig03, double &ig33, double &ig55); + + void setPolynomialExpansionConsts(int n, double sigma); + + void updateFlow_boxFilter( + const oclMat& R0, const oclMat& R1, oclMat& flowx, oclMat &flowy, + oclMat& M, oclMat &bufM, int blockSize, bool updateMatrices); + + void updateFlow_gaussianBlur( + const oclMat& R0, const oclMat& R1, oclMat& flowx, oclMat& flowy, + oclMat& M, oclMat &bufM, int blockSize, bool updateMatrices); + + oclMat frames_[2]; + oclMat pyrLevel_[2], M_, bufM_, R_[2], blurredFrame_[2]; + std::vector pyramid0_, pyramid1_; + }; + + //////////////// build warping maps //////////////////// + //! builds plane warping maps + CV_EXPORTS void buildWarpPlaneMaps(Size src_size, Rect dst_roi, const Mat &K, const Mat &R, const Mat &T, float scale, oclMat &map_x, oclMat &map_y); + //! builds cylindrical warping maps + CV_EXPORTS void buildWarpCylindricalMaps(Size src_size, Rect dst_roi, const Mat &K, const Mat &R, float scale, oclMat &map_x, oclMat &map_y); + //! builds spherical warping maps + CV_EXPORTS void buildWarpSphericalMaps(Size src_size, Rect dst_roi, const Mat &K, const Mat &R, float scale, oclMat &map_x, oclMat &map_y); + //! builds Affine warping maps + CV_EXPORTS void buildWarpAffineMaps(const Mat &M, bool inverse, Size dsize, oclMat &xmap, oclMat &ymap); + + //! builds Perspective warping maps + CV_EXPORTS void buildWarpPerspectiveMaps(const Mat &M, bool inverse, Size dsize, oclMat &xmap, oclMat &ymap); + + ///////////////////////////////////// interpolate frames ////////////////////////////////////////////// + //! Interpolate frames (images) using provided optical flow (displacement field). + //! frame0 - frame 0 (32-bit floating point images, single channel) + //! frame1 - frame 1 (the same type and size) + //! fu - forward horizontal displacement + //! fv - forward vertical displacement + //! bu - backward horizontal displacement + //! bv - backward vertical displacement + //! pos - new frame position + //! newFrame - new frame + //! buf - temporary buffer, will have width x 6*height size, CV_32FC1 type and contain 6 oclMat; + //! occlusion masks 0, occlusion masks 1, + //! interpolated forward flow 0, interpolated forward flow 1, + //! interpolated backward flow 0, interpolated backward flow 1 + //! + CV_EXPORTS void interpolateFrames(const oclMat &frame0, const oclMat &frame1, + const oclMat &fu, const oclMat &fv, + const oclMat &bu, const oclMat &bv, + float pos, oclMat &newFrame, oclMat &buf); + + //! computes moments of the rasterized shape or a vector of points + CV_EXPORTS Moments ocl_moments(InputArray _array, bool binaryImage); + + class CV_EXPORTS StereoBM_OCL + { + public: + enum { BASIC_PRESET = 0, PREFILTER_XSOBEL = 1 }; + + enum { DEFAULT_NDISP = 64, DEFAULT_WINSZ = 19 }; + + //! the default constructor + StereoBM_OCL(); + //! the full constructor taking the camera-specific preset, number of disparities and the SAD window size. ndisparities must be multiple of 8. + StereoBM_OCL(int preset, int ndisparities = DEFAULT_NDISP, int winSize = DEFAULT_WINSZ); + + //! the stereo correspondence operator. Finds the disparity for the specified rectified stereo pair + //! Output disparity has CV_8U type. + void operator() ( const oclMat &left, const oclMat &right, oclMat &disparity); + + //! Some heuristics that tries to estmate + // if current GPU will be faster then CPU in this algorithm. + // It queries current active device. + static bool checkIfGpuCallReasonable(); + + int preset; + int ndisp; + int winSize; + + // If avergeTexThreshold == 0 => post procesing is disabled + // If avergeTexThreshold != 0 then disparity is set 0 in each point (x,y) where for left image + // SumOfHorizontalGradiensInWindow(x, y, winSize) < (winSize * winSize) * avergeTexThreshold + // i.e. input left image is low textured. + float avergeTexThreshold; + private: + oclMat minSSD, leBuf, riBuf; + }; + + class CV_EXPORTS StereoBeliefPropagation + { + public: + enum { DEFAULT_NDISP = 64 }; + enum { DEFAULT_ITERS = 5 }; + enum { DEFAULT_LEVELS = 5 }; + static void estimateRecommendedParams(int width, int height, int &ndisp, int &iters, int &levels); + explicit StereoBeliefPropagation(int ndisp = DEFAULT_NDISP, + int iters = DEFAULT_ITERS, + int levels = DEFAULT_LEVELS, + int msg_type = CV_16S); + StereoBeliefPropagation(int ndisp, int iters, int levels, + float max_data_term, float data_weight, + float max_disc_term, float disc_single_jump, + int msg_type = CV_32F); + void operator()(const oclMat &left, const oclMat &right, oclMat &disparity); + void operator()(const oclMat &data, oclMat &disparity); + int ndisp; + int iters; + int levels; + float max_data_term; + float data_weight; + float max_disc_term; + float disc_single_jump; + int msg_type; + private: + oclMat u, d, l, r, u2, d2, l2, r2; + std::vector datas; + oclMat out; + }; + + class CV_EXPORTS StereoConstantSpaceBP + { + public: + enum { DEFAULT_NDISP = 128 }; + enum { DEFAULT_ITERS = 8 }; + enum { DEFAULT_LEVELS = 4 }; + enum { DEFAULT_NR_PLANE = 4 }; + static void estimateRecommendedParams(int width, int height, int &ndisp, int &iters, int &levels, int &nr_plane); + explicit StereoConstantSpaceBP( + int ndisp = DEFAULT_NDISP, + int iters = DEFAULT_ITERS, + int levels = DEFAULT_LEVELS, + int nr_plane = DEFAULT_NR_PLANE, + int msg_type = CV_32F); + StereoConstantSpaceBP(int ndisp, int iters, int levels, int nr_plane, + float max_data_term, float data_weight, float max_disc_term, float disc_single_jump, + int min_disp_th = 0, + int msg_type = CV_32F); + void operator()(const oclMat &left, const oclMat &right, oclMat &disparity); + int ndisp; + int iters; + int levels; + int nr_plane; + float max_data_term; + float data_weight; + float max_disc_term; + float disc_single_jump; + int min_disp_th; + int msg_type; + bool use_local_init_data_cost; + private: + oclMat u[2], d[2], l[2], r[2]; + oclMat disp_selected_pyr[2]; + oclMat data_cost; + oclMat data_cost_selected; + oclMat temp; + oclMat out; + }; + + // Implementation of the Zach, Pock and Bischof Dual TV-L1 Optical Flow method + // + // see reference: + // [1] C. Zach, T. Pock and H. Bischof, "A Duality Based Approach for Realtime TV-L1 Optical Flow". + // [2] Javier Sanchez, Enric Meinhardt-Llopis and Gabriele Facciolo. "TV-L1 Optical Flow Estimation". + class CV_EXPORTS OpticalFlowDual_TVL1_OCL + { + public: + OpticalFlowDual_TVL1_OCL(); + + void operator ()(const oclMat& I0, const oclMat& I1, oclMat& flowx, oclMat& flowy); + + void collectGarbage(); + + /** + * Time step of the numerical scheme. + */ + double tau; + + /** + * Weight parameter for the data term, attachment parameter. + * This is the most relevant parameter, which determines the smoothness of the output. + * The smaller this parameter is, the smoother the solutions we obtain. + * It depends on the range of motions of the images, so its value should be adapted to each image sequence. + */ + double lambda; + + /** + * Weight parameter for (u - v)^2, tightness parameter. + * It serves as a link between the attachment and the regularization terms. + * In theory, it should have a small value in order to maintain both parts in correspondence. + * The method is stable for a large range of values of this parameter. + */ + double theta; + + /** + * Number of scales used to create the pyramid of images. + */ + int nscales; + + /** + * Number of warpings per scale. + * Represents the number of times that I1(x+u0) and grad( I1(x+u0) ) are computed per scale. + * This is a parameter that assures the stability of the method. + * It also affects the running time, so it is a compromise between speed and accuracy. + */ + int warps; + + /** + * Stopping criterion threshold used in the numerical scheme, which is a trade-off between precision and running time. + * A small value will yield more accurate solutions at the expense of a slower convergence. + */ + double epsilon; + + /** + * Stopping criterion iterations number used in the numerical scheme. + */ + int iterations; + + bool useInitialFlow; + + private: + void procOneScale(const oclMat& I0, const oclMat& I1, oclMat& u1, oclMat& u2); + + std::vector I0s; + std::vector I1s; + std::vector u1s; + std::vector u2s; + + oclMat I1x_buf; + oclMat I1y_buf; + + oclMat I1w_buf; + oclMat I1wx_buf; + oclMat I1wy_buf; + + oclMat grad_buf; + oclMat rho_c_buf; + + oclMat p11_buf; + oclMat p12_buf; + oclMat p21_buf; + oclMat p22_buf; + + oclMat diff_buf; + oclMat norm_buf; + }; + // current supported sorting methods + enum + { + SORT_BITONIC, // only support power-of-2 buffer size + SORT_SELECTION, // cannot sort duplicate keys + SORT_MERGE, + SORT_RADIX // only support signed int/float keys(CV_32S/CV_32F) + }; + //! Returns the sorted result of all the elements in input based on equivalent keys. + // + // The element unit in the values to be sorted is determined from the data type, + // i.e., a CV_32FC2 input {a1a2, b1b2} will be considered as two elements, regardless its + // matrix dimension. + // both keys and values will be sorted inplace + // Key needs to be single channel oclMat. + // + // Example: + // input - + // keys = {2, 3, 1} (CV_8UC1) + // values = {10,5, 4,3, 6,2} (CV_8UC2) + // sortByKey(keys, values, SORT_SELECTION, false); + // output - + // keys = {1, 2, 3} (CV_8UC1) + // values = {6,2, 10,5, 4,3} (CV_8UC2) + void CV_EXPORTS sortByKey(oclMat& keys, oclMat& values, int method, bool isGreaterThan = false); + } +} +#if defined _MSC_VER && _MSC_VER >= 1200 +# pragma warning( push) +# pragma warning( disable: 4267) +#endif +#include "opencv2/ocl/matrix_operations.hpp" +#if defined _MSC_VER && _MSC_VER >= 1200 +# pragma warning( pop) +#endif + +#endif /* __OPENCV_OCL_HPP__ */ diff --cc modules/ocl/perf/main.cpp index bbc6716,0875903..65218a9 --- a/modules/ocl/perf/main.cpp +++ b/modules/ocl/perf/main.cpp @@@ -40,16 -40,8 +40,16 @@@ // //M*/ - #include "precomp.hpp" + #include "perf_precomp.hpp" +static int cvErrorCallback(int /*status*/, const char * /*func_name*/, + const char *err_msg, const char * /*file_name*/, + int /*line*/, void * /*userdata*/) +{ + TestSystem::instance().printError(err_msg); + return 0; +} + int main(int argc, const char *argv[]) { const char *keys = diff --cc modules/ocl/perf/perf_haar.cpp index 38e9d5e,26bed5e..f1a6e43 --- a/modules/ocl/perf/perf_haar.cpp +++ b/modules/ocl/perf/perf_haar.cpp @@@ -43,12 -43,49 +43,13 @@@ // the use of this software, even if advised of the possibility of such damage. // //M*/ - #include "precomp.hpp" + #include "perf_precomp.hpp" + ///////////// Haar //////////////////////// -namespace cv -{ -namespace ocl -{ - -struct getRect -{ - Rect operator()(const CvAvgComp &e) const - { - return e.rect; - } -}; - -class CascadeClassifier_GPU : public OclCascadeClassifier -{ -public: - void detectMultiScale(oclMat &image, - CV_OUT std::vector& faces, - double scaleFactor = 1.1, - int minNeighbors = 3, int flags = 0, - Size minSize = Size(), - Size maxSize = Size()) - { - (void)maxSize; - MemStorage storage(cvCreateMemStorage(0)); - //CvMat img=image; - CvSeq *objs = oclHaarDetectObjects(image, storage, scaleFactor, minNeighbors, flags, minSize); - vector vecAvgComp; - Seq(objs).copyTo(vecAvgComp); - faces.resize(vecAvgComp.size()); - std::transform(vecAvgComp.begin(), vecAvgComp.end(), faces.begin(), getRect()); - } - -}; -} -} PERFTEST(Haar) { - Mat img = imread(abspath("basketball1.png"), CV_LOAD_IMAGE_GRAYSCALE); + Mat img = imread(abspath("basketball1.png"), IMREAD_GRAYSCALE); if (img.empty()) { @@@ -101,6 -138,6 +102,6 @@@ GPU_FULL_ON; d_img.upload(img); faceCascade.detectMultiScale(d_img, oclfaces, - 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30)); + 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30)); GPU_FULL_OFF; --} ++} diff --cc modules/ocl/perf/perf_hough.cpp index 53c7b3b,0000000..61e8e48 mode 100644,000000..100644 --- a/modules/ocl/perf/perf_hough.cpp +++ b/modules/ocl/perf/perf_hough.cpp @@@ -1,98 -1,0 +1,98 @@@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved. +// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other oclMaterials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors as is and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + - #include "precomp.hpp" ++#include "perf_precomp.hpp" + +#ifdef HAVE_OPENCL + +using namespace cv; +using namespace perf; + +////////////////////////////////////////////////////////////////////// +// HoughCircles + +typedef std::tr1::tuple Size_Dp_MinDist_t; +typedef perf::TestBaseWithParam Size_Dp_MinDist; + +PERF_TEST_P(Size_Dp_MinDist, OCL_HoughCircles, + testing::Combine( + testing::Values(perf::sz720p, perf::szSXGA, perf::sz1080p), + testing::Values(1.0f, 2.0f, 4.0f), + testing::Values(1.0f, 10.0f))) +{ + const cv::Size size = std::tr1::get<0>(GetParam()); + const float dp = std::tr1::get<1>(GetParam()); + const float minDist = std::tr1::get<2>(GetParam()); + + const int minRadius = 10; + const int maxRadius = 30; + const int cannyThreshold = 100; + const int votesThreshold = 15; + + cv::RNG rng(123456789); + + cv::Mat src(size, CV_8UC1, cv::Scalar::all(0)); + + const int numCircles = rng.uniform(50, 100); + for (int i = 0; i < numCircles; ++i) + { + cv::Point center(rng.uniform(0, src.cols), rng.uniform(0, src.rows)); + const int radius = rng.uniform(minRadius, maxRadius + 1); + + cv::circle(src, center, radius, cv::Scalar::all(255), -1); + } + + cv::ocl::oclMat ocl_src(src); + cv::ocl::oclMat ocl_circles; + + declare.time(10.0).iterations(25); + + TEST_CYCLE() + { + cv::ocl::HoughCircles(ocl_src, ocl_circles, HOUGH_GRADIENT, dp, minDist, cannyThreshold, votesThreshold, minRadius, maxRadius); + } + + cv::Mat circles(ocl_circles); + SANITY_CHECK(circles); +} + +#endif // HAVE_OPENCL diff --cc modules/ocl/perf/perf_precomp.hpp index 385320b,2df1b2c..6d3f31c --- a/modules/ocl/perf/perf_precomp.hpp +++ b/modules/ocl/perf/perf_precomp.hpp @@@ -40,14 -40,9 +40,17 @@@ // //M*/ + #ifndef __OPENCV_PERF_PRECOMP_HPP__ + #define __OPENCV_PERF_PRECOMP_HPP__ + +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wmissing-declarations" +# if defined __clang__ || defined __APPLE__ +# pragma GCC diagnostic ignored "-Wmissing-prototypes" +# pragma GCC diagnostic ignored "-Wextra" +# endif +#endif + #include #include #include @@@ -489,29 -483,31 +492,31 @@@ struct name##_test: Runnable { #define SUBTEST TestSystem::instance().startNewSubtest() #define CPU_ON \ - while (!TestSystem::instance().cpu_stop()) { \ - TestSystem::instance().cpuOn() + while (!TestSystem::instance().cpu_stop()) { \ + TestSystem::instance().cpuOn() #define CPU_OFF \ - TestSystem::instance().cpuOff(); \ - } TestSystem::instance().cpuComplete() + TestSystem::instance().cpuOff(); \ + } TestSystem::instance().cpuComplete() #define GPU_ON \ - while (!TestSystem::instance().stop()) { \ - TestSystem::instance().gpuOn() + while (!TestSystem::instance().stop()) { \ + TestSystem::instance().gpuOn() #define GPU_OFF \ - ocl::finish();\ - TestSystem::instance().gpuOff(); \ - } TestSystem::instance().gpuComplete() + ocl::finish(); \ + TestSystem::instance().gpuOff(); \ + } TestSystem::instance().gpuComplete() #define GPU_FULL_ON \ - while (!TestSystem::instance().stop()) { \ - TestSystem::instance().gpufullOn() + while (!TestSystem::instance().stop()) { \ + TestSystem::instance().gpufullOn() #define GPU_FULL_OFF \ - TestSystem::instance().gpufullOff(); \ - } TestSystem::instance().gpufullComplete() + TestSystem::instance().gpufullOff(); \ + } TestSystem::instance().gpufullComplete() #define WARMUP_ON \ - while (!TestSystem::instance().warmupStop()) { + while (!TestSystem::instance().warmupStop()) { #define WARMUP_OFF \ - ocl::finish();\ - } TestSystem::instance().warmupComplete() + ocl::finish(); \ + } TestSystem::instance().warmupComplete() + + #endif diff --cc modules/ocl/src/color.cpp index d449547,493dbc3..13136e0 --- a/modules/ocl/src/color.cpp +++ b/modules/ocl/src/color.cpp @@@ -209,20 -209,20 +209,20 @@@ void cvtColor_caller(const oclMat &src Gray2RGB_caller(src, dst); break; } - case CV_BGR2YUV: - case CV_RGB2YUV: + case COLOR_BGR2YUV: + case COLOR_RGB2YUV: { CV_Assert(scn == 3 || scn == 4); - bidx = code == COLOR_BGR2YUV ? 0 : 2; - bidx = code == CV_RGB2YUV ? 0 : 2; ++ bidx = code == COLOR_RGB2YUV ? 0 : 2; dst.create(sz, CV_MAKETYPE(depth, 3)); RGB2YUV_caller(src, dst, bidx); break; } - case CV_YUV2BGR: - case CV_YUV2RGB: + case COLOR_YUV2BGR: + case COLOR_YUV2RGB: { CV_Assert(scn == 3 || scn == 4); - bidx = code == COLOR_YUV2BGR ? 0 : 2; - bidx = code == CV_YUV2RGB ? 0 : 2; ++ bidx = code == COLOR_YUV2RGB ? 0 : 2; dst.create(sz, CV_MAKETYPE(depth, 3)); YUV2RGB_caller(src, dst, bidx); break; diff --cc modules/ocl/src/filtering.cpp index 7911370,6e858d1..7138542 --- a/modules/ocl/src/filtering.cpp +++ b/modules/ocl/src/filtering.cpp @@@ -598,14 -598,15 +598,15 @@@ static void GPUFilter2D(const oclMat &s CV_Assert((src.cols == dst.cols) && (src.rows == dst.rows)); CV_Assert((src.oclchannels() == dst.oclchannels())); - CV_Assert((borderType != 0)); CV_Assert(ksize.height > 0 && ksize.width > 0 && ((ksize.height & 1) == 1) && ((ksize.width & 1) == 1)); CV_Assert((anchor.x == -1 && anchor.y == -1) || (anchor.x == ksize.width >> 1 && anchor.y == ksize.height >> 1)); + CV_Assert(ksize.width == ksize.height); Context *clCxt = src.clCxt; - int cn = src.oclchannels(); - int depth = src.depth(); - String kernelName = "filter2D"; + int filterWidth = ksize.width; + bool ksize_3x3 = filterWidth == 3 && src.type() != CV_32FC4; // CV_32FC4 is not tuned up with filter2d_3x3 kernel + - string kernelName = ksize_3x3 ? "filter2D_3x3" : "filter2D"; ++ String kernelName = ksize_3x3 ? "filter2D_3x3" : "filter2D"; size_t src_offset_x = (src.offset % src.step) / src.elemSize(); size_t src_offset_y = src.offset / src.step; @@@ -613,46 -614,72 +614,72 @@@ size_t dst_offset_x = (dst.offset % dst.step) / dst.elemSize(); size_t dst_offset_y = dst.offset / dst.step; - int vector_lengths[4][7] = {{4, 4, 4, 4, 4, 4, 4}, - {4, 4, 1, 1, 1, 1, 1}, - {1, 1, 1, 1, 1, 1, 1}, - {4, 4, 4, 4, 1, 1, 4} - }; + int paddingPixels = filterWidth & (-2); - int vector_length = vector_lengths[cn - 1][depth]; - int offset_cols = (dst_offset_x) & (vector_length - 1); - int cols = dst.cols + offset_cols; - int rows = divUp(dst.rows, vector_length); + size_t localThreads[3] = {ksize_3x3 ? 256 : 16, ksize_3x3 ? 1 : 16, 1}; + size_t globalThreads[3] = {src.wholecols, src.wholerows, 1}; - size_t localThreads[3] = {256, 1, 1}; - size_t globalThreads[3] = { divUp(cols, localThreads[0]) *localThreads[0], - divUp(rows, localThreads[1]) *localThreads[1], 1 - }; + int cn = src.oclchannels(); + int src_step = (int)(src.step/src.elemSize()); + int dst_step = (int)(dst.step/src.elemSize()); - ++ + int localWidth = localThreads[0] + paddingPixels; + int localHeight = localThreads[1] + paddingPixels; + + // 260 = divup((localThreads[0] + filterWidth * 2), 4) * 4 + // 6 = (ROWS_PER_GROUP_WHICH_IS_4 + filterWidth * 2) + size_t localMemSize = ksize_3x3 ? 260 * 6 * src.elemSize() : (localWidth * localHeight) * src.elemSize(); + + int vector_lengths[4][7] = {{4, 4, 4, 4, 4, 4, 4}, + {4, 4, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 1}, + {4, 4, 4, 4, 1, 1, 4} + }; + int cols = dst.cols + ((dst_offset_x) & (vector_lengths[cn - 1][src.depth()] - 1)); - vector< pair > args; - args.push_back(make_pair(sizeof(cl_mem), (void *)&src.data)); - args.push_back(make_pair(sizeof(cl_mem), (void *)&dst.data)); - args.push_back(make_pair(sizeof(cl_int), (void *)&src_step)); - args.push_back(make_pair(sizeof(cl_int), (void *)&dst_step)); - args.push_back(make_pair(sizeof(cl_mem), (void *)&mat_kernel.data)); - args.push_back(make_pair(localMemSize, (void *)NULL)); - args.push_back(make_pair(sizeof(cl_int), (void *)&src.wholerows)); - args.push_back(make_pair(sizeof(cl_int), (void *)&src.wholecols)); - args.push_back(make_pair(sizeof(cl_int), (void *)&src_offset_x)); - args.push_back(make_pair(sizeof(cl_int), (void *)&src_offset_y)); - args.push_back(make_pair(sizeof(cl_int), (void *)&dst_offset_x)); - args.push_back(make_pair(sizeof(cl_int), (void *)&dst_offset_y)); - args.push_back(make_pair(sizeof(cl_int), (void *)&src.cols)); - args.push_back(make_pair(sizeof(cl_int), (void *)&src.rows)); - args.push_back(make_pair(sizeof(cl_int), (void *)&cols)); + std::vector< std::pair > args; + args.push_back(std::make_pair(sizeof(cl_mem), (void *)&src.data)); - args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.step)); ++ args.push_back(std::make_pair(sizeof(cl_mem), (void *)&dst.data)); ++ args.push_back(std::make_pair(sizeof(cl_int), (void *)&src_step)); ++ args.push_back(std::make_pair(sizeof(cl_int), (void *)&dst_step)); ++ args.push_back(std::make_pair(sizeof(cl_mem), (void *)&mat_kernel.data)); ++ args.push_back(std::make_pair(localMemSize, (void *)NULL)); ++ args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.wholerows)); ++ args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.wholecols)); + args.push_back(std::make_pair(sizeof(cl_int), (void *)&src_offset_x)); + args.push_back(std::make_pair(sizeof(cl_int), (void *)&src_offset_y)); - args.push_back(std::make_pair(sizeof(cl_mem), (void *)&dst.data)); - args.push_back(std::make_pair(sizeof(cl_int), (void *)&dst.step)); + args.push_back(std::make_pair(sizeof(cl_int), (void *)&dst_offset_x)); + args.push_back(std::make_pair(sizeof(cl_int), (void *)&dst_offset_y)); - args.push_back(std::make_pair(sizeof(cl_mem), (void *)&mat_kernel.data)); + args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.cols)); + args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.rows)); + args.push_back(std::make_pair(sizeof(cl_int), (void *)&cols)); - args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.wholecols)); - args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.wholerows)); - - const int buffer_size = 100; - char opt_buffer [buffer_size] = ""; - sprintf(opt_buffer, "-DANCHOR=%d -DANX=%d -DANY=%d", ksize.width, anchor.x, anchor.y); - - openCLExecuteKernel(clCxt, &filtering_laplacian, kernelName, globalThreads, localThreads, args, cn, depth, opt_buffer); + char btype[30]; + switch (borderType) + { + case 0: + sprintf(btype, "BORDER_CONSTANT"); + break; + case 1: + sprintf(btype, "BORDER_REPLICATE"); + break; + case 2: + sprintf(btype, "BORDER_REFLECT"); + break; + case 3: + CV_Error(CV_StsUnsupportedFormat, "BORDER_WRAP is not supported!"); + return; + case 4: + sprintf(btype, "BORDER_REFLECT_101"); + break; + } + int type = src.depth(); + char build_options[150]; + sprintf(build_options, "-D %s -D IMG_C_%d_%d -D CN=%d -D FILTER_SIZE=%d", btype, cn, type, cn, ksize.width); + openCLExecuteKernel(clCxt, &filtering_laplacian, kernelName, globalThreads, localThreads, args, -1, -1, build_options); } + Ptr cv::ocl::getLinearFilter_GPU(int srcType, int dstType, const Mat &kernel, const Size &ksize, - Point anchor, int borderType) + const Point &anchor, int borderType) { static const GPUFilter2D_t GPUFilter2D_callers[] = {0, GPUFilter2D, 0, GPUFilter2D, GPUFilter2D}; diff --cc modules/ocl/test/test_color.cpp index efc96de,a0293fc..b0a2230 --- a/modules/ocl/test/test_color.cpp +++ b/modules/ocl/test/test_color.cpp @@@ -43,10 -43,7 +43,10 @@@ // //M*/ - #include "precomp.hpp" + #include "test_precomp.hpp" + +using namespace cv; + #ifdef HAVE_OPENCL //#define MAT_DEBUG diff --cc modules/ocl/test/test_hough.cpp index 365e0da,0000000..9e45076 mode 100644,000000..100644 --- a/modules/ocl/test/test_hough.cpp +++ b/modules/ocl/test/test_hough.cpp @@@ -1,112 -1,0 +1,112 @@@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + - #include "precomp.hpp" ++#include "test_precomp.hpp" + +#ifdef HAVE_OPENCL + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// HoughCircles + +PARAM_TEST_CASE(HoughCircles, cv::Size) +{ + static void drawCircles(cv::Mat& dst, const std::vector& circles, bool fill) + { + dst.setTo(cv::Scalar::all(0)); + + for (size_t i = 0; i < circles.size(); ++i) + cv::circle(dst, cv::Point2f(circles[i][0], circles[i][1]), (int)circles[i][2], cv::Scalar::all(255), fill ? -1 : 1); + } +}; + +TEST_P(HoughCircles, Accuracy) +{ + const cv::Size size = GET_PARAM(0); + + const float dp = 2.0f; + const float minDist = 10.0f; + const int minRadius = 10; + const int maxRadius = 20; + const int cannyThreshold = 100; + const int votesThreshold = 15; + + std::vector circles_gold(4); + circles_gold[0] = cv::Vec3i(20, 20, minRadius); + circles_gold[1] = cv::Vec3i(90, 87, minRadius + 3); + circles_gold[2] = cv::Vec3i(30, 70, minRadius + 8); + circles_gold[3] = cv::Vec3i(80, 10, maxRadius); + + cv::Mat src(size, CV_8UC1); + drawCircles(src, circles_gold, true); + cv::ocl::oclMat d_src(src); + + cv::ocl::oclMat d_circles; + cv::ocl::HoughCircles(d_src, d_circles, cv::HOUGH_GRADIENT, dp, minDist, cannyThreshold, votesThreshold, minRadius, maxRadius); + ASSERT_TRUE(d_circles.rows > 0); + + cv::Mat circles; + d_circles.download(circles); + + for (int i = 0; i < circles.cols; ++i) + { + cv::Vec3f cur = circles.at(i); + + bool found = false; + + for (size_t j = 0; j < circles_gold.size(); ++j) + { + cv::Vec3f gold = circles_gold[j]; + + if (std::fabs(cur[0] - gold[0]) < minDist && std::fabs(cur[1] - gold[1]) < minDist && std::fabs(cur[2] - gold[2]) < minDist) + { + found = true; + break; + } + } + + ASSERT_TRUE(found); + } +} + +INSTANTIATE_TEST_CASE_P(Hough, HoughCircles, DIFFERENT_SIZES); + +#endif // HAVE_OPENCL diff --cc modules/ocl/test/test_moments.cpp index c2aefde,65034ac..9f42327 --- a/modules/ocl/test/test_moments.cpp +++ b/modules/ocl/test/test_moments.cpp @@@ -1,5 -1,6 +1,5 @@@ - #include "precomp.hpp" + #include "test_precomp.hpp" #include -#include "opencv2/imgproc/imgproc_c.h" #ifdef HAVE_OPENCL diff --cc modules/ocl/test/test_objdetect.cpp index d9c9a84,d75d991..5a47d72 --- a/modules/ocl/test/test_objdetect.cpp +++ b/modules/ocl/test/test_objdetect.cpp @@@ -43,13 -43,12 +43,13 @@@ // //M*/ - #include "precomp.hpp" + #include "test_precomp.hpp" -#include "opencv2/core/core.hpp" -#include "opencv2/objdetect/objdetect.hpp" +#include "opencv2/objdetect.hpp" +using namespace std; using namespace cv; using namespace testing; + #ifdef HAVE_OPENCL extern string workdir; diff --cc modules/python/src2/cv2.cpp index 2de187c,745914c..e94da95 --- a/modules/python/src2/cv2.cpp +++ b/modules/python/src2/cv2.cpp @@@ -126,16 -124,7 +126,17 @@@ typedef Ptr Ptr_Featur typedef Ptr Ptr_DescriptorExtractor; typedef Ptr Ptr_Feature2D; typedef Ptr Ptr_DescriptorMatcher; -typedef Ptr Ptr_CLAHE; +typedef Ptr Ptr_BackgroundSubtractor; +typedef Ptr Ptr_BackgroundSubtractorMOG; +typedef Ptr Ptr_BackgroundSubtractorMOG2; +typedef Ptr Ptr_BackgroundSubtractorGMG; + +typedef Ptr Ptr_StereoMatcher; +typedef Ptr Ptr_StereoBM; +typedef Ptr Ptr_StereoSGBM; + +typedef Ptr Ptr_ChannelFeatureBuilder; ++typedef Ptr Ptr_CLAHE; typedef SimpleBlobDetector::Params SimpleBlobDetector_Params; diff --cc modules/video/src/simpleflow.cpp index f987b42,7a32245..6aa8f7d --- a/modules/video/src/simpleflow.cpp +++ b/modules/video/src/simpleflow.cpp @@@ -319,13 -287,13 +319,13 @@@ static Mat upscaleOpticalFlow(int new_r static Mat calcIrregularityMat(const Mat& flow, int radius) { const int rows = flow.rows; const int cols = flow.cols; - Mat irregularity(rows, cols, CV_32F); + Mat irregularity = Mat::zeros(rows, cols, CV_32F); for (int r = 0; r < rows; ++r) { - const int start_row = max(0, r - radius); - const int end_row = min(rows - 1, r + radius); + const int start_row = std::max(0, r - radius); + const int end_row = std::min(rows - 1, r + radius); for (int c = 0; c < cols; ++c) { - const int start_col = max(0, c - radius); - const int end_col = min(cols - 1, c + radius); + const int start_col = std::max(0, c - radius); + const int end_col = std::min(cols - 1, c + radius); for (int dr = start_row; dr <= end_row; ++dr) { for (int dc = start_col; dc <= end_col; ++dc) { const float diff = dist(flow.at(r, c), flow.at(dr, dc)); diff --cc samples/gpu/CMakeLists.txt index a14c590,80889fb..b85c760 --- a/samples/gpu/CMakeLists.txt +++ b/samples/gpu/CMakeLists.txt @@@ -1,11 -1,7 +1,10 @@@ SET(OPENCV_GPU_SAMPLES_REQUIRED_DEPS opencv_core opencv_flann opencv_imgproc opencv_highgui opencv_ml opencv_video opencv_objdetect opencv_features2d opencv_calib3d opencv_legacy opencv_contrib opencv_gpu - opencv_superres) + opencv_nonfree opencv_softcascade opencv_superres + opencv_gpuarithm opencv_gpufilters opencv_gpuwarping opencv_gpuimgproc + opencv_gpufeatures2d opencv_gpuoptflow opencv_gpubgsegm + opencv_gpustereo opencv_gpulegacy) - ocv_check_dependencies(${OPENCV_GPU_SAMPLES_REQUIRED_DEPS}) if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) @@@ -32,6 -24,10 +31,10 @@@ ocv_include_directories(${CUDA_INCLUDE_DIRS}) endif() + if(HAVE_OPENCL) + ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/ocl/include") + endif() - ++ if(CMAKE_COMPILER_IS_GNUCXX AND NOT ENABLE_NOISY_WARNINGS) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function") endif() @@@ -47,10 -43,11 +50,14 @@@ if(HAVE_opencv_nonfree) target_link_libraries(${the_target} opencv_nonfree) endif() + if(HAVE_opencv_gpucodec) + target_link_libraries(${the_target} opencv_gpucodec) + endif() + if(HAVE_OPENCL) + target_link_libraries(${the_target} opencv_ocl) + endif() - ++ set_target_properties(${the_target} PROPERTIES OUTPUT_NAME "${project}-example-${name}" PROJECT_LABEL "(EXAMPLE_${project_upper}) ${name}") @@@ -84,4 -81,4 +91,3 @@@ if (INSTALL_C_EXAMPLES AND NOT WIN32 DESTINATION share/OpenCV/samples/${project} PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) endif() -- diff --cc samples/gpu/super_resolution.cpp index 4f3b4e2,d62b42a..5b6d6f1 --- a/samples/gpu/super_resolution.cpp +++ b/samples/gpu/super_resolution.cpp @@@ -1,13 -1,17 +1,18 @@@ #include #include #include -#include "opencv2/core/core.hpp" -#include "opencv2/highgui/highgui.hpp" -#include "opencv2/imgproc/imgproc.hpp" -#include "opencv2/contrib/contrib.hpp" -#include "opencv2/superres/superres.hpp" +#include "opencv2/core.hpp" +#include "opencv2/core/utility.hpp" +#include "opencv2/highgui.hpp" +#include "opencv2/imgproc.hpp" +#include "opencv2/contrib.hpp" +#include "opencv2/superres.hpp" #include "opencv2/superres/optical_flow.hpp" + #include "opencv2/opencv_modules.hpp" + + #if defined(HAVE_OPENCV_OCL) + #include "opencv2/ocl/ocl.hpp" + #endif using namespace std; using namespace cv; @@@ -47,21 -51,50 +52,50 @@@ static Ptr createO else { cerr << "Incorrect Optical Flow algorithm - " << name << endl; - exit(-1); } + return 0; } - + #if defined(HAVE_OPENCV_OCL) + static Ptr createOptFlow(const string& name) + { + if (name == "farneback") + { + return createOptFlow_Farneback_OCL(); + } + else if (name == "simple") + { + useOclChanged = true; + std::cout<<"simple on OpenCL has not been implemented. Use CPU instead!\n"; + return createOptFlow_Simple(); + } + else if (name == "tvl1") + return createOptFlow_DualTVL1_OCL(); + else if (name == "brox") + { + std::cout<<"brox has not been implemented!\n"; + return NULL; + } + else if (name == "pyrlk") + return createOptFlow_PyrLK_OCL(); + else + { + cerr << "Incorrect Optical Flow algorithm - " << name << endl; + } + return 0; + } + #endif int main(int argc, const char* argv[]) { + useOclChanged = false; CommandLineParser cmd(argc, argv, - "{ v | video | | Input video }" - "{ o | output | | Output video }" - "{ s | scale | 4 | Scale factor }" - "{ i | iterations | 180 | Iteration count }" - "{ t | temporal | 4 | Radius of the temporal search area }" - "{ f | flow | farneback | Optical flow algorithm (farneback, simple, tvl1, brox, pyrlk) }" - "{ g | gpu | | CPU as default device, cuda for CUDA and ocl for OpenCL }" - "{ h | help | false | Print help message }" + "{ v video | | Input video }" + "{ o output | | Output video }" + "{ s scale | 4 | Scale factor }" + "{ i iterations | 180 | Iteration count }" + "{ t temporal | 4 | Radius of the temporal search area }" + "{ f flow | farneback | Optical flow algorithm (farneback, simple, tvl1, brox, pyrlk) }" - "{ gpu | false | Use GPU }" ++ "{ g | false | CPU as default device, cuda for CUDA and ocl for OpenCL }" + "{ h help | false | Print help message }" ); if (cmd.get("help")) @@@ -77,13 -110,72 +111,72 @@@ const int iterations = cmd.get("iterations"); const int temporalAreaRadius = cmd.get("temporal"); const string optFlow = cmd.get("flow"); - const bool useGpu = cmd.get("gpu"); + string gpuOption = cmd.get("gpu"); + + std::transform(gpuOption.begin(), gpuOption.end(), gpuOption.begin(), ::tolower); + + bool useCuda = false; + bool useOcl = false; + + if(gpuOption.compare("ocl") == 0) + useOcl = true; + else if(gpuOption.compare("cuda") == 0) + useCuda = true; + #ifndef HAVE_OPENCV_OCL + if(useOcl) + { + { + cout<<"OPENCL is not compiled\n"; + return 0; + } + } + #endif + #if defined(HAVE_OPENCV_OCL) + std::vectorinfo; + if(useCuda) + { + CV_Assert(!useOcl); + info.clear(); + } - ++ + if(useOcl) + { + CV_Assert(!useCuda); + cv::ocl::getDevice(info); + } + #endif Ptr superRes; - if (useGpu) - superRes = createSuperResolution_BTVL1_GPU(); + + + #if defined(HAVE_OPENCV_OCL) + if(useOcl) + { + Ptr of = createOptFlow(optFlow); + if (of.empty()) + exit(-1); + if(useOclChanged) + { + superRes = createSuperResolution_BTVL1(); + useOcl = !useOcl; + }else + superRes = createSuperResolution_BTVL1_OCL(); + superRes->set("opticalFlow", of); + } else - superRes = createSuperResolution_BTVL1(); + #endif + { + if (useCuda) + superRes = createSuperResolution_BTVL1_GPU(); + else + superRes = createSuperResolution_BTVL1(); + + Ptr of = createOptFlow(optFlow, useCuda); - ++ + if (of.empty()) + exit(-1); + superRes->set("opticalFlow", of); + } superRes->set("scale", scale); superRes->set("iterations", iterations);