diff --git a/3rdparty/ffmpeg/ffopencv.c b/3rdparty/ffmpeg/ffopencv.c index 82ac060375..b412e90071 100644 --- a/3rdparty/ffmpeg/ffopencv.c +++ b/3rdparty/ffmpeg/ffopencv.c @@ -1 +1 @@ -#include "cap_ffmpeg_impl_v2.hpp" +#include "cap_ffmpeg_impl.hpp" diff --git a/3rdparty/lib/armeabi-v7a/libnative_camera_r2.2.0.so b/3rdparty/lib/armeabi-v7a/libnative_camera_r2.2.0.so index 34ec871ce8..e6d04049f4 100755 Binary files a/3rdparty/lib/armeabi-v7a/libnative_camera_r2.2.0.so and b/3rdparty/lib/armeabi-v7a/libnative_camera_r2.2.0.so differ diff --git a/3rdparty/lib/armeabi-v7a/libnative_camera_r2.3.3.so b/3rdparty/lib/armeabi-v7a/libnative_camera_r2.3.3.so index a2e8fc0f1d..99a1e6fd43 100644 Binary files a/3rdparty/lib/armeabi-v7a/libnative_camera_r2.3.3.so and b/3rdparty/lib/armeabi-v7a/libnative_camera_r2.3.3.so differ diff --git a/3rdparty/lib/armeabi-v7a/libnative_camera_r3.0.1.so b/3rdparty/lib/armeabi-v7a/libnative_camera_r3.0.1.so index f2d17920e4..7af4ebb09e 100755 Binary files a/3rdparty/lib/armeabi-v7a/libnative_camera_r3.0.1.so and b/3rdparty/lib/armeabi-v7a/libnative_camera_r3.0.1.so differ diff --git a/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.0.so b/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.0.so index b4d746f703..940f853ac4 100755 Binary files a/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.0.so and b/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.0.so differ diff --git a/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.3.so b/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.3.so index bd34dcfb91..33413102b8 100755 Binary files a/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.3.so and b/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.3.so differ diff --git a/3rdparty/lib/armeabi/libnative_camera_r2.2.0.so b/3rdparty/lib/armeabi/libnative_camera_r2.2.0.so index b74dd5fb31..d98ef2f60f 100755 Binary files a/3rdparty/lib/armeabi/libnative_camera_r2.2.0.so and b/3rdparty/lib/armeabi/libnative_camera_r2.2.0.so differ diff --git a/3rdparty/lib/armeabi/libnative_camera_r2.3.3.so b/3rdparty/lib/armeabi/libnative_camera_r2.3.3.so index 05f51c31bc..3e1059a3d3 100755 Binary files a/3rdparty/lib/armeabi/libnative_camera_r2.3.3.so and b/3rdparty/lib/armeabi/libnative_camera_r2.3.3.so differ diff --git a/3rdparty/lib/armeabi/libnative_camera_r3.0.1.so b/3rdparty/lib/armeabi/libnative_camera_r3.0.1.so index 2c0d05441b..2eb3b64207 100755 Binary files a/3rdparty/lib/armeabi/libnative_camera_r3.0.1.so and b/3rdparty/lib/armeabi/libnative_camera_r3.0.1.so differ diff --git a/3rdparty/lib/armeabi/libnative_camera_r4.0.0.so b/3rdparty/lib/armeabi/libnative_camera_r4.0.0.so index b0c7e8fd7f..01dfcace67 100755 Binary files a/3rdparty/lib/armeabi/libnative_camera_r4.0.0.so and b/3rdparty/lib/armeabi/libnative_camera_r4.0.0.so differ diff --git a/3rdparty/lib/armeabi/libnative_camera_r4.0.3.so b/3rdparty/lib/armeabi/libnative_camera_r4.0.3.so index b3d327225b..8ad64ba41d 100755 Binary files a/3rdparty/lib/armeabi/libnative_camera_r4.0.3.so and b/3rdparty/lib/armeabi/libnative_camera_r4.0.3.so differ diff --git a/3rdparty/lib/x86/libnative_camera_r2.3.3.so b/3rdparty/lib/x86/libnative_camera_r2.3.3.so index ce7d4b37a0..0756424bab 100755 Binary files a/3rdparty/lib/x86/libnative_camera_r2.3.3.so and b/3rdparty/lib/x86/libnative_camera_r2.3.3.so differ diff --git a/3rdparty/lib/x86/libnative_camera_r3.0.1.so b/3rdparty/lib/x86/libnative_camera_r3.0.1.so index 4f2d43916b..3cfab8f8ab 100755 Binary files a/3rdparty/lib/x86/libnative_camera_r3.0.1.so and b/3rdparty/lib/x86/libnative_camera_r3.0.1.so differ diff --git a/3rdparty/lib/x86/libnative_camera_r4.0.3.so b/3rdparty/lib/x86/libnative_camera_r4.0.3.so index 28e0f8fd13..ce81f75101 100755 Binary files a/3rdparty/lib/x86/libnative_camera_r4.0.3.so and b/3rdparty/lib/x86/libnative_camera_r4.0.3.so differ diff --git a/doc/conf.py b/doc/conf.py index a0932df32d..448c5a6fcd 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -56,7 +56,7 @@ version_patch = re.search("^W*#\W*define\W+CV_SUBMINOR_VERSION\W+(\d+)\W*$", ver # The short X.Y version. version = version_major + '.' + version_minor # The full version, including alpha/beta/rc tags. -release = version_major + '.' + version_minor + '.' + version_patch + "-beta" +release = version_major + '.' + version_minor + '.' + version_patch # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/modules/androidcamera/camera_wrapper/camera_wrapper.cpp b/modules/androidcamera/camera_wrapper/camera_wrapper.cpp index d986a61775..e899a0f54d 100644 --- a/modules/androidcamera/camera_wrapper/camera_wrapper.cpp +++ b/modules/androidcamera/camera_wrapper/camera_wrapper.cpp @@ -49,6 +49,8 @@ #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, CAMERA_LOG_TAG, __VA_ARGS__)) #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, CAMERA_LOG_TAG, __VA_ARGS__)) +#include + using namespace android; void debugShowFPS() @@ -200,18 +202,25 @@ protected: return strstr(supported_modes, mode) > 0; } - float getFocusDistance(int focus_distance_type){ - if (focus_distance_type >= 0 && focus_distance_type < 3) { + float getFocusDistance(int focus_distance_type) + { +#if !defined(ANDROID_r2_2_0) + if (focus_distance_type >= 0 && focus_distance_type < 3) + { float focus_distances[3]; const char* output = params.get(CameraParameters::KEY_FOCUS_DISTANCES); int val_num = CameraHandler::split_float(output, focus_distances, ',', 3); - if(val_num == 3){ + if(val_num == 3) + { return focus_distances[focus_distance_type]; - } else { + } + else + { LOGE("Invalid focus distances."); } } - return -1; +#endif + return -1; } static int getModeNum(const char** modes, const int modes_num, const char* mode_name) @@ -299,7 +308,9 @@ const char* CameraHandler::flashModesNames[ANDROID_CAMERA_FLASH_MODES_NUM] = const char* CameraHandler::focusModesNames[ANDROID_CAMERA_FOCUS_MODES_NUM] = { CameraParameters::FOCUS_MODE_AUTO, +#if !defined(ANDROID_r2_2_0) CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO, +#endif CameraParameters::FOCUS_MODE_EDOF, CameraParameters::FOCUS_MODE_FIXED, CameraParameters::FOCUS_MODE_INFINITY @@ -326,17 +337,61 @@ const char* CameraHandler::antibandingModesNames[ANDROID_CAMERA_ANTIBANDING_MODE CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback, int cameraId, void* userData, CameraParameters* prevCameraParameters) { - LOGD("CameraHandler::initCameraConnect(%p, %d, %p, %p)", callback, cameraId, userData, prevCameraParameters); + typedef sp (*Android22ConnectFuncType)(); + typedef sp (*Android23ConnectFuncType)(int); + typedef sp (*Android3DConnectFuncType)(int, int); + + enum { + CAMERA_SUPPORT_MODE_2D = 0x01, /* Camera Sensor supports 2D mode. */ + CAMERA_SUPPORT_MODE_3D = 0x02, /* Camera Sensor supports 3D mode. */ + CAMERA_SUPPORT_MODE_NONZSL = 0x04, /* Camera Sensor in NON-ZSL mode. */ + CAMERA_SUPPORT_MODE_ZSL = 0x08 /* Camera Sensor supports ZSL mode. */ + }; + + const char Android22ConnectName[] = "_ZN7android6Camera7connectEv"; + const char Android23ConnectName[] = "_ZN7android6Camera7connectEi"; + const char Android3DConnectName[] = "_ZN7android6Camera7connectEii"; + + LOGD("CameraHandler::initCameraConnect(%p, %d, %p, %p)", callback, cameraId, userData, prevCameraParameters); + sp camera = 0; + + void* CameraHALHandle = dlopen("libcamera_client.so", RTLD_LAZY); + + if (!CameraHALHandle) + { + LOGE("Cannot link to \"libcamera_client.so\""); + return NULL; + } + + // reset errors + dlerror(); -#ifdef ANDROID_r2_2_0 - camera = Camera::connect(); -#else - /* This is 2.3 or higher. The connect method has cameraID parameter */ - camera = Camera::connect(cameraId); -#endif - + if (Android22ConnectFuncType Android22Connect = (Android22ConnectFuncType)dlsym(CameraHALHandle, Android22ConnectName)) + { + LOGD("Connecting to CameraService v 2.2"); + camera = Android22Connect(); + } + else if (Android23ConnectFuncType Android23Connect = (Android23ConnectFuncType)dlsym(CameraHALHandle, Android23ConnectName)) + { + LOGD("Connecting to CameraService v 2.3"); + camera = Android23Connect(cameraId); + } + else if (Android3DConnectFuncType Android3DConnect = (Android3DConnectFuncType)dlsym(CameraHALHandle, Android3DConnectName)) + { + LOGD("Connecting to CameraService v 3D"); + camera = Android3DConnect(cameraId, CAMERA_SUPPORT_MODE_2D); + } + else + { + dlclose(CameraHALHandle); + LOGE("Cannot connect to CameraService. Connect method was not found!"); + return NULL; + } + + dlclose(CameraHALHandle); + if ( 0 == camera.get() ) { LOGE("initCameraConnect: Unable to connect to CameraService\n"); diff --git a/modules/calib3d/test/test_chesscorners_timing.cpp b/modules/calib3d/test/test_chesscorners_timing.cpp index cc7625793b..1fd9e4a30d 100644 --- a/modules/calib3d/test/test_chesscorners_timing.cpp +++ b/modules/calib3d/test/test_chesscorners_timing.cpp @@ -75,7 +75,6 @@ void CV_ChessboardDetectorTimingTest::run( int start_from ) sprintf( filepath, "%scameracalibration/", ts->get_data_path().c_str() ); sprintf( filename, "%schessboard_timing_list.dat", filepath ); - printf("Reading file %s\n", filename); CvFileStorage* fs = cvOpenFileStorage( filename, 0, CV_STORAGE_READ ); CvFileNode* board_list = fs ? cvGetFileNodeByName( fs, 0, "boards" ) : 0; diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index 3f321b6d92..de9c846894 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -16,13 +16,7 @@ else() set(cuda_link_libs "") endif() -set(OPENCV_VERSION_FILE "${opencv_core_BINARY_DIR}/version_string.inc") -add_custom_command(OUTPUT "${OPENCV_VERSION_FILE}" - COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OPENCV_BUILD_INFO_FILE}" "${OPENCV_VERSION_FILE}" - MAIN_DEPENDENCY "${OPENCV_BUILD_INFO_FILE}" - COMMENT "") - -ocv_glob_module_sources(SOURCES ${lib_cuda} ${cuda_objs} "${OPENCV_VERSION_FILE}") +ocv_glob_module_sources(SOURCES ${lib_cuda} ${cuda_objs} "${opencv_core_BINARY_DIR}/version_string.inc") ocv_create_module(${cuda_link_libs}) ocv_add_precompiled_headers(${the_module}) diff --git a/modules/core/include/opencv2/core/devmem2d.hpp b/modules/core/include/opencv2/core/devmem2d.hpp index 1afb645a4a..276aeb2331 100644 --- a/modules/core/include/opencv2/core/devmem2d.hpp +++ b/modules/core/include/opencv2/core/devmem2d.hpp @@ -1,161 +1,161 @@ -/*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 GpuMaterials 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_DevMem2D_HPP__ -#define __OPENCV_CORE_DevMem2D_HPP__ - -#ifdef __cplusplus - -#ifdef __CUDACC__ - #define __CV_GPU_HOST_DEVICE__ __host__ __device__ __forceinline__ -#else - #define __CV_GPU_HOST_DEVICE__ -#endif - -namespace cv -{ - namespace gpu - { - // Simple lightweight structures that encapsulates information about an image on device. - // It is intended to pass to nvcc-compiled code. GpuMat depends on headers that nvcc can't compile - - template struct StaticAssert; - template <> struct StaticAssert {static __CV_GPU_HOST_DEVICE__ void check(){}}; - - template struct DevPtr - { - typedef T elem_type; - typedef int index_type; - - enum { elem_size = sizeof(elem_type) }; - - T* data; - - __CV_GPU_HOST_DEVICE__ DevPtr() : data(0) {} - __CV_GPU_HOST_DEVICE__ DevPtr(T* data_) : data(data_) {} - - __CV_GPU_HOST_DEVICE__ size_t elemSize() const { return elem_size; } - __CV_GPU_HOST_DEVICE__ operator T*() { return data; } - __CV_GPU_HOST_DEVICE__ operator const T*() const { return data; } - }; - - template struct PtrSz : public DevPtr - { - __CV_GPU_HOST_DEVICE__ PtrSz() : size(0) {} - __CV_GPU_HOST_DEVICE__ PtrSz(T* data_, size_t size_) : DevPtr(data_), size(size_) {} - - size_t size; - }; - - template struct PtrStep : public DevPtr - { - __CV_GPU_HOST_DEVICE__ PtrStep() : step(0) {} - __CV_GPU_HOST_DEVICE__ PtrStep(T* data_, size_t step_) : DevPtr(data_), step(step_) {} - - /** \brief stride between two consecutive rows in bytes. Step is stored always and everywhere in bytes!!! */ - size_t step; - - __CV_GPU_HOST_DEVICE__ T* ptr(int y = 0) { return ( T*)( ( char*)DevPtr::data + y * step); } - __CV_GPU_HOST_DEVICE__ const T* ptr(int y = 0) const { return (const T*)( (const char*)DevPtr::data + y * step); } - - __CV_GPU_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; } - __CV_GPU_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; } - }; - - template struct PtrStepSz : public PtrStep - { - __CV_GPU_HOST_DEVICE__ PtrStepSz() : cols(0), rows(0) {} - __CV_GPU_HOST_DEVICE__ PtrStepSz(int rows_, int cols_, T* data_, size_t step_) - : PtrStep(data_, step_), cols(cols_), rows(rows_) {} - - int cols; - int rows; - }; - - template struct DevMem2D_ : public PtrStepSz - { - DevMem2D_() {} - DevMem2D_(int rows_, int cols_, T* data_, size_t step_) : PtrStepSz(rows_, cols_, data_, step_) {} - - template - explicit DevMem2D_(const DevMem2D_& d) : PtrStepSz(d.rows, d.cols, (T*)d.data, d.step) {} - }; - - template struct PtrElemStep_ : public PtrStep - { - PtrElemStep_(const DevMem2D_& mem) : PtrStep(mem.data, mem.step) - { - StaticAssert<256 % sizeof(T) == 0>::check(); - - PtrStep::step /= PtrStep::elem_size; - } - __CV_GPU_HOST_DEVICE__ T* ptr(int y = 0) { return PtrStep::data + y * PtrStep::step; } - __CV_GPU_HOST_DEVICE__ const T* ptr(int y = 0) const { return PtrStep::data + y * PtrStep::step; } - - __CV_GPU_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; } - __CV_GPU_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; } - }; - - template struct PtrStep_ : public PtrStep - { - PtrStep_() {} - PtrStep_(const DevMem2D_& mem) : PtrStep(mem.data, mem.step) {} - }; - - typedef DevMem2D_ DevMem2Db; - typedef DevMem2Db DevMem2D; - typedef DevMem2D_ DevMem2Df; - typedef DevMem2D_ DevMem2Di; - - typedef PtrStep PtrStepb; - typedef PtrStep PtrStepf; - typedef PtrStep PtrStepi; - - typedef PtrElemStep_ PtrElemStep; - typedef PtrElemStep_ PtrElemStepf; - typedef PtrElemStep_ PtrElemStepi; - } -} - -#endif // __cplusplus - -#endif /* __OPENCV_GPU_DevMem2D_HPP__ */ +/*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 GpuMaterials 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_DevMem2D_HPP__ +#define __OPENCV_CORE_DevMem2D_HPP__ + +#ifdef __cplusplus + +#ifdef __CUDACC__ + #define __CV_GPU_HOST_DEVICE__ __host__ __device__ __forceinline__ +#else + #define __CV_GPU_HOST_DEVICE__ +#endif + +namespace cv +{ + namespace gpu + { + // Simple lightweight structures that encapsulates information about an image on device. + // It is intended to pass to nvcc-compiled code. GpuMat depends on headers that nvcc can't compile + + template struct StaticAssert; + template <> struct StaticAssert {static __CV_GPU_HOST_DEVICE__ void check(){}}; + + template struct DevPtr + { + typedef T elem_type; + typedef int index_type; + + enum { elem_size = sizeof(elem_type) }; + + T* data; + + __CV_GPU_HOST_DEVICE__ DevPtr() : data(0) {} + __CV_GPU_HOST_DEVICE__ DevPtr(T* data_) : data(data_) {} + + __CV_GPU_HOST_DEVICE__ size_t elemSize() const { return elem_size; } + __CV_GPU_HOST_DEVICE__ operator T*() { return data; } + __CV_GPU_HOST_DEVICE__ operator const T*() const { return data; } + }; + + template struct PtrSz : public DevPtr + { + __CV_GPU_HOST_DEVICE__ PtrSz() : size(0) {} + __CV_GPU_HOST_DEVICE__ PtrSz(T* data_, size_t size_) : DevPtr(data_), size(size_) {} + + size_t size; + }; + + template struct PtrStep : public DevPtr + { + __CV_GPU_HOST_DEVICE__ PtrStep() : step(0) {} + __CV_GPU_HOST_DEVICE__ PtrStep(T* data_, size_t step_) : DevPtr(data_), step(step_) {} + + /** \brief stride between two consecutive rows in bytes. Step is stored always and everywhere in bytes!!! */ + size_t step; + + __CV_GPU_HOST_DEVICE__ T* ptr(int y = 0) { return ( T*)( ( char*)DevPtr::data + y * step); } + __CV_GPU_HOST_DEVICE__ const T* ptr(int y = 0) const { return (const T*)( (const char*)DevPtr::data + y * step); } + + __CV_GPU_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; } + __CV_GPU_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; } + }; + + template struct PtrStepSz : public PtrStep + { + __CV_GPU_HOST_DEVICE__ PtrStepSz() : cols(0), rows(0) {} + __CV_GPU_HOST_DEVICE__ PtrStepSz(int rows_, int cols_, T* data_, size_t step_) + : PtrStep(data_, step_), cols(cols_), rows(rows_) {} + + int cols; + int rows; + }; + + template struct DevMem2D_ : public PtrStepSz + { + DevMem2D_() {} + DevMem2D_(int rows_, int cols_, T* data_, size_t step_) : PtrStepSz(rows_, cols_, data_, step_) {} + + template + explicit DevMem2D_(const DevMem2D_& d) : PtrStepSz(d.rows, d.cols, (T*)d.data, d.step) {} + }; + + template struct PtrElemStep_ : public PtrStep + { + PtrElemStep_(const DevMem2D_& mem) : PtrStep(mem.data, mem.step) + { + StaticAssert<256 % sizeof(T) == 0>::check(); + + PtrStep::step /= PtrStep::elem_size; + } + __CV_GPU_HOST_DEVICE__ T* ptr(int y = 0) { return PtrStep::data + y * PtrStep::step; } + __CV_GPU_HOST_DEVICE__ const T* ptr(int y = 0) const { return PtrStep::data + y * PtrStep::step; } + + __CV_GPU_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; } + __CV_GPU_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; } + }; + + template struct PtrStep_ : public PtrStep + { + PtrStep_() {} + PtrStep_(const DevMem2D_& mem) : PtrStep(mem.data, mem.step) {} + }; + + typedef DevMem2D_ DevMem2Db; + typedef DevMem2Db DevMem2D; + typedef DevMem2D_ DevMem2Df; + typedef DevMem2D_ DevMem2Di; + + typedef PtrStep PtrStepb; + typedef PtrStep PtrStepf; + typedef PtrStep PtrStepi; + + typedef PtrElemStep_ PtrElemStep; + typedef PtrElemStep_ PtrElemStepf; + typedef PtrElemStep_ PtrElemStepi; + } +} + +#endif // __cplusplus + +#endif /* __OPENCV_GPU_DevMem2D_HPP__ */ diff --git a/modules/gpu/src/cuda/bf_match.cu b/modules/gpu/src/cuda/bf_match.cu index 7d6d62b530..ad8cc88179 100644 --- a/modules/gpu/src/cuda/bf_match.cu +++ b/modules/gpu/src/cuda/bf_match.cu @@ -97,7 +97,7 @@ namespace cv { namespace gpu { namespace device } template - __device__ void loopUnrolledCached(int queryIdx, const DevMem2D_& query, int imgIdx, const DevMem2D_& train, const Mask& mask, + __device__ void loopUnrolledCached(int queryIdx, const DevMem2D_& query,volatile int imgIdx, const DevMem2D_& train, const Mask& mask, typename Dist::value_type* s_query, typename Dist::value_type* s_train, float& bestDistance, int& bestTrainIdx, int& bestImgIdx) { @@ -253,7 +253,7 @@ namespace cv { namespace gpu { namespace device // Match Unrolled template - __device__ void loopUnrolled(int queryIdx, const DevMem2D_& query, int imgIdx, const DevMem2D_& train, const Mask& mask, + __device__ void loopUnrolled(int queryIdx, const DevMem2D_& query,volatile int imgIdx, const DevMem2D_& train, const Mask& mask, typename Dist::value_type* s_query, typename Dist::value_type* s_train, float& bestDistance, int& bestTrainIdx, int& bestImgIdx) { @@ -409,7 +409,7 @@ namespace cv { namespace gpu { namespace device // Match template - __device__ void loop(int queryIdx, const DevMem2D_& query, int imgIdx, const DevMem2D_& train, const Mask& mask, + __device__ void loop(int queryIdx, const DevMem2D_& query, volatile int imgIdx, const DevMem2D_& train, const Mask& mask, typename Dist::value_type* s_query, typename Dist::value_type* s_train, float& bestDistance, int& bestTrainIdx, int& bestImgIdx) { diff --git a/modules/gpu/src/pyrlk.cpp b/modules/gpu/src/pyrlk.cpp index 394c41f35e..d85076b879 100644 --- a/modules/gpu/src/pyrlk.cpp +++ b/modules/gpu/src/pyrlk.cpp @@ -126,18 +126,19 @@ void cv::gpu::PyrLKOpticalFlow::buildImagePyramid(const GpuMat& img0, vector 32 && winSize.width > 2 * winSize.height) { - block.x = 32; + block.x = isDeviceArch11 ? 16 : 32; block.y = 8; } else { - block.x = block.y = 16; + block.x = 16; + block.y = isDeviceArch11 ? 8 : 16; } patch.x = (winSize.width + block.x - 1) / block.x; @@ -166,7 +167,7 @@ void cv::gpu::PyrLKOpticalFlow::sparse(const GpuMat& prevImg, const GpuMat& next const int cn = prevImg.channels(); dim3 block, patch; - calcPatchSize(winSize, cn, block, patch); + calcPatchSize(winSize, cn, block, patch, isDeviceArch11_); CV_Assert(derivLambda >= 0); CV_Assert(maxLevel >= 0 && winSize.width > 2 && winSize.height > 2); diff --git a/modules/highgui/src/cap_ffmpeg.cpp b/modules/highgui/src/cap_ffmpeg.cpp index 54159142fe..be89b9c9e2 100644 --- a/modules/highgui/src/cap_ffmpeg.cpp +++ b/modules/highgui/src/cap_ffmpeg.cpp @@ -42,11 +42,7 @@ #include "precomp.hpp" #ifdef HAVE_FFMPEG -#ifdef NEW_FFMPEG -#include "cap_ffmpeg_impl_v2.hpp" -#else #include "cap_ffmpeg_impl.hpp" -#endif #else #include "cap_ffmpeg_api.hpp" #endif diff --git a/modules/highgui/src/cap_ffmpeg_impl_v2.hpp b/modules/highgui/src/cap_ffmpeg_impl_v2.hpp deleted file mode 100755 index 555ff8f0b6..0000000000 --- a/modules/highgui/src/cap_ffmpeg_impl_v2.hpp +++ /dev/null @@ -1,2138 +0,0 @@ -/*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 "cap_ffmpeg_api.hpp" -#include -#include -#include - -#if defined _MSC_VER && _MSC_VER >= 1200 -#pragma warning( disable: 4244 4510 4512 4610 ) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#include "ffmpeg_codecs.hpp" - -#include - -#ifdef WIN32 - #define HAVE_FFMPEG_SWSCALE 1 - #include - #include -#else - -// if the header path is not specified explicitly, let's deduce it -#if !defined HAVE_FFMPEG_AVCODEC_H && !defined HAVE_LIBAVCODEC_AVCODEC_H - -#if defined(HAVE_GENTOO_FFMPEG) - #define HAVE_LIBAVCODEC_AVCODEC_H 1 - #if defined(HAVE_FFMPEG_SWSCALE) - #define HAVE_LIBSWSCALE_SWSCALE_H 1 - #endif -#elif defined HAVE_FFMPEG - #define HAVE_FFMPEG_AVCODEC_H 1 - #if defined(HAVE_FFMPEG_SWSCALE) - #define HAVE_FFMPEG_SWSCALE_H 1 - #endif -#endif - -#endif - -#if defined(HAVE_FFMPEG_AVCODEC_H) - #include -#endif -#if defined(HAVE_FFMPEG_SWSCALE_H) - #include -#endif - -#if defined(HAVE_LIBAVCODEC_AVCODEC_H) - #include -#endif -#if defined(HAVE_LIBSWSCALE_SWSCALE_H) - #include -#endif - -#endif - -#ifdef __cplusplus -} -#endif - -#if defined _MSC_VER && _MSC_VER >= 1200 -#pragma warning( default: 4244 4510 4512 4610 ) -#endif - -#ifdef NDEBUG -#define CV_WARN(message) -#else -#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__) -#endif - -/* PIX_FMT_RGBA32 macro changed in newer ffmpeg versions */ -#ifndef PIX_FMT_RGBA32 -#define PIX_FMT_RGBA32 PIX_FMT_RGB32 -#endif - -#define CALC_FFMPEG_VERSION(a,b,c) ( a<<16 | b<<8 | c ) - -#if defined WIN32 || defined _WIN32 - #include -#elif defined __linux__ || defined __APPLE__ - #include - #include - #include - #include -#endif - -#ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif - -int get_number_of_cpus(void) -{ -#if defined WIN32 || defined _WIN32 - SYSTEM_INFO sysinfo; - GetSystemInfo( &sysinfo ); - - return (int)sysinfo.dwNumberOfProcessors; -#elif defined __linux__ - return (int)sysconf( _SC_NPROCESSORS_ONLN ); -#elif defined __APPLE__ - int numCPU=0; - int mib[4]; - size_t len = sizeof(numCPU); - - /* set the mib for hw.ncpu */ - mib[0] = CTL_HW; - mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU; - - /* get the number of CPUs from the system */ - sysctl(mib, 2, &numCPU, &len, NULL, 0); - - if( numCPU < 1 ) - { - mib[1] = HW_NCPU; - sysctl( mib, 2, &numCPU, &len, NULL, 0 ); - - if( numCPU < 1 ) - numCPU = 1; - } - - return (int)numCPU; -#else - return 1; -#endif -} - - -char * FOURCC2str( int fourcc ) -{ - char * mystr=(char*)malloc(5); - mystr[0]=(char)((fourcc )&255); - mystr[1]=(char)((fourcc>> 8)&255); - mystr[2]=(char)((fourcc>>16)&255); - mystr[3]=(char)((fourcc>>24)&255); - mystr[4]=0; - return mystr; -} - - -struct Image_FFMPEG -{ - unsigned char* data; - int step; - int width; - int height; - int cn; -}; - - -inline void _opencv_ffmpeg_free(void** ptr) -{ - if(*ptr) free(*ptr); - *ptr = 0; -} - - -struct CvCapture_FFMPEG -{ - bool open( const char* filename ); - void close(); - - double getProperty(int); - bool setProperty(int, double); - bool grabFrame(); - bool retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn); - - void init(); - bool reopen(); - - void seek(int64_t frame_number); - void seek(double sec); - bool slowSeek( int framenumber ); - - int64_t get_total_frames(); - double get_duration_sec(); - double get_fps(); - int get_bitrate(); - - double r2d(AVRational r); - int64_t dts_to_frame_number(int64_t dts); - double dts_to_sec(int64_t dts); - - AVFormatContext * ic; - AVCodec * avcodec; - int video_stream; - AVStream * video_st; - AVFrame * picture; - AVFrame rgb_picture; - int64_t picture_pts; - - AVPacket packet; - Image_FFMPEG frame; - #if defined(HAVE_FFMPEG_SWSCALE) - struct SwsContext *img_convert_ctx; - #endif - - int64_t frame_number; - - double eps_zero; -/* - 'filename' contains the filename of the videosource, - 'filename==NULL' indicates that ffmpeg's seek support works - for the particular file. - 'filename!=NULL' indicates that the slow fallback function is used for seeking, - and so the filename is needed to reopen the file on backward seeking. -*/ - char * filename; -}; - -void CvCapture_FFMPEG::init() -{ - ic = 0; - video_stream = -1; - video_st = 0; - picture = 0; - picture_pts = 0; - memset( &rgb_picture, 0, sizeof(rgb_picture) ); - memset( &frame, 0, sizeof(frame) ); - filename = 0; - packet.data = NULL; -#if defined(HAVE_FFMPEG_SWSCALE) - img_convert_ctx = 0; -#endif - - avcodec = 0; - frame_number = 0; - eps_zero = 0.000025; -} - - -void CvCapture_FFMPEG::close() -{ - if( picture ) - av_free(picture); - - if( video_st ) - { -#if LIBAVFORMAT_BUILD > 4628 - avcodec_close( video_st->codec ); - -#else - avcodec_close( &(video_st->codec) ); - -#endif - video_st = NULL; - } - - if( ic ) - { -#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2) - av_close_input_file(ic); -#else - avformat_close_input(&ic); -#endif - - ic = NULL; - } - - if( rgb_picture.data[0] ) - { - free( rgb_picture.data[0] ); - rgb_picture.data[0] = 0; - } - - // free last packet if exist - if (packet.data) { - av_free_packet (&packet); - } - - init(); -} - - -/* - Used to reopen a video if the slower fallback function for seeking is used. -*/ -bool CvCapture_FFMPEG::reopen() -{ - /*if ( filename==NULL ) return false; - - #if LIBAVFORMAT_BUILD > 4628 - avcodec_close( video_st->codec ); - #else - avcodec_close( &video_st->codec ); - #endif - #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2) - av_close_input_file(ic); - av_open_input_file(&ic, filename, ) - #else - avformat_close_input(&ic); - avformat_open_input(&ic, filename, NULL, NULL); - #endif - - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 3, 0) - avformat_find_stream_info(ic, NULL); - #else - av_find_stream_info(ic); - #endif - #if LIBAVFORMAT_BUILD > 4628 - AVCodecContext *enc = ic->streams[video_stream]->codec; - #else - AVCodecContext *enc = &ic->streams[video_stream]->codec; - #endif - - #ifdef FF_API_THREAD_INIT - avcodec_thread_init(enc, std::min(get_number_of_cpus(), 16)); - #endif - - AVCodec *codec = avcodec_find_decoder(enc->codec_id); - #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0) - avcodec_open2(enc, codec, NULL); - #else - avcodec_open(enc, codec); - #endif - video_st = ic->streams[video_stream]; - - // reset framenumber to zero - frame_number = 0; - picture_pts=0;*/ - - return true; -} - -#ifndef AVSEEK_FLAG_FRAME -#define AVSEEK_FLAG_FRAME 0 -#endif -#ifndef AVSEEK_FLAG_ANY -#define AVSEEK_FLAG_ANY 1 -#endif - -bool CvCapture_FFMPEG::open( const char* _filename ) -{ - unsigned i; - bool valid = false; - - close(); - -#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0) - avformat_network_init(); -#endif - - /* register all codecs, demux and protocols */ - av_register_all(); - - av_log_set_level(AV_LOG_ERROR); - - int err = avformat_open_input(&ic, _filename, NULL, NULL); - if (err < 0) { - CV_WARN("Error opening file"); - goto exit_func; - } - err = -#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 3, 0) - avformat_find_stream_info(ic, NULL); -#else - av_find_stream_info(ic); -#endif - if (err < 0) { - CV_WARN("Could not find codec parameters"); - goto exit_func; - } - for(i = 0; i < ic->nb_streams; i++) - { -#if LIBAVFORMAT_BUILD > 4628 - AVCodecContext *enc = ic->streams[i]->codec; -#else - AVCodecContext *enc = &ic->streams[i]->codec; -#endif - -#ifdef FF_API_THREAD_INIT - avcodec_thread_init(enc, get_number_of_cpus()); -#else - enc->thread_count = get_number_of_cpus(); -#endif - -#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) -#define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO -#endif - - if( AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream < 0) { - AVCodec *codec = avcodec_find_decoder(enc->codec_id); - if (!codec || -#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0) - avcodec_open2(enc, codec, NULL) -#else - avcodec_open(enc, codec) -#endif - < 0) goto exit_func; - - video_stream = i; - video_st = ic->streams[i]; - picture = avcodec_alloc_frame(); - - rgb_picture.data[0] = (uint8_t*)malloc( - avpicture_get_size( PIX_FMT_BGR24, - enc->width, enc->height )); - avpicture_fill( (AVPicture*)&rgb_picture, rgb_picture.data[0], - PIX_FMT_BGR24, enc->width, enc->height ); - - frame.width = enc->width; - frame.height = enc->height; - frame.cn = 3; - frame.step = rgb_picture.linesize[0]; - frame.data = rgb_picture.data[0]; - break; - } - } - - if(video_stream >= 0) valid = true; - - // perform check if source is seekable via ffmpeg's seek function av_seek_frame(...) - /*err = av_seek_frame(ic, video_stream, 10, 0); - if (err < 0) - { - filename=(char*)malloc(strlen(_filename)+1); - strcpy(filename, _filename); - // reopen videofile to 'seek' back to first frame - reopen(); - } - else - { - // seek seems to work, so we don't need the filename, - // but we still need to seek back to filestart - filename=NULL; - int64_t ts = video_st->first_dts; - int flags = AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD; - av_seek_frame(ic, video_stream, ts, flags); - }*/ - exit_func: - - if( !valid ) - close(); - - return valid; -} - - -bool CvCapture_FFMPEG::grabFrame() -{ - bool valid = false; - static bool bFirstTime = true; - int got_picture; - - int count_errs = 0; - const int max_number_of_attempts = 64; - - if (bFirstTime) - { - bFirstTime = false; - packet.data = NULL; - } - - if( !ic || !video_st ) return false; - - if (packet.data != NULL) - { - av_free_packet (&packet); - } - - // get the next frame - while (!valid) - { - int ret = av_read_frame(ic, &packet); - - if (ret == AVERROR(EAGAIN)) continue; - - /* else if (ret < 0) break; */ - - if( packet.stream_index != video_stream ) - { - av_free_packet (&packet); - count_errs++; - if (count_errs > max_number_of_attempts) break; else - continue; - } - - // Decode video frame - avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet); - - // Did we get a video frame? - if(got_picture) - { - frame_number++; - picture_pts = packet.pts; - valid = true; - } - else - { - count_errs++; - if (count_errs > max_number_of_attempts) - break; - } - - } - - // return if we have a new picture or not - return valid; -} - - -bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn) -{ - if( !video_st || !picture->data[0] ) - return false; - - avpicture_fill((AVPicture*)&rgb_picture, rgb_picture.data[0], PIX_FMT_RGB24, video_st->codec->width, video_st->codec->height); - - frame.width = video_st->codec->width; - frame.height = video_st->codec->height; - - img_convert_ctx = sws_getContext( - video_st->codec->width, video_st->codec->height, - video_st->codec->pix_fmt, - video_st->codec->width, video_st->codec->height, - PIX_FMT_BGR24, - SWS_BICUBIC, - NULL, NULL, NULL - ); - - img_convert_ctx = sws_getCachedContext( - img_convert_ctx, - video_st->codec->width, video_st->codec->height, - video_st->codec->pix_fmt, - video_st->codec->width, video_st->codec->height, - PIX_FMT_BGR24, - SWS_BICUBIC, - NULL, NULL, NULL - ); - - if (img_convert_ctx == NULL) - return false;//CV_Error(0, "Cannot initialize the conversion context!"); - - sws_scale( - img_convert_ctx, - picture->data, - picture->linesize, - 0, video_st->codec->height, - rgb_picture.data, - rgb_picture.linesize - ); - - sws_freeContext(img_convert_ctx); - - - - frame_number++; - - *data = frame.data; - *step = frame.step; - *width = frame.width; - *height = frame.height; - *cn = frame.cn; - - return true; -} - -#if defined(__APPLE__) -#define AV_NOPTS_VALUE_ ((int64_t)0x8000000000000000LL) -#else -#define AV_NOPTS_VALUE_ ((int64_t)AV_NOPTS_VALUE) -#endif - -double CvCapture_FFMPEG::getProperty( int property_id ) -{ - // if( !capture || !video_st || !picture->data[0] ) return 0; - if( !video_st ) return 0; - - // double frameScale = av_q2d (video_st->time_base) * av_q2d (video_st->r_frame_rate); - //int64_t timestamp; - //timestamp = picture_pts; - - switch( property_id ) - { - case CV_FFMPEG_CAP_PROP_POS_MSEC: - return 1000.0*static_cast(frame_number)/static_cast(get_fps()); - break; - case CV_FFMPEG_CAP_PROP_POS_FRAMES: - return (double)static_cast(frame_number); - break; - case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO: - return r2d(ic->streams[video_stream]->time_base); - break; - case CV_FFMPEG_CAP_PROP_FRAME_COUNT: - return (double)static_cast(get_total_frames()); - break; - case CV_FFMPEG_CAP_PROP_FRAME_WIDTH: - return (double)frame.width; - break; - case CV_FFMPEG_CAP_PROP_FRAME_HEIGHT: - return (double)frame.height; - break; - case CV_FFMPEG_CAP_PROP_FPS: -#if LIBAVCODEC_BUILD > 4753 - return av_q2d (video_st->r_frame_rate); -#else - return (double)video_st->codec.frame_rate - / (double)video_st->codec.frame_rate_base; -#endif - break; - case CV_FFMPEG_CAP_PROP_FOURCC: -#if LIBAVFORMAT_BUILD > 4628 - return (double)video_st->codec->codec_tag; -#else - return (double)video_st->codec.codec_tag; -#endif - break; - } - - return 0; -} - -double CvCapture_FFMPEG::r2d(AVRational r) -{ - if (r.num == 0 || r.den == 0) - { - return 0.0; - } - else - { - return static_cast(r.num) / static_cast(r.den); - } -} - -double CvCapture_FFMPEG::get_duration_sec() -{ - double sec = static_cast(ic->duration) / static_cast(AV_TIME_BASE); - - if (sec < eps_zero) - { - sec = static_cast(ic->streams[video_stream]->duration) * r2d(ic->streams[video_stream]->time_base); - } - - if (sec < eps_zero) - { - sec = static_cast(static_cast(ic->streams[video_stream]->duration)) * r2d(ic->streams[video_stream]->time_base); - } - - return sec; -} - -int CvCapture_FFMPEG::get_bitrate() -{ - return ic->bit_rate; -} - -double CvCapture_FFMPEG::get_fps() -{ - double fps = r2d(ic->streams[video_stream]->r_frame_rate); - - if (fps < eps_zero) - { - fps = r2d(ic->streams[video_stream]->avg_frame_rate); - } - - if (fps < eps_zero) - { - fps = 1.0 / r2d(ic->streams[video_stream]->codec->time_base); - } - - return fps; -} - -int64_t CvCapture_FFMPEG::get_total_frames() -{ - int64_t nbf = ic->streams[video_stream]->nb_frames; - - if (nbf == 0) - { - nbf = (int64_t)floor(get_duration_sec() * get_fps() + 0.5); - } - return nbf; -} - -int64_t CvCapture_FFMPEG::dts_to_frame_number(int64_t dts) -{ - double sec = dts_to_sec(dts); - return static_cast(get_fps() * sec); -} - -double CvCapture_FFMPEG::dts_to_sec(int64_t dts) -{ - return static_cast(dts - ic->streams[video_stream]->start_time) * r2d(ic->streams[video_stream]->time_base); -} - -void CvCapture_FFMPEG::seek(int64_t frame_number) -{ - frame_number = std::min(frame_number, get_total_frames()); - int64_t dts = dts_to_frame_number(ic->streams[video_stream]->cur_dts); - - if (abs(dts - 2 - frame_number) > 16) - { - double sec = static_cast(frame_number) / static_cast(get_fps()); - int64_t time_stamp = ic->streams[video_stream]->start_time; - double time_base = r2d(ic->streams[video_stream]->time_base); - time_stamp += static_cast(sec / time_base); - av_seek_frame(ic, video_stream, time_stamp, AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD); - } - - while(dts - 2 < frame_number) - { - /* cv::Mat imag = read(); */ - if (!grabFrame()) break; - - dts = dts_to_frame_number(ic->streams[video_stream]->cur_dts); - } -} - -void CvCapture_FFMPEG::seek(double sec) -{ - seek(static_cast(sec * get_fps())); -} - -// this is a VERY slow fallback function, ONLY used if ffmpeg's av_seek_frame delivers no correct result! -bool CvCapture_FFMPEG::slowSeek( int framenumber ) -{ - if ( framenumber>picture_pts ) - { - while ( picture_ptsduration)); - break; - } - - picture_pts=(int64_t)value; - } - break; - default: - return false; - } - - return true; -} - - -///////////////// FFMPEG CvVideoWriter implementation ////////////////////////// -struct CvVideoWriter_FFMPEG -{ - bool open( const char* filename, int fourcc, - double fps, int width, int height, bool isColor ); - void close(); - bool writeFrame( const unsigned char* data, int step, int width, int height, int cn, int origin ); - - void init(); - - AVOutputFormat * fmt; - AVFormatContext * oc; - uint8_t * outbuf; - uint32_t outbuf_size; - FILE * outfile; - AVFrame * picture; - AVFrame * input_picture; - uint8_t * picbuf; - AVStream * video_st; - int input_pix_fmt; - Image_FFMPEG temp_image; - int frame_width, frame_height; - bool ok; -#if defined(HAVE_FFMPEG_SWSCALE) - struct SwsContext *img_convert_ctx; -#endif -}; - -static const char * icvFFMPEGErrStr(int err) -{ -#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) - switch(err) { - case AVERROR_BSF_NOT_FOUND: - return "Bitstream filter not found"; - case AVERROR_DECODER_NOT_FOUND: - return "Decoder not found"; - case AVERROR_DEMUXER_NOT_FOUND: - return "Demuxer not found"; - case AVERROR_ENCODER_NOT_FOUND: - return "Encoder not found"; - case AVERROR_EOF: - return "End of file"; - case AVERROR_EXIT: - return "Immediate exit was requested; the called function should not be restarted"; - case AVERROR_FILTER_NOT_FOUND: - return "Filter not found"; - case AVERROR_INVALIDDATA: - return "Invalid data found when processing input"; - case AVERROR_MUXER_NOT_FOUND: - return "Muxer not found"; - case AVERROR_OPTION_NOT_FOUND: - return "Option not found"; - case AVERROR_PATCHWELCOME: - return "Not yet implemented in FFmpeg, patches welcome"; - case AVERROR_PROTOCOL_NOT_FOUND: - return "Protocol not found"; - case AVERROR_STREAM_NOT_FOUND: - return "Stream not found"; - default: - break; - } -#else - switch(err) { - case AVERROR_NUMEXPECTED: - return "Incorrect filename syntax"; - case AVERROR_INVALIDDATA: - return "Invalid data in header"; - case AVERROR_NOFMT: - return "Unknown format"; - case AVERROR_IO: - return "I/O error occurred"; - case AVERROR_NOMEM: - return "Memory allocation error"; - default: - break; - } -#endif - - return "Unspecified error"; -} - -/* function internal to FFMPEG (libavformat/riff.c) to lookup codec id by fourcc tag*/ -extern "C" { - enum CodecID codec_get_bmp_id(unsigned int tag); -} - -void CvVideoWriter_FFMPEG::init() -{ - fmt = 0; - oc = 0; - outbuf = 0; - outbuf_size = 0; - outfile = 0; - picture = 0; - input_picture = 0; - picbuf = 0; - video_st = 0; - input_pix_fmt = 0; - memset(&temp_image, 0, sizeof(temp_image)); -#if defined(HAVE_FFMPEG_SWSCALE) - img_convert_ctx = 0; -#endif - frame_width = frame_height = 0; - ok = false; -} - -/** - * the following function is a modified version of code - * found in ffmpeg-0.4.9-pre1/output_example.c - */ -static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bool alloc) -{ - AVFrame * picture; - uint8_t * picture_buf; - int size; - - picture = avcodec_alloc_frame(); - if (!picture) - return NULL; - size = avpicture_get_size( (PixelFormat) pix_fmt, width, height); - if(alloc){ - picture_buf = (uint8_t *) malloc(size); - if (!picture_buf) - { - av_free(picture); - return NULL; - } - avpicture_fill((AVPicture *)picture, picture_buf, - (PixelFormat) pix_fmt, width, height); - } - else { - } - return picture; -} - -/* add a video output stream to the container */ -static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc, - CodecID codec_id, - int w, int h, int bitrate, - double fps, int pixel_format) -{ - AVCodecContext *c; - AVStream *st; - int frame_rate, frame_rate_base; - AVCodec *codec; - -#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0) - st = avformat_new_stream(oc, 0); -#else - st = av_new_stream(oc, 0); -#endif - - if (!st) { - CV_WARN("Could not allocate stream"); - return NULL; - } - -#if LIBAVFORMAT_BUILD > 4628 - c = st->codec; -#else - c = &(st->codec); -#endif - -#if LIBAVFORMAT_BUILD > 4621 - c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); -#else - c->codec_id = oc->oformat->video_codec; -#endif - - if(codec_id != CODEC_ID_NONE){ - c->codec_id = codec_id; - } - - //if(codec_tag) c->codec_tag=codec_tag; - codec = avcodec_find_encoder(c->codec_id); - - c->codec_type = AVMEDIA_TYPE_VIDEO; - - /* put sample parameters */ - unsigned long long lbit_rate = static_cast(bitrate); - lbit_rate += (bitrate / 4); - lbit_rate = std::min(lbit_rate, static_cast(std::numeric_limits::max())); - c->bit_rate = bitrate; - - // took advice from - // http://ffmpeg-users.933282.n4.nabble.com/warning-clipping-1-dct-coefficients-to-127-127-td934297.html - c->qmin = 3; - - /* resolution must be a multiple of two */ - c->width = w; - c->height = h; - - /* time base: this is the fundamental unit of time (in seconds) in terms - of which frame timestamps are represented. for fixed-fps content, - timebase should be 1/framerate and timestamp increments should be - identically 1. */ - frame_rate=(int)(fps+0.5); - frame_rate_base=1; - while (fabs((double)frame_rate/frame_rate_base) - fps > 0.001){ - frame_rate_base*=10; - frame_rate=(int)(fps*frame_rate_base + 0.5); - } -#if LIBAVFORMAT_BUILD > 4752 - c->time_base.den = frame_rate; - c->time_base.num = frame_rate_base; - /* adjust time base for supported framerates */ - if(codec && codec->supported_framerates){ - const AVRational *p= codec->supported_framerates; - AVRational req = {frame_rate, frame_rate_base}; - const AVRational *best=NULL; - AVRational best_error= {INT_MAX, 1}; - for(; p->den!=0; p++){ - AVRational error= av_sub_q(req, *p); - if(error.num <0) error.num *= -1; - if(av_cmp_q(error, best_error) < 0){ - best_error= error; - best= p; - } - } - c->time_base.den= best->num; - c->time_base.num= best->den; - } -#else - c->frame_rate = frame_rate; - c->frame_rate_base = frame_rate_base; -#endif - - c->gop_size = 12; /* emit one intra frame every twelve frames at most */ - c->pix_fmt = (PixelFormat) pixel_format; - - if (c->codec_id == CODEC_ID_MPEG2VIDEO) { - c->max_b_frames = 2; - } - if (c->codec_id == CODEC_ID_MPEG1VIDEO || c->codec_id == CODEC_ID_MSMPEG4V3){ - /* needed to avoid using macroblocks in which some coeffs overflow - this doesnt happen with normal video, it just happens here as the - motion of the chroma plane doesnt match the luma plane */ - /* avoid FFMPEG warning 'clipping 1 dct coefficients...' */ - c->mb_decision=2; - } -#if LIBAVCODEC_VERSION_INT>0x000409 - // some formats want stream headers to be seperate - if(oc->oformat->flags & AVFMT_GLOBALHEADER) - { - c->flags |= CODEC_FLAG_GLOBAL_HEADER; - } -#endif - - return st; -} - -static const int OPENCV_NO_FRAMES_WRITTEN_CODE = 1000; - -int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_t * outbuf, uint32_t outbuf_size, AVFrame * picture ) -{ -#if LIBAVFORMAT_BUILD > 4628 - AVCodecContext * c = video_st->codec; -#else - AVCodecContext * c = &(video_st->codec); -#endif - int out_size; - int ret = 0; - - if (oc->oformat->flags & AVFMT_RAWPICTURE) { - /* raw video case. The API will change slightly in the near - futur for that */ - AVPacket pkt; - av_init_packet(&pkt); - -#ifndef PKT_FLAG_KEY -#define PKT_FLAG_KEY AV_PKT_FLAG_KEY -#endif - - pkt.flags |= PKT_FLAG_KEY; - pkt.stream_index= video_st->index; - pkt.data= (uint8_t *)picture; - pkt.size= sizeof(AVPicture); - - ret = av_write_frame(oc, &pkt); - } else { - /* encode the image */ - out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture); - /* if zero size, it means the image was buffered */ - if (out_size > 0) { - AVPacket pkt; - av_init_packet(&pkt); - -#if LIBAVFORMAT_BUILD > 4752 - if(c->coded_frame->pts != (int64_t)AV_NOPTS_VALUE) - pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base); -#else - pkt.pts = c->coded_frame->pts; -#endif - if(c->coded_frame->key_frame) - pkt.flags |= PKT_FLAG_KEY; - pkt.stream_index= video_st->index; - pkt.data= outbuf; - pkt.size= out_size; - - /* write the compressed frame in the media file */ - ret = av_write_frame(oc, &pkt); - } else { - ret = OPENCV_NO_FRAMES_WRITTEN_CODE; - } - } - return ret; -} - -/// write a frame with FFMPEG -bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int width, int height, int cn, int origin ) -{ - bool ret = false; - - if( (width & -2) != frame_width || (height & -2) != frame_height || !data ) - return false; - width = frame_width; - height = frame_height; - - // typecast from opaque data type to implemented struct -#if LIBAVFORMAT_BUILD > 4628 - AVCodecContext *c = video_st->codec; -#else - AVCodecContext *c = &(video_st->codec); -#endif - -#if LIBAVFORMAT_BUILD < 5231 - // It is not needed in the latest versions of the ffmpeg - if( c->codec_id == CODEC_ID_RAWVIDEO && origin != 1 ) - { - if( !temp_image.data ) - { - temp_image.step = (width*cn + 3) & -4; - temp_image.width = width; - temp_image.height = height; - temp_image.cn = cn; - temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height); - } - for( int y = 0; y < height; y++ ) - memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, width*cn); - data = temp_image.data; - step = temp_image.step; - } -#else - if( width*cn != step ) - { - if( !temp_image.data ) - { - temp_image.step = width*cn; - temp_image.width = width; - temp_image.height = height; - temp_image.cn = cn; - temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height); - } - if (origin == 1) - for( int y = 0; y < height; y++ ) - memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, temp_image.step); - else - for( int y = 0; y < height; y++ ) - memcpy(temp_image.data + y*temp_image.step, data + y*step, temp_image.step); - data = temp_image.data; - step = temp_image.step; - } -#endif - - // check parameters - if (input_pix_fmt == PIX_FMT_BGR24) { - if (cn != 3) { - return false; - } - } - else if (input_pix_fmt == PIX_FMT_GRAY8) { - if (cn != 1) { - return false; - } - } - else { - assert(false); - } - - if ( c->pix_fmt != input_pix_fmt ) { - assert( input_picture ); - // let input_picture point to the raw data buffer of 'image' - avpicture_fill((AVPicture *)input_picture, (uint8_t *) data, - (PixelFormat)input_pix_fmt, width, height); - -#if !defined(HAVE_FFMPEG_SWSCALE) - // convert to the color format needed by the codec - if( img_convert((AVPicture *)picture, c->pix_fmt, - (AVPicture *)input_picture, (PixelFormat)input_pix_fmt, - width, height) < 0){ - return false; - } -#else - img_convert_ctx = sws_getContext(width, - height, - (PixelFormat)input_pix_fmt, - c->width, - c->height, - c->pix_fmt, - SWS_BICUBIC, - NULL, NULL, NULL); - - if ( sws_scale(img_convert_ctx, input_picture->data, - input_picture->linesize, 0, - height, - picture->data, picture->linesize) < 0 ) - { - return false; - } - sws_freeContext(img_convert_ctx); -#endif - } - else{ - avpicture_fill((AVPicture *)picture, (uint8_t *) data, - (PixelFormat)input_pix_fmt, width, height); - } - - ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, picture) >= 0; - - return ret; -} - -/// close video output stream and free associated memory -void CvVideoWriter_FFMPEG::close() -{ - unsigned i; - - // nothing to do if already released - if ( !picture ) - return; - - /* no more frame to compress. The codec has a latency of a few - frames if using B frames, so we get the last frames by - passing the same picture again */ - // TODO -- do we need to account for latency here? - - /* write the trailer, if any */ - if(ok && oc) - { - if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) - { - for(;;) - { - int ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, NULL); - if( ret == OPENCV_NO_FRAMES_WRITTEN_CODE || ret < 0 ) - break; - } - } - av_write_trailer(oc); - } - - // free pictures -#if LIBAVFORMAT_BUILD > 4628 - if( video_st->codec->pix_fmt != input_pix_fmt){ -#else - if( video_st->codec.pix_fmt != input_pix_fmt){ -#endif - if(picture->data[0]) - free(picture->data[0]); - picture->data[0] = 0; - } - av_free(picture); - - if (input_picture) { - av_free(input_picture); - } - - /* close codec */ -#if LIBAVFORMAT_BUILD > 4628 - avcodec_close(video_st->codec); -#else - avcodec_close(&(video_st->codec)); -#endif - - av_free(outbuf); - - /* free the streams */ - for(i = 0; i < oc->nb_streams; i++) { - av_freep(&oc->streams[i]->codec); - av_freep(&oc->streams[i]); - } - - if (!(fmt->flags & AVFMT_NOFILE)) { - /* close the output file */ - -#if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0) -#if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0) - url_fclose(oc->pb); -#else - url_fclose(&oc->pb); -#endif -#else - avio_close(oc->pb); -#endif - - } - - /* free the stream */ - av_free(oc); - - if( temp_image.data ) - { - free(temp_image.data); - temp_image.data = 0; - } - - init(); - } - - /// Create a video writer object that uses FFMPEG - bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, - double fps, int width, int height, bool is_color ) - { - CodecID codec_id = CODEC_ID_NONE; - int err, codec_pix_fmt; - double bitrate_scale = 1; - - close(); - - // check arguments - if( !filename ) - return false; - if(fps <= 0) - return false; - - // we allow frames of odd width or height, but in this case we truncate - // the rightmost column/the bottom row. Probably, this should be handled more elegantly, - // but some internal functions inside FFMPEG swscale require even width/height. - width &= -2; - height &= -2; - if( width <= 0 || height <= 0 ) - return false; - - // tell FFMPEG to register codecs - av_register_all(); - av_log_set_level(AV_LOG_ERROR); - - /* auto detect the output format from the name and fourcc code. */ - -#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) - fmt = av_guess_format(NULL, filename, NULL); -#else - fmt = guess_format(NULL, filename, NULL); -#endif - - if (!fmt) - return false; - - /* determine optimal pixel format */ - if (is_color) { - input_pix_fmt = PIX_FMT_BGR24; - } - else { - input_pix_fmt = PIX_FMT_GRAY8; - } - - /* Lookup codec_id for given fourcc */ -#if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0) - if( (codec_id = codec_get_bmp_id( fourcc )) == CODEC_ID_NONE ) - return false; -#else - const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL}; - if( (codec_id = av_codec_get_id(tags, fourcc)) == CODEC_ID_NONE ) - return false; -#endif - - // alloc memory for context -#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) - oc = avformat_alloc_context(); -#else - oc = av_alloc_format_context(); -#endif - assert (oc); - - /* set file name */ - oc->oformat = fmt; - snprintf(oc->filename, sizeof(oc->filename), "%s", filename); - - /* set some options */ - oc->max_delay = (int)(0.7*AV_TIME_BASE); /* This reduces buffer underrun warnings with MPEG */ - - // set a few optimal pixel formats for lossless codecs of interest.. - switch (codec_id) { -#if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0) - case CODEC_ID_JPEGLS: - // BGR24 or GRAY8 depending on is_color... - codec_pix_fmt = input_pix_fmt; - break; -#endif - case CODEC_ID_HUFFYUV: - codec_pix_fmt = PIX_FMT_YUV422P; - break; - case CODEC_ID_MJPEG: - case CODEC_ID_LJPEG: - codec_pix_fmt = PIX_FMT_YUVJ420P; - bitrate_scale = 3; - break; - case CODEC_ID_RAWVIDEO: - codec_pix_fmt = input_pix_fmt == PIX_FMT_GRAY8 || - input_pix_fmt == PIX_FMT_GRAY16LE || - input_pix_fmt == PIX_FMT_GRAY16BE ? input_pix_fmt : PIX_FMT_YUV420P; - break; - default: - // good for lossy formats, MPEG, etc. - codec_pix_fmt = PIX_FMT_YUV420P; - break; - } - - double bitrate = MIN(bitrate_scale*fps*width*height, (double)INT_MAX/2); - - // TODO -- safe to ignore output audio stream? - video_st = icv_add_video_stream_FFMPEG(oc, codec_id, - width, height, (int)(bitrate + 0.5), - fps, codec_pix_fmt); - - /* set the output parameters (must be done even if no - parameters). */ -#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) - if (av_set_parameters(oc, NULL) < 0) { - return false; - } -#endif - -#if 0 -#if FF_API_DUMP_FORMAT - dump_format(oc, 0, filename, 1); -#else - av_dump_format(oc, 0, filename, 1); -#endif -#endif - - /* now that all the parameters are set, we can open the audio and - video codecs and allocate the necessary encode buffers */ - if (!video_st){ - return false; - } - - AVCodec *codec; - AVCodecContext *c; - -#if LIBAVFORMAT_BUILD > 4628 - c = (video_st->codec); -#else - c = &(video_st->codec); -#endif - - c->codec_tag = fourcc; - /* find the video encoder */ - codec = avcodec_find_encoder(c->codec_id); - if (!codec) { - fprintf(stderr, "Could not find encoder for codec id %d: %s", c->codec_id, icvFFMPEGErrStr( - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) - AVERROR_ENCODER_NOT_FOUND - #else - -1 - #endif - )); - return false; - } - - unsigned long long lbit_rate = static_cast(c->bit_rate); - lbit_rate += (bitrate / 4); - lbit_rate = std::min(lbit_rate, static_cast(std::numeric_limits::max())); - c->bit_rate_tolerance = static_cast(lbit_rate); - - /* open the codec */ - if ((err= -#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0) - avcodec_open2(c, codec, NULL) -#else - avcodec_open(c, codec) -#endif - ) < 0) { - fprintf(stderr, "Could not open codec '%s': %s", codec->name, icvFFMPEGErrStr(err)); - return false; - } - - outbuf = NULL; - - if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) { - /* allocate output buffer */ - /* assume we will never get codec output with more than 4 bytes per pixel... */ - outbuf_size = width*height*4; - outbuf = (uint8_t *) av_malloc(outbuf_size); - } - - bool need_color_convert; - need_color_convert = (c->pix_fmt != input_pix_fmt); - - /* allocate the encoded raw picture */ - picture = icv_alloc_picture_FFMPEG(c->pix_fmt, c->width, c->height, need_color_convert); - if (!picture) { - return false; - } - - /* if the output format is not our input format, then a temporary - picture of the input format is needed too. It is then converted - to the required output format */ - input_picture = NULL; - if ( need_color_convert ) { - input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, c->width, c->height, false); - if (!input_picture) { - return false; - } - } - - /* open the output file, if needed */ - if (!(fmt->flags & AVFMT_NOFILE)) { -#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) - if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) -#else - if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) -#endif - { - return false; - } - } - - /* write the stream header, if any */ - err=avformat_write_header(oc, NULL); - if(err < 0) - { - close(); - remove(filename); - return false; - } - frame_width = width; - frame_height = height; - ok = true; - return true; - } - - - - CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename ) - { - CvCapture_FFMPEG* capture = (CvCapture_FFMPEG*)malloc(sizeof(*capture)); - capture->init(); - if( capture->open( filename )) - return capture; - capture->close(); - free(capture); - return 0; - } - - - void cvReleaseCapture_FFMPEG(CvCapture_FFMPEG** capture) - { - if( capture && *capture ) - { - (*capture)->close(); - free(*capture); - *capture = 0; - } - } - - int cvSetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id, double value) - { - return capture->setProperty(prop_id, value); - } - - double cvGetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id) - { - return capture->getProperty(prop_id); - } - - int cvGrabFrame_FFMPEG(CvCapture_FFMPEG* capture) - { - return capture->grabFrame(); - } - - int cvRetrieveFrame_FFMPEG(CvCapture_FFMPEG* capture, unsigned char** data, int* step, int* width, int* height, int* cn) - { - return capture->retrieveFrame(0, data, step, width, height, cn); - } - - CvVideoWriter_FFMPEG* cvCreateVideoWriter_FFMPEG( const char* filename, int fourcc, double fps, - int width, int height, int isColor ) - { - CvVideoWriter_FFMPEG* writer = (CvVideoWriter_FFMPEG*)malloc(sizeof(*writer)); - writer->init(); - if( writer->open( filename, fourcc, fps, width, height, isColor != 0 )) - return writer; - writer->close(); - free(writer); - return 0; - } - - - void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer ) - { - if( writer && *writer ) - { - (*writer)->close(); - free(*writer); - *writer = 0; - } - } - - - int cvWriteFrame_FFMPEG( CvVideoWriter_FFMPEG* writer, - const unsigned char* data, int step, - int width, int height, int cn, int origin) - { - return writer->writeFrame(data, step, width, height, cn, origin); - } - - -/* - * For CUDA encoder - */ - -struct OutputMediaStream_FFMPEG -{ - bool open(const char* fileName, int width, int height, double fps); - void close(); - - void write(unsigned char* data, int size, int keyFrame); - - // add a video output stream to the container - static AVStream* addVideoStream(AVFormatContext *oc, CodecID codec_id, int w, int h, int bitrate, double fps, PixelFormat pixel_format); - - AVOutputFormat* fmt_; - AVFormatContext* oc_; - AVStream* video_st_; -}; - -void OutputMediaStream_FFMPEG::close() -{ - // no more frame to compress. The codec has a latency of a few - // frames if using B frames, so we get the last frames by - // passing the same picture again - - // TODO -- do we need to account for latency here? - - if (oc_) - { - // write the trailer, if any - av_write_trailer(oc_); - - // free the streams - for (unsigned int i = 0; i < oc_->nb_streams; ++i) - { - av_freep(&oc_->streams[i]->codec); - av_freep(&oc_->streams[i]); - } - - if (!(fmt_->flags & AVFMT_NOFILE) && oc_->pb) - { - // close the output file - - #if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0) - #if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0) - url_fclose(oc_->pb); - #else - url_fclose(&oc_->pb); - #endif - #else - avio_close(oc_->pb); - #endif - } - - // free the stream - av_free(oc_); - } -} - -AVStream* OutputMediaStream_FFMPEG::addVideoStream(AVFormatContext *oc, CodecID codec_id, int w, int h, int bitrate, double fps, PixelFormat pixel_format) -{ - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0) - AVStream* st = avformat_new_stream(oc, 0); - #else - AVStream* st = av_new_stream(oc, 0); - #endif - if (!st) - return 0; - - #if LIBAVFORMAT_BUILD > 4628 - AVCodecContext* c = st->codec; - #else - AVCodecContext* c = &(st->codec); - #endif - - c->codec_id = codec_id; - c->codec_type = AVMEDIA_TYPE_VIDEO; - - // put sample parameters - unsigned long long lbit_rate = static_cast(bitrate); - lbit_rate += (bitrate / 4); - lbit_rate = std::min(lbit_rate, static_cast(std::numeric_limits::max())); - c->bit_rate = bitrate; - - // took advice from - // http://ffmpeg-users.933282.n4.nabble.com/warning-clipping-1-dct-coefficients-to-127-127-td934297.html - c->qmin = 3; - - // resolution must be a multiple of two - c->width = w; - c->height = h; - - AVCodec* codec = avcodec_find_encoder(c->codec_id); - - // time base: this is the fundamental unit of time (in seconds) in terms - // of which frame timestamps are represented. for fixed-fps content, - // timebase should be 1/framerate and timestamp increments should be - // identically 1 - - int frame_rate = static_cast(fps+0.5); - int frame_rate_base = 1; - while (fabs(static_cast(frame_rate)/frame_rate_base) - fps > 0.001) - { - frame_rate_base *= 10; - frame_rate = static_cast(fps*frame_rate_base + 0.5); - } - c->time_base.den = frame_rate; - c->time_base.num = frame_rate_base; - - #if LIBAVFORMAT_BUILD > 4752 - // adjust time base for supported framerates - if (codec && codec->supported_framerates) - { - AVRational req = {frame_rate, frame_rate_base}; - const AVRational* best = NULL; - AVRational best_error = {INT_MAX, 1}; - - for (const AVRational* p = codec->supported_framerates; p->den!=0; ++p) - { - AVRational error = av_sub_q(req, *p); - - if (error.num < 0) - error.num *= -1; - - if (av_cmp_q(error, best_error) < 0) - { - best_error= error; - best= p; - } - } - - c->time_base.den= best->num; - c->time_base.num= best->den; - } - #endif - - c->gop_size = 12; // emit one intra frame every twelve frames at most - c->pix_fmt = pixel_format; - - if (c->codec_id == CODEC_ID_MPEG2VIDEO) - c->max_b_frames = 2; - - if (c->codec_id == CODEC_ID_MPEG1VIDEO || c->codec_id == CODEC_ID_MSMPEG4V3) - { - // needed to avoid using macroblocks in which some coeffs overflow - // this doesnt happen with normal video, it just happens here as the - // motion of the chroma plane doesnt match the luma plane - - // avoid FFMPEG warning 'clipping 1 dct coefficients...' - - c->mb_decision = 2; - } - - #if LIBAVCODEC_VERSION_INT > 0x000409 - // some formats want stream headers to be seperate - if (oc->oformat->flags & AVFMT_GLOBALHEADER) - { - c->flags |= CODEC_FLAG_GLOBAL_HEADER; - } - #endif - - return st; -} - -bool OutputMediaStream_FFMPEG::open(const char* fileName, int width, int height, double fps) -{ - fmt_ = 0; - oc_ = 0; - video_st_ = 0; - - // tell FFMPEG to register codecs - av_register_all(); - - av_log_set_level(AV_LOG_ERROR); - - // auto detect the output format from the name and fourcc code - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) - fmt_ = av_guess_format(NULL, fileName, NULL); - #else - fmt_ = guess_format(NULL, fileName, NULL); - #endif - if (!fmt_) - return false; - - CodecID codec_id = CODEC_ID_H264; - - // alloc memory for context - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) - oc_ = avformat_alloc_context(); - #else - oc_ = av_alloc_format_context(); - #endif - if (!oc_) - return false; - - // set some options - oc_->oformat = fmt_; - snprintf(oc_->filename, sizeof(oc_->filename), "%s", fileName); - - oc_->max_delay = (int)(0.7 * AV_TIME_BASE); // This reduces buffer underrun warnings with MPEG - - // set a few optimal pixel formats for lossless codecs of interest.. - PixelFormat codec_pix_fmt = PIX_FMT_YUV420P; - int bitrate_scale = 64; - - // TODO -- safe to ignore output audio stream? - video_st_ = addVideoStream(oc_, codec_id, width, height, width * height * bitrate_scale, fps, codec_pix_fmt); - if (!video_st_) - return false; - - // set the output parameters (must be done even if no parameters) - #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) - if (av_set_parameters(oc_, NULL) < 0) - return false; - #endif - - // now that all the parameters are set, we can open the audio and - // video codecs and allocate the necessary encode buffers - - #if LIBAVFORMAT_BUILD > 4628 - AVCodecContext* c = (video_st_->codec); - #else - AVCodecContext* c = &(video_st_->codec); - #endif - - c->codec_tag = MKTAG('H', '2', '6', '4'); - c->bit_rate_tolerance = c->bit_rate; - - // open the output file, if needed - if (!(fmt_->flags & AVFMT_NOFILE)) - { - #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) - int err = url_fopen(&oc_->pb, fileName, URL_WRONLY); - #else - int err = avio_open(&oc_->pb, fileName, AVIO_FLAG_WRITE); - #endif - - if (err != 0) - return false; - } - - // write the stream header, if any - #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) - av_write_header(oc_); - #else - avformat_write_header(oc_, NULL); - #endif - - return true; -} - -void OutputMediaStream_FFMPEG::write(unsigned char* data, int size, int keyFrame) -{ - // if zero size, it means the image was buffered - if (size > 0) - { - AVPacket pkt; - av_init_packet(&pkt); - - if (keyFrame) - pkt.flags |= PKT_FLAG_KEY; - - pkt.stream_index = video_st_->index; - pkt.data = data; - pkt.size = size; - - // write the compressed frame in the media file - av_write_frame(oc_, &pkt); - } -} - -struct OutputMediaStream_FFMPEG* create_OutputMediaStream_FFMPEG(const char* fileName, int width, int height, double fps) -{ - OutputMediaStream_FFMPEG* stream = (OutputMediaStream_FFMPEG*) malloc(sizeof(OutputMediaStream_FFMPEG)); - - if (stream->open(fileName, width, height, fps)) - return stream; - - stream->close(); - free(stream); - - return 0; -} - -void release_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream) -{ - stream->close(); - free(stream); -} - -void write_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream, unsigned char* data, int size, int keyFrame) -{ - stream->write(data, size, keyFrame); -} - -/* - * For CUDA decoder - */ - -enum -{ - VideoCodec_MPEG1 = 0, - VideoCodec_MPEG2, - VideoCodec_MPEG4, - VideoCodec_VC1, - VideoCodec_H264, - VideoCodec_JPEG, - VideoCodec_H264_SVC, - VideoCodec_H264_MVC, - - // Uncompressed YUV - VideoCodec_YUV420 = (('I'<<24)|('Y'<<16)|('U'<<8)|('V')), // Y,U,V (4:2:0) - VideoCodec_YV12 = (('Y'<<24)|('V'<<16)|('1'<<8)|('2')), // Y,V,U (4:2:0) - VideoCodec_NV12 = (('N'<<24)|('V'<<16)|('1'<<8)|('2')), // Y,UV (4:2:0) - VideoCodec_YUYV = (('Y'<<24)|('U'<<16)|('Y'<<8)|('V')), // YUYV/YUY2 (4:2:2) - VideoCodec_UYVY = (('U'<<24)|('Y'<<16)|('V'<<8)|('Y')), // UYVY (4:2:2) -}; - -enum -{ - VideoChromaFormat_Monochrome = 0, - VideoChromaFormat_YUV420, - VideoChromaFormat_YUV422, - VideoChromaFormat_YUV444, -}; - -struct InputMediaStream_FFMPEG -{ -public: - bool open(const char* fileName, int* codec, int* chroma_format, int* width, int* height); - void close(); - - bool read(unsigned char** data, int* size, int* endOfFile); - -private: - InputMediaStream_FFMPEG(const InputMediaStream_FFMPEG&); - InputMediaStream_FFMPEG& operator =(const InputMediaStream_FFMPEG&); - - AVFormatContext* ctx_; - int video_stream_id_; - AVPacket pkt_; -}; - -bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma_format, int* width, int* height) -{ - int err; - - ctx_ = 0; - video_stream_id_ = -1; - memset(&pkt_, 0, sizeof(AVPacket)); - - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0) - avformat_network_init(); - #endif - - // register all codecs, demux and protocols - av_register_all(); - - av_log_set_level(AV_LOG_ERROR); - - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0) - err = avformat_open_input(&ctx_, fileName, 0, 0); - #else - err = av_open_input_file(&ctx_, fileName, 0, 0, 0); - #endif - if (err < 0) - return false; - - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 3, 0) - err = avformat_find_stream_info(ctx_, 0); - #else - err = av_find_stream_info(ctx_); - #endif - if (err < 0) - return false; - - for (unsigned int i = 0; i < ctx_->nb_streams; ++i) - { - #if LIBAVFORMAT_BUILD > 4628 - AVCodecContext *enc = ctx_->streams[i]->codec; - #else - AVCodecContext *enc = &ctx_->streams[i]->codec; - #endif - - if (enc->codec_type == AVMEDIA_TYPE_VIDEO) - { - video_stream_id_ = static_cast(i); - - switch (enc->codec_id) - { - case CODEC_ID_MPEG1VIDEO: - *codec = ::VideoCodec_MPEG1; - break; - - case CODEC_ID_MPEG2VIDEO: - *codec = ::VideoCodec_MPEG2; - break; - - case CODEC_ID_MPEG4: - *codec = ::VideoCodec_MPEG4; - break; - - case CODEC_ID_VC1: - *codec = ::VideoCodec_VC1; - break; - - case CODEC_ID_H264: - *codec = ::VideoCodec_H264; - break; - - default: - return false; - }; - - switch (enc->pix_fmt) - { - case PIX_FMT_YUV420P: - *chroma_format = ::VideoChromaFormat_YUV420; - break; - - case PIX_FMT_YUV422P: - *chroma_format = ::VideoChromaFormat_YUV422; - break; - - case PIX_FMT_YUV444P: - *chroma_format = ::VideoChromaFormat_YUV444; - break; - - default: - return false; - } - - *width = enc->coded_width; - *height = enc->coded_height; - - break; - } - } - - if (video_stream_id_ < 0) - return false; - - av_init_packet(&pkt_); - - return true; -} - -void InputMediaStream_FFMPEG::close() -{ - if (ctx_) - { - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 24, 2) - avformat_close_input(&ctx_); - #else - av_close_input_file(ctx_); - #endif - } - - // free last packet if exist - if (pkt_.data) - av_free_packet(&pkt_); -} - -bool InputMediaStream_FFMPEG::read(unsigned char** data, int* size, int* endOfFile) -{ - // free last packet if exist - if (pkt_.data) - av_free_packet(&pkt_); - - // get the next frame - for (;;) - { - int ret = av_read_frame(ctx_, &pkt_); - - if (ret == AVERROR(EAGAIN)) - continue; - - if (ret < 0) - { - if (ret == AVERROR_EOF) - *endOfFile = true; - return false; - } - - if (pkt_.stream_index != video_stream_id_) - { - av_free_packet(&pkt_); - continue; - } - - break; - } - - *data = pkt_.data; - *size = pkt_.size; - *endOfFile = false; - - return true; -} - -InputMediaStream_FFMPEG* create_InputMediaStream_FFMPEG(const char* fileName, int* codec, int* chroma_format, int* width, int* height) -{ - InputMediaStream_FFMPEG* stream = (InputMediaStream_FFMPEG*) malloc(sizeof(InputMediaStream_FFMPEG)); - - if (stream && stream->open(fileName, codec, chroma_format, width, height)) - return stream; - - stream->close(); - free(stream); - - return 0; -} - -void release_InputMediaStream_FFMPEG(InputMediaStream_FFMPEG* stream) -{ - stream->close(); - free(stream); -} - -int read_InputMediaStream_FFMPEG(InputMediaStream_FFMPEG* stream, unsigned char** data, int* size, int* endOfFile) -{ - return stream->read(data, size, endOfFile); -} diff --git a/modules/imgproc/doc/planar_subdivisions.rst b/modules/imgproc/doc/planar_subdivisions.rst deleted file mode 100644 index 7cd8ee84a6..0000000000 --- a/modules/imgproc/doc/planar_subdivisions.rst +++ /dev/null @@ -1,325 +0,0 @@ -Planar Subdivisions (C API) -============================ - -.. highlight:: c - -CvSubdiv2D ----------- - -.. ocv:struct:: CvSubdiv2D - -Planar subdivision. - -:: - - #define CV_SUBDIV2D_FIELDS() \ - CV_GRAPH_FIELDS() \ - int quad_edges; \ - int is_geometry_valid; \ - CvSubdiv2DEdge recent_edge; \ - CvPoint2D32f topleft; \ - CvPoint2D32f bottomright; - - typedef struct CvSubdiv2D - { - CV_SUBDIV2D_FIELDS() - } - CvSubdiv2D; - -.. - -Planar subdivision is the subdivision of a plane into a set of -non-overlapped regions (facets) that cover the whole plane. The above -structure describes a subdivision built on a 2D point set, where the points -are linked together and form a planar graph, which, together with a few -edges connecting the exterior subdivision points (namely, convex hull points) -with infinity, subdivides a plane into facets by its edges. - -For every subdivision, there is a dual subdivision in which facets and -points (subdivision vertices) swap their roles. This means that a facet is -treated as a vertex (called a virtual point below) of the dual subdivision and -the original subdivision vertices become facets. In the figure below, the -original subdivision is marked with solid lines and dual subdivision - -with dotted lines. - -.. image:: pics/subdiv.png - -OpenCV subdivides a plane into triangles using the Delaunay's -algorithm. Subdivision is built iteratively starting from a dummy -triangle that includes all the subdivision points for sure. In this -case, the dual subdivision is a Voronoi diagram of the input 2D point set. The -subdivisions can be used for the 3D piece-wise transformation of a plane, -morphing, fast location of points on the plane, building special graphs -(such as NNG,RNG), and so forth. - -CvQuadEdge2D ------------- - -.. ocv:struct:: CvQuadEdge2D - -Quad-edge of a planar subdivision. - -:: - - /* one of edges within quad-edge, lower 2 bits is index (0..3) - and upper bits are quad-edge pointer */ - typedef long CvSubdiv2DEdge; - - /* quad-edge structure fields */ - #define CV_QUADEDGE2D_FIELDS() \ - int flags; \ - struct CvSubdiv2DPoint* pt[4]; \ - CvSubdiv2DEdge next[4]; - - typedef struct CvQuadEdge2D - { - CV_QUADEDGE2D_FIELDS() - } - CvQuadEdge2D; - -.. - -Quad-edge is a basic element of a subdivision containing four edges (e, eRot, reversed e, and reversed eRot): - -.. image:: pics/quadedge.png - -CvSubdiv2DPoint ---------------- - -.. ocv:struct:: CvSubdiv2DPoint - -Point of an original or dual subdivision. - -:: - - #define CV_SUBDIV2D_POINT_FIELDS()\ - int flags; \ - CvSubdiv2DEdge first; \ - CvPoint2D32f pt; \ - int id; - - #define CV_SUBDIV2D_VIRTUAL_POINT_FLAG (1 << 30) - - typedef struct CvSubdiv2DPoint - { - CV_SUBDIV2D_POINT_FIELDS() - } - CvSubdiv2DPoint; - -.. - -* id - This integer can be used to index auxiliary data associated with each vertex of the planar subdivision. - -CalcSubdivVoronoi2D -------------------- -Calculates the coordinates of the Voronoi diagram cells. - -.. ocv:cfunction:: void cvCalcSubdivVoronoi2D( CvSubdiv2D* subdiv ) -.. ocv:pyoldfunction:: cv.CalcSubdivVoronoi2D(subdiv)-> None - - :param subdiv: Delaunay subdivision, in which all the points are already added. - -The function calculates the coordinates -of virtual points. All virtual points corresponding to a vertex of the -original subdivision form (when connected together) a boundary of the Voronoi -cell at that point. - -ClearSubdivVoronoi2D --------------------- -Removes all virtual points. - -.. ocv:cfunction:: void cvClearSubdivVoronoi2D( CvSubdiv2D* subdiv ) -.. ocv:pyoldfunction:: cv.ClearSubdivVoronoi2D(subdiv)-> None - - :param subdiv: Delaunay subdivision. - -The function removes all of the virtual points. It -is called internally in -:ocv:cfunc:`CalcSubdivVoronoi2D` -if the subdivision -was modified after the previous call to the function. - -CreateSubdivDelaunay2D ----------------------- -Creates an empty Delaunay triangulation. - -.. ocv:cfunction:: CvSubdiv2D* cvCreateSubdivDelaunay2D( CvRect rect, CvMemStorage* storage ) -.. ocv:pyoldfunction:: cv.CreateSubdivDelaunay2D(rect, storage)-> emptyDelaunayTriangulation - - :param rect: Rectangle that includes all of the 2D points that are to be added to the subdivision. - - :param storage: Container for the subdivision. - -The function creates an empty Delaunay -subdivision where 2D points can be added using the function -:ocv:cfunc:`SubdivDelaunay2DInsert` -. All of the points to be added must be within -the specified rectangle, otherwise a runtime error is raised. - -Note that the triangulation is a single large triangle that covers the given rectangle. Hence the three vertices of this triangle are outside the rectangle -``rect`` -. - -FindNearestPoint2D ------------------- -Finds the subdivision vertex closest to the given point. - -.. ocv:cfunction:: CvSubdiv2DPoint* cvFindNearestPoint2D( CvSubdiv2D* subdiv, CvPoint2D32f pt ) -.. ocv:pyoldfunction:: cv.FindNearestPoint2D(subdiv, pt)-> point - - :param subdiv: Delaunay or another subdivision. - - :param pt: Input point. - -The function is another function that -locates the input point within the subdivision. It finds the subdivision vertex that -is the closest to the input point. It is not necessarily one of vertices -of the facet containing the input point, though the facet (located using -:ocv:cfunc:`Subdiv2DLocate` -) is used as a starting -point. The function returns a pointer to the found subdivision vertex. - -Subdiv2DEdgeDst ---------------- -Returns the edge destination. - -.. ocv:cfunction:: CvSubdiv2DPoint* cvSubdiv2DEdgeDst( CvSubdiv2DEdge edge ) -.. ocv:pyoldfunction:: cv.Subdiv2DEdgeDst(edge)-> point - - :param edge: Subdivision edge (not a quad-edge). - -The function returns the edge destination. The -returned pointer may be NULL if the edge is from a dual subdivision and -the virtual point coordinates are not calculated yet. The virtual points -can be calculated using the function -:ocv:cfunc:`CalcSubdivVoronoi2D`. - -Subdiv2DGetEdge ---------------- -Returns one of the edges related to the given edge. - -.. ocv:cfunction:: CvSubdiv2DEdge cvSubdiv2DGetEdge( CvSubdiv2DEdge edge, CvNextEdgeType type ) -.. ocv:pyoldfunction:: cv.Subdiv2DGetEdge(edge, type)-> CvSubdiv2DEdge - - :param edge: Subdivision edge (not a quad-edge). - - :param type: Parameter specifying which of the related edges to return. The following values are possible: - - * **CV_NEXT_AROUND_ORG** next around the edge origin ( ``eOnext`` on the picture below if ``e`` is the input edge) - - * **CV_NEXT_AROUND_DST** next around the edge vertex ( ``eDnext`` ) - - * **CV_PREV_AROUND_ORG** previous around the edge origin (reversed ``eRnext`` ) - - * **CV_PREV_AROUND_DST** previous around the edge destination (reversed ``eLnext`` ) - - * **CV_NEXT_AROUND_LEFT** next around the left facet ( ``eLnext`` ) - - * **CV_NEXT_AROUND_RIGHT** next around the right facet ( ``eRnext`` ) - - * **CV_PREV_AROUND_LEFT** previous around the left facet (reversed ``eOnext`` ) - - * **CV_PREV_AROUND_RIGHT** previous around the right facet (reversed ``eDnext`` ) - -.. image:: pics/quadedge.png - -The function returns one of the edges related to the input edge. - -Subdiv2DNextEdge ----------------- -Returns next edge around the edge origin. - -.. ocv:cfunction:: CvSubdiv2DEdge cvSubdiv2DNextEdge( CvSubdiv2DEdge edge ) -.. ocv:pyoldfunction:: cv.Subdiv2DNextEdge(edge)-> CvSubdiv2DEdge - - :param edge: Subdivision edge (not a quad-edge). - -The function returns the next edge around the edge origin: -``eOnext`` -on the picture above if -``e`` -is the input edge). - -Subdiv2DLocate --------------- -Returns the location of a point within a Delaunay triangulation. - -.. ocv:cfunction:: CvSubdiv2DPointLocation cvSubdiv2DLocate( CvSubdiv2D* subdiv, CvPoint2D32f pt, CvSubdiv2DEdge* edge, CvSubdiv2DPoint** vertex=NULL ) -.. ocv:pyoldfunction:: cv.Subdiv2DLocate(subdiv, pt) -> (loc, where) - - :param subdiv: Delaunay or another subdivision. - - :param pt: Point to locate. - - :param edge: Output edge that the point belongs to or is located to the right of it. - - :param vertex: Optional output vertex double pointer the input point coincides with. - -The function locates the input point within the subdivision. There are five cases: - -* - The point falls into some facet. The function returns - ``CV_PTLOC_INSIDE`` - and - ``*edge`` - will contain one of edges of the facet. - -* - The point falls onto the edge. The function returns - ``CV_PTLOC_ON_EDGE`` - and - ``*edge`` - will contain this edge. - -* - The point coincides with one of the subdivision vertices. The function returns - ``CV_PTLOC_VERTEX`` - and - ``*vertex`` - will contain a pointer to the vertex. - -* - The point is outside the subdivision reference rectangle. The function returns - ``CV_PTLOC_OUTSIDE_RECT`` - and no pointers are filled. - -* - One of input arguments is invalid. A runtime error is raised or, if silent or "parent" error processing mode is selected, - ``CV_PTLOC_ERROR`` - is returnd. - -Subdiv2DRotateEdge ------------------- -Returns another edge of the same quad-edge. - -.. ocv:cfunction:: CvSubdiv2DEdge cvSubdiv2DRotateEdge( CvSubdiv2DEdge edge, int rotate ) -.. ocv:pyoldfunction:: cv.Subdiv2DRotateEdge(edge, rotate)-> CvSubdiv2DEdge - - :param edge: Subdivision edge (not a quad-edge). - - :param rotate: Parameter specifying which of the edges of the same quad-edge as the input one to return. The following values are possible: - - * **0** the input edge ( ``e`` on the picture below if ``e`` is the input edge) - - * **1** the rotated edge ( ``eRot`` ) - - * **2** the reversed edge (reversed ``e`` (in green)) - - * **3** the reversed rotated edge (reversed ``eRot`` (in green)) - -The function returns one of the edges of the same quad-edge as the input edge. - -SubdivDelaunay2DInsert ----------------------- -Inserts a single point into a Delaunay triangulation. - -.. ocv:cfunction:: CvSubdiv2DPoint* cvSubdivDelaunay2DInsert( CvSubdiv2D* subdiv, CvPoint2D32f pt) -.. ocv:pyoldfunction:: cv.SubdivDelaunay2DInsert(subdiv, pt)-> point - - :param subdiv: Delaunay subdivision created by the function :ocv:cfunc:`CreateSubdivDelaunay2D`. - - :param pt: Inserted point. - -The function inserts a single point into a subdivision and modifies the subdivision topology appropriately. If a point with the same coordinates exists already, no new point is added. The function returns a pointer to the allocated point. No virtual point coordinates are calculated at this stage. - diff --git a/modules/java/android_test/src/org/opencv/test/features2d/BruteForceDescriptorMatcherTest.java b/modules/java/android_test/src/org/opencv/test/features2d/BruteForceDescriptorMatcherTest.java index 581329ce32..342328e49f 100644 --- a/modules/java/android_test/src/org/opencv/test/features2d/BruteForceDescriptorMatcherTest.java +++ b/modules/java/android_test/src/org/opencv/test/features2d/BruteForceDescriptorMatcherTest.java @@ -19,8 +19,6 @@ import org.opencv.features2d.KeyPoint; import org.opencv.test.OpenCVTestCase; import org.opencv.test.OpenCVTestRunner; -import android.util.Log; - public class BruteForceDescriptorMatcherTest extends OpenCVTestCase { DescriptorMatcher matcher; @@ -173,8 +171,6 @@ public class BruteForceDescriptorMatcherTest extends OpenCVTestCase { Mat query = getQueryDescriptors(); List matches = new ArrayList(); matcher.knnMatch(query, train, matches, k); - Log.d("knnMatch", "train = " + train); - Log.d("knnMatch", "query = " + query); /* Log.d("knnMatch", "train = " + train); Log.d("knnMatch", "query = " + query); diff --git a/modules/java/gen_java.py b/modules/java/gen_java.py index 8647a56e19..aef2a18163 100644 --- a/modules/java/gen_java.py +++ b/modules/java/gen_java.py @@ -1,1399 +1,1408 @@ -import sys, re, os.path -from string import Template - -try: - from cStringIO import StringIO -except: - from StringIO import StringIO - -class_ignore_list = ( - #core - "FileNode", "FileStorage", "KDTree", - #highgui - "VideoWriter", "VideoCapture", - #features2d - #"KeyPoint", "MSER", "StarDetector", "SURF", "DMatch", - #ml - #"EM", -) - -const_ignore_list = ( - "CV_CAP_OPENNI", - "CV_CAP_PROP_OPENNI_", - "WINDOW_AUTOSIZE", - "CV_WND_PROP_", - "CV_WINDOW_", - "CV_EVENT_", - "CV_GUI_", - "CV_PUSH_BUTTON", - "CV_CHECKBOX", - "CV_RADIOBOX", - - #attention! - #the following constants are added to this list using code automatic generation - #TODO: should be checked - "CV_CAP_ANY", - "CV_CAP_MIL", - "CV_CAP_VFW", - "CV_CAP_V4L", - "CV_CAP_V4L2", - "CV_CAP_FIREWARE", - "CV_CAP_FIREWIRE", - "CV_CAP_IEEE1394", - "CV_CAP_DC1394", - "CV_CAP_CMU1394", - "CV_CAP_STEREO", - "CV_CAP_TYZX", - "CV_TYZX_LEFT", - "CV_TYZX_RIGHT", - "CV_TYZX_COLOR", - "CV_TYZX_Z", - "CV_CAP_QT", - "CV_CAP_UNICAP", - "CV_CAP_DSHOW", - "CV_CAP_PVAPI", - "CV_CAP_PROP_DC1394_OFF", - "CV_CAP_PROP_DC1394_MODE_MANUAL", - "CV_CAP_PROP_DC1394_MODE_AUTO", - "CV_CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO", - "CV_CAP_PROP_POS_MSEC", - "CV_CAP_PROP_POS_FRAMES", - "CV_CAP_PROP_POS_AVI_RATIO", - "CV_CAP_PROP_FPS", - "CV_CAP_PROP_FOURCC", - "CV_CAP_PROP_FRAME_COUNT", - "CV_CAP_PROP_FORMAT", - "CV_CAP_PROP_MODE", - "CV_CAP_PROP_BRIGHTNESS", - "CV_CAP_PROP_CONTRAST", - "CV_CAP_PROP_SATURATION", - "CV_CAP_PROP_HUE", - "CV_CAP_PROP_GAIN", - "CV_CAP_PROP_EXPOSURE", - "CV_CAP_PROP_CONVERT_RGB", - "CV_CAP_PROP_WHITE_BALANCE_BLUE_U", - "CV_CAP_PROP_RECTIFICATION", - "CV_CAP_PROP_MONOCROME", - "CV_CAP_PROP_SHARPNESS", - "CV_CAP_PROP_AUTO_EXPOSURE", - "CV_CAP_PROP_GAMMA", - "CV_CAP_PROP_TEMPERATURE", - "CV_CAP_PROP_TRIGGER", - "CV_CAP_PROP_TRIGGER_DELAY", - "CV_CAP_PROP_WHITE_BALANCE_RED_V", - "CV_CAP_PROP_MAX_DC1394", - "CV_CAP_GSTREAMER_QUEUE_LENGTH", - "CV_CAP_PROP_PVAPI_MULTICASTIP", - "CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING", - "EVENT_.*", - "CV_L?(BGRA?|RGBA?|GRAY|XYZ|YCrCb|Luv|Lab|HLS|YUV|HSV)\d*2L?(BGRA?|RGBA?|GRAY|XYZ|YCrCb|Luv|Lab|HLS|YUV|HSV).*", - "CV_COLORCVT_MAX", - "CV_.*Bayer.*", - "CV_YUV420(i|sp|p)2.+", - "CV_TM_.+", - "CV_FLOODFILL_.+", - "CV_ADAPTIVE_THRESH_.+", - "WINDOW_.+", - "WND_PROP_.+", -) - -const_private_list = ( - "CV_MOP_.+", - "CV_INTER_.+", - "CV_THRESH_.+", - "CV_INPAINT_.+", - "CV_RETR_.+", - "CV_CHAIN_APPROX_.+", - "OPPONENTEXTRACTOR", - "GRIDRETECTOR", - "PYRAMIDDETECTOR", - "DYNAMICDETECTOR", -) - -# { Module : { public : [[name, val],...], private : [[]...] } } -missing_consts = \ -{ - 'Core' : - { - 'private' : - ( - ('CV_8U', 0 ), ('CV_8S', 1 ), - ('CV_16U', 2 ), ('CV_16S', 3 ), - ('CV_32S', 4 ), - ('CV_32F', 5 ), ('CV_64F', 6 ), - ('CV_USRTYPE1', 7 ), - ), # private - 'public' : - ( - ('SVD_MODIFY_A', 1), ('SVD_NO_UV', 2), ('SVD_FULL_UV', 4), - ('FILLED', -1), - ('LINE_AA', 16), ('LINE_8', 8), ('LINE_4', 4), - ('REDUCE_SUM', 0), ('REDUCE_AVG', 1), ('REDUCE_MAX', 2), ('REDUCE_MIN', 3), - ) #public - }, # Core - - "Imgproc": - { - 'private' : - ( - ('IPL_BORDER_CONSTANT', 0 ), - ('IPL_BORDER_REPLICATE', 1 ), - ('IPL_BORDER_REFLECT', 2 ), - ('IPL_BORDER_WRAP', 3 ), - ('IPL_BORDER_REFLECT_101', 4 ), - ('IPL_BORDER_TRANSPARENT', 5 ), - ) # private - }, # Imgproc - - "Calib3d": - { - 'private' : - ( - ('CV_LMEDS', 4), - ('CV_RANSAC', 8), - ('CV_FM_LMEDS', 'CV_LMEDS'), - ('CV_FM_RANSAC','CV_RANSAC'), - ('CV_FM_7POINT', 1), - ('CV_FM_8POINT', 2), - ('CV_CALIB_USE_INTRINSIC_GUESS', 1), - ('CV_CALIB_FIX_ASPECT_RATIO', 2), - ('CV_CALIB_FIX_PRINCIPAL_POINT', 4), - ('CV_CALIB_ZERO_TANGENT_DIST', 8), - ('CV_CALIB_FIX_FOCAL_LENGTH', 16), - ('CV_CALIB_FIX_K1', 32), - ('CV_CALIB_FIX_K2', 64), - ('CV_CALIB_FIX_K3', 128), - ('CV_CALIB_FIX_K4', 2048), - ('CV_CALIB_FIX_K5', 4096), - ('CV_CALIB_FIX_K6', 8192), - ('CV_CALIB_RATIONAL_MODEL', 16384), - ('CV_CALIB_FIX_INTRINSIC', 256), - ('CV_CALIB_SAME_FOCAL_LENGTH', 512), - ('CV_CALIB_ZERO_DISPARITY', 1024), - ) # public - }, # Calib3d - -} - - -# c_type : { java/jni correspondence } -type_dict = { -# "simple" : { j_type : "?", jn_type : "?", jni_type : "?", suffix : "?" }, - "" : { "j_type" : "", "jn_type" : "long", "jni_type" : "jlong" }, # c-tor ret_type - "void" : { "j_type" : "void", "jn_type" : "void", "jni_type" : "void" }, - "env" : { "j_type" : "", "jn_type" : "", "jni_type" : "JNIEnv*"}, - "cls" : { "j_type" : "", "jn_type" : "", "jni_type" : "jclass"}, - "bool" : { "j_type" : "boolean", "jn_type" : "boolean", "jni_type" : "jboolean", "suffix" : "Z" }, - "int" : { "j_type" : "int", "jn_type" : "int", "jni_type" : "jint", "suffix" : "I" }, - "long" : { "j_type" : "int", "jn_type" : "int", "jni_type" : "jint", "suffix" : "I" }, - "float" : { "j_type" : "float", "jn_type" : "float", "jni_type" : "jfloat", "suffix" : "F" }, - "double" : { "j_type" : "double", "jn_type" : "double", "jni_type" : "jdouble", "suffix" : "D" }, - "size_t" : { "j_type" : "long", "jn_type" : "long", "jni_type" : "jlong", "suffix" : "J" }, - "__int64" : { "j_type" : "long", "jn_type" : "long", "jni_type" : "jlong", "suffix" : "J" }, - "int64" : { "j_type" : "long", "jn_type" : "long", "jni_type" : "jlong", "suffix" : "J" }, - "double[]": { "j_type" : "double[]", "jn_type" : "double[]", "jni_type" : "jdoubleArray", "suffix" : "_3D" }, - -# "complex" : { j_type : "?", jn_args : (("", ""),), jn_name : "", jni_var : "", jni_name : "", "suffix" : "?" }, - - "vector_Point" : { "j_type" : "MatOfPoint", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_Point2f" : { "j_type" : "MatOfPoint2f", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - #"vector_Point2d" : { "j_type" : "MatOfPoint2d", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_Point3i" : { "j_type" : "MatOfPoint3", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_Point3f" : { "j_type" : "MatOfPoint3f", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - #"vector_Point3d" : { "j_type" : "MatOfPoint3d", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_KeyPoint" : { "j_type" : "MatOfKeyPoint", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_DMatch" : { "j_type" : "MatOfDMatch", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_Rect" : { "j_type" : "MatOfRect", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_uchar" : { "j_type" : "MatOfByte", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_char" : { "j_type" : "MatOfByte", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_int" : { "j_type" : "MatOfInt", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_float" : { "j_type" : "MatOfFloat", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_double" : { "j_type" : "MatOfDouble", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_Vec4i" : { "j_type" : "MatOfInt4", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_Vec4f" : { "j_type" : "MatOfFloat4", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - "vector_Vec6f" : { "j_type" : "MatOfFloat6", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - - "vector_Mat" : { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, - - "vector_vector_KeyPoint": { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector< vector > %(n)s" }, - "vector_vector_DMatch" : { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector< vector > %(n)s" }, - "vector_vector_char" : { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector< vector > %(n)s" }, - "vector_vector_Point" : { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector< vector > %(n)s" }, - "vector_vector_Point2f" : { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector< vector > %(n)s" }, - "vector_vector_Point3f" : { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector< vector > %(n)s" }, - - "Mat" : { "j_type" : "Mat", "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),), - "jni_var" : "Mat& %(n)s = *((Mat*)%(n)s_nativeObj)", - "jni_type" : "jlong", #"jni_name" : "*%(n)s", - "suffix" : "J" }, - - "Point" : { "j_type" : "Point", "jn_args" : (("double", ".x"), ("double", ".y")), - "jni_var" : "Point %(n)s((int)%(n)s_x, (int)%(n)s_y)", "jni_type" : "jdoubleArray", - "suffix" : "DD"}, - "Point2f" : { "j_type" : "Point", "jn_args" : (("double", ".x"), ("double", ".y")), - "jni_var" : "Point2f %(n)s((float)%(n)s_x, (float)%(n)s_y)", "jni_type" : "jdoubleArray", - "suffix" : "DD"}, - "Point2d" : { "j_type" : "Point", "jn_args" : (("double", ".x"), ("double", ".y")), - "jni_var" : "Point2d %(n)s(%(n)s_x, %(n)s_y)", "jni_type" : "jdoubleArray", - "suffix" : "DD"}, - "Point3i" : { "j_type" : "Point3", "jn_args" : (("double", ".x"), ("double", ".y"), ("double", ".z")), - "jni_var" : "Point3i %(n)s((int)%(n)s_x, (int)%(n)s_y, (int)%(n)s_z)", "jni_type" : "jdoubleArray", - "suffix" : "DDD"}, - "Point3f" : { "j_type" : "Point3", "jn_args" : (("double", ".x"), ("double", ".y"), ("double", ".z")), - "jni_var" : "Point3f %(n)s((float)%(n)s_x, (float)%(n)s_y, (float)%(n)s_z)", "jni_type" : "jdoubleArray", - "suffix" : "DDD"}, - "Point3d" : { "j_type" : "Point3", "jn_args" : (("double", ".x"), ("double", ".y"), ("double", ".z")), - "jni_var" : "Point3d %(n)s(%(n)s_x, %(n)s_y, %(n)s_z)", "jni_type" : "jdoubleArray", - "suffix" : "DDD"}, - "KeyPoint": { "j_type" : "KeyPoint", "jn_args" : (("float", ".x"), ("float", ".y"), ("float", ".size"), - ("float", ".angle"), ("float", ".response"), ("int", ".octave"), ("int", ".class_id")), - "jni_var" : "KeyPoint %(n)s(%(n)s_x, %(n)s_y, %(n)s_size, %(n)s_angle, %(n)s_response, %(n)s_octave, %(n)s_class_id)", - "jni_type" : "jdoubleArray", - "suffix" : "FFFFFII"}, - "DMatch" : { "j_type" : "DMatch", "jn_args" : ( ('int', 'queryIdx'), ('int', 'trainIdx'), - ('int', 'imgIdx'), ('float', 'distance'), ), - "jni_var" : "DMatch %(n)s(%(n)s_queryIdx, %(n)s_trainIdx, %(n)s_imgIdx, %(n)s_distance)", - "jni_type" : "jdoubleArray", - "suffix" : "IIIF"}, - "Rect" : { "j_type" : "Rect", "jn_args" : (("int", ".x"), ("int", ".y"), ("int", ".width"), ("int", ".height")), - "jni_var" : "Rect %(n)s(%(n)s_x, %(n)s_y, %(n)s_width, %(n)s_height)", "jni_type" : "jdoubleArray", - "suffix" : "IIII"}, - "Size" : { "j_type" : "Size", "jn_args" : (("double", ".width"), ("double", ".height")), - "jni_var" : "Size %(n)s((int)%(n)s_width, (int)%(n)s_height)", "jni_type" : "jdoubleArray", - "suffix" : "DD"}, - "Size2f" : { "j_type" : "Size", "jn_args" : (("double", ".width"), ("double", ".height")), - "jni_var" : "Size2f %(n)s((float)%(n)s_width, (float)%(n)s_height)", "jni_type" : "jdoubleArray", - "suffix" : "DD"}, - "RotatedRect": { "j_type" : "RotatedRect", "jn_args" : (("double", ".center.x"), ("double", ".center.y"), ("double", ".size.width"), ("double", ".size.height"), ("double", ".angle")), - "jni_var" : "RotatedRect %(n)s(cv::Point2f(%(n)s_center_x, %(n)s_center_y), cv::Size2f(%(n)s_size_width, %(n)s_size_height), %(n)s_angle)", - "jni_type" : "jdoubleArray", "suffix" : "DDDDD"}, - "Scalar" : { "j_type" : "Scalar", "jn_args" : (("double", ".val[0]"), ("double", ".val[1]"), ("double", ".val[2]"), ("double", ".val[3]")), - "jni_var" : "Scalar %(n)s(%(n)s_val0, %(n)s_val1, %(n)s_val2, %(n)s_val3)", "jni_type" : "jdoubleArray", - "suffix" : "DDDD"}, - "Range" : { "j_type" : "Range", "jn_args" : (("int", ".start"), ("int", ".end")), - "jni_var" : "Range %(n)s(%(n)s_start, %(n)s_end)", "jni_type" : "jdoubleArray", - "suffix" : "II"}, - "CvSlice" : { "j_type" : "Range", "jn_args" : (("int", ".start"), ("int", ".end")), - "jni_var" : "Range %(n)s(%(n)s_start, %(n)s_end)", "jni_type" : "jdoubleArray", - "suffix" : "II"}, - "string" : { "j_type" : "String", "jn_type" : "String", - "jni_type" : "jstring", "jni_name" : "n_%(n)s", - "jni_var" : 'const char* utf_%(n)s = env->GetStringUTFChars(%(n)s, 0); std::string n_%(n)s( utf_%(n)s ? utf_%(n)s : "" ); env->ReleaseStringUTFChars(%(n)s, utf_%(n)s)', - "suffix" : "Ljava_lang_String_2"}, - "String" : { "j_type" : "String", "jn_type" : "String", - "jni_type" : "jstring", "jni_name" : "n_%(n)s", - "jni_var" : 'const char* utf_%(n)s = env->GetStringUTFChars(%(n)s, 0); String n_%(n)s( utf_%(n)s ? utf_%(n)s : "" ); env->ReleaseStringUTFChars(%(n)s, utf_%(n)s)', - "suffix" : "Ljava_lang_String_2"}, - "c_string": { "j_type" : "String", "jn_type" : "String", - "jni_type" : "jstring", "jni_name" : "n_%(n)s.c_str()", - "jni_var" : 'const char* utf_%(n)s = env->GetStringUTFChars(%(n)s, 0); std::string n_%(n)s( utf_%(n)s ? utf_%(n)s : "" ); env->ReleaseStringUTFChars(%(n)s, utf_%(n)s)', - "suffix" : "Ljava_lang_String_2"}, -"TermCriteria": { "j_type" : "TermCriteria", "jn_args" : (("int", ".type"), ("int", ".maxCount"), ("double", ".epsilon")), - "jni_var" : "TermCriteria %(n)s(%(n)s_type, %(n)s_maxCount, %(n)s_epsilon)", "jni_type" : "jdoubleArray", - "suffix" : "IID"}, -"CvTermCriteria": { "j_type" : "TermCriteria", "jn_args" : (("int", ".type"), ("int", ".maxCount"), ("double", ".epsilon")), - "jni_var" : "TermCriteria %(n)s(%(n)s_type, %(n)s_maxCount, %(n)s_epsilon)", "jni_type" : "jdoubleArray", - "suffix" : "IID"}, - "Vec2d" : { "j_type" : "double[]", "jn_args" : (("double", ".val[0]"), ("double", ".val[1]")), - "jn_type" : "double[]", - "jni_var" : "Vec2d %(n)s(%(n)s_val0, %(n)s_val1)", "jni_type" : "jdoubleArray", - "suffix" : "DD"}, - "Vec3d" : { "j_type" : "double[]", "jn_args" : (("double", ".val[0]"), ("double", ".val[1]"), ("double", ".val[2]")), - "jn_type" : "double[]", - "jni_var" : "Vec3d %(n)s(%(n)s_val0, %(n)s_val1, %(n)s_val2)", "jni_type" : "jdoubleArray", - "suffix" : "DDD"}, - -} - -# { class : { func : {j_code, jn_code, cpp_code} } } -ManualFuncs = { - 'Core' : - { - 'minMaxLoc' : { - 'j_code' : """ - // manual port - public static class MinMaxLocResult { - public double minVal; - public double maxVal; - public Point minLoc; - public Point maxLoc; - - public MinMaxLocResult() { - minVal=0; maxVal=0; - minLoc=new Point(); - maxLoc=new Point(); - } - } - - // C++: minMaxLoc(Mat src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray()) - - //javadoc: minMaxLoc(src, mask) - public static MinMaxLocResult minMaxLoc(Mat src, Mat mask) { - MinMaxLocResult res = new MinMaxLocResult(); - long maskNativeObj=0; - if (mask != null) { - maskNativeObj=mask.nativeObj; - } - double resarr[] = n_minMaxLocManual(src.nativeObj, maskNativeObj); - res.minVal=resarr[0]; - res.maxVal=resarr[1]; - res.minLoc.x=resarr[2]; - res.minLoc.y=resarr[3]; - res.maxLoc.x=resarr[4]; - res.maxLoc.y=resarr[5]; - return res; - } - - //javadoc: minMaxLoc(src) - public static MinMaxLocResult minMaxLoc(Mat src) { - return minMaxLoc(src, null); - } - -""", - 'jn_code' : -""" private static native double[] n_minMaxLocManual(long src_nativeObj, long mask_nativeObj);\n""", - 'cpp_code' : -""" -// C++: minMaxLoc(Mat src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray()) - -JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Core_n_1minMaxLocManual - (JNIEnv* env, jclass cls, jlong src_nativeObj, jlong mask_nativeObj) -{ - try { - LOGD("Core::n_1minMaxLoc()"); - jdoubleArray result; - result = env->NewDoubleArray(6); - if (result == NULL) { - return NULL; /* out of memory error thrown */ - } - - Mat& src = *((Mat*)src_nativeObj); - - double minVal, maxVal; - Point minLoc, maxLoc; - if (mask_nativeObj != 0) { - Mat& mask = *((Mat*)mask_nativeObj); - minMaxLoc(src, &minVal, &maxVal, &minLoc, &maxLoc, mask); - } else { - minMaxLoc(src, &minVal, &maxVal, &minLoc, &maxLoc); - } - - jdouble fill[6]; - fill[0]=minVal; - fill[1]=maxVal; - fill[2]=minLoc.x; - fill[3]=minLoc.y; - fill[4]=maxLoc.x; - fill[5]=maxLoc.y; - - env->SetDoubleArrayRegion(result, 0, 6, fill); - - return result; - - } catch(cv::Exception e) { - LOGD("Core::n_1minMaxLoc() catched cv::Exception: %s", e.what()); - jclass je = env->FindClass("org/opencv/core/CvException"); - if(!je) je = env->FindClass("java/lang/Exception"); - env->ThrowNew(je, e.what()); - return NULL; - } catch (...) { - LOGD("Core::n_1minMaxLoc() catched unknown exception (...)"); - jclass je = env->FindClass("java/lang/Exception"); - env->ThrowNew(je, "Unknown exception in JNI code {core::minMaxLoc()}"); - return NULL; - } -} - -""", - }, # minMaxLoc - - 'getTextSize' : - { - 'j_code' : -""" - // C++: Size getTextSize(const string& text, int fontFace, double fontScale, int thickness, int* baseLine); - //javadoc:getTextSize(text, fontFace, fontScale, thickness, baseLine) - public static Size getTextSize(String text, int fontFace, double fontScale, int thickness, int[] baseLine) { - if(baseLine != null && baseLine.length != 1) - throw new java.lang.IllegalArgumentException("'baseLine' must be 'int[1]' or 'null'."); - Size retVal = new Size(n_getTextSize(text, fontFace, fontScale, thickness, baseLine)); - return retVal; - } -""", - 'jn_code' : -""" private static native double[] n_getTextSize(String text, int fontFace, double fontScale, int thickness, int[] baseLine);\n""", - 'cpp_code' : -""" -// C++: Size getTextSize(const string& text, int fontFace, double fontScale, int thickness, int* baseLine); - -JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Core_n_1getTextSize - (JNIEnv* env, jclass cls, jstring text, jint fontFace, jdouble fontScale, jint thickness, jintArray baseLine) -{ - try { - LOGD("Core::n_1getTextSize()"); - jdoubleArray result; - result = env->NewDoubleArray(2); - if (result == NULL) { - return NULL; /* out of memory error thrown */ - } - - const char* utf_text = env->GetStringUTFChars(text, 0); - std::string n_text( utf_text ? utf_text : "" ); - env->ReleaseStringUTFChars(text, utf_text); - - int _baseLine; - int* pbaseLine = 0; - - if (baseLine != NULL) - pbaseLine = &_baseLine; - - cv::Size rsize = cv::getTextSize(n_text, (int)fontFace, (double)fontScale, (int)thickness, pbaseLine); - - jdouble fill[2]; - fill[0]=rsize.width; - fill[1]=rsize.height; - - env->SetDoubleArrayRegion(result, 0, 2, fill); - - if (baseLine != NULL) - env->SetIntArrayRegion(baseLine, 0, 1, pbaseLine); - - return result; - - } catch(cv::Exception e) { - LOGD("Core::n_1getTextSize() catched cv::Exception: %s", e.what()); - jclass je = env->FindClass("org/opencv/core/CvException"); - if(!je) je = env->FindClass("java/lang/Exception"); - env->ThrowNew(je, e.what()); - return NULL; - } catch (...) { - LOGD("Core::n_1getTextSize() catched unknown exception (...)"); - jclass je = env->FindClass("java/lang/Exception"); - env->ThrowNew(je, "Unknown exception in JNI code {core::getTextSize()}"); - return NULL; - } -} - -""", - }, # getTextSize -## "checkRange" : #TBD -## {'j_code' : '/* TBD: checkRange() */', 'jn_code' : '', 'cpp_code' : '' }, - - "checkHardwareSupport" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - "setUseOptimized" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - "useOptimized" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - - }, # Core - - 'Highgui' : - { - "namedWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - "destroyWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - "destroyAllWindows" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - "startWindowThread" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - "setWindowProperty" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - "getWindowProperty" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - "getTrackbarPos" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - "setTrackbarPos" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - "imshow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - "waitKey" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - "moveWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - "resizeWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, - }, # Highgui - -} - -# { class : { func : {arg_name : ctype} } } -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' }, - }, # '', i.e. no class -} # func_arg_fix - -class ConstInfo(object): - def __init__(self, cname, name, val, addedManually=False): - self.cname = cname - self.name = re.sub(r"^Cv", "", name) - self.value = val - self.addedManually = addedManually - - -class ClassPropInfo(object): - def __init__(self, decl): # [f_ctype, f_name, '', '/RW'] - self.ctype = decl[0] - self.name = decl[1] - self.rw = "/RW" in decl[3] - -class ClassInfo(object): - def __init__(self, decl): # [ 'class/struct cname', ': base', [modlist] ] - name = decl[0] - name = name[name.find(" ")+1:].strip() - self.cname = self.name = self.jname = re.sub(r"^cv\.", "", name) - self.cname = self.cname.replace(".", "::") - self.methods = {} - self.methods_suffixes = {} - self.consts = [] # using a list to save the occurence order - self.private_consts = [] - self.imports = set() - self.props= [] - self.jname = self.name - for m in decl[2]: - if m.startswith("="): - self.jname = m[1:] - self.base = '' - if decl[1]: - self.base = re.sub(r"\b"+self.jname+r"\b", "", decl[1].replace(":", "")).strip() - - - -class ArgInfo(object): - def __init__(self, arg_tuple): # [ ctype, name, def val, [mod], argno ] - self.pointer = False - ctype = arg_tuple[0] - if ctype.endswith("*"): - ctype = ctype[:-1] - self.pointer = True - if ctype == 'vector_Point2d': - ctype = 'vector_Point2f' - elif ctype == 'vector_Point3d': - ctype = 'vector_Point3f' - self.ctype = ctype - self.name = arg_tuple[1] - self.defval = arg_tuple[2] - self.out = "" - if "/O" in arg_tuple[3]: - self.out = "O" - if "/IO" in arg_tuple[3]: - self.out = "IO" - - -class FuncInfo(object): - def __init__(self, decl): # [ funcname, return_ctype, [modifiers], [args] ] - name = re.sub(r"^cv\.", "", decl[0]) - self.cname = name.replace(".", "::") - classname = "" - dpos = name.rfind(".") - if dpos >= 0: - classname = name[:dpos] - name = name[dpos+1:] - self.classname = classname - self.jname = self.name = name - if "[" in name: - self.jname = "getelem" - for m in decl[2]: - if m.startswith("="): - self.jname = m[1:] - self.static = ["","static"][ "/S" in decl[2] ] - self.ctype = re.sub(r"^CvTermCriteria", "TermCriteria", decl[1] or "") - self.args = [] - arg_fix_map = func_arg_fix.get(classname, {}).get(self.jname, {}) - for a in decl[3]: - arg = a[:] - arg[0] = arg_fix_map.get(arg[1], arg[0]) - ai = ArgInfo(arg) - self.args.append(ai) - - - -class FuncFamilyInfo(object): - def __init__(self, decl): # [ funcname, return_ctype, [modifiers], [args] ] - self.funcs = [] - self.funcs.append( FuncInfo(decl) ) - self.jname = self.funcs[0].jname - self.isconstructor = self.funcs[0].name == self.funcs[0].classname - - - - def add_func(self, fi): - self.funcs.append( fi ) - - -class JavaWrapperGenerator(object): - def __init__(self): - self.clear() - - def clear(self): - self.classes = { "Mat" : ClassInfo([ 'class Mat', '', [], [] ]) } - self.module = "" - self.Module = "" - self.java_code= {} # { class : {j_code, jn_code} } - self.cpp_code = None - self.ported_func_list = [] - self.skipped_func_list = [] - self.def_args_hist = {} # { def_args_cnt : funcs_cnt } - self.classes_map = [] - self.classes_simple = [] - - def add_class_code_stream(self, class_name, cls_base = ''): - jname = self.classes[class_name].jname - self.java_code[class_name] = { "j_code" : StringIO(), "jn_code" : StringIO(), } - if class_name != self.Module: - if cls_base: - self.java_code[class_name]["j_code"].write(""" -// -// This file is auto-generated. Please don't modify it! -// -package org.opencv.%(m)s; - -$imports - -// C++: class %(c)s -//javadoc: %(c)s -public class %(jc)s extends %(base)s { - - protected %(jc)s(long addr) { super(addr); } - -""" % { 'm' : self.module, 'c' : class_name, 'jc' : jname, 'base' : cls_base }) - else: # not cls_base - self.java_code[class_name]["j_code"].write(""" -// -// This file is auto-generated. Please don't modify it! -// -package org.opencv.%(m)s; - -$imports - -// C++: class %(c)s -//javadoc: %(c)s -public class %(jc)s { - - protected final long nativeObj; - protected %(jc)s(long addr) { nativeObj = addr; } - -""" % { 'm' : self.module, 'c' : class_name, 'jc' : jname }) - else: # class_name == self.Module - self.java_code[class_name]["j_code"].write(""" -// -// This file is auto-generated. Please don't modify it! -// -package org.opencv.%(m)s; - -$imports - -public class %(jc)s { -""" % { 'm' : self.module, 'jc' : jname } ) - - self.java_code[class_name]["jn_code"].write(""" - // - // native stuff - // - static { System.loadLibrary("opencv_java"); } -""" ) - - - - def add_class(self, decl): - classinfo = ClassInfo(decl) - if classinfo.name in class_ignore_list: - return - name = classinfo.name - if name in self.classes: - print "Generator error: class %s (%s) is duplicated" % \ - (name, classinfo.cname) - return - self.classes[name] = classinfo - if name in type_dict: - print "Duplicated class: " + name - return - if '/Simple' in decl[2]: - self.classes_simple.append(name) - if ('/Map' in decl[2]): - self.classes_map.append(name) - #adding default c-tor - ffi = FuncFamilyInfo(['cv.'+name+'.'+name, '', [], []]) - classinfo.methods[ffi.jname] = ffi - type_dict[name] = \ - { "j_type" : classinfo.jname, - "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),), - "jni_name" : "(*("+name+"*)%(n)s_nativeObj)", "jni_type" : "jlong", - "suffix" : "J" } - type_dict[name+'*'] = \ - { "j_type" : classinfo.jname, - "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),), - "jni_name" : "("+name+"*)%(n)s_nativeObj", "jni_type" : "jlong", - "suffix" : "J" } - - # missing_consts { Module : { public : [[name, val],...], private : [[]...] } } - if name in missing_consts: - if 'private' in missing_consts[name]: - for (n, val) in missing_consts[name]['private']: - classinfo.private_consts.append( ConstInfo(n, n, val, True) ) - if 'public' in missing_consts[name]: - for (n, val) in missing_consts[name]['public']: - classinfo.consts.append( ConstInfo(n, n, val, True) ) - - # class props - for p in decl[3]: - if True: #"vector" not in p[0]: - classinfo.props.append( ClassPropInfo(p) ) - else: - print "Skipped property: [%s]" % name, p - - self.add_class_code_stream(name, classinfo.base) - if classinfo.base: - self.get_imports(name, classinfo.base) - - - def add_const(self, decl): # [ "const cname", val, [], [] ] - name = decl[0].replace("const ", "").strip() - name = re.sub(r"^cv\.", "", name) - cname = name.replace(".", "::") - for c in const_ignore_list: - if re.match(c, name): - return - # class member? - dpos = name.rfind(".") - if dpos >= 0: - classname = name[:dpos] - name = name[dpos+1:] - else: - classname = self.Module - if classname not in self.classes: - # this class isn't wrapped - # skipping this const - return - - consts = self.classes[classname].consts - for c in const_private_list: - if re.match(c, name): - consts = self.classes[classname].private_consts - break - - constinfo = ConstInfo(cname, name, decl[1]) - # checking duplication - for list in self.classes[classname].consts, self.classes[classname].private_consts: - for c in list: - if c.name == constinfo.name: - if c.addedManually: - return - print "Generator error: constant %s (%s) is duplicated" \ - % (constinfo.name, constinfo.cname) - sys.exit(-1) - - consts.append(constinfo) - - def add_func(self, decl): - ffi = FuncFamilyInfo(decl) - classname = ffi.funcs[0].classname or self.Module - if classname in class_ignore_list: - return - if classname in ManualFuncs and ffi.jname in ManualFuncs[classname]: - return - if classname not in self.classes: - print "Generator error: the class %s for method %s is missing" % \ - (classname, ffi.jname) - sys.exit(-1) - func_map = self.classes[classname].methods - if ffi.jname in func_map: - func_map[ffi.jname].add_func(ffi.funcs[0]) - else: - func_map[ffi.jname] = ffi - # calc args with def val - cnt = len([a for a in ffi.funcs[0].args if a.defval]) - self.def_args_hist[cnt] = self.def_args_hist.get(cnt, 0) + 1 - - def save(self, path, buf): - f = open(path, "wt") - f.write(buf) - f.close() - - def gen(self, srcfiles, module, output_path): - self.clear() - self.module = module - self.Module = module.capitalize() - parser = hdr_parser.CppHeaderParser() - - self.add_class( ['class ' + self.Module, '', [], []] ) # [ 'class/struct cname', ':bases', [modlist] [props] ] - - # scan the headers and build more descriptive maps of classes, consts, functions - for hdr in srcfiles: - decls = parser.parse(hdr) - for decl in decls: - name = decl[0] - if name.startswith("struct") or name.startswith("class"): - self.add_class(decl) - elif name.startswith("const"): - self.add_const(decl) - else: # function - self.add_func(decl) - - self.cpp_code = StringIO() - self.cpp_code.write(""" -// -// This file is auto-generated, please don't edit! -// - -#include - -#include "converters.h" - -#ifdef DEBUG -#include -#define MODULE_LOG_TAG "OpenCV.%(m)s" -#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, MODULE_LOG_TAG, __VA_ARGS__)) -#else //DEBUG -#define LOGD(...) -#endif //DEBUG - -#include "opencv2/%(m)s/%(m)s.hpp" - -using namespace cv; - -extern "C" { - -""" % {'m' : module} ) - - # generate code for the classes - for name in self.classes.keys(): - if name == "Mat": - continue - self.gen_class(name) - # saving code streams - imports = "\n".join([ "import %s;" % c for c in \ - sorted(self.classes[name].imports) if not c.startswith('org.opencv.'+self.module) ]) - self.java_code[name]["j_code"].write("\n\n%s\n}\n" % self.java_code[name]["jn_code"].getvalue()) - java_code = self.java_code[name]["j_code"].getvalue() - java_code = Template(java_code).substitute(imports = imports) - self.save("%s/%s+%s.java" % (output_path, module, self.classes[name].jname), java_code) - - self.cpp_code.write( '\n} // extern "C"\n' ) - self.save(output_path+"/"+module+".cpp", self.cpp_code.getvalue()) - - # report - report = StringIO() - report.write("PORTED FUNCs LIST (%i of %i):\n\n" % \ - (len(self.ported_func_list), len(self.ported_func_list)+ len(self.skipped_func_list)) - ) - report.write("\n".join(self.ported_func_list)) - report.write("\n\nSKIPPED FUNCs LIST (%i of %i):\n\n" % \ - (len(self.skipped_func_list), len(self.ported_func_list)+ len(self.skipped_func_list)) - ) - report.write("".join(self.skipped_func_list)) - - for i in self.def_args_hist.keys(): - report.write("\n%i def args - %i funcs" % (i, self.def_args_hist[i])) - - report.write("\n\nclass as MAP:\n\t" + "\n\t".join(self.classes_map)) - report.write("\n\nclass SIMPLE:\n\t" + "\n\t".join(self.classes_simple)) - - self.save(output_path+"/"+module+".txt", report.getvalue()) - - print "Done %i of %i funcs." % (len(self.ported_func_list), len(self.ported_func_list)+ len(self.skipped_func_list)) - - - - def get_imports(self, scope_classname, ctype): - imports = self.classes[scope_classname or self.Module].imports - if ctype.startswith('vector_vector'): - imports.add("org.opencv.core.Mat") - imports.add("java.util.List") - imports.add("org.opencv.utils.Converters") - self.get_imports(scope_classname, ctype.replace('vector_vector', 'vector')) - return - if ctype.startswith('vector'): - imports.add("org.opencv.core.Mat") - if type_dict[ctype]['j_type'].startswith('MatOf'): - imports.add("org.opencv.core." + type_dict[ctype]['j_type']) - return - else: - imports.add("java.util.List") - imports.add("org.opencv.utils.Converters") - self.get_imports(scope_classname, ctype.replace('vector_', '')) - return - j_type = '' - if ctype in type_dict: - j_type = type_dict[ctype]['j_type'] - elif ctype in ("Algorithm"): - j_type = ctype - if j_type in ( "CvType", "Mat", "Point", "Point3", "Range", "Rect", "RotatedRect", "Scalar", "Size", "TermCriteria", "Algorithm" ): - imports.add("org.opencv.core." + j_type) - if j_type == 'String': - imports.add("java.lang.String") - return - - - - def gen_func(self, fi, prop_name=''): - j_code = self.java_code[fi.classname or self.Module]["j_code"] - jn_code = self.java_code[fi.classname or self.Module]["jn_code"] - cpp_code = self.cpp_code - - # c_decl - # e.g: void add(Mat src1, Mat src2, Mat dst, Mat mask = Mat(), int dtype = -1) - if prop_name: - c_decl = "%s %s::%s" % (fi.ctype, fi.classname, prop_name) - else: - decl_args = [] - for a in fi.args: - s = a.ctype or ' _hidden_ ' - if a.pointer: - s += "*" - elif a.out: - s += "&" - s += " " + a.name - if a.defval: - s += " = "+a.defval - decl_args.append(s) - c_decl = "%s %s %s(%s)" % ( fi.static, fi.ctype, fi.cname, ", ".join(decl_args) ) - - # java comment - j_code.write( "\n //\n // C++: %s\n //\n\n" % c_decl ) - # check if we 'know' all the types - if fi.ctype not in type_dict: # unsupported ret type - msg = "// Return type '%s' is not supported, skipping the function\n\n" % fi.ctype - self.skipped_func_list.append(c_decl + "\n" + msg) - j_code.write( " "*4 + msg ) - print "SKIP:", c_decl, "\n\tdue to RET type", fi.ctype - return - for a in fi.args: - if a.ctype not in type_dict: - msg = "// Unknown type '%s' (%s), skipping the function\n\n" % (a.ctype, a.out or "I") - self.skipped_func_list.append(c_decl + "\n" + msg) - j_code.write( " "*4 + msg ) - print "SKIP:", c_decl, "\n\tdue to ARG type", a.ctype, "/" + (a.out or "I") - return - - self.ported_func_list.append(c_decl) - - # jn & cpp comment - jn_code.write( "\n // C++: %s\n" % c_decl ) - cpp_code.write( "\n//\n// %s\n//\n" % c_decl ) - - # java args - args = fi.args[:] # copy - suffix_counter = int( self.classes[fi.classname or self.Module].methods_suffixes.get(fi.jname, -1) ) - while True: - suffix_counter += 1 - self.classes[fi.classname or self.Module].methods_suffixes[fi.jname] = suffix_counter - # java native method args - jn_args = [] - # jni (cpp) function args - jni_args = [ArgInfo([ "env", "env", "", [], "" ]), ArgInfo([ "cls", "cls", "", [], "" ])] - j_prologue = [] - j_epilogue = [] - c_prologue = [] - c_epilogue = [] - if type_dict[fi.ctype]["jni_type"] == "jdoubleArray": - fields = type_dict[fi.ctype]["jn_args"] - c_epilogue.append( \ - ("jdoubleArray _da_retval_ = env->NewDoubleArray(%(cnt)i); " + - "jdouble _tmp_retval_[%(cnt)i] = {%(args)s}; " + - "env->SetDoubleArrayRegion(_da_retval_, 0, %(cnt)i, _tmp_retval_);") % - { "cnt" : len(fields), "args" : ", ".join(["_retval_" + f[1] for f in fields]) } ) - if fi.classname and fi.ctype and not fi.static: # non-static class method except c-tor - # adding 'self' - jn_args.append ( ArgInfo([ "__int64", "nativeObj", "", [], "" ]) ) - jni_args.append( ArgInfo([ "__int64", "self", "", [], "" ]) ) - self.get_imports(fi.classname, fi.ctype) - for a in args: - if not a.ctype: # hidden - continue - self.get_imports(fi.classname, a.ctype) - if "vector" in a.ctype: # pass as Mat - jn_args.append ( ArgInfo([ "__int64", "%s_mat.nativeObj" % a.name, "", [], "" ]) ) - jni_args.append ( ArgInfo([ "__int64", "%s_mat_nativeObj" % a.name, "", [], "" ]) ) - c_prologue.append( type_dict[a.ctype]["jni_var"] % {"n" : a.name} + ";" ) - c_prologue.append( "Mat& %(n)s_mat = *((Mat*)%(n)s_mat_nativeObj)" % {"n" : a.name} + ";" ) - if "I" in a.out or not a.out: - if a.ctype.startswith("vector_vector_"): - self.classes[fi.classname or self.Module].imports.add("java.util.ArrayList") - j_prologue.append( "List %(n)s_tmplm = new ArrayList((%(n)s != null) ? %(n)s.size() : 0);" % {"n" : a.name } ) - j_prologue.append( "Mat %(n)s_mat = Converters.%(t)s_to_Mat(%(n)s, %(n)s_tmplm);" % {"n" : a.name, "t" : a.ctype} ) - else: - if not type_dict[a.ctype]["j_type"].startswith("MatOf"): - j_prologue.append( "Mat %(n)s_mat = Converters.%(t)s_to_Mat(%(n)s);" % {"n" : a.name, "t" : a.ctype} ) - else: - j_prologue.append( "Mat %s_mat = %s;" % (a.name, a.name) ) - c_prologue.append( "Mat_to_%(t)s( %(n)s_mat, %(n)s );" % {"n" : a.name, "t" : a.ctype} ) - else: - if not type_dict[a.ctype]["j_type"].startswith("MatOf"): - j_prologue.append( "Mat %s_mat = new Mat();" % a.name ) - else: - j_prologue.append( "Mat %s_mat = %s;" % (a.name, a.name) ) - if "O" in a.out: - if not type_dict[a.ctype]["j_type"].startswith("MatOf"): - j_epilogue.append("Converters.Mat_to_%(t)s(%(n)s_mat, %(n)s);" % {"t" : a.ctype, "n" : a.name}) - c_epilogue.append( "%(t)s_to_Mat( %(n)s, %(n)s_mat );" % {"n" : a.name, "t" : a.ctype} ) - else: - fields = type_dict[a.ctype].get("jn_args", ((a.ctype, ""),)) - if "I" in a.out or not a.out or a.ctype in self.classes: # input arg, pass by primitive fields - for f in fields: - jn_args.append ( ArgInfo([ f[0], a.name + f[1], "", [], "" ]) ) - jni_args.append( ArgInfo([ f[0], a.name + f[1].replace(".","_").replace("[","").replace("]",""), "", [], "" ]) ) - if a.out and a.ctype not in self.classes: # out arg, pass as double[] - jn_args.append ( ArgInfo([ "double[]", "%s_out" % a.name, "", [], "" ]) ) - jni_args.append ( ArgInfo([ "double[]", "%s_out" % a.name, "", [], "" ]) ) - j_prologue.append( "double[] %s_out = new double[%i];" % (a.name, len(fields)) ) - c_epilogue.append( \ - "jdouble tmp_%(n)s[%(cnt)i] = {%(args)s}; env->SetDoubleArrayRegion(%(n)s_out, 0, %(cnt)i, tmp_%(n)s);" % - { "n" : a.name, "cnt" : len(fields), "args" : ", ".join([a.name + f[1] for f in fields]) } ) - if a.ctype in ('bool', 'int', 'long', 'float', 'double'): - j_epilogue.append('if(%(n)s!=null) %(n)s[0] = (%(t)s)%(n)s_out[0];' % {'n':a.name,'t':a.ctype}) - else: - set_vals = [] - i = 0 - for f in fields: - set_vals.append( "%(n)s%(f)s = %(t)s%(n)s_out[%(i)i]" % - {"n" : a.name, "t": ("("+type_dict[f[0]]["j_type"]+")", "")[f[0]=="double"], "f" : f[1], "i" : i} - ) - i += 1 - j_epilogue.append( "if("+a.name+"!=null){ " + "; ".join(set_vals) + "; } ") - - - # java part: - # private java NATIVE method decl - # e.g. - # private static native void add_0(long src1, long src2, long dst, long mask, int dtype); - jn_code.write( Template(\ - " private static native $type $name($args);\n").substitute(\ - type = type_dict[fi.ctype].get("jn_type", "double[]"), \ - name = fi.jname + '_' + str(suffix_counter), \ - args = ", ".join(["%s %s" % (type_dict[a.ctype]["jn_type"], a.name.replace(".","_").replace("[","").replace("]","")) for a in jn_args]) - ) ); - - # java part: - - #java doc comment - f_name = fi.name - if fi.classname: - f_name = fi.classname + "::" + fi.name - java_doc = "//javadoc: " + f_name + "(%s)" % ", ".join([a.name for a in args if a.ctype]) - j_code.write(" "*4 + java_doc + "\n") - - # public java wrapper method impl (calling native one above) - # e.g. - # public static void add( Mat src1, Mat src2, Mat dst, Mat mask, int dtype ) - # { add_0( src1.nativeObj, src2.nativeObj, dst.nativeObj, mask.nativeObj, dtype ); } - ret_type = fi.ctype - if fi.ctype.endswith('*'): - ret_type = ret_type[:-1] - ret_val = type_dict[ret_type]["j_type"] + " retVal = " - tail = "" - ret = "return retVal;" - if ret_type.startswith('vector'): - tail = ")" - j_type = type_dict[ret_type]["j_type"] - if j_type.startswith('MatOf'): - ret_val += j_type + ".fromNativeAddr(" - else: - ret_val = "Mat retValMat = new Mat(" - j_prologue.append( j_type + ' retVal = new Array' + j_type+'();') - self.classes[fi.classname or self.Module].imports.add('java.util.ArrayList') - j_epilogue.append('Converters.Mat_to_' + ret_type + '(retValMat, retVal);') - elif ret_type == "void": - ret_val = "" - ret = "return;" - elif ret_type == "": # c-tor - if fi.classname and self.classes[fi.classname].base: - ret_val = "super( " - tail = " )" - else: - ret_val = "nativeObj = " - ret = "return;" - elif ret_type in self.classes: # wrapped class - ret_val = type_dict[ret_type]["j_type"] + " retVal = new " + self.classes[ret_type].jname + "(" - tail = ")" - elif "jn_type" not in type_dict[ret_type]: - ret_val = type_dict[fi.ctype]["j_type"] + " retVal = new " + type_dict[ret_type]["j_type"] + "(" - tail = ")" - - static = "static" - if fi.classname: - static = fi.static - - j_args = [] - for a in args: - if not a.ctype: #hidden - continue - jt = type_dict[a.ctype]["j_type"] - if a.out and a.ctype in ('bool', 'int', 'long', 'float', 'double'): - jt += '[]' - j_args.append( jt + ' ' + a.name ) - - j_code.write( Template(\ -""" public $static $j_type $j_name($j_args) - { - $prologue - $ret_val$jn_name($jn_args_call)$tail; - $epilogue - $ret - } - -""" - ).substitute(\ - ret = ret, \ - ret_val = ret_val, \ - tail = tail, \ - prologue = "\n ".join(j_prologue), \ - epilogue = "\n ".join(j_epilogue), \ - static=static, \ - j_type=type_dict[fi.ctype]["j_type"], \ - j_name=fi.jname, \ - j_args=", ".join(j_args), \ - jn_name=fi.jname + '_' + str(suffix_counter), \ - jn_args_call=", ".join( [a.name for a in jn_args] ),\ - ) - ) - - - # cpp part: - # jni_func(..) { _retval_ = cv_func(..); return _retval_; } - ret = "return _retval_;" - default = "return 0;" - if fi.ctype == "void": - ret = "return;" - default = "return;" - elif not fi.ctype: # c-tor - ret = "return (jlong) _retval_;" - elif fi.ctype.startswith('vector'): # c-tor - ret = "return (jlong) _retval_;" - elif fi.ctype == "string": - ret = "return env->NewStringUTF(_retval_.c_str());" - default = 'return env->NewStringUTF("");' - elif fi.ctype in self.classes: # wrapped class: - ret = "return (jlong) new %s(_retval_);" % fi.ctype - elif ret_type in self.classes: # pointer to wrapped class: - ret = "return (jlong) _retval_;" - elif type_dict[fi.ctype]["jni_type"] == "jdoubleArray": - ret = "return _da_retval_;" - - # hack: replacing func call with property set/get - name = fi.name - if prop_name: - if args: - name = prop_name + " = " - else: - name = prop_name + ";//" - - cvname = "cv::" + name - retval = fi.ctype + " _retval_ = " - if fi.ctype == "void": - retval = "" - elif fi.ctype.startswith('vector'): - retval = type_dict[fi.ctype]['jni_var'] % {"n" : '_ret_val_vector_'} + " = " - c_epilogue.append("Mat* _retval_ = new Mat();") - c_epilogue.append(fi.ctype+"_to_Mat(_ret_val_vector_, *_retval_);") - if fi.classname: - if not fi.ctype: # c-tor - retval = fi.classname + "* _retval_ = " - cvname = "new " + fi.classname - elif fi.static: - cvname = "%s::%s" % (fi.classname, name) - else: - cvname = "me->" + name - c_prologue.append(\ - "%(cls)s* me = (%(cls)s*) self; //TODO: check for NULL" \ - % { "cls" : fi.classname} \ - ) - cvargs = [] - for a in args: - if a.pointer: - jni_name = "&%(n)s" - else: - jni_name = "%(n)s" - if not a.ctype: # hidden - jni_name = a.defval - cvargs.append( type_dict[a.ctype].get("jni_name", jni_name) % {"n" : a.name}) - if "vector" not in a.ctype : - if ("I" in a.out or not a.out or a.ctype in self.classes) and "jni_var" in type_dict[a.ctype]: # complex type - c_prologue.append(type_dict[a.ctype]["jni_var"] % {"n" : a.name} + ";") - if a.out and "I" not in a.out and a.ctype not in self.classes and a.ctype: - c_prologue.append("%s %s;" % (a.ctype, a.name)) - - rtype = type_dict[fi.ctype].get("jni_type", "jdoubleArray") - clazz = self.Module - if fi.classname: - clazz = self.classes[fi.classname].jname - cpp_code.write ( Template( \ -""" - -JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_${clazz}_$fname - ($args) -{ - try { - LOGD("$module::$fname()"); - $prologue - $retval$cvname( $cvargs ); - $epilogue - $ret - } catch(cv::Exception e) { - LOGD("$module::$fname() catched cv::Exception: %s", e.what()); - jclass je = env->FindClass("org/opencv/core/CvException"); - if(!je) je = env->FindClass("java/lang/Exception"); - env->ThrowNew(je, e.what()); - $default - } catch (...) { - LOGD("$module::$fname() catched unknown exception (...)"); - jclass je = env->FindClass("java/lang/Exception"); - env->ThrowNew(je, "Unknown exception in JNI code {$module::$fname()}"); - $default - } -} - - -""" ).substitute( \ - rtype = rtype, \ - module = self.module, \ - clazz = clazz.replace('_', '_1'), \ - fname = (fi.jname + '_' + str(suffix_counter)).replace('_', '_1'), \ - args = ", ".join(["%s %s" % (type_dict[a.ctype].get("jni_type"), a.name) for a in jni_args]), \ - prologue = "\n ".join(c_prologue), \ - epilogue = " ".join(c_epilogue), \ - ret = ret, \ - cvname = cvname, \ - cvargs = ", ".join(cvargs), \ - default = default, \ - retval = retval, \ - ) ) - - # processing args with default values - if not args or not args[-1].defval: - break - while args and args[-1].defval: - # 'smart' overloads filtering - a = args.pop() - if a.name in ('mask', 'dtype', 'ddepth', 'lineType', 'borderType', 'borderMode', 'criteria'): - break - - - - def gen_class(self, name): - # generate code for the class - ci = self.classes[name] - # constants - if ci.private_consts: - self.java_code[name]['j_code'].write(""" - private static final int - %s;\n\n""" % (",\n"+" "*12).join(["%s = %s" % (c.name, c.value) for c in ci.private_consts]) - ) - if ci.consts: - self.java_code[name]['j_code'].write(""" - public static final int - %s;\n\n""" % (",\n"+" "*12).join(["%s = %s" % (c.name, c.value) for c in ci.consts]) - ) - # c-tors - fflist = ci.methods.items() - fflist.sort() - for n, ffi in fflist: - if ffi.isconstructor: - for fi in ffi.funcs: - fi.jname = ci.jname - self.gen_func(fi) - # other methods - for n, ffi in fflist: - if not ffi.isconstructor: - for fi in ffi.funcs: - self.gen_func(fi) - # props - for pi in ci.props: - # getter - getter_name = name + ".get_" + pi.name - #print getter_name - fi = FuncInfo( [getter_name, pi.ctype, [], []] ) # [ funcname, return_ctype, [modifiers], [args] ] - self.gen_func(fi, pi.name) - if pi.rw: - #setter - setter_name = name + ".set_" + pi.name - #print setter_name - fi = FuncInfo( [ setter_name, "void", [], [ [pi.ctype, pi.name, "", [], ""] ] ] ) - self.gen_func(fi, pi.name) - - # manual ports - if name in ManualFuncs: - for func in ManualFuncs[name].keys(): - self.java_code[name]["j_code"].write ( ManualFuncs[name][func]["j_code"] ) - self.java_code[name]["jn_code"].write( ManualFuncs[name][func]["jn_code"] ) - self.cpp_code.write( ManualFuncs[name][func]["cpp_code"] ) - - if name != self.Module: - # finalize() - self.java_code[name]["j_code"].write( -""" - @Override - protected void finalize() throws Throwable { - delete(nativeObj); - } -""" ) - - self.java_code[name]["jn_code"].write( -""" - // native support for java finalize() - private static native void delete(long nativeObj); -""" ) - - # native support for java finalize() - self.cpp_code.write( \ -""" -// -// native support for java finalize() -// static void %(cls)s::delete( __int64 self ) -// - -JNIEXPORT void JNICALL Java_org_opencv_%(module)s_%(j_cls)s_delete - (JNIEnv* env, jclass cls, jlong self) -{ - delete (%(cls)s*) self; -} - -""" % {"module" : module, "cls" : name, "j_cls" : ci.jname} - ) - - -if __name__ == "__main__": - if len(sys.argv) < 4: - print "Usage:\n", \ - os.path.basename(sys.argv[0]), \ - " [...]" - print "Current args are: ", ", ".join(["'"+a+"'" for a in sys.argv]) - exit(0) - - dstdir = "." - hdr_parser_path = os.path.abspath(sys.argv[1]) - if hdr_parser_path.endswith(".py"): - hdr_parser_path = os.path.dirname(hdr_parser_path) - sys.path.append(hdr_parser_path) - import hdr_parser - module = sys.argv[2] - srcfiles = sys.argv[3:] - print "Generating module '" + module + "' from headers:\n\t" + "\n\t".join(srcfiles) - generator = JavaWrapperGenerator() - generator.gen(srcfiles, module, dstdir) - +import sys, re, os.path +from string import Template + +try: + from cStringIO import StringIO +except: + from StringIO import StringIO + +class_ignore_list = ( + #core + "FileNode", "FileStorage", "KDTree", + #highgui + "VideoWriter", "VideoCapture", + #features2d + #"KeyPoint", "MSER", "StarDetector", "SURF", "DMatch", + #ml + #"EM", +) + +const_ignore_list = ( + "CV_CAP_OPENNI", + "CV_CAP_PROP_OPENNI_", + "WINDOW_AUTOSIZE", + "CV_WND_PROP_", + "CV_WINDOW_", + "CV_EVENT_", + "CV_GUI_", + "CV_PUSH_BUTTON", + "CV_CHECKBOX", + "CV_RADIOBOX", + + #attention! + #the following constants are added to this list using code automatic generation + #TODO: should be checked + "CV_CAP_ANY", + "CV_CAP_MIL", + "CV_CAP_VFW", + "CV_CAP_V4L", + "CV_CAP_V4L2", + "CV_CAP_FIREWARE", + "CV_CAP_FIREWIRE", + "CV_CAP_IEEE1394", + "CV_CAP_DC1394", + "CV_CAP_CMU1394", + "CV_CAP_STEREO", + "CV_CAP_TYZX", + "CV_TYZX_LEFT", + "CV_TYZX_RIGHT", + "CV_TYZX_COLOR", + "CV_TYZX_Z", + "CV_CAP_QT", + "CV_CAP_UNICAP", + "CV_CAP_DSHOW", + "CV_CAP_PVAPI", + "CV_CAP_PROP_DC1394_OFF", + "CV_CAP_PROP_DC1394_MODE_MANUAL", + "CV_CAP_PROP_DC1394_MODE_AUTO", + "CV_CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO", + "CV_CAP_PROP_POS_MSEC", + "CV_CAP_PROP_POS_FRAMES", + "CV_CAP_PROP_POS_AVI_RATIO", + "CV_CAP_PROP_FPS", + "CV_CAP_PROP_FOURCC", + "CV_CAP_PROP_FRAME_COUNT", + "CV_CAP_PROP_FORMAT", + "CV_CAP_PROP_MODE", + "CV_CAP_PROP_BRIGHTNESS", + "CV_CAP_PROP_CONTRAST", + "CV_CAP_PROP_SATURATION", + "CV_CAP_PROP_HUE", + "CV_CAP_PROP_GAIN", + "CV_CAP_PROP_EXPOSURE", + "CV_CAP_PROP_CONVERT_RGB", + "CV_CAP_PROP_WHITE_BALANCE_BLUE_U", + "CV_CAP_PROP_RECTIFICATION", + "CV_CAP_PROP_MONOCROME", + "CV_CAP_PROP_SHARPNESS", + "CV_CAP_PROP_AUTO_EXPOSURE", + "CV_CAP_PROP_GAMMA", + "CV_CAP_PROP_TEMPERATURE", + "CV_CAP_PROP_TRIGGER", + "CV_CAP_PROP_TRIGGER_DELAY", + "CV_CAP_PROP_WHITE_BALANCE_RED_V", + "CV_CAP_PROP_MAX_DC1394", + "CV_CAP_GSTREAMER_QUEUE_LENGTH", + "CV_CAP_PROP_PVAPI_MULTICASTIP", + "CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING", + "EVENT_.*", + "CV_L?(BGRA?|RGBA?|GRAY|XYZ|YCrCb|Luv|Lab|HLS|YUV|HSV)\d*2L?(BGRA?|RGBA?|GRAY|XYZ|YCrCb|Luv|Lab|HLS|YUV|HSV).*", + "CV_COLORCVT_MAX", + "CV_.*Bayer.*", + "CV_YUV420(i|sp|p)2.+", + "CV_TM_.+", + "CV_FLOODFILL_.+", + "CV_ADAPTIVE_THRESH_.+", + "WINDOW_.+", + "WND_PROP_.+", +) + +const_private_list = ( + "CV_MOP_.+", + "CV_INTER_.+", + "CV_THRESH_.+", + "CV_INPAINT_.+", + "CV_RETR_.+", + "CV_CHAIN_APPROX_.+", + "OPPONENTEXTRACTOR", + "GRIDRETECTOR", + "PYRAMIDDETECTOR", + "DYNAMICDETECTOR", +) + +# { Module : { public : [[name, val],...], private : [[]...] } } +missing_consts = \ +{ + 'Core' : + { + 'private' : + ( + ('CV_8U', 0 ), ('CV_8S', 1 ), + ('CV_16U', 2 ), ('CV_16S', 3 ), + ('CV_32S', 4 ), + ('CV_32F', 5 ), ('CV_64F', 6 ), + ('CV_USRTYPE1', 7 ), + ), # private + 'public' : + ( + ('SVD_MODIFY_A', 1), ('SVD_NO_UV', 2), ('SVD_FULL_UV', 4), + ('FILLED', -1), + ('LINE_AA', 16), ('LINE_8', 8), ('LINE_4', 4), + ('REDUCE_SUM', 0), ('REDUCE_AVG', 1), ('REDUCE_MAX', 2), ('REDUCE_MIN', 3), + ) #public + }, # Core + + "Imgproc": + { + 'private' : + ( + ('IPL_BORDER_CONSTANT', 0 ), + ('IPL_BORDER_REPLICATE', 1 ), + ('IPL_BORDER_REFLECT', 2 ), + ('IPL_BORDER_WRAP', 3 ), + ('IPL_BORDER_REFLECT_101', 4 ), + ('IPL_BORDER_TRANSPARENT', 5 ), + ) # private + }, # Imgproc + + "Calib3d": + { + 'private' : + ( + ('CV_LMEDS', 4), + ('CV_RANSAC', 8), + ('CV_FM_LMEDS', 'CV_LMEDS'), + ('CV_FM_RANSAC','CV_RANSAC'), + ('CV_FM_7POINT', 1), + ('CV_FM_8POINT', 2), + ('CV_CALIB_USE_INTRINSIC_GUESS', 1), + ('CV_CALIB_FIX_ASPECT_RATIO', 2), + ('CV_CALIB_FIX_PRINCIPAL_POINT', 4), + ('CV_CALIB_ZERO_TANGENT_DIST', 8), + ('CV_CALIB_FIX_FOCAL_LENGTH', 16), + ('CV_CALIB_FIX_K1', 32), + ('CV_CALIB_FIX_K2', 64), + ('CV_CALIB_FIX_K3', 128), + ('CV_CALIB_FIX_K4', 2048), + ('CV_CALIB_FIX_K5', 4096), + ('CV_CALIB_FIX_K6', 8192), + ('CV_CALIB_RATIONAL_MODEL', 16384), + ('CV_CALIB_FIX_INTRINSIC', 256), + ('CV_CALIB_SAME_FOCAL_LENGTH', 512), + ('CV_CALIB_ZERO_DISPARITY', 1024), + ) # public + }, # Calib3d + + "Video": + { + 'private' : + ( + ('CV_LKFLOW_INITIAL_GUESSES', 4 ), + ('CV_LKFLOW_GET_MIN_EIGENVALS', 8 ), + ) # private + }, # Video + +} + + +# c_type : { java/jni correspondence } +type_dict = { +# "simple" : { j_type : "?", jn_type : "?", jni_type : "?", suffix : "?" }, + "" : { "j_type" : "", "jn_type" : "long", "jni_type" : "jlong" }, # c-tor ret_type + "void" : { "j_type" : "void", "jn_type" : "void", "jni_type" : "void" }, + "env" : { "j_type" : "", "jn_type" : "", "jni_type" : "JNIEnv*"}, + "cls" : { "j_type" : "", "jn_type" : "", "jni_type" : "jclass"}, + "bool" : { "j_type" : "boolean", "jn_type" : "boolean", "jni_type" : "jboolean", "suffix" : "Z" }, + "int" : { "j_type" : "int", "jn_type" : "int", "jni_type" : "jint", "suffix" : "I" }, + "long" : { "j_type" : "int", "jn_type" : "int", "jni_type" : "jint", "suffix" : "I" }, + "float" : { "j_type" : "float", "jn_type" : "float", "jni_type" : "jfloat", "suffix" : "F" }, + "double" : { "j_type" : "double", "jn_type" : "double", "jni_type" : "jdouble", "suffix" : "D" }, + "size_t" : { "j_type" : "long", "jn_type" : "long", "jni_type" : "jlong", "suffix" : "J" }, + "__int64" : { "j_type" : "long", "jn_type" : "long", "jni_type" : "jlong", "suffix" : "J" }, + "int64" : { "j_type" : "long", "jn_type" : "long", "jni_type" : "jlong", "suffix" : "J" }, + "double[]": { "j_type" : "double[]", "jn_type" : "double[]", "jni_type" : "jdoubleArray", "suffix" : "_3D" }, + +# "complex" : { j_type : "?", jn_args : (("", ""),), jn_name : "", jni_var : "", jni_name : "", "suffix" : "?" }, + + "vector_Point" : { "j_type" : "MatOfPoint", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_Point2f" : { "j_type" : "MatOfPoint2f", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + #"vector_Point2d" : { "j_type" : "MatOfPoint2d", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_Point3i" : { "j_type" : "MatOfPoint3", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_Point3f" : { "j_type" : "MatOfPoint3f", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + #"vector_Point3d" : { "j_type" : "MatOfPoint3d", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_KeyPoint" : { "j_type" : "MatOfKeyPoint", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_DMatch" : { "j_type" : "MatOfDMatch", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_Rect" : { "j_type" : "MatOfRect", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_uchar" : { "j_type" : "MatOfByte", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_char" : { "j_type" : "MatOfByte", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_int" : { "j_type" : "MatOfInt", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_float" : { "j_type" : "MatOfFloat", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_double" : { "j_type" : "MatOfDouble", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_Vec4i" : { "j_type" : "MatOfInt4", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_Vec4f" : { "j_type" : "MatOfFloat4", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + "vector_Vec6f" : { "j_type" : "MatOfFloat6", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + + "vector_Mat" : { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector %(n)s", "suffix" : "J" }, + + "vector_vector_KeyPoint": { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector< vector > %(n)s" }, + "vector_vector_DMatch" : { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector< vector > %(n)s" }, + "vector_vector_char" : { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector< vector > %(n)s" }, + "vector_vector_Point" : { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector< vector > %(n)s" }, + "vector_vector_Point2f" : { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector< vector > %(n)s" }, + "vector_vector_Point3f" : { "j_type" : "List", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "vector< vector > %(n)s" }, + + "Mat" : { "j_type" : "Mat", "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),), + "jni_var" : "Mat& %(n)s = *((Mat*)%(n)s_nativeObj)", + "jni_type" : "jlong", #"jni_name" : "*%(n)s", + "suffix" : "J" }, + + "Point" : { "j_type" : "Point", "jn_args" : (("double", ".x"), ("double", ".y")), + "jni_var" : "Point %(n)s((int)%(n)s_x, (int)%(n)s_y)", "jni_type" : "jdoubleArray", + "suffix" : "DD"}, + "Point2f" : { "j_type" : "Point", "jn_args" : (("double", ".x"), ("double", ".y")), + "jni_var" : "Point2f %(n)s((float)%(n)s_x, (float)%(n)s_y)", "jni_type" : "jdoubleArray", + "suffix" : "DD"}, + "Point2d" : { "j_type" : "Point", "jn_args" : (("double", ".x"), ("double", ".y")), + "jni_var" : "Point2d %(n)s(%(n)s_x, %(n)s_y)", "jni_type" : "jdoubleArray", + "suffix" : "DD"}, + "Point3i" : { "j_type" : "Point3", "jn_args" : (("double", ".x"), ("double", ".y"), ("double", ".z")), + "jni_var" : "Point3i %(n)s((int)%(n)s_x, (int)%(n)s_y, (int)%(n)s_z)", "jni_type" : "jdoubleArray", + "suffix" : "DDD"}, + "Point3f" : { "j_type" : "Point3", "jn_args" : (("double", ".x"), ("double", ".y"), ("double", ".z")), + "jni_var" : "Point3f %(n)s((float)%(n)s_x, (float)%(n)s_y, (float)%(n)s_z)", "jni_type" : "jdoubleArray", + "suffix" : "DDD"}, + "Point3d" : { "j_type" : "Point3", "jn_args" : (("double", ".x"), ("double", ".y"), ("double", ".z")), + "jni_var" : "Point3d %(n)s(%(n)s_x, %(n)s_y, %(n)s_z)", "jni_type" : "jdoubleArray", + "suffix" : "DDD"}, + "KeyPoint": { "j_type" : "KeyPoint", "jn_args" : (("float", ".x"), ("float", ".y"), ("float", ".size"), + ("float", ".angle"), ("float", ".response"), ("int", ".octave"), ("int", ".class_id")), + "jni_var" : "KeyPoint %(n)s(%(n)s_x, %(n)s_y, %(n)s_size, %(n)s_angle, %(n)s_response, %(n)s_octave, %(n)s_class_id)", + "jni_type" : "jdoubleArray", + "suffix" : "FFFFFII"}, + "DMatch" : { "j_type" : "DMatch", "jn_args" : ( ('int', 'queryIdx'), ('int', 'trainIdx'), + ('int', 'imgIdx'), ('float', 'distance'), ), + "jni_var" : "DMatch %(n)s(%(n)s_queryIdx, %(n)s_trainIdx, %(n)s_imgIdx, %(n)s_distance)", + "jni_type" : "jdoubleArray", + "suffix" : "IIIF"}, + "Rect" : { "j_type" : "Rect", "jn_args" : (("int", ".x"), ("int", ".y"), ("int", ".width"), ("int", ".height")), + "jni_var" : "Rect %(n)s(%(n)s_x, %(n)s_y, %(n)s_width, %(n)s_height)", "jni_type" : "jdoubleArray", + "suffix" : "IIII"}, + "Size" : { "j_type" : "Size", "jn_args" : (("double", ".width"), ("double", ".height")), + "jni_var" : "Size %(n)s((int)%(n)s_width, (int)%(n)s_height)", "jni_type" : "jdoubleArray", + "suffix" : "DD"}, + "Size2f" : { "j_type" : "Size", "jn_args" : (("double", ".width"), ("double", ".height")), + "jni_var" : "Size2f %(n)s((float)%(n)s_width, (float)%(n)s_height)", "jni_type" : "jdoubleArray", + "suffix" : "DD"}, + "RotatedRect": { "j_type" : "RotatedRect", "jn_args" : (("double", ".center.x"), ("double", ".center.y"), ("double", ".size.width"), ("double", ".size.height"), ("double", ".angle")), + "jni_var" : "RotatedRect %(n)s(cv::Point2f(%(n)s_center_x, %(n)s_center_y), cv::Size2f(%(n)s_size_width, %(n)s_size_height), %(n)s_angle)", + "jni_type" : "jdoubleArray", "suffix" : "DDDDD"}, + "Scalar" : { "j_type" : "Scalar", "jn_args" : (("double", ".val[0]"), ("double", ".val[1]"), ("double", ".val[2]"), ("double", ".val[3]")), + "jni_var" : "Scalar %(n)s(%(n)s_val0, %(n)s_val1, %(n)s_val2, %(n)s_val3)", "jni_type" : "jdoubleArray", + "suffix" : "DDDD"}, + "Range" : { "j_type" : "Range", "jn_args" : (("int", ".start"), ("int", ".end")), + "jni_var" : "Range %(n)s(%(n)s_start, %(n)s_end)", "jni_type" : "jdoubleArray", + "suffix" : "II"}, + "CvSlice" : { "j_type" : "Range", "jn_args" : (("int", ".start"), ("int", ".end")), + "jni_var" : "Range %(n)s(%(n)s_start, %(n)s_end)", "jni_type" : "jdoubleArray", + "suffix" : "II"}, + "string" : { "j_type" : "String", "jn_type" : "String", + "jni_type" : "jstring", "jni_name" : "n_%(n)s", + "jni_var" : 'const char* utf_%(n)s = env->GetStringUTFChars(%(n)s, 0); std::string n_%(n)s( utf_%(n)s ? utf_%(n)s : "" ); env->ReleaseStringUTFChars(%(n)s, utf_%(n)s)', + "suffix" : "Ljava_lang_String_2"}, + "String" : { "j_type" : "String", "jn_type" : "String", + "jni_type" : "jstring", "jni_name" : "n_%(n)s", + "jni_var" : 'const char* utf_%(n)s = env->GetStringUTFChars(%(n)s, 0); String n_%(n)s( utf_%(n)s ? utf_%(n)s : "" ); env->ReleaseStringUTFChars(%(n)s, utf_%(n)s)', + "suffix" : "Ljava_lang_String_2"}, + "c_string": { "j_type" : "String", "jn_type" : "String", + "jni_type" : "jstring", "jni_name" : "n_%(n)s.c_str()", + "jni_var" : 'const char* utf_%(n)s = env->GetStringUTFChars(%(n)s, 0); std::string n_%(n)s( utf_%(n)s ? utf_%(n)s : "" ); env->ReleaseStringUTFChars(%(n)s, utf_%(n)s)', + "suffix" : "Ljava_lang_String_2"}, +"TermCriteria": { "j_type" : "TermCriteria", "jn_args" : (("int", ".type"), ("int", ".maxCount"), ("double", ".epsilon")), + "jni_var" : "TermCriteria %(n)s(%(n)s_type, %(n)s_maxCount, %(n)s_epsilon)", "jni_type" : "jdoubleArray", + "suffix" : "IID"}, +"CvTermCriteria": { "j_type" : "TermCriteria", "jn_args" : (("int", ".type"), ("int", ".maxCount"), ("double", ".epsilon")), + "jni_var" : "TermCriteria %(n)s(%(n)s_type, %(n)s_maxCount, %(n)s_epsilon)", "jni_type" : "jdoubleArray", + "suffix" : "IID"}, + "Vec2d" : { "j_type" : "double[]", "jn_args" : (("double", ".val[0]"), ("double", ".val[1]")), + "jn_type" : "double[]", + "jni_var" : "Vec2d %(n)s(%(n)s_val0, %(n)s_val1)", "jni_type" : "jdoubleArray", + "suffix" : "DD"}, + "Vec3d" : { "j_type" : "double[]", "jn_args" : (("double", ".val[0]"), ("double", ".val[1]"), ("double", ".val[2]")), + "jn_type" : "double[]", + "jni_var" : "Vec3d %(n)s(%(n)s_val0, %(n)s_val1, %(n)s_val2)", "jni_type" : "jdoubleArray", + "suffix" : "DDD"}, + +} + +# { class : { func : {j_code, jn_code, cpp_code} } } +ManualFuncs = { + 'Core' : + { + 'minMaxLoc' : { + 'j_code' : """ + // manual port + public static class MinMaxLocResult { + public double minVal; + public double maxVal; + public Point minLoc; + public Point maxLoc; + + public MinMaxLocResult() { + minVal=0; maxVal=0; + minLoc=new Point(); + maxLoc=new Point(); + } + } + + // C++: minMaxLoc(Mat src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray()) + + //javadoc: minMaxLoc(src, mask) + public static MinMaxLocResult minMaxLoc(Mat src, Mat mask) { + MinMaxLocResult res = new MinMaxLocResult(); + long maskNativeObj=0; + if (mask != null) { + maskNativeObj=mask.nativeObj; + } + double resarr[] = n_minMaxLocManual(src.nativeObj, maskNativeObj); + res.minVal=resarr[0]; + res.maxVal=resarr[1]; + res.minLoc.x=resarr[2]; + res.minLoc.y=resarr[3]; + res.maxLoc.x=resarr[4]; + res.maxLoc.y=resarr[5]; + return res; + } + + //javadoc: minMaxLoc(src) + public static MinMaxLocResult minMaxLoc(Mat src) { + return minMaxLoc(src, null); + } + +""", + 'jn_code' : +""" private static native double[] n_minMaxLocManual(long src_nativeObj, long mask_nativeObj);\n""", + 'cpp_code' : +""" +// C++: minMaxLoc(Mat src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray()) + +JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Core_n_1minMaxLocManual + (JNIEnv* env, jclass cls, jlong src_nativeObj, jlong mask_nativeObj) +{ + try { + LOGD("Core::n_1minMaxLoc()"); + jdoubleArray result; + result = env->NewDoubleArray(6); + if (result == NULL) { + return NULL; /* out of memory error thrown */ + } + + Mat& src = *((Mat*)src_nativeObj); + + double minVal, maxVal; + Point minLoc, maxLoc; + if (mask_nativeObj != 0) { + Mat& mask = *((Mat*)mask_nativeObj); + minMaxLoc(src, &minVal, &maxVal, &minLoc, &maxLoc, mask); + } else { + minMaxLoc(src, &minVal, &maxVal, &minLoc, &maxLoc); + } + + jdouble fill[6]; + fill[0]=minVal; + fill[1]=maxVal; + fill[2]=minLoc.x; + fill[3]=minLoc.y; + fill[4]=maxLoc.x; + fill[5]=maxLoc.y; + + env->SetDoubleArrayRegion(result, 0, 6, fill); + + return result; + + } catch(cv::Exception e) { + LOGD("Core::n_1minMaxLoc() catched cv::Exception: %s", e.what()); + jclass je = env->FindClass("org/opencv/core/CvException"); + if(!je) je = env->FindClass("java/lang/Exception"); + env->ThrowNew(je, e.what()); + return NULL; + } catch (...) { + LOGD("Core::n_1minMaxLoc() catched unknown exception (...)"); + jclass je = env->FindClass("java/lang/Exception"); + env->ThrowNew(je, "Unknown exception in JNI code {core::minMaxLoc()}"); + return NULL; + } +} + +""", + }, # minMaxLoc + + 'getTextSize' : + { + 'j_code' : +""" + // C++: Size getTextSize(const string& text, int fontFace, double fontScale, int thickness, int* baseLine); + //javadoc:getTextSize(text, fontFace, fontScale, thickness, baseLine) + public static Size getTextSize(String text, int fontFace, double fontScale, int thickness, int[] baseLine) { + if(baseLine != null && baseLine.length != 1) + throw new java.lang.IllegalArgumentException("'baseLine' must be 'int[1]' or 'null'."); + Size retVal = new Size(n_getTextSize(text, fontFace, fontScale, thickness, baseLine)); + return retVal; + } +""", + 'jn_code' : +""" private static native double[] n_getTextSize(String text, int fontFace, double fontScale, int thickness, int[] baseLine);\n""", + 'cpp_code' : +""" +// C++: Size getTextSize(const string& text, int fontFace, double fontScale, int thickness, int* baseLine); + +JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Core_n_1getTextSize + (JNIEnv* env, jclass cls, jstring text, jint fontFace, jdouble fontScale, jint thickness, jintArray baseLine) +{ + try { + LOGD("Core::n_1getTextSize()"); + jdoubleArray result; + result = env->NewDoubleArray(2); + if (result == NULL) { + return NULL; /* out of memory error thrown */ + } + + const char* utf_text = env->GetStringUTFChars(text, 0); + std::string n_text( utf_text ? utf_text : "" ); + env->ReleaseStringUTFChars(text, utf_text); + + int _baseLine; + int* pbaseLine = 0; + + if (baseLine != NULL) + pbaseLine = &_baseLine; + + cv::Size rsize = cv::getTextSize(n_text, (int)fontFace, (double)fontScale, (int)thickness, pbaseLine); + + jdouble fill[2]; + fill[0]=rsize.width; + fill[1]=rsize.height; + + env->SetDoubleArrayRegion(result, 0, 2, fill); + + if (baseLine != NULL) + env->SetIntArrayRegion(baseLine, 0, 1, pbaseLine); + + return result; + + } catch(cv::Exception e) { + LOGD("Core::n_1getTextSize() catched cv::Exception: %s", e.what()); + jclass je = env->FindClass("org/opencv/core/CvException"); + if(!je) je = env->FindClass("java/lang/Exception"); + env->ThrowNew(je, e.what()); + return NULL; + } catch (...) { + LOGD("Core::n_1getTextSize() catched unknown exception (...)"); + jclass je = env->FindClass("java/lang/Exception"); + env->ThrowNew(je, "Unknown exception in JNI code {core::getTextSize()}"); + return NULL; + } +} + +""", + }, # getTextSize +## "checkRange" : #TBD +## {'j_code' : '/* TBD: checkRange() */', 'jn_code' : '', 'cpp_code' : '' }, + + "checkHardwareSupport" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + "setUseOptimized" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + "useOptimized" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + + }, # Core + + 'Highgui' : + { + "namedWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + "destroyWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + "destroyAllWindows" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + "startWindowThread" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + "setWindowProperty" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + "getWindowProperty" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + "getTrackbarPos" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + "setTrackbarPos" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + "imshow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + "waitKey" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + "moveWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + "resizeWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, + }, # Highgui + +} + +# { class : { func : {arg_name : ctype} } } +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' }, + }, # '', i.e. no class +} # func_arg_fix + +class ConstInfo(object): + def __init__(self, cname, name, val, addedManually=False): + self.cname = cname + self.name = re.sub(r"^Cv", "", name) + self.value = val + self.addedManually = addedManually + + +class ClassPropInfo(object): + def __init__(self, decl): # [f_ctype, f_name, '', '/RW'] + self.ctype = decl[0] + self.name = decl[1] + self.rw = "/RW" in decl[3] + +class ClassInfo(object): + def __init__(self, decl): # [ 'class/struct cname', ': base', [modlist] ] + name = decl[0] + name = name[name.find(" ")+1:].strip() + self.cname = self.name = self.jname = re.sub(r"^cv\.", "", name) + self.cname = self.cname.replace(".", "::") + self.methods = {} + self.methods_suffixes = {} + self.consts = [] # using a list to save the occurence order + self.private_consts = [] + self.imports = set() + self.props= [] + self.jname = self.name + for m in decl[2]: + if m.startswith("="): + self.jname = m[1:] + self.base = '' + if decl[1]: + self.base = re.sub(r"\b"+self.jname+r"\b", "", decl[1].replace(":", "")).strip() + + + +class ArgInfo(object): + def __init__(self, arg_tuple): # [ ctype, name, def val, [mod], argno ] + self.pointer = False + ctype = arg_tuple[0] + if ctype.endswith("*"): + ctype = ctype[:-1] + self.pointer = True + if ctype == 'vector_Point2d': + ctype = 'vector_Point2f' + elif ctype == 'vector_Point3d': + ctype = 'vector_Point3f' + self.ctype = ctype + self.name = arg_tuple[1] + self.defval = arg_tuple[2] + self.out = "" + if "/O" in arg_tuple[3]: + self.out = "O" + if "/IO" in arg_tuple[3]: + self.out = "IO" + + +class FuncInfo(object): + def __init__(self, decl): # [ funcname, return_ctype, [modifiers], [args] ] + name = re.sub(r"^cv\.", "", decl[0]) + self.cname = name.replace(".", "::") + classname = "" + dpos = name.rfind(".") + if dpos >= 0: + classname = name[:dpos] + name = name[dpos+1:] + self.classname = classname + self.jname = self.name = name + if "[" in name: + self.jname = "getelem" + for m in decl[2]: + if m.startswith("="): + self.jname = m[1:] + self.static = ["","static"][ "/S" in decl[2] ] + self.ctype = re.sub(r"^CvTermCriteria", "TermCriteria", decl[1] or "") + self.args = [] + arg_fix_map = func_arg_fix.get(classname, {}).get(self.jname, {}) + for a in decl[3]: + arg = a[:] + arg[0] = arg_fix_map.get(arg[1], arg[0]) + ai = ArgInfo(arg) + self.args.append(ai) + + + +class FuncFamilyInfo(object): + def __init__(self, decl): # [ funcname, return_ctype, [modifiers], [args] ] + self.funcs = [] + self.funcs.append( FuncInfo(decl) ) + self.jname = self.funcs[0].jname + self.isconstructor = self.funcs[0].name == self.funcs[0].classname + + + + def add_func(self, fi): + self.funcs.append( fi ) + + +class JavaWrapperGenerator(object): + def __init__(self): + self.clear() + + def clear(self): + self.classes = { "Mat" : ClassInfo([ 'class Mat', '', [], [] ]) } + self.module = "" + self.Module = "" + self.java_code= {} # { class : {j_code, jn_code} } + self.cpp_code = None + self.ported_func_list = [] + self.skipped_func_list = [] + self.def_args_hist = {} # { def_args_cnt : funcs_cnt } + self.classes_map = [] + self.classes_simple = [] + + def add_class_code_stream(self, class_name, cls_base = ''): + jname = self.classes[class_name].jname + self.java_code[class_name] = { "j_code" : StringIO(), "jn_code" : StringIO(), } + if class_name != self.Module: + if cls_base: + self.java_code[class_name]["j_code"].write(""" +// +// This file is auto-generated. Please don't modify it! +// +package org.opencv.%(m)s; + +$imports + +// C++: class %(c)s +//javadoc: %(c)s +public class %(jc)s extends %(base)s { + + protected %(jc)s(long addr) { super(addr); } + +""" % { 'm' : self.module, 'c' : class_name, 'jc' : jname, 'base' : cls_base }) + else: # not cls_base + self.java_code[class_name]["j_code"].write(""" +// +// This file is auto-generated. Please don't modify it! +// +package org.opencv.%(m)s; + +$imports + +// C++: class %(c)s +//javadoc: %(c)s +public class %(jc)s { + + protected final long nativeObj; + protected %(jc)s(long addr) { nativeObj = addr; } + +""" % { 'm' : self.module, 'c' : class_name, 'jc' : jname }) + else: # class_name == self.Module + self.java_code[class_name]["j_code"].write(""" +// +// This file is auto-generated. Please don't modify it! +// +package org.opencv.%(m)s; + +$imports + +public class %(jc)s { +""" % { 'm' : self.module, 'jc' : jname } ) + + self.java_code[class_name]["jn_code"].write(""" + // + // native stuff + // + static { System.loadLibrary("opencv_java"); } +""" ) + + + + def add_class(self, decl): + classinfo = ClassInfo(decl) + if classinfo.name in class_ignore_list: + return + name = classinfo.name + if name in self.classes: + print "Generator error: class %s (%s) is duplicated" % \ + (name, classinfo.cname) + return + self.classes[name] = classinfo + if name in type_dict: + print "Duplicated class: " + name + return + if '/Simple' in decl[2]: + self.classes_simple.append(name) + if ('/Map' in decl[2]): + self.classes_map.append(name) + #adding default c-tor + ffi = FuncFamilyInfo(['cv.'+name+'.'+name, '', [], []]) + classinfo.methods[ffi.jname] = ffi + type_dict[name] = \ + { "j_type" : classinfo.jname, + "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),), + "jni_name" : "(*("+name+"*)%(n)s_nativeObj)", "jni_type" : "jlong", + "suffix" : "J" } + type_dict[name+'*'] = \ + { "j_type" : classinfo.jname, + "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),), + "jni_name" : "("+name+"*)%(n)s_nativeObj", "jni_type" : "jlong", + "suffix" : "J" } + + # missing_consts { Module : { public : [[name, val],...], private : [[]...] } } + if name in missing_consts: + if 'private' in missing_consts[name]: + for (n, val) in missing_consts[name]['private']: + classinfo.private_consts.append( ConstInfo(n, n, val, True) ) + if 'public' in missing_consts[name]: + for (n, val) in missing_consts[name]['public']: + classinfo.consts.append( ConstInfo(n, n, val, True) ) + + # class props + for p in decl[3]: + if True: #"vector" not in p[0]: + classinfo.props.append( ClassPropInfo(p) ) + else: + print "Skipped property: [%s]" % name, p + + self.add_class_code_stream(name, classinfo.base) + if classinfo.base: + self.get_imports(name, classinfo.base) + + + def add_const(self, decl): # [ "const cname", val, [], [] ] + name = decl[0].replace("const ", "").strip() + name = re.sub(r"^cv\.", "", name) + cname = name.replace(".", "::") + for c in const_ignore_list: + if re.match(c, name): + return + # class member? + dpos = name.rfind(".") + if dpos >= 0: + classname = name[:dpos] + name = name[dpos+1:] + else: + classname = self.Module + if classname not in self.classes: + # this class isn't wrapped + # skipping this const + return + + consts = self.classes[classname].consts + for c in const_private_list: + if re.match(c, name): + consts = self.classes[classname].private_consts + break + + constinfo = ConstInfo(cname, name, decl[1]) + # checking duplication + for list in self.classes[classname].consts, self.classes[classname].private_consts: + for c in list: + if c.name == constinfo.name: + if c.addedManually: + return + print "Generator error: constant %s (%s) is duplicated" \ + % (constinfo.name, constinfo.cname) + sys.exit(-1) + + consts.append(constinfo) + + def add_func(self, decl): + ffi = FuncFamilyInfo(decl) + classname = ffi.funcs[0].classname or self.Module + if classname in class_ignore_list: + return + if classname in ManualFuncs and ffi.jname in ManualFuncs[classname]: + return + if classname not in self.classes: + print "Generator error: the class %s for method %s is missing" % \ + (classname, ffi.jname) + sys.exit(-1) + func_map = self.classes[classname].methods + if ffi.jname in func_map: + func_map[ffi.jname].add_func(ffi.funcs[0]) + else: + func_map[ffi.jname] = ffi + # calc args with def val + cnt = len([a for a in ffi.funcs[0].args if a.defval]) + self.def_args_hist[cnt] = self.def_args_hist.get(cnt, 0) + 1 + + def save(self, path, buf): + f = open(path, "wt") + f.write(buf) + f.close() + + def gen(self, srcfiles, module, output_path): + self.clear() + self.module = module + self.Module = module.capitalize() + parser = hdr_parser.CppHeaderParser() + + self.add_class( ['class ' + self.Module, '', [], []] ) # [ 'class/struct cname', ':bases', [modlist] [props] ] + + # scan the headers and build more descriptive maps of classes, consts, functions + for hdr in srcfiles: + decls = parser.parse(hdr) + for decl in decls: + name = decl[0] + if name.startswith("struct") or name.startswith("class"): + self.add_class(decl) + elif name.startswith("const"): + self.add_const(decl) + else: # function + self.add_func(decl) + + self.cpp_code = StringIO() + self.cpp_code.write(""" +// +// This file is auto-generated, please don't edit! +// + +#include + +#include "converters.h" + +#ifdef DEBUG +#include +#define MODULE_LOG_TAG "OpenCV.%(m)s" +#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, MODULE_LOG_TAG, __VA_ARGS__)) +#else //DEBUG +#define LOGD(...) +#endif //DEBUG + +#include "opencv2/%(m)s/%(m)s.hpp" + +using namespace cv; + +extern "C" { + +""" % {'m' : module} ) + + # generate code for the classes + for name in self.classes.keys(): + if name == "Mat": + continue + self.gen_class(name) + # saving code streams + imports = "\n".join([ "import %s;" % c for c in \ + sorted(self.classes[name].imports) if not c.startswith('org.opencv.'+self.module) ]) + self.java_code[name]["j_code"].write("\n\n%s\n}\n" % self.java_code[name]["jn_code"].getvalue()) + java_code = self.java_code[name]["j_code"].getvalue() + java_code = Template(java_code).substitute(imports = imports) + self.save("%s/%s+%s.java" % (output_path, module, self.classes[name].jname), java_code) + + self.cpp_code.write( '\n} // extern "C"\n' ) + self.save(output_path+"/"+module+".cpp", self.cpp_code.getvalue()) + + # report + report = StringIO() + report.write("PORTED FUNCs LIST (%i of %i):\n\n" % \ + (len(self.ported_func_list), len(self.ported_func_list)+ len(self.skipped_func_list)) + ) + report.write("\n".join(self.ported_func_list)) + report.write("\n\nSKIPPED FUNCs LIST (%i of %i):\n\n" % \ + (len(self.skipped_func_list), len(self.ported_func_list)+ len(self.skipped_func_list)) + ) + report.write("".join(self.skipped_func_list)) + + for i in self.def_args_hist.keys(): + report.write("\n%i def args - %i funcs" % (i, self.def_args_hist[i])) + + report.write("\n\nclass as MAP:\n\t" + "\n\t".join(self.classes_map)) + report.write("\n\nclass SIMPLE:\n\t" + "\n\t".join(self.classes_simple)) + + self.save(output_path+"/"+module+".txt", report.getvalue()) + + print "Done %i of %i funcs." % (len(self.ported_func_list), len(self.ported_func_list)+ len(self.skipped_func_list)) + + + + def get_imports(self, scope_classname, ctype): + imports = self.classes[scope_classname or self.Module].imports + if ctype.startswith('vector_vector'): + imports.add("org.opencv.core.Mat") + imports.add("java.util.List") + imports.add("org.opencv.utils.Converters") + self.get_imports(scope_classname, ctype.replace('vector_vector', 'vector')) + return + if ctype.startswith('vector'): + imports.add("org.opencv.core.Mat") + if type_dict[ctype]['j_type'].startswith('MatOf'): + imports.add("org.opencv.core." + type_dict[ctype]['j_type']) + return + else: + imports.add("java.util.List") + imports.add("org.opencv.utils.Converters") + self.get_imports(scope_classname, ctype.replace('vector_', '')) + return + j_type = '' + if ctype in type_dict: + j_type = type_dict[ctype]['j_type'] + elif ctype in ("Algorithm"): + j_type = ctype + if j_type in ( "CvType", "Mat", "Point", "Point3", "Range", "Rect", "RotatedRect", "Scalar", "Size", "TermCriteria", "Algorithm" ): + imports.add("org.opencv.core." + j_type) + if j_type == 'String': + imports.add("java.lang.String") + return + + + + def gen_func(self, fi, prop_name=''): + j_code = self.java_code[fi.classname or self.Module]["j_code"] + jn_code = self.java_code[fi.classname or self.Module]["jn_code"] + cpp_code = self.cpp_code + + # c_decl + # e.g: void add(Mat src1, Mat src2, Mat dst, Mat mask = Mat(), int dtype = -1) + if prop_name: + c_decl = "%s %s::%s" % (fi.ctype, fi.classname, prop_name) + else: + decl_args = [] + for a in fi.args: + s = a.ctype or ' _hidden_ ' + if a.pointer: + s += "*" + elif a.out: + s += "&" + s += " " + a.name + if a.defval: + s += " = "+a.defval + decl_args.append(s) + c_decl = "%s %s %s(%s)" % ( fi.static, fi.ctype, fi.cname, ", ".join(decl_args) ) + + # java comment + j_code.write( "\n //\n // C++: %s\n //\n\n" % c_decl ) + # check if we 'know' all the types + if fi.ctype not in type_dict: # unsupported ret type + msg = "// Return type '%s' is not supported, skipping the function\n\n" % fi.ctype + self.skipped_func_list.append(c_decl + "\n" + msg) + j_code.write( " "*4 + msg ) + print "SKIP:", c_decl, "\n\tdue to RET type", fi.ctype + return + for a in fi.args: + if a.ctype not in type_dict: + msg = "// Unknown type '%s' (%s), skipping the function\n\n" % (a.ctype, a.out or "I") + self.skipped_func_list.append(c_decl + "\n" + msg) + j_code.write( " "*4 + msg ) + print "SKIP:", c_decl, "\n\tdue to ARG type", a.ctype, "/" + (a.out or "I") + return + + self.ported_func_list.append(c_decl) + + # jn & cpp comment + jn_code.write( "\n // C++: %s\n" % c_decl ) + cpp_code.write( "\n//\n// %s\n//\n" % c_decl ) + + # java args + args = fi.args[:] # copy + suffix_counter = int( self.classes[fi.classname or self.Module].methods_suffixes.get(fi.jname, -1) ) + while True: + suffix_counter += 1 + self.classes[fi.classname or self.Module].methods_suffixes[fi.jname] = suffix_counter + # java native method args + jn_args = [] + # jni (cpp) function args + jni_args = [ArgInfo([ "env", "env", "", [], "" ]), ArgInfo([ "cls", "cls", "", [], "" ])] + j_prologue = [] + j_epilogue = [] + c_prologue = [] + c_epilogue = [] + if type_dict[fi.ctype]["jni_type"] == "jdoubleArray": + fields = type_dict[fi.ctype]["jn_args"] + c_epilogue.append( \ + ("jdoubleArray _da_retval_ = env->NewDoubleArray(%(cnt)i); " + + "jdouble _tmp_retval_[%(cnt)i] = {%(args)s}; " + + "env->SetDoubleArrayRegion(_da_retval_, 0, %(cnt)i, _tmp_retval_);") % + { "cnt" : len(fields), "args" : ", ".join(["_retval_" + f[1] for f in fields]) } ) + if fi.classname and fi.ctype and not fi.static: # non-static class method except c-tor + # adding 'self' + jn_args.append ( ArgInfo([ "__int64", "nativeObj", "", [], "" ]) ) + jni_args.append( ArgInfo([ "__int64", "self", "", [], "" ]) ) + self.get_imports(fi.classname, fi.ctype) + for a in args: + if not a.ctype: # hidden + continue + self.get_imports(fi.classname, a.ctype) + if "vector" in a.ctype: # pass as Mat + jn_args.append ( ArgInfo([ "__int64", "%s_mat.nativeObj" % a.name, "", [], "" ]) ) + jni_args.append ( ArgInfo([ "__int64", "%s_mat_nativeObj" % a.name, "", [], "" ]) ) + c_prologue.append( type_dict[a.ctype]["jni_var"] % {"n" : a.name} + ";" ) + c_prologue.append( "Mat& %(n)s_mat = *((Mat*)%(n)s_mat_nativeObj)" % {"n" : a.name} + ";" ) + if "I" in a.out or not a.out: + if a.ctype.startswith("vector_vector_"): + self.classes[fi.classname or self.Module].imports.add("java.util.ArrayList") + j_prologue.append( "List %(n)s_tmplm = new ArrayList((%(n)s != null) ? %(n)s.size() : 0);" % {"n" : a.name } ) + j_prologue.append( "Mat %(n)s_mat = Converters.%(t)s_to_Mat(%(n)s, %(n)s_tmplm);" % {"n" : a.name, "t" : a.ctype} ) + else: + if not type_dict[a.ctype]["j_type"].startswith("MatOf"): + j_prologue.append( "Mat %(n)s_mat = Converters.%(t)s_to_Mat(%(n)s);" % {"n" : a.name, "t" : a.ctype} ) + else: + j_prologue.append( "Mat %s_mat = %s;" % (a.name, a.name) ) + c_prologue.append( "Mat_to_%(t)s( %(n)s_mat, %(n)s );" % {"n" : a.name, "t" : a.ctype} ) + else: + if not type_dict[a.ctype]["j_type"].startswith("MatOf"): + j_prologue.append( "Mat %s_mat = new Mat();" % a.name ) + else: + j_prologue.append( "Mat %s_mat = %s;" % (a.name, a.name) ) + if "O" in a.out: + if not type_dict[a.ctype]["j_type"].startswith("MatOf"): + j_epilogue.append("Converters.Mat_to_%(t)s(%(n)s_mat, %(n)s);" % {"t" : a.ctype, "n" : a.name}) + c_epilogue.append( "%(t)s_to_Mat( %(n)s, %(n)s_mat );" % {"n" : a.name, "t" : a.ctype} ) + else: + fields = type_dict[a.ctype].get("jn_args", ((a.ctype, ""),)) + if "I" in a.out or not a.out or a.ctype in self.classes: # input arg, pass by primitive fields + for f in fields: + jn_args.append ( ArgInfo([ f[0], a.name + f[1], "", [], "" ]) ) + jni_args.append( ArgInfo([ f[0], a.name + f[1].replace(".","_").replace("[","").replace("]",""), "", [], "" ]) ) + if a.out and a.ctype not in self.classes: # out arg, pass as double[] + jn_args.append ( ArgInfo([ "double[]", "%s_out" % a.name, "", [], "" ]) ) + jni_args.append ( ArgInfo([ "double[]", "%s_out" % a.name, "", [], "" ]) ) + j_prologue.append( "double[] %s_out = new double[%i];" % (a.name, len(fields)) ) + c_epilogue.append( \ + "jdouble tmp_%(n)s[%(cnt)i] = {%(args)s}; env->SetDoubleArrayRegion(%(n)s_out, 0, %(cnt)i, tmp_%(n)s);" % + { "n" : a.name, "cnt" : len(fields), "args" : ", ".join([a.name + f[1] for f in fields]) } ) + if a.ctype in ('bool', 'int', 'long', 'float', 'double'): + j_epilogue.append('if(%(n)s!=null) %(n)s[0] = (%(t)s)%(n)s_out[0];' % {'n':a.name,'t':a.ctype}) + else: + set_vals = [] + i = 0 + for f in fields: + set_vals.append( "%(n)s%(f)s = %(t)s%(n)s_out[%(i)i]" % + {"n" : a.name, "t": ("("+type_dict[f[0]]["j_type"]+")", "")[f[0]=="double"], "f" : f[1], "i" : i} + ) + i += 1 + j_epilogue.append( "if("+a.name+"!=null){ " + "; ".join(set_vals) + "; } ") + + + # java part: + # private java NATIVE method decl + # e.g. + # private static native void add_0(long src1, long src2, long dst, long mask, int dtype); + jn_code.write( Template(\ + " private static native $type $name($args);\n").substitute(\ + type = type_dict[fi.ctype].get("jn_type", "double[]"), \ + name = fi.jname + '_' + str(suffix_counter), \ + args = ", ".join(["%s %s" % (type_dict[a.ctype]["jn_type"], a.name.replace(".","_").replace("[","").replace("]","")) for a in jn_args]) + ) ); + + # java part: + + #java doc comment + f_name = fi.name + if fi.classname: + f_name = fi.classname + "::" + fi.name + java_doc = "//javadoc: " + f_name + "(%s)" % ", ".join([a.name for a in args if a.ctype]) + j_code.write(" "*4 + java_doc + "\n") + + # public java wrapper method impl (calling native one above) + # e.g. + # public static void add( Mat src1, Mat src2, Mat dst, Mat mask, int dtype ) + # { add_0( src1.nativeObj, src2.nativeObj, dst.nativeObj, mask.nativeObj, dtype ); } + ret_type = fi.ctype + if fi.ctype.endswith('*'): + ret_type = ret_type[:-1] + ret_val = type_dict[ret_type]["j_type"] + " retVal = " + tail = "" + ret = "return retVal;" + if ret_type.startswith('vector'): + tail = ")" + j_type = type_dict[ret_type]["j_type"] + if j_type.startswith('MatOf'): + ret_val += j_type + ".fromNativeAddr(" + else: + ret_val = "Mat retValMat = new Mat(" + j_prologue.append( j_type + ' retVal = new Array' + j_type+'();') + self.classes[fi.classname or self.Module].imports.add('java.util.ArrayList') + j_epilogue.append('Converters.Mat_to_' + ret_type + '(retValMat, retVal);') + elif ret_type == "void": + ret_val = "" + ret = "return;" + elif ret_type == "": # c-tor + if fi.classname and self.classes[fi.classname].base: + ret_val = "super( " + tail = " )" + else: + ret_val = "nativeObj = " + ret = "return;" + elif ret_type in self.classes: # wrapped class + ret_val = type_dict[ret_type]["j_type"] + " retVal = new " + self.classes[ret_type].jname + "(" + tail = ")" + elif "jn_type" not in type_dict[ret_type]: + ret_val = type_dict[fi.ctype]["j_type"] + " retVal = new " + type_dict[ret_type]["j_type"] + "(" + tail = ")" + + static = "static" + if fi.classname: + static = fi.static + + j_args = [] + for a in args: + if not a.ctype: #hidden + continue + jt = type_dict[a.ctype]["j_type"] + if a.out and a.ctype in ('bool', 'int', 'long', 'float', 'double'): + jt += '[]' + j_args.append( jt + ' ' + a.name ) + + j_code.write( Template(\ +""" public $static $j_type $j_name($j_args) + { + $prologue + $ret_val$jn_name($jn_args_call)$tail; + $epilogue + $ret + } + +""" + ).substitute(\ + ret = ret, \ + ret_val = ret_val, \ + tail = tail, \ + prologue = "\n ".join(j_prologue), \ + epilogue = "\n ".join(j_epilogue), \ + static=static, \ + j_type=type_dict[fi.ctype]["j_type"], \ + j_name=fi.jname, \ + j_args=", ".join(j_args), \ + jn_name=fi.jname + '_' + str(suffix_counter), \ + jn_args_call=", ".join( [a.name for a in jn_args] ),\ + ) + ) + + + # cpp part: + # jni_func(..) { _retval_ = cv_func(..); return _retval_; } + ret = "return _retval_;" + default = "return 0;" + if fi.ctype == "void": + ret = "return;" + default = "return;" + elif not fi.ctype: # c-tor + ret = "return (jlong) _retval_;" + elif fi.ctype.startswith('vector'): # c-tor + ret = "return (jlong) _retval_;" + elif fi.ctype == "string": + ret = "return env->NewStringUTF(_retval_.c_str());" + default = 'return env->NewStringUTF("");' + elif fi.ctype in self.classes: # wrapped class: + ret = "return (jlong) new %s(_retval_);" % fi.ctype + elif ret_type in self.classes: # pointer to wrapped class: + ret = "return (jlong) _retval_;" + elif type_dict[fi.ctype]["jni_type"] == "jdoubleArray": + ret = "return _da_retval_;" + + # hack: replacing func call with property set/get + name = fi.name + if prop_name: + if args: + name = prop_name + " = " + else: + name = prop_name + ";//" + + cvname = "cv::" + name + retval = fi.ctype + " _retval_ = " + if fi.ctype == "void": + retval = "" + elif fi.ctype.startswith('vector'): + retval = type_dict[fi.ctype]['jni_var'] % {"n" : '_ret_val_vector_'} + " = " + c_epilogue.append("Mat* _retval_ = new Mat();") + c_epilogue.append(fi.ctype+"_to_Mat(_ret_val_vector_, *_retval_);") + if fi.classname: + if not fi.ctype: # c-tor + retval = fi.classname + "* _retval_ = " + cvname = "new " + fi.classname + elif fi.static: + cvname = "%s::%s" % (fi.classname, name) + else: + cvname = "me->" + name + c_prologue.append(\ + "%(cls)s* me = (%(cls)s*) self; //TODO: check for NULL" \ + % { "cls" : fi.classname} \ + ) + cvargs = [] + for a in args: + if a.pointer: + jni_name = "&%(n)s" + else: + jni_name = "%(n)s" + if not a.ctype: # hidden + jni_name = a.defval + cvargs.append( type_dict[a.ctype].get("jni_name", jni_name) % {"n" : a.name}) + if "vector" not in a.ctype : + if ("I" in a.out or not a.out or a.ctype in self.classes) and "jni_var" in type_dict[a.ctype]: # complex type + c_prologue.append(type_dict[a.ctype]["jni_var"] % {"n" : a.name} + ";") + if a.out and "I" not in a.out and a.ctype not in self.classes and a.ctype: + c_prologue.append("%s %s;" % (a.ctype, a.name)) + + rtype = type_dict[fi.ctype].get("jni_type", "jdoubleArray") + clazz = self.Module + if fi.classname: + clazz = self.classes[fi.classname].jname + cpp_code.write ( Template( \ +""" + +JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_${clazz}_$fname + ($args) +{ + try { + LOGD("$module::$fname()"); + $prologue + $retval$cvname( $cvargs ); + $epilogue + $ret + } catch(cv::Exception e) { + LOGD("$module::$fname() catched cv::Exception: %s", e.what()); + jclass je = env->FindClass("org/opencv/core/CvException"); + if(!je) je = env->FindClass("java/lang/Exception"); + env->ThrowNew(je, e.what()); + $default + } catch (...) { + LOGD("$module::$fname() catched unknown exception (...)"); + jclass je = env->FindClass("java/lang/Exception"); + env->ThrowNew(je, "Unknown exception in JNI code {$module::$fname()}"); + $default + } +} + + +""" ).substitute( \ + rtype = rtype, \ + module = self.module, \ + clazz = clazz.replace('_', '_1'), \ + fname = (fi.jname + '_' + str(suffix_counter)).replace('_', '_1'), \ + args = ", ".join(["%s %s" % (type_dict[a.ctype].get("jni_type"), a.name) for a in jni_args]), \ + prologue = "\n ".join(c_prologue), \ + epilogue = " ".join(c_epilogue), \ + ret = ret, \ + cvname = cvname, \ + cvargs = ", ".join(cvargs), \ + default = default, \ + retval = retval, \ + ) ) + + # processing args with default values + if not args or not args[-1].defval: + break + while args and args[-1].defval: + # 'smart' overloads filtering + a = args.pop() + if a.name in ('mask', 'dtype', 'ddepth', 'lineType', 'borderType', 'borderMode', 'criteria'): + break + + + + def gen_class(self, name): + # generate code for the class + ci = self.classes[name] + # constants + if ci.private_consts: + self.java_code[name]['j_code'].write(""" + private static final int + %s;\n\n""" % (",\n"+" "*12).join(["%s = %s" % (c.name, c.value) for c in ci.private_consts]) + ) + if ci.consts: + self.java_code[name]['j_code'].write(""" + public static final int + %s;\n\n""" % (",\n"+" "*12).join(["%s = %s" % (c.name, c.value) for c in ci.consts]) + ) + # c-tors + fflist = ci.methods.items() + fflist.sort() + for n, ffi in fflist: + if ffi.isconstructor: + for fi in ffi.funcs: + fi.jname = ci.jname + self.gen_func(fi) + # other methods + for n, ffi in fflist: + if not ffi.isconstructor: + for fi in ffi.funcs: + self.gen_func(fi) + # props + for pi in ci.props: + # getter + getter_name = name + ".get_" + pi.name + #print getter_name + fi = FuncInfo( [getter_name, pi.ctype, [], []] ) # [ funcname, return_ctype, [modifiers], [args] ] + self.gen_func(fi, pi.name) + if pi.rw: + #setter + setter_name = name + ".set_" + pi.name + #print setter_name + fi = FuncInfo( [ setter_name, "void", [], [ [pi.ctype, pi.name, "", [], ""] ] ] ) + self.gen_func(fi, pi.name) + + # manual ports + if name in ManualFuncs: + for func in ManualFuncs[name].keys(): + self.java_code[name]["j_code"].write ( ManualFuncs[name][func]["j_code"] ) + self.java_code[name]["jn_code"].write( ManualFuncs[name][func]["jn_code"] ) + self.cpp_code.write( ManualFuncs[name][func]["cpp_code"] ) + + if name != self.Module: + # finalize() + self.java_code[name]["j_code"].write( +""" + @Override + protected void finalize() throws Throwable { + delete(nativeObj); + } +""" ) + + self.java_code[name]["jn_code"].write( +""" + // native support for java finalize() + private static native void delete(long nativeObj); +""" ) + + # native support for java finalize() + self.cpp_code.write( \ +""" +// +// native support for java finalize() +// static void %(cls)s::delete( __int64 self ) +// + +JNIEXPORT void JNICALL Java_org_opencv_%(module)s_%(j_cls)s_delete + (JNIEnv* env, jclass cls, jlong self) +{ + delete (%(cls)s*) self; +} + +""" % {"module" : module, "cls" : name, "j_cls" : ci.jname} + ) + + +if __name__ == "__main__": + if len(sys.argv) < 4: + print "Usage:\n", \ + os.path.basename(sys.argv[0]), \ + " [...]" + print "Current args are: ", ", ".join(["'"+a+"'" for a in sys.argv]) + exit(0) + + dstdir = "." + hdr_parser_path = os.path.abspath(sys.argv[1]) + if hdr_parser_path.endswith(".py"): + hdr_parser_path = os.path.dirname(hdr_parser_path) + sys.path.append(hdr_parser_path) + import hdr_parser + module = sys.argv[2] + srcfiles = sys.argv[3:] + print "Generating module '" + module + "' from headers:\n\t" + "\n\t".join(srcfiles) + generator = JavaWrapperGenerator() + generator.gen(srcfiles, module, dstdir) + diff --git a/modules/java/src/cpp/converters.cpp b/modules/java/src/cpp/converters.cpp index f2e5da17e0..380ed3810c 100644 --- a/modules/java/src/cpp/converters.cpp +++ b/modules/java/src/cpp/converters.cpp @@ -1,457 +1,442 @@ -#include "converters.h" - -#ifdef DEBUG -#include -#define MODULE_LOG_TAG "OpenCV.converters" -#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, MODULE_LOG_TAG, __VA_ARGS__)) -#else //DEBUG -#define LOGD(...) -#endif //DEBUG - -using namespace cv; - -#define CHECK_MAT(cond) if(!(cond)){ LOGD("FAILED: " #cond); return; } - - -// vector_int - -void Mat_to_vector_int(Mat& mat, vector& v_int) -{ - v_int.clear(); - CHECK_MAT(mat.type()==CV_32SC1 && mat.cols==1); - v_int = (vector) mat; -} - -void vector_int_to_Mat(vector& v_int, Mat& mat) -{ - mat = Mat(v_int, true); -} - - -//vector_double - -void Mat_to_vector_double(Mat& mat, vector& v_double) -{ - v_double.clear(); - CHECK_MAT(mat.type()==CV_64FC1 && mat.cols==1); - v_double = (vector) mat; -} - -void vector_double_to_Mat(vector& v_double, Mat& mat) -{ - mat = Mat(v_double, true); -} - - -// vector_float - -void Mat_to_vector_float(Mat& mat, vector& v_float) -{ - v_float.clear(); - CHECK_MAT(mat.type()==CV_32FC1 && mat.cols==1); - v_float = (vector) mat; -} - -void vector_float_to_Mat(vector& v_float, Mat& mat) -{ - mat = Mat(v_float, true); -} - - -//vector_uchar - -void Mat_to_vector_uchar(Mat& mat, vector& v_uchar) -{ - v_uchar.clear(); - CHECK_MAT(mat.type()==CV_8UC1 && mat.cols==1); - v_uchar = (vector) mat; -} - -void vector_uchar_to_Mat(vector& v_uchar, Mat& mat) -{ - mat = Mat(v_uchar, true); -} - -void Mat_to_vector_char(Mat& mat, vector& v_char) -{ - v_char.clear(); - CHECK_MAT(mat.type()==CV_8SC1 && mat.cols==1); - v_char = (vector) mat; -} - -void vector_char_to_Mat(vector& v_char, Mat& mat) -{ - mat = Mat(v_char, true); -} - - -//vector_Rect - -void Mat_to_vector_Rect(Mat& mat, vector& v_rect) -{ - v_rect.clear(); - CHECK_MAT(mat.type()==CV_32SC4 && mat.cols==1); - v_rect = (vector) mat; -} - -void vector_Rect_to_Mat(vector& v_rect, Mat& mat) -{ - mat = Mat(v_rect, true); -} - - -//vector_Point -void Mat_to_vector_Point(Mat& mat, vector& v_point) -{ - v_point.clear(); - CHECK_MAT(mat.type()==CV_32SC2 && mat.cols==1); - v_point = (vector) mat; -} - -//vector_Point2f -void Mat_to_vector_Point2f(Mat& mat, vector& v_point) -{ - v_point.clear(); - CHECK_MAT(mat.type()==CV_32FC2 && mat.cols==1); - v_point = (vector) mat; -} - -//vector_Point2d -void Mat_to_vector_Point2d(Mat& mat, vector& v_point) -{ - v_point.clear(); - CHECK_MAT(mat.type()==CV_64FC2 && mat.cols==1); - v_point = (vector) mat; -} - - -//vector_Point3i -void Mat_to_vector_Point3i(Mat& mat, vector& v_point) -{ - v_point.clear(); - CHECK_MAT(mat.type()==CV_32SC3 && mat.cols==1); - v_point = (vector) mat; -} - -//vector_Point3f -void Mat_to_vector_Point3f(Mat& mat, vector& v_point) -{ - v_point.clear(); - CHECK_MAT(mat.type()==CV_32FC3 && mat.cols==1); - v_point = (vector) mat; -} - -//vector_Point3d -void Mat_to_vector_Point3d(Mat& mat, vector& v_point) -{ - v_point.clear(); - CHECK_MAT(mat.type()==CV_64FC3 && mat.cols==1); - v_point = (vector) mat; -} - - -void vector_Point_to_Mat(vector& v_point, Mat& mat) -{ - mat = Mat(v_point, true); -} - -void vector_Point2f_to_Mat(vector& v_point, Mat& mat) -{ - mat = Mat(v_point, true); -} - -void vector_Point2d_to_Mat(vector& v_point, Mat& mat) -{ - mat = Mat(v_point, true); -} - -void vector_Point3i_to_Mat(vector& v_point, Mat& mat) -{ - mat = Mat(v_point, true); -} - -void vector_Point3f_to_Mat(vector& v_point, Mat& mat) -{ - mat = Mat(v_point, true); -} - -void vector_Point3d_to_Mat(vector& v_point, Mat& mat) -{ - mat = Mat(v_point, true); -} - -#ifdef HAVE_OPENCV_FEATURES2D -//vector_KeyPoint -void Mat_to_vector_KeyPoint(Mat& mat, vector& v_kp) -{ - v_kp.clear(); - CHECK_MAT(mat.type()==CV_32FC(7) && mat.cols==1); - for(int i=0; i v = mat.at< Vec >(i, 0); - KeyPoint kp(v[0], v[1], v[2], v[3], v[4], (int)v[5], (int)v[6]); - v_kp.push_back(kp); - } - return; -} - - -void vector_KeyPoint_to_Mat(vector& v_kp, Mat& mat) -{ - int count = v_kp.size(); - mat.create(count, 1, CV_32FC(7)); - for(int i=0; i >(i, 0) = Vec(kp.pt.x, kp.pt.y, kp.size, kp.angle, kp.response, kp.octave, kp.class_id); - } -} -#endif - - -//vector_Mat -void Mat_to_vector_Mat(cv::Mat& mat, std::vector& v_mat) -{ - v_mat.clear(); - if(mat.type() == CV_32SC2 && mat.cols == 1) - { - v_mat.reserve(mat.rows); - for(int i=0; i a = mat.at< Vec >(i, 0); - long long addr = (((long long)a[0])<<32) | a[1]; - Mat& m = *( (Mat*) addr ); - v_mat.push_back(m); - } - } else { - LOGD("Mat_to_vector_Mat() FAILED: mat.type() == CV_32SC2 && mat.cols == 1"); - } -} - - -void vector_Mat_to_Mat(std::vector& v_mat, cv::Mat& mat) -{ - int count = v_mat.size(); - mat.create(count, 1, CV_32SC2); - for(int i=0; i >(i, 0) = Vec(addr>>32, addr&0xffffffff); - } -} - -#ifdef HAVE_OPENCV_FEATURES2D -//vector_DMatch -void Mat_to_vector_DMatch(Mat& mat, vector& v_dm) -{ - v_dm.clear(); - CHECK_MAT(mat.type()==CV_32FC4 && mat.cols==1); - for(int i=0; i v = mat.at< Vec >(i, 0); - DMatch dm((int)v[0], (int)v[1], (int)v[2], v[3]); - v_dm.push_back(dm); - } - return; -} - - -void vector_DMatch_to_Mat(vector& v_dm, Mat& mat) -{ - int count = v_dm.size(); - mat.create(count, 1, CV_32FC4); - for(int i=0; i >(i, 0) = Vec(dm.queryIdx, dm.trainIdx, dm.imgIdx, dm.distance); - } -} -#endif - -void Mat_to_vector_vector_Point(Mat& mat, vector< vector< Point > >& vv_pt) -{ - vector vm; - vm.reserve( mat.rows ); - Mat_to_vector_Mat(mat, vm); - for(size_t i=0; i vpt; - Mat_to_vector_Point(vm[i], vpt); - vv_pt.push_back(vpt); - } -} - -void Mat_to_vector_vector_Point2f(Mat& mat, vector< vector< Point2f > >& vv_pt) -{ - vector vm; - vm.reserve( mat.rows ); - Mat_to_vector_Mat(mat, vm); - for(size_t i=0; i vpt; - Mat_to_vector_Point2f(vm[i], vpt); - vv_pt.push_back(vpt); - } -} - -void Mat_to_vector_vector_Point3f(Mat& mat, vector< vector< Point3f > >& vv_pt) -{ - vector vm; - vm.reserve( mat.rows ); - Mat_to_vector_Mat(mat, vm); - for(size_t i=0; i vpt; - Mat_to_vector_Point3f(vm[i], vpt); - vv_pt.push_back(vpt); - } -} - -#ifdef HAVE_OPENCV_FEATURES2D -void Mat_to_vector_vector_KeyPoint(Mat& mat, vector< vector< KeyPoint > >& vv_kp) -{ - vector vm; - vm.reserve( mat.rows ); - Mat_to_vector_Mat(mat, vm); - for(size_t i=0; i vkp; - Mat_to_vector_KeyPoint(vm[i], vkp); - vv_kp.push_back(vkp); - } -} - -void vector_vector_KeyPoint_to_Mat(vector< vector< KeyPoint > >& vv_kp, Mat& mat) -{ - vector vm; - vm.reserve( vv_kp.size() ); - for(size_t i=0; i >& vv_dm) -{ - vector vm; - vm.reserve( mat.rows ); - Mat_to_vector_Mat(mat, vm); - for(size_t i=0; i vdm; - Mat_to_vector_DMatch(vm[i], vdm); - vv_dm.push_back(vdm); - } -} - -void vector_vector_DMatch_to_Mat(vector< vector< DMatch > >& vv_dm, Mat& mat) -{ - vector vm; - vm.reserve( vv_dm.size() ); - for(size_t i=0; i >& vv_ch) -{ - vector vm; - vm.reserve( mat.rows ); - Mat_to_vector_Mat(mat, vm); - for(size_t i=0; i vch; - Mat_to_vector_char(vm[i], vch); - vv_ch.push_back(vch); - } -} - -void vector_vector_char_to_Mat(vector< vector< char > >& vv_ch, Mat& mat) -{ - vector vm; - vm.reserve( vv_ch.size() ); - for(size_t i=0; i >& vv_pt, Mat& mat) -{ - vector vm; - vm.reserve( vv_pt.size() ); - for(size_t i=0; i >& vv_pt, Mat& mat) -{ - vector vm; - vm.reserve( vv_pt.size() ); - for(size_t i=0; i >& vv_pt, Mat& mat) -{ - vector vm; - vm.reserve( vv_pt.size() ); - for(size_t i=0; i >& vv_pt, Mat& mat) -{ - vector vm; - vm.reserve( vv_pt.size() ); - for(size_t i=0; i& v_vec, Mat& mat) -{ - mat = Mat(v_vec, true); -} - -void vector_Vec4f_to_Mat(vector& v_vec, Mat& mat) -{ - mat = Mat(v_vec, true); -} - -void vector_Vec6f_to_Mat(vector& v_vec, Mat& mat) -{ - mat = Mat(v_vec, true); -} +#include "converters.h" + +#ifdef DEBUG +#include +#define MODULE_LOG_TAG "OpenCV.converters" +#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, MODULE_LOG_TAG, __VA_ARGS__)) +#else //DEBUG +#define LOGD(...) +#endif //DEBUG + +using namespace cv; + +#define CHECK_MAT(cond) if(!(cond)){ LOGD("FAILED: " #cond); return; } + + +// vector_int + +void Mat_to_vector_int(Mat& mat, vector& v_int) +{ + v_int.clear(); + CHECK_MAT(mat.type()==CV_32SC1 && mat.cols==1); + v_int = (vector) mat; +} + +void vector_int_to_Mat(vector& v_int, Mat& mat) +{ + mat = Mat(v_int, true); +} + + +//vector_double + +void Mat_to_vector_double(Mat& mat, vector& v_double) +{ + v_double.clear(); + CHECK_MAT(mat.type()==CV_64FC1 && mat.cols==1); + v_double = (vector) mat; +} + +void vector_double_to_Mat(vector& v_double, Mat& mat) +{ + mat = Mat(v_double, true); +} + + +// vector_float + +void Mat_to_vector_float(Mat& mat, vector& v_float) +{ + v_float.clear(); + CHECK_MAT(mat.type()==CV_32FC1 && mat.cols==1); + v_float = (vector) mat; +} + +void vector_float_to_Mat(vector& v_float, Mat& mat) +{ + mat = Mat(v_float, true); +} + + +//vector_uchar + +void Mat_to_vector_uchar(Mat& mat, vector& v_uchar) +{ + v_uchar.clear(); + CHECK_MAT(mat.type()==CV_8UC1 && mat.cols==1); + v_uchar = (vector) mat; +} + +void vector_uchar_to_Mat(vector& v_uchar, Mat& mat) +{ + mat = Mat(v_uchar, true); +} + +void Mat_to_vector_char(Mat& mat, vector& v_char) +{ + v_char.clear(); + CHECK_MAT(mat.type()==CV_8SC1 && mat.cols==1); + v_char = (vector) mat; +} + +void vector_char_to_Mat(vector& v_char, Mat& mat) +{ + mat = Mat(v_char, true); +} + + +//vector_Rect + +void Mat_to_vector_Rect(Mat& mat, vector& v_rect) +{ + v_rect.clear(); + CHECK_MAT(mat.type()==CV_32SC4 && mat.cols==1); + v_rect = (vector) mat; +} + +void vector_Rect_to_Mat(vector& v_rect, Mat& mat) +{ + mat = Mat(v_rect, true); +} + + +//vector_Point +void Mat_to_vector_Point(Mat& mat, vector& v_point) +{ + v_point.clear(); + CHECK_MAT(mat.type()==CV_32SC2 && mat.cols==1); + v_point = (vector) mat; +} + +//vector_Point2f +void Mat_to_vector_Point2f(Mat& mat, vector& v_point) +{ + v_point.clear(); + CHECK_MAT(mat.type()==CV_32FC2 && mat.cols==1); + v_point = (vector) mat; +} + +//vector_Point2d +void Mat_to_vector_Point2d(Mat& mat, vector& v_point) +{ + v_point.clear(); + CHECK_MAT(mat.type()==CV_64FC2 && mat.cols==1); + v_point = (vector) mat; +} + + +//vector_Point3i +void Mat_to_vector_Point3i(Mat& mat, vector& v_point) +{ + v_point.clear(); + CHECK_MAT(mat.type()==CV_32SC3 && mat.cols==1); + v_point = (vector) mat; +} + +//vector_Point3f +void Mat_to_vector_Point3f(Mat& mat, vector& v_point) +{ + v_point.clear(); + CHECK_MAT(mat.type()==CV_32FC3 && mat.cols==1); + v_point = (vector) mat; +} + +//vector_Point3d +void Mat_to_vector_Point3d(Mat& mat, vector& v_point) +{ + v_point.clear(); + CHECK_MAT(mat.type()==CV_64FC3 && mat.cols==1); + v_point = (vector) mat; +} + + +void vector_Point_to_Mat(vector& v_point, Mat& mat) +{ + mat = Mat(v_point, true); +} + +void vector_Point2f_to_Mat(vector& v_point, Mat& mat) +{ + mat = Mat(v_point, true); +} + +void vector_Point2d_to_Mat(vector& v_point, Mat& mat) +{ + mat = Mat(v_point, true); +} + +void vector_Point3i_to_Mat(vector& v_point, Mat& mat) +{ + mat = Mat(v_point, true); +} + +void vector_Point3f_to_Mat(vector& v_point, Mat& mat) +{ + mat = Mat(v_point, true); +} + +void vector_Point3d_to_Mat(vector& v_point, Mat& mat) +{ + mat = Mat(v_point, true); +} + +#ifdef HAVE_OPENCV_FEATURES2D +//vector_KeyPoint +void Mat_to_vector_KeyPoint(Mat& mat, vector& v_kp) +{ + v_kp.clear(); + CHECK_MAT(mat.type()==CV_32FC(7) && mat.cols==1); + for(int i=0; i v = mat.at< Vec >(i, 0); + KeyPoint kp(v[0], v[1], v[2], v[3], v[4], (int)v[5], (int)v[6]); + v_kp.push_back(kp); + } + return; +} + + +void vector_KeyPoint_to_Mat(vector& v_kp, Mat& mat) +{ + int count = v_kp.size(); + mat.create(count, 1, CV_32FC(7)); + for(int i=0; i >(i, 0) = Vec(kp.pt.x, kp.pt.y, kp.size, kp.angle, kp.response, kp.octave, kp.class_id); + } +} +#endif + + +//vector_Mat +void Mat_to_vector_Mat(cv::Mat& mat, std::vector& v_mat) +{ + v_mat.clear(); + if(mat.type() == CV_32SC2 && mat.cols == 1) + { + v_mat.reserve(mat.rows); + for(int i=0; i a = mat.at< Vec >(i, 0); + long long addr = (((long long)a[0])<<32) | a[1]; + Mat& m = *( (Mat*) addr ); + v_mat.push_back(m); + } + } else { + LOGD("Mat_to_vector_Mat() FAILED: mat.type() == CV_32SC2 && mat.cols == 1"); + } +} + + +void vector_Mat_to_Mat(std::vector& v_mat, cv::Mat& mat) +{ + int count = v_mat.size(); + mat.create(count, 1, CV_32SC2); + for(int i=0; i >(i, 0) = Vec(addr>>32, addr&0xffffffff); + } +} + +#ifdef HAVE_OPENCV_FEATURES2D +//vector_DMatch +void Mat_to_vector_DMatch(Mat& mat, vector& v_dm) +{ + v_dm.clear(); + CHECK_MAT(mat.type()==CV_32FC4 && mat.cols==1); + for(int i=0; i v = mat.at< Vec >(i, 0); + DMatch dm((int)v[0], (int)v[1], (int)v[2], v[3]); + v_dm.push_back(dm); + } + return; +} + + +void vector_DMatch_to_Mat(vector& v_dm, Mat& mat) +{ + int count = v_dm.size(); + mat.create(count, 1, CV_32FC4); + for(int i=0; i >(i, 0) = Vec(dm.queryIdx, dm.trainIdx, dm.imgIdx, dm.distance); + } +} +#endif + +void Mat_to_vector_vector_Point(Mat& mat, vector< vector< Point > >& vv_pt) +{ + vector vm; + vm.reserve( mat.rows ); + Mat_to_vector_Mat(mat, vm); + for(size_t i=0; i vpt; + Mat_to_vector_Point(vm[i], vpt); + vv_pt.push_back(vpt); + } +} + +void Mat_to_vector_vector_Point2f(Mat& mat, vector< vector< Point2f > >& vv_pt) +{ + vector vm; + vm.reserve( mat.rows ); + Mat_to_vector_Mat(mat, vm); + for(size_t i=0; i vpt; + Mat_to_vector_Point2f(vm[i], vpt); + vv_pt.push_back(vpt); + } +} + +void Mat_to_vector_vector_Point3f(Mat& mat, vector< vector< Point3f > >& vv_pt) +{ + vector vm; + vm.reserve( mat.rows ); + Mat_to_vector_Mat(mat, vm); + for(size_t i=0; i vpt; + Mat_to_vector_Point3f(vm[i], vpt); + vv_pt.push_back(vpt); + } +} + +#ifdef HAVE_OPENCV_FEATURES2D +void Mat_to_vector_vector_KeyPoint(Mat& mat, vector< vector< KeyPoint > >& vv_kp) +{ + vector vm; + vm.reserve( mat.rows ); + Mat_to_vector_Mat(mat, vm); + for(size_t i=0; i vkp; + Mat_to_vector_KeyPoint(vm[i], vkp); + vv_kp.push_back(vkp); + } +} + +void vector_vector_KeyPoint_to_Mat(vector< vector< KeyPoint > >& vv_kp, Mat& mat) +{ + vector vm; + vm.reserve( vv_kp.size() ); + for(size_t i=0; i >& vv_dm) +{ + vector vm; + vm.reserve( mat.rows ); + Mat_to_vector_Mat(mat, vm); + for(size_t i=0; i vdm; + Mat_to_vector_DMatch(vm[i], vdm); + vv_dm.push_back(vdm); + } +} + +void vector_vector_DMatch_to_Mat(vector< vector< DMatch > >& vv_dm, Mat& mat) +{ + vector vm; + vm.reserve( vv_dm.size() ); + for(size_t i=0; i >& vv_ch) +{ + vector vm; + vm.reserve( mat.rows ); + Mat_to_vector_Mat(mat, vm); + for(size_t i=0; i vch; + Mat_to_vector_char(vm[i], vch); + vv_ch.push_back(vch); + } +} + +void vector_vector_char_to_Mat(vector< vector< char > >& vv_ch, Mat& mat) +{ + vector vm; + vm.reserve( vv_ch.size() ); + for(size_t i=0; i >& vv_pt, Mat& mat) +{ + vector vm; + vm.reserve( vv_pt.size() ); + for(size_t i=0; i >& vv_pt, Mat& mat) +{ + vector vm; + vm.reserve( vv_pt.size() ); + for(size_t i=0; i >& vv_pt, Mat& mat) +{ + vector vm; + vm.reserve( vv_pt.size() ); + for(size_t i=0; i& v_vec, Mat& mat) +{ + mat = Mat(v_vec, true); +} + +void vector_Vec4f_to_Mat(vector& v_vec, Mat& mat) +{ + mat = Mat(v_vec, true); +} + +void vector_Vec6f_to_Mat(vector& v_vec, Mat& mat) +{ + mat = Mat(v_vec, true); +} diff --git a/modules/java/src/cpp/converters.h b/modules/java/src/cpp/converters.h index c3364dc123..9550defc47 100644 --- a/modules/java/src/cpp/converters.h +++ b/modules/java/src/cpp/converters.h @@ -68,7 +68,6 @@ void vector_vector_Point_to_Mat(std::vector< std::vector< cv::Point > >& vv_pt, void Mat_to_vector_vector_Point2f(cv::Mat& mat, std::vector< std::vector< cv::Point2f > >& vv_pt); void vector_vector_Point2f_to_Mat(std::vector< std::vector< cv::Point2f > >& vv_pt, cv::Mat& mat); -void vector_vector_Point_to_Mat(std::vector< std::vector< cv::Point > >& vv_pt, cv::Mat& mat); void Mat_to_vector_vector_Point3f(cv::Mat& mat, std::vector< std::vector< cv::Point3f > >& vv_pt); void vector_vector_Point3f_to_Mat(std::vector< std::vector< cv::Point3f > >& vv_pt, cv::Mat& mat); diff --git a/modules/java/src/java/core+MatOfByte.java b/modules/java/src/java/core+MatOfByte.java index dbd489ec80..a5d92839f8 100644 --- a/modules/java/src/java/core+MatOfByte.java +++ b/modules/java/src/java/core+MatOfByte.java @@ -4,38 +4,34 @@ import java.util.Arrays; import java.util.List; public class MatOfByte extends Mat { - // 8UC(x) - private static final int _depth = CvType.CV_8U; - private final int _channels; - - public MatOfByte(int channels) { - super(); - _channels = channels; - } + // 8UC(x) + private static final int _depth = CvType.CV_8U; + private static final int _channels = 1; public MatOfByte() { - this(1); + super(); } - - public MatOfByte(int channels, long addr) { + + protected MatOfByte(long addr) { super(addr); - _channels = channels; if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } - public MatOfByte(int channels, Mat m) { - super(m, Range.all()); - _channels = channels; + public static MatOfByte fromNativeAddr(long addr) { + return new MatOfByte(addr); + } + + public MatOfByte(Mat m) { + super(m, Range.all()); if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } - public MatOfByte(int channels, byte...a) { + public MatOfByte(byte...a) { super(); - _channels = channels; fromArray(a); } @@ -51,9 +47,11 @@ public class MatOfByte extends Mat { alloc(num); put(0, 0, a); //TODO: check ret val! } - + public byte[] toArray() { - int num = (int) total(); + int num = checkVector(_channels, _depth); + if(num < 0) + throw new RuntimeException("Native Mat has unexpected type or size: " + toString()); byte[] a = new byte[num * _channels]; if(num == 0) return a; @@ -62,20 +60,20 @@ public class MatOfByte extends Mat { } public void fromList(List lb) { - if(lb==null || lb.size()==0) - return; - Byte ab[] = lb.toArray(null); - byte a[] = new byte[ab.length]; - for(int i=0; i toList() { - byte[] a = toArray(); - Byte ab[] = new Byte[a.length]; - for(int i=0; i0) super.create(elemNumber, 1, CvType.makeType(_depth, _channels)); @@ -68,12 +72,12 @@ public class MatOfDMatch extends Mat { } public void fromList(List ldm) { - DMatch adm[] = ldm.toArray(null); - fromArray(adm); + DMatch adm[] = ldm.toArray(new DMatch[0]); + fromArray(adm); } - + public List toList() { - DMatch[] adm = toArray(); - return Arrays.asList(adm); + DMatch[] adm = toArray(); + return Arrays.asList(adm); } } diff --git a/modules/java/src/java/core+MatOfDouble.java b/modules/java/src/java/core+MatOfDouble.java index 165b9dbdef..2ea210bfa5 100644 --- a/modules/java/src/java/core+MatOfDouble.java +++ b/modules/java/src/java/core+MatOfDouble.java @@ -4,38 +4,34 @@ import java.util.Arrays; import java.util.List; public class MatOfDouble extends Mat { - // 64FC(x) - private static final int _depth = CvType.CV_64F; - private final int _channels; - - public MatOfDouble(int channels) { - super(); - _channels = channels; - } + // 64FC(x) + private static final int _depth = CvType.CV_64F; + private static final int _channels = 1; public MatOfDouble() { - this(1); + super(); } - public MatOfDouble(int channels, long addr) { + protected MatOfDouble(long addr) { super(addr); - _channels = channels; if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } - public MatOfDouble(int channels, Mat m) { - super(m, Range.all()); - _channels = channels; + public static MatOfDouble fromNativeAddr(long addr) { + return new MatOfDouble(addr); + } + + public MatOfDouble(Mat m) { + super(m, Range.all()); if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } - public MatOfDouble(int channels, double...a) { + public MatOfDouble(double...a) { super(); - _channels = channels; fromArray(a); } @@ -51,9 +47,11 @@ public class MatOfDouble extends Mat { alloc(num); put(0, 0, a); //TODO: check ret val! } - + public double[] toArray() { - int num = (int) total(); + int num = checkVector(_channels, _depth); + if(num < 0) + throw new RuntimeException("Native Mat has unexpected type or size: " + toString()); double[] a = new double[num * _channels]; if(num == 0) return a; @@ -62,20 +60,20 @@ public class MatOfDouble extends Mat { } public void fromList(List lb) { - if(lb==null || lb.size()==0) - return; - Double ab[] = lb.toArray(null); - double a[] = new double[ab.length]; - for(int i=0; i toList() { - double[] a = toArray(); - Double ab[] = new Double[a.length]; - for(int i=0; i lb) { - if(lb==null || lb.size()==0) - return; - Float ab[] = lb.toArray(null); - float a[] = new float[ab.length]; - for(int i=0; i toList() { - float[] a = toArray(); - Float ab[] = new Float[a.length]; - for(int i=0; i lb) { - if(lb==null || lb.size()==0) - return; - Integer ab[] = lb.toArray(null); - int a[] = new int[ab.length]; - for(int i=0; i toList() { - int[] a = toArray(); - Integer ab[] = new Integer[a.length]; - for(int i=0; i0) super.create(elemNumber, 1, CvType.makeType(_depth, _channels)); @@ -71,12 +75,12 @@ public class MatOfKeyPoint extends Mat { } public void fromList(List lkp) { - KeyPoint akp[] = lkp.toArray(null); - fromArray(akp); + KeyPoint akp[] = lkp.toArray(new KeyPoint[0]); + fromArray(akp); } - + public List toList() { - KeyPoint[] akp = toArray(); - return Arrays.asList(akp); + KeyPoint[] akp = toArray(); + return Arrays.asList(akp); } } diff --git a/modules/java/src/java/core+MatOfPoint.java b/modules/java/src/java/core+MatOfPoint.java index b0dc449987..81475e96da 100644 --- a/modules/java/src/java/core+MatOfPoint.java +++ b/modules/java/src/java/core+MatOfPoint.java @@ -4,23 +4,27 @@ import java.util.Arrays; import java.util.List; public class MatOfPoint extends Mat { - // 32SC2 - private static final int _depth = CvType.CV_32S; - private static final int _channels = 2; + // 32SC2 + private static final int _depth = CvType.CV_32S; + private static final int _channels = 2; public MatOfPoint() { super(); } - public MatOfPoint(long addr) { + protected MatOfPoint(long addr) { super(addr); if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } + public static MatOfPoint fromNativeAddr(long addr) { + return new MatOfPoint(addr); + } + public MatOfPoint(Mat m) { - super(m, Range.all()); + super(m, Range.all()); if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? @@ -30,7 +34,7 @@ public class MatOfPoint extends Mat { super(); fromArray(a); } - + public void alloc(int elemNumber) { if(elemNumber>0) super.create(elemNumber, 1, CvType.makeType(_depth, _channels)); @@ -49,7 +53,7 @@ public class MatOfPoint extends Mat { } put(0, 0, buff); //TODO: check ret val! } - + public Point[] toArray() { int num = (int) total(); Point[] ap = new Point[num]; @@ -63,12 +67,12 @@ public class MatOfPoint extends Mat { } public void fromList(List lp) { - Point ap[] = lp.toArray(null); - fromArray(ap); + Point ap[] = lp.toArray(new Point[0]); + fromArray(ap); } - + public List toList() { - Point[] ap = toArray(); - return Arrays.asList(ap); + Point[] ap = toArray(); + return Arrays.asList(ap); } } diff --git a/modules/java/src/java/core+MatOfPoint2f.java b/modules/java/src/java/core+MatOfPoint2f.java index d8667695e2..dd1257f5c9 100644 --- a/modules/java/src/java/core+MatOfPoint2f.java +++ b/modules/java/src/java/core+MatOfPoint2f.java @@ -4,23 +4,27 @@ import java.util.Arrays; import java.util.List; public class MatOfPoint2f extends Mat { - // 32FC2 - private static final int _depth = CvType.CV_32F; - private static final int _channels = 2; + // 32FC2 + private static final int _depth = CvType.CV_32F; + private static final int _channels = 2; public MatOfPoint2f() { super(); } - public MatOfPoint2f(long addr) { + protected MatOfPoint2f(long addr) { super(addr); if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } + public static MatOfPoint2f fromNativeAddr(long addr) { + return new MatOfPoint2f(addr); + } + public MatOfPoint2f(Mat m) { - super(m, Range.all()); + super(m, Range.all()); if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? @@ -30,7 +34,7 @@ public class MatOfPoint2f extends Mat { super(); fromArray(a); } - + public void alloc(int elemNumber) { if(elemNumber>0) super.create(elemNumber, 1, CvType.makeType(_depth, _channels)); @@ -49,7 +53,7 @@ public class MatOfPoint2f extends Mat { } put(0, 0, buff); //TODO: check ret val! } - + public Point[] toArray() { int num = (int) total(); Point[] ap = new Point[num]; @@ -63,12 +67,12 @@ public class MatOfPoint2f extends Mat { } public void fromList(List lp) { - Point ap[] = lp.toArray(null); - fromArray(ap); + Point ap[] = lp.toArray(new Point[0]); + fromArray(ap); } - + public List toList() { - Point[] ap = toArray(); - return Arrays.asList(ap); + Point[] ap = toArray(); + return Arrays.asList(ap); } } diff --git a/modules/java/src/java/core+MatOfPoint3.java b/modules/java/src/java/core+MatOfPoint3.java index 71a60829d8..25320759ca 100644 --- a/modules/java/src/java/core+MatOfPoint3.java +++ b/modules/java/src/java/core+MatOfPoint3.java @@ -4,23 +4,27 @@ import java.util.Arrays; import java.util.List; public class MatOfPoint3 extends Mat { - // 32SC3 - private static final int _depth = CvType.CV_32S; - private static final int _channels = 3; + // 32SC3 + private static final int _depth = CvType.CV_32S; + private static final int _channels = 3; public MatOfPoint3() { super(); } - public MatOfPoint3(long addr) { + protected MatOfPoint3(long addr) { super(addr); if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } + public static MatOfPoint3 fromNativeAddr(long addr) { + return new MatOfPoint3(addr); + } + public MatOfPoint3(Mat m) { - super(m, Range.all()); + super(m, Range.all()); if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? @@ -30,7 +34,7 @@ public class MatOfPoint3 extends Mat { super(); fromArray(a); } - + public void alloc(int elemNumber) { if(elemNumber>0) super.create(elemNumber, 1, CvType.makeType(_depth, _channels)); @@ -50,7 +54,7 @@ public class MatOfPoint3 extends Mat { } put(0, 0, buff); //TODO: check ret val! } - + public Point3[] toArray() { int num = (int) total(); Point3[] ap = new Point3[num]; @@ -64,12 +68,12 @@ public class MatOfPoint3 extends Mat { } public void fromList(List lp) { - Point3 ap[] = lp.toArray(null); - fromArray(ap); + Point3 ap[] = lp.toArray(new Point3[0]); + fromArray(ap); } - + public List toList() { - Point3[] ap = toArray(); - return Arrays.asList(ap); + Point3[] ap = toArray(); + return Arrays.asList(ap); } } diff --git a/modules/java/src/java/core+MatOfPoint3f.java b/modules/java/src/java/core+MatOfPoint3f.java index 76e180bc3f..f765f23605 100644 --- a/modules/java/src/java/core+MatOfPoint3f.java +++ b/modules/java/src/java/core+MatOfPoint3f.java @@ -4,23 +4,27 @@ import java.util.Arrays; import java.util.List; public class MatOfPoint3f extends Mat { - // 32FC3 - private static final int _depth = CvType.CV_32F; - private static final int _channels = 3; + // 32FC3 + private static final int _depth = CvType.CV_32F; + private static final int _channels = 3; public MatOfPoint3f() { super(); } - public MatOfPoint3f(long addr) { + protected MatOfPoint3f(long addr) { super(addr); if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } + public static MatOfPoint3f fromNativeAddr(long addr) { + return new MatOfPoint3f(addr); + } + public MatOfPoint3f(Mat m) { - super(m, Range.all()); + super(m, Range.all()); if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? @@ -30,7 +34,7 @@ public class MatOfPoint3f extends Mat { super(); fromArray(a); } - + public void alloc(int elemNumber) { if(elemNumber>0) super.create(elemNumber, 1, CvType.makeType(_depth, _channels)); @@ -50,7 +54,7 @@ public class MatOfPoint3f extends Mat { } put(0, 0, buff); //TODO: check ret val! } - + public Point3[] toArray() { int num = (int) total(); Point3[] ap = new Point3[num]; @@ -64,12 +68,12 @@ public class MatOfPoint3f extends Mat { } public void fromList(List lp) { - Point3 ap[] = lp.toArray(null); - fromArray(ap); + Point3 ap[] = lp.toArray(new Point3[0]); + fromArray(ap); } - + public List toList() { - Point3[] ap = toArray(); - return Arrays.asList(ap); + Point3[] ap = toArray(); + return Arrays.asList(ap); } } diff --git a/modules/java/src/java/core+MatOfRect.java b/modules/java/src/java/core+MatOfRect.java index 2688b56235..4798df738b 100644 --- a/modules/java/src/java/core+MatOfRect.java +++ b/modules/java/src/java/core+MatOfRect.java @@ -5,23 +5,27 @@ import java.util.List; public class MatOfRect extends Mat { - // 32SC4 - private static final int _depth = CvType.CV_32S; - private static final int _channels = 4; + // 32SC4 + private static final int _depth = CvType.CV_32S; + private static final int _channels = 4; public MatOfRect() { super(); } - public MatOfRect(long addr) { + protected MatOfRect(long addr) { super(addr); if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } + public static MatOfRect fromNativeAddr(long addr) { + return new MatOfRect(addr); + } + public MatOfRect(Mat m) { - super(m, Range.all()); + super(m, Range.all()); if(checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? @@ -31,7 +35,7 @@ public class MatOfRect extends Mat { super(); fromArray(a); } - + public void alloc(int elemNumber) { if(elemNumber>0) super.create(elemNumber, 1, CvType.makeType(_depth, _channels)); @@ -44,7 +48,7 @@ public class MatOfRect extends Mat { alloc(num); int buff[] = new int[num * _channels]; for(int i=0; i lr) { - Rect ap[] = lr.toArray(null); - fromArray(ap); + Rect ap[] = lr.toArray(new Rect[0]); + fromArray(ap); } - + public List toList() { - Rect[] ar = toArray(); - return Arrays.asList(ar); + Rect[] ar = toArray(); + return Arrays.asList(ar); } } diff --git a/modules/legacy/src/em.cpp b/modules/legacy/src/em.cpp index 1ed3b23ed7..54e8a1b622 100644 --- a/modules/legacy/src/em.cpp +++ b/modules/legacy/src/em.cpp @@ -1,59 +1,59 @@ /*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. - // - // - // Intel License Agreement - // For Open Source Computer Vision Library - // - // Copyright( C) 2000, Intel Corporation, 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 ifadvised 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. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright( C) 2000, Intel Corporation, 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 ifadvised of the possibility of such damage. +// +//M*/ #include "precomp.hpp" using namespace cv; CvEMParams::CvEMParams() : nclusters(10), cov_mat_type(CvEM::COV_MAT_DIAGONAL), -start_step(CvEM::START_AUTO_STEP), probs(0), weights(0), means(0), covs(0) + start_step(CvEM::START_AUTO_STEP), probs(0), weights(0), means(0), covs(0) { term_crit=cvTermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, FLT_EPSILON ); } CvEMParams::CvEMParams( int _nclusters, int _cov_mat_type, int _start_step, - CvTermCriteria _term_crit, const CvMat* _probs, - const CvMat* _weights, const CvMat* _means, const CvMat** _covs ) : -nclusters(_nclusters), cov_mat_type(_cov_mat_type), start_step(_start_step), -probs(_probs), weights(_weights), means(_means), covs(_covs), term_crit(_term_crit) + CvTermCriteria _term_crit, const CvMat* _probs, + const CvMat* _weights, const CvMat* _means, const CvMat** _covs ) : + nclusters(_nclusters), cov_mat_type(_cov_mat_type), start_step(_start_step), + probs(_probs), weights(_weights), means(_means), covs(_covs), term_crit(_term_crit) {} CvEM::CvEM() : logLikelihood(DBL_MAX) @@ -61,7 +61,7 @@ CvEM::CvEM() : logLikelihood(DBL_MAX) } CvEM::CvEM( const CvMat* samples, const CvMat* sample_idx, - CvEMParams params, CvMat* labels ) : logLikelihood(DBL_MAX) + CvEMParams params, CvMat* labels ) : logLikelihood(DBL_MAX) { train(samples, sample_idx, params, labels); } @@ -142,7 +142,7 @@ void init_params(const CvEMParams& src, prbs = src.probs; weights = src.weights; means = src.means; - + if(src.covs) { covsHdrs.resize(src.nclusters); @@ -152,7 +152,7 @@ void init_params(const CvEMParams& src, } bool CvEM::train( const CvMat* _samples, const CvMat* _sample_idx, - CvEMParams _params, CvMat* _labels ) + CvEMParams _params, CvMat* _labels ) { CV_Assert(_sample_idx == 0); Mat samples = cvarrToMat(_samples), labels0, labels; @@ -161,7 +161,7 @@ bool CvEM::train( const CvMat* _samples, const CvMat* _sample_idx, bool isOk = train(samples, Mat(), _params, _labels ? &labels : 0); CV_Assert( labels0.data == labels.data ); - + return isOk; } @@ -204,7 +204,7 @@ bool CvEM::train( const Mat& _samples, const Mat& _sample_idx, Mat prbs, weights, means, logLikelihoods; std::vector covsHdrs; init_params(_params, prbs, weights, means, covsHdrs); - + emObj = EM(_params.nclusters, _params.cov_mat_type, _params.term_crit); bool isOk = false; if( _params.start_step == EM::START_AUTO_STEP ) @@ -224,7 +224,7 @@ bool CvEM::train( const Mat& _samples, const Mat& _sample_idx, logLikelihood = sum(logLikelihoods).val[0]; set_mat_hdrs(); } - + return isOk; } diff --git a/modules/legacy/test/test_em.cpp b/modules/legacy/test/test_em.cpp index 411fc9ebd4..823561ac2b 100644 --- a/modules/legacy/test/test_em.cpp +++ b/modules/legacy/test/test_em.cpp @@ -45,45 +45,45 @@ using namespace std; using namespace cv; static -void defaultDistribs( Mat& means, vector& covs ) +void defaultDistribs( Mat& means, vector& covs, int type=CV_32FC1 ) { float mp0[] = {0.0f, 0.0f}, cp0[] = {0.67f, 0.0f, 0.0f, 0.67f}; float mp1[] = {5.0f, 0.0f}, cp1[] = {1.0f, 0.0f, 0.0f, 1.0f}; float mp2[] = {1.0f, 5.0f}, cp2[] = {1.0f, 0.0f, 0.0f, 1.0f}; - means.create(3, 2, CV_32FC1); + means.create(3, 2, type); Mat m0( 1, 2, CV_32FC1, mp0 ), c0( 2, 2, CV_32FC1, cp0 ); Mat m1( 1, 2, CV_32FC1, mp1 ), c1( 2, 2, CV_32FC1, cp1 ); Mat m2( 1, 2, CV_32FC1, mp2 ), c2( 2, 2, CV_32FC1, cp2 ); means.resize(3), covs.resize(3); Mat mr0 = means.row(0); - m0.copyTo(mr0); - c0.copyTo(covs[0]); + m0.convertTo(mr0, type); + c0.convertTo(covs[0], type); Mat mr1 = means.row(1); - m1.copyTo(mr1); - c1.copyTo(covs[1]); + m1.convertTo(mr1, type); + c1.convertTo(covs[1], type); Mat mr2 = means.row(2); - m2.copyTo(mr2); - c2.copyTo(covs[2]); + m2.convertTo(mr2, type); + c2.convertTo(covs[2], type); } // generate points sets by normal distributions static -void generateData( Mat& data, Mat& labels, const vector& sizes, const Mat& _means, const vector& covs, int labelType ) +void generateData( Mat& data, Mat& labels, const vector& sizes, const Mat& _means, const vector& covs, int dataType, int labelType ) { vector::const_iterator sit = sizes.begin(); int total = 0; for( ; sit != sizes.end(); ++sit ) total += *sit; - assert( _means.rows == (int)sizes.size() && covs.size() == sizes.size() ); - assert( !data.empty() && data.rows == total ); - assert( data.type() == CV_32FC1 ); - + CV_Assert( _means.rows == (int)sizes.size() && covs.size() == sizes.size() ); + CV_Assert( !data.empty() && data.rows == total ); + CV_Assert( data.type() == dataType ); + labels.create( data.rows, 1, labelType ); - randn( data, Scalar::all(0.0), Scalar::all(1.0) ); + randn( data, Scalar::all(-1.0), Scalar::all(1.0) ); vector means(sizes.size()); for(int i = 0; i < _means.rows; i++) means[i] = _means.row(i); @@ -98,8 +98,8 @@ void generateData( Mat& data, Mat& labels, const vector& sizes, const Mat& assert( cit->rows == data.cols && cit->cols == data.cols ); for( int i = bi; i < ei; i++, p++ ) { - Mat r(1, data.cols, CV_32FC1, data.ptr(i)); - r = r * (*cit) + *mit; + Mat r = data.row(i); + r = r * (*cit) + *mit; if( labelType == CV_32FC1 ) labels.at(p, 0) = (float)l; else if( labelType == CV_32SC1 ) @@ -129,7 +129,7 @@ int maxIdx( const vector& count ) } static -bool getLabelsMap( const Mat& labels, const vector& sizes, vector& labelsMap ) +bool getLabelsMap( const Mat& labels, const vector& sizes, vector& labelsMap, bool checkClusterUniq=true ) { size_t total = 0, nclusters = sizes.size(); for(size_t i = 0; i < sizes.size(); i++) @@ -158,21 +158,25 @@ bool getLabelsMap( const Mat& labels, const vector& sizes, vector& lab startIndex += sizes[clusterIndex]; int cls = maxIdx( count ); - CV_Assert( !buzy[cls] ); + CV_Assert( !checkClusterUniq || !buzy[cls] ); labelsMap[clusterIndex] = cls; buzy[cls] = true; } - for(size_t i = 0; i < buzy.size(); i++) - if(!buzy[i]) - return false; + + if(checkClusterUniq) + { + for(size_t i = 0; i < buzy.size(); i++) + if(!buzy[i]) + return false; + } return true; } static -bool calcErr( const Mat& labels, const Mat& origLabels, const vector& sizes, float& err, bool labelsEquivalent = true ) +bool calcErr( const Mat& labels, const Mat& origLabels, const vector& sizes, float& err, bool labelsEquivalent, bool checkClusterUniq ) { err = 0; CV_Assert( !labels.empty() && !origLabels.empty() ); @@ -186,7 +190,7 @@ bool calcErr( const Mat& labels, const Mat& origLabels, const vector& sizes bool isFlt = labels.type() == CV_32FC1; if( !labelsEquivalent ) { - if( !getLabelsMap( labels, sizes, labelsMap ) ) + if( !getLabelsMap( labels, sizes, labelsMap, checkClusterUniq ) ) return false; for( int i = 0; i < labels.rows; i++ ) @@ -234,7 +238,7 @@ int CV_CvEMTest::runCase( int caseIndex, const CvEMParams& params, em.train( trainData, Mat(), params, &labels ); // check train error - if( !calcErr( labels, trainLabels, sizes, err , false ) ) + if( !calcErr( labels, trainLabels, sizes, err , false, false ) ) { ts->printf( cvtest::TS::LOG, "Case index %i : Bad output labels.\n", caseIndex ); code = cvtest::TS::FAIL_INVALID_OUTPUT; @@ -252,7 +256,7 @@ int CV_CvEMTest::runCase( int caseIndex, const CvEMParams& params, Mat sample = testData.row(i); labels.at(i,0) = (int)em.predict( sample, 0 ); } - if( !calcErr( labels, testLabels, sizes, err, false ) ) + if( !calcErr( labels, testLabels, sizes, err, false, false ) ) { ts->printf( cvtest::TS::LOG, "Case index %i : Bad output labels.\n", caseIndex ); code = cvtest::TS::FAIL_INVALID_OUTPUT; @@ -279,11 +283,11 @@ void CV_CvEMTest::run( int /*start_from*/ ) // train data Mat trainData( pointsCount, 2, CV_32FC1 ), trainLabels; vector sizes( sizesArr, sizesArr + sizeof(sizesArr) / sizeof(sizesArr[0]) ); - generateData( trainData, trainLabels, sizes, means, covs, CV_32SC1 ); + generateData( trainData, trainLabels, sizes, means, covs, CV_32FC1, CV_32SC1 ); // test data Mat testData( pointsCount, 2, CV_32FC1 ), testLabels; - generateData( testData, testLabels, sizes, means, covs, CV_32SC1 ); + generateData( testData, testLabels, sizes, means, covs, CV_32FC1, CV_32SC1 ); CvEMParams params; params.nclusters = 3; @@ -440,5 +444,5 @@ protected: } }; -TEST(ML_CvEM, accuracy) { CV_CvEMTest test; test.safe_run(); } -TEST(ML_CvEM, save_load) { CV_CvEMTest_SaveLoad test; test.safe_run(); } +TEST(Legacy_CvEM, accuracy) { CV_CvEMTest test; test.safe_run(); } +TEST(Legacy_CvEM, save_load) { CV_CvEMTest_SaveLoad test; test.safe_run(); }