1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

Compare commits

..

539 Commits

Author SHA1 Message Date
Roman Donchenko 9f8de69505 Set status to -tp2. 2014-02-05 13:57:04 +04:00
Andrey Pavlenko 02bf4984cb Merge pull request #2284 from KonstantinMatskevich:ocl_test_cascade 2014-02-05 13:37:06 +04:00
Konstantin Matskevich 84fa60abb8 update test for cascade 2014-02-05 12:06:48 +04:00
Andrey Pavlenko e6f3c9b0bf Merge pull request #2281 from vpisarev:ocl_surf 2014-02-05 11:07:19 +04:00
Andrey Pavlenko 055f41c92a Merge pull request #2250 from ilya-lavrenov:tapi_renaming 2014-02-05 09:27:06 +04:00
Ilya Lavrenov 2e8579fe9b cleaned up super_resolution sample from old OCL 2014-02-05 00:28:10 +04:00
Vadim Pisarevsky 3e0c72a8f7 fixed warnings/errors from GCC 2014-02-04 21:50:04 +04:00
Andrey Pavlenko 564f5fcca3 Merge pull request #2280 from ilya-lavrenov:attempt_pvc 2014-02-04 21:22:49 +04:00
Vadim Pisarevsky 092d058d06 fixed warnings from OCL and DOC builders 2014-02-04 21:19:31 +04:00
Andrey Pavlenko b7ffed7b46 Merge pull request #2279 from alalek:fix_memory_leak_getumat 2014-02-04 20:45:27 +04:00
Vadim Pisarevsky 38f5c7140c undone change in ocl.hpp (explicit Image2D constructor) 2014-02-04 20:41:11 +04:00
Vadim Pisarevsky c18d1ee2a9 SURF kind of works (let's see if the tests pass) 2014-02-04 20:00:51 +04:00
Ilya Lavrenov c7fe162829 renamed **2 -> ** 2014-02-04 19:55:11 +04:00
Ilya Lavrenov d957e8e40d attempt to fix pure virtual call in Mat::deallocate 2014-02-04 19:50:37 +04:00
Andrey Pavlenko 42ac3123ec Merge pull request #2192 from alalek:buffer_pool 2014-02-04 19:13:08 +04:00
Alexander Alekhin 83a2b566a3 fix memory leak for Mat::getUMat() operation 2014-02-04 17:25:09 +04:00
Alexander Alekhin 485635310c core/ocl: OpenCLBufferPool 2014-02-04 16:48:35 +04:00
Andrey Pavlenko 22146e4b18 Merge pull request #2234 from KonstantinMatskevich:ocl_tapi_hog 2014-02-04 16:35:12 +04:00
Andrey Pavlenko bd6620fa87 Merge pull request #2252 from ilya-lavrenov:ocl_ref 2014-02-04 16:34:28 +04:00
Andrey Pavlenko 49db511882 Merge pull request #2268 from ilya-lavrenov:tapi_pow 2014-02-04 16:32:43 +04:00
Andrey Pavlenko 5968b8816e Merge pull request #2275 from ElenaGvozdeva:ocl_matchTemplate 2014-02-04 16:32:11 +04:00
Elena Gvozdeva 85d519b6c3 fixed 2014-02-04 10:54:02 +04:00
Vadim Pisarevsky 8d5e952263 very preliminary port of SURF to T-API (compiles but certainly does not work) 2014-02-04 03:21:03 +04:00
Ilya Lavrenov da5b316b4e minor ocl.cpp refactoring
fix for cv::LUT and cv::transpose
2014-02-04 01:52:48 +04:00
Andrey Pavlenko 92c8b94ba9 Merge pull request #2265 from vpisarev:ocl_facedetect_amd3 2014-02-04 00:39:09 +04:00
Ilya Lavrenov 98b72ff389 optimized cv::pow for integer power 2014-02-03 22:36:57 +04:00
Andrey Pavlenko 9dede73d9f Merge pull request #2153 from scottbreyfogle:constrained-hough-lines 2014-02-03 17:35:15 +04:00
Andrey Pavlenko 810dc262ad Merge pull request #2196 from KonstantinMatskevich:ocl_bugcautching 2014-02-03 17:32:20 +04:00
Andrey Pavlenko b3a48e1eed Merge pull request #2264 from alalek:bug_fix_3470 2014-02-03 17:31:57 +04:00
Roman Donchenko 109e71e4ef Merge pull request #2263 from ilya-lavrenov:include_fix 2014-02-03 17:25:12 +04:00
Vadim Pisarevsky b5d8f4d5e5 Merge pull request #2031 from berak:b_flann_timer_30 2014-02-03 17:00:21 +04:00
Vadim Pisarevsky 7cfb7bc8cd Merge pull request #2120 from prclibo:master 2014-02-03 16:59:04 +04:00
Konstantin Matskevich 3495c5953c fixes 2014-02-03 16:38:06 +04:00
Vadim Pisarevsky de4b1c668d hopefully fixed compile warnings and the doc builder warnings 2014-02-03 16:36:36 +04:00
Roman Donchenko 652a0bd5ce Merge pull request #2262 from SpecLad:merge-2.4 2014-02-03 15:33:41 +04:00
Vadim Pisarevsky 30593ee55e 3rd attempt to prepare patch with improved OpenCL kernels of CascadeClassifier. 2014-02-03 15:12:27 +04:00
Ilya Lavrenov 9a1e461450 fix for PR 2166 2014-02-03 14:47:32 +04:00
Konstantin Matskevich 5c38519c65 some changes 2014-02-03 14:46:53 +04:00
Konstantin Matskevich 3ea32b87bb perf test 2014-02-03 14:46:52 +04:00
Konstantin Matskevich 9a62df1650 HOG 2014-02-03 14:46:52 +04:00
Alexander Alekhin 91ca834be9 bug fix for issue 3470 2014-02-03 14:46:22 +04:00
Andrey Pavlenko 0fef7f8b96 Merge pull request #2217 from ilya-lavrenov:tapi_superres 2014-02-03 14:38:59 +04:00
Konstantin Matskevich ffeb223150 test for failure 2014-02-03 14:34:02 +04:00
Ilya Lavrenov cc47edb850 more strict checks and reseting state 2014-02-03 14:32:25 +04:00
Konstantin Matskevich aa23a842a1 test for failure 2014-02-03 14:32:25 +04:00
Andrey Pavlenko 13875b5fbc Merge pull request #2257 from ilya-lavrenov:tapi_opencl_game2 2014-02-03 14:26:05 +04:00
Andrey Pavlenko a2fcaccf8b Merge pull request #2258 from ilya-lavrenov:tapi_video 2014-02-03 14:17:49 +04:00
Andrey Pavlenko cb1e4b2ede Merge pull request #2256 from ilya-lavrenov:tapi_matchTempl 2014-02-03 14:10:21 +04:00
Roman Donchenko 2bbda9d225 Merge remote-tracking branch 'origin/2.4' into merge-2.4
Conflicts:
	modules/cudaimgproc/test/test_color.cpp
	modules/dynamicuda/include/opencv2/dynamicuda/dynamicuda.hpp
	modules/gpu/perf/perf_imgproc.cpp
	modules/gpu/src/imgproc.cpp
	modules/gpu/test/test_core.cpp
	modules/gpu/test/test_imgproc.cpp
	modules/java/generator/src/cpp/VideoCapture.cpp
	samples/gpu/performance/CMakeLists.txt
	samples/tapi/CMakeLists.txt
2014-02-03 13:23:59 +04:00
Roman Donchenko 206df7fdb1 Merge pull request #2255 from ilya-lavrenov:ocl_doc 2014-02-03 12:14:14 +04:00
Roman Donchenko 82330a51bd Merge pull request #2253 from ilya-lavrenov:cuda 2014-02-03 12:12:12 +04:00
Roman Donchenko c967069922 Merge pull request #2254 from ilya-lavrenov:opengl 2014-02-03 12:11:28 +04:00
Ilya Lavrenov e844c08203 some fixes and improvements in cv::matchTemplate 2014-02-02 19:20:37 +04:00
Ilya Lavrenov 31b7cdc695 implemented OpenCL version of cv::updateMotionHistory 2014-02-02 17:52:57 +04:00
Ilya Lavrenov 19f799ba1e fix2 for OpenCL on/off 2014-02-02 15:35:13 +04:00
Ilya Lavrenov 02692f9ac0 fix MACRO 2014-02-01 22:43:41 +04:00
Andrey Pavlenko 75dde49b64 Merge pull request #2230 from ilya-lavrenov:tapi_openc_on-off_game 2014-02-01 22:32:39 +04:00
Ilya Lavrenov f8dd9960af one more ocl deletion 2014-02-01 21:50:14 +04:00
Ilya Lavrenov 66b2acc8ee removed ocl from allmodules list 2014-02-01 20:55:50 +04:00
Ilya Lavrenov ec3eb14138 unused function in case of unavailable OpenGL 2014-02-01 18:14:10 +04:00
Ilya Lavrenov a6104bd025 fixed unused function in case of unavailable CUDA 2014-02-01 18:11:45 +04:00
Ilya Lavrenov 6ad4823f0c ported superres to T-API 2014-02-01 17:20:18 +04:00
Scott Breyfogle aaa9be7c65 Merge remote-tracking branch 'original/master' into constrained-hough-lines 2014-01-31 14:27:51 -08:00
Scott Breyfogle b074c67a56 Add static cast to hough lines 2014-01-31 14:26:45 -08:00
Roman Donchenko 2bef73c968 Merge pull request #2249 from jet47:gpu-tests-disable 2014-01-31 20:49:05 +04:00
Roman Donchenko a518d7a1cb Merge pull request #2248 from jet47:gpu-npp-disable 2014-01-31 20:48:52 +04:00
Roman Donchenko 9ef8aeadd3 Merge pull request #2247 from jet47:gpu-test-cufft 2014-01-31 20:48:38 +04:00
Andrey Pavlenko 983799d398 Merge pull request #2219 from ilya-lavrenov:createHanningWindow 2014-01-31 19:38:57 +04:00
Ilya Lavrenov 0ebb3ab0ea optimized createHanningWindow 2014-01-31 19:35:12 +04:00
Andrey Pavlenko c909a21035 Merge pull request #2219 from ilya-lavrenov:createHanningWindow 2014-01-31 19:25:29 +04:00
Andrey Pavlenko 25d2ab8a68 Merge pull request #2218 from alalek:fix_defects_code_coverity 2014-01-31 19:23:02 +04:00
Andrey Pavlenko 6925dbd9f9 Merge pull request #2216 from ElenaGvozdeva:ocl_MOG2 2014-01-31 19:22:38 +04:00
Andrey Pavlenko 5894f82f14 Merge pull request #2202 from ilya-lavrenov:tapi_GFTTDetector 2014-01-31 19:22:18 +04:00
Andrey Pavlenko b0befeb1b3 Merge pull request #2232 from ilya-lavrenov:ABF_drop 2014-01-31 19:17:16 +04:00
Ilya Lavrenov c01e8e9361 removed ABF 2014-01-31 19:15:40 +04:00
Andrey Pavlenko 2c35438771 Merge pull request #2228 from ilya-lavrenov:tapi_experiments 2014-01-31 19:14:19 +04:00
Andrey Pavlenko 09b55a77c8 Merge pull request #2243 from ilya-lavrenov:ocl2trash 2014-01-31 19:08:27 +04:00
Andrey Pavlenko 82bab2b03b Merge pull request #2236 from ilya-lavrenov:tapi_boxfilter 2014-01-31 19:04:49 +04:00
Andrey Pavlenko 0b57d3717f Merge pull request #2244 from ilya-lavrenov:tapi_device_cache 2014-01-31 19:04:30 +04:00
Andrey Pavlenko b104b04d53 Merge pull request #2245 from ilya-lavrenov:redundant_sync 2014-01-31 19:04:07 +04:00
Andrey Pavlenko e8d66f5cb7 Merge pull request #2246 from alalek:intersection_loop_bug 2014-01-31 18:58:01 +04:00
Roman Donchenko e2db68f822 Merge pull request #2242 from jet47:gpu-test-fix 2014-01-31 17:24:21 +04:00
Vladislav Vinogradov 952027a853 disable gpu CvtColor.*2HSV tests:
possible bug in CPU version
2014-01-31 16:20:45 +04:00
Vladislav Vinogradov e91bf95d58 disable gpu Subtract_Array test:
possible bug in CPU version
2014-01-31 16:15:11 +04:00
Vladislav Vinogradov dbce90692a disable gpu Canny and HoughCircles perf tests:
it fails because driver terminates CUDA kernels after time out
2014-01-31 16:14:07 +04:00
Vladislav Vinogradov e630be3890 disable NPP for GpuMat methods and for copyMakeBorder 2014-01-31 15:52:06 +04:00
Vladislav Vinogradov 8401ed9395 disable some gpu tests if library was built without CUFFT 2014-01-31 15:40:59 +04:00
Roman Donchenko 7161b5bbad Merge pull request #2241 from asmorkalov:ocv_highgui_test_output_fix 2014-01-31 14:56:10 +04:00
Alexander Alekhin 9300af90cd imgproc/intersection: fix loop index 2014-01-31 14:42:38 +04:00
Ilya Lavrenov d15bf6261a redundant clFinish in upload since clEnqueueWriteBuffer above is already blocked 2014-01-31 14:39:03 +04:00
Roman Donchenko 7e6293d9ec Merge pull request #2240 from jet47:gpu-generalized-hough 2014-01-31 14:24:04 +04:00
Ilya Lavrenov 50cf152977 cached commonly used device properties 2014-01-31 14:00:05 +04:00
Roman Donchenko b13d4bafa8 Merge pull request #2238 from asmorkalov:ocv_test_package_reports 2014-01-31 13:56:48 +04:00
Ilya Lavrenov 0f168936a0 OCL module 2 trash 2014-01-31 13:19:16 +04:00
Vladislav Vinogradov 49731ad530 gpu test output files moved from cwd to temp folder 2014-01-31 13:19:15 +04:00
Alexander Smorkalov 3d261e8a01 Reports path fix for opencv_run_all_tests.sh.in script. 2014-01-31 13:17:12 +04:00
Roman Donchenko 9041c31813 Merge pull request #2223 from cosminBoaca:add_prob_result_bayes_classifier 2014-01-31 12:49:19 +04:00
Alexander Smorkalov 87935f3560 Highgui test output fixes.
Useless output to console fixed;
Test output files moved from cwd to temp folder.
2014-01-31 12:49:10 +04:00
Vladislav Vinogradov 063d8b4211 disable performance test for gpu generalized hough 2014-01-31 12:40:40 +04:00
Roman Donchenko 1f3206af70 Merge pull request #2237 from ivylee:lbph_chi_square_alt 2014-01-31 12:22:24 +04:00
Elena Gvozdeva 69630ee9d9 fixed test 2014-01-31 10:46:29 +04:00
Ilya Lavrenov 68f5dd4170 simplified cv::boxFilter OpenCL impl 2014-01-31 01:53:38 +04:00
Ivy Lee b7f2b671a2 Fixed Bug #3514 Incorrect Chi-Square distance used in LBPH FaceRecognizer 2014-01-30 21:53:05 +00:00
Cosmin Boaca f756171f7b Fixed alignment 2014-01-30 16:43:56 +02:00
Cosmin Boaca 8782eb8657 Fixed alignment 2014-01-30 16:41:38 +02:00
Cosmin Boaca b90f82e61f Merge branch 'add_prob_result_bayes_classifier', remote-tracking branch 'upstream/master' into add_prob_result_bayes_classifier 2014-01-30 16:38:15 +02:00
Andrey Pavlenko 77bbd65fa6 Merge pull request #2220 from ilya-lavrenov:tapi_accumulate 2014-01-30 17:33:06 +04:00
Andrey Pavlenko 66cc440c82 Merge pull request #2226 from ilya-lavrenov:tapi_calcHist 2014-01-30 17:28:43 +04:00
Ilya Lavrenov 1ab1594d00 workaround 2014-01-30 17:26:56 +04:00
Cosmin Boaca 2cd22a3ca3 Fixed broken alignment 2014-01-30 13:37:53 +02:00
Cosmin Boaca e6f86ea39d Merge branch 'add_prob_result_bayes_classifier', remote-tracking branch 'upstream/master' into add_prob_result_bayes_classifier 2014-01-30 13:32:32 +02:00
Ilya Lavrenov 372cdac07c moved kernelToStr to ocl.hpp 2014-01-30 15:23:11 +04:00
Roman Donchenko d14e007fdb Merge pull request #2231 from asmorkalov:android_toolchain_update 2014-01-30 13:22:11 +04:00
Ilya Lavrenov 231bc17de7 added conditional compilation 2014-01-30 13:07:13 +04:00
Roman Donchenko 40f6f679b8 Merge pull request #2224 from SpecLad:obsolete-immediate 2014-01-30 12:43:51 +04:00
Roman Donchenko 2b3013fd20 Merge pull request #2229 from ilya-lavrenov:possible_memory_leak 2014-01-30 12:23:20 +04:00
Alexander Smorkalov c815043607 Android toolchain file sync with original project.
Original project: https://github.com/taka-no-me/android-cmake/
Revision: 5db45cfb87fec180b74963d3680dd60d4d8d8c3a
2014-01-30 11:08:49 +04:00
Ilya Lavrenov 1862dbc5ab fixed fp problem 2014-01-30 05:48:15 +04:00
Ilya Lavrenov 0d19cbcc7a added performance test 2014-01-30 02:01:38 +04:00
Ilya Lavrenov 86353eb541 fix for PR 2196 2014-01-30 01:47:25 +04:00
Ilya Lavrenov e7e63fac6c eliminated possible memory leak 2014-01-30 01:21:04 +04:00
Ilya Lavrenov 6d64907f18 async 2014-01-30 00:19:18 +04:00
Ilya Lavrenov 6fa41c5a64 some experiments 2014-01-30 00:12:59 +04:00
Ilya Lavrenov faa6074f3d added performance test 2014-01-29 20:34:37 +04:00
Ilya Lavrenov 384a28622d added cv::calcHist to T-API (only for CV_8UC1 with 256 bins) 2014-01-29 20:19:15 +04:00
Alexander Alekhin 6fa49f6e80 fix unintialized fields 2014-01-29 19:59:03 +04:00
Alexander Alekhin f91f55927e fix memory management problem 2014-01-29 19:59:01 +04:00
Roman Donchenko 0dad2876e2 Removed all use of the obsolete IMMEDIATE parameter to configure_file.
It's not documented, and it does nothing unless CMake 2.0 compatibility
is enabled (and it isn't):

https://github.com/Kitware/CMake/blob/v2.6.0/Source/cmConfigureFileCommand.cxx
2014-01-29 19:34:02 +04:00
Roman Donchenko afa62c4161 Merge pull request #2212 from SpecLad:hog-sample-const-mat 2014-01-29 17:20:25 +04:00
Roman Donchenko 9b9eadc941 Merge pull request #2214 from cosminBoaca:add_returnDFVal_parallel_predict 2014-01-29 17:12:48 +04:00
Roman Donchenko 5ae9add102 Merge pull request #2221 from asmorkalov:ocv_test_install_custom 2014-01-29 17:09:28 +04:00
Alexander Smorkalov d45350a06a opencv_run_all_tests.sh script added to -tests package. 2014-01-29 16:31:24 +04:00
Cosmin Boaca 97092e31bc Added result_probabilities parameter to CvNormalBayesClassifier::predict method. Issue #3401 2014-01-29 13:57:51 +02:00
Elena Gvozdeva 96b6f338e1 fixed 2014-01-29 14:27:29 +04:00
Ilya Lavrenov 7c96d98a24 implemented OpenCL version of cv::accumulate**** 2014-01-29 11:42:46 +04:00
Elena Gvozdeva 17c6b4d306 fixed warnings 2014-01-29 11:05:05 +04:00
Ilya Lavrenov 41bc5808c0 optimized createHanningWindow 2014-01-28 23:37:20 +04:00
Alexander Alekhin 5474935a81 fixes for defects from code coverity 2014-01-28 20:24:10 +04:00
Roman Donchenko 3e59ddbace Merge pull request #2215 from asmorkalov:ocv_testpack_fix 2014-01-28 17:51:07 +04:00
Alexander Smorkalov d9dc5ffa91 Multiple fixes for tests deb package build.
Added opencv_testing.sh.in file;
opencv_testing.sh installation guarded by OS check.
2014-01-28 16:32:26 +04:00
Andrey Pavlenko fff5a6c058 Merge pull request #2213 from ilya-lavrenov:tapi_buildPyramid 2014-01-28 16:31:30 +04:00
Elena Gvozdeva 0edd0aaf69 fixed 2014-01-28 16:23:39 +04:00
Elena Gvozdeva 1391ca1da5 Added ocl_Mog2 2014-01-28 16:23:38 +04:00
Cosmin Boaca 3985980b2f Added returnDFVal parameter to parallel CvSVM::predict function 2014-01-28 11:54:39 +02:00
Roman Donchenko 84c29745f2 Merge pull request #2211 from SpecLad:merge-2.4 2014-01-28 12:44:29 +04:00
Roman Donchenko 7a0a9d010b Merge pull request #2205 from jet47:bug-3477-fix 2014-01-28 12:23:32 +04:00
Andrey Pavlenko 51aa649499 Merge pull request #2097 from pclove1:blur_border_isolated 2014-01-28 10:51:11 +04:00
Vladislav Vinogradov c41e8006c7 fix #3477:
CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING property is not supported
by all VideoCapture backends. Some backends can return 0.0 or -1.0.
2014-01-28 10:28:00 +04:00
Seunghoon Park eb9d7c4dd5 fixing bug #3345. use norm to make sure two matrices are the same. 2014-01-27 20:57:40 -05:00
Seunghoon Park 73389b2b9c Merge branch '2.4' into blur_border_isolated 2014-01-27 20:44:03 -05:00
Roman Donchenko 452ea4c15f Merge pull request #2209 from asmorkalov:ocv_test_install 2014-01-27 20:59:53 +04:00
Andrey Pavlenko 6deda99f07 Merge pull request #2207 from ilya-lavrenov:tapi_macro 2014-01-27 18:56:06 +04:00
Ilya Lavrenov 78c2b3ca2a refactored imgproc 2014-01-27 18:47:16 +04:00
Alexander Smorkalov 39201e68e2 Code review notes fixed.
Env setup for testing package implemented using /etc/profile.d;
Variable with path for all native samples added;
Path for test binaries and test data updated.
2014-01-27 18:47:09 +04:00
Ilya Lavrenov 48a084c236 OpenCL version of cv::buildPyramid 2014-01-27 18:42:44 +04:00
Andrey Pavlenko d9b24457fa Merge pull request #2208 from alalek:ocl_dynload_warn 2014-01-27 18:24:14 +04:00
Roman Donchenko 6a511755b2 Fixed build for samples/cpp/train_HOG.cpp.
get_hogdescriptor_visu is passed img->clone(), which is not usable
as a non-const reference (and it doesn't modify the argument, anyway).
2014-01-27 17:39:33 +04:00
Andrey Pavlenko ce48b6afde Merge pull request #2203 from ilya-lavrenov:tapi_umat_vectors 2014-01-27 16:06:12 +04:00
Andrey Pavlenko 4dd805b7a9 Merge pull request #2206 from ilya-lavrenov:ocl_warn_fix 2014-01-27 16:05:54 +04:00
Alexander Smorkalov f332cba14b OpenCV C/C++/OCL/CUDA samples install path fixed. Install rools for tests added. 2014-01-27 15:49:24 +04:00
Roman Donchenko bbc35d609d Merge remote-tracking branch 'origin/2.4' into merge-2.4
Conflicts:
	cmake/OpenCVDetectPython.cmake
	cmake/OpenCVModule.cmake
	modules/core/src/gpumat.cpp
	modules/cudaimgproc/test/test_hough.cpp
	modules/gpu/CMakeLists.txt
	modules/gpu/src/cuda/generalized_hough.cu
	modules/gpu/src/generalized_hough.cpp
	modules/python/CMakeLists.txt
2014-01-27 15:28:14 +04:00
Alexander Alekhin 1ff9a8ef52 core/ocl: added warning about incompatible configuration 2014-01-27 13:52:52 +04:00
Ilya Lavrenov c8f2050cc2 warn fix 2014-01-27 12:34:30 +04:00
Ilya Lavrenov 321782b9b7 added macro with ability of returning values 2014-01-27 12:32:26 +04:00
Ilya Lavrenov f767077a41 fixed condition 2014-01-27 12:00:53 +04:00
Ilya Lavrenov 2dd294cc84 fixed cv::split; enabled test 2014-01-27 12:00:53 +04:00
Ilya Lavrenov fa5492343a added STD_VECTOR_UMAT support to _OutputArray::create 2014-01-27 11:59:59 +04:00
Andrey Pavlenko 06acf7090c Merge pull request #2027 from AD-530:brief_cl 2014-01-27 09:49:46 +04:00
Andrey Pavlenko a64d3c1744 Merge pull request #2155 from vbystricky:ocl_calcOpticalFlowPyrLK 2014-01-25 17:08:07 +04:00
Andrey Pavlenko 1db8aa8628 Merge pull request #2204 from ilya-lavrenov:tapi_stitch_perf_fix 2014-01-25 16:54:00 +04:00
Andrey Pavlenko 3f61007563 Merge pull request #2191 from ilya-lavrenov:tapi_macro 2014-01-25 16:32:54 +04:00
Ilya Lavrenov 9968197ebf doc fix 2014-01-25 14:44:28 +04:00
Ilya Lavrenov 7184925105 fix 2014-01-25 11:50:28 +04:00
Ilya Lavrenov e559256719 added cv::GFTTDetector 2014-01-25 00:23:59 +04:00
Ilya Lavrenov 7f785e0a11 refactored core using new macro 2014-01-24 23:59:00 +04:00
vbystricky bb09d44e0a Unused code removed 2014-01-24 17:37:54 +04:00
vbystricky 27fb7e1802 Change type of result vector of ocl version from row to column 2014-01-24 17:37:53 +04:00
vbystricky 094bc92318 Fix build error 2014-01-24 17:37:53 +04:00
vbystricky a7e5a488a8 Change method of setting arguments to kernel to safe one 2014-01-24 17:37:52 +04:00
vbystricky e96ba8140c Grow up epsilon for sanity checks 2014-01-24 17:37:52 +04:00
vbystricky 3a798a27e5 Add perfomance test 2014-01-24 17:37:52 +04:00
vbystricky ece635bf3c Fix builds errors 2014-01-24 17:37:51 +04:00
vbystricky 3ba6636651 Fix builds errors 2014-01-24 17:37:51 +04:00
vbystricky 33fc46cdec Validate parameters for using OpenCL version, before upload UMat 2014-01-24 17:37:50 +04:00
vbystricky 4152135e63 Fix error with some opencl functions on the build WITH_OPENCL=OFF 2014-01-24 17:37:50 +04:00
vbystricky c57e427fba Move OpticalFlowPyrLK from ocl module to video module 2014-01-24 17:37:50 +04:00
Andrey Pavlenko ac3f06bc7f Merge pull request #2149 from ElenaGvozdeva:ocl_matchTemplate 2014-01-24 17:33:06 +04:00
Ilya Lavrenov cc514ac7a9 added new macros useful for tracking whether OpenCL impl run or not 2014-01-24 17:16:40 +04:00
Andrey Pavlenko 22c804d97c Merge pull request #2182 from KonstantinMatskevich:ocl_tapi_samples 2014-01-24 17:03:42 +04:00
Andrey Pavlenko 5424c55565 Merge pull request #2142 from KonstantinMatskevich:ocl_tapi_bfmatcher 2014-01-24 16:50:03 +04:00
Andrey Pavlenko b0caa588ec Merge pull request #2190 from KonstantinMatskevich:ocl_dumpinfo 2014-01-24 16:44:19 +04:00
Konstantin Matskevich c7a6537b83 add brackets 2014-01-24 16:35:51 +04:00
Andrey Pavlenko d093cb54d5 Merge pull request #2194 from apavlenko:2.4_perf_haar_iter 2014-01-24 16:13:19 +04:00
Roman Donchenko 24caa80143 Merge pull request #2197 from asmorkalov:ocv_packaging2 2014-01-24 14:27:44 +04:00
Konstantin Matskevich ae827a638c fixes 2014-01-24 14:01:31 +04:00
Konstantin Matskevich 07778e1760 fixes 2014-01-24 13:37:19 +04:00
Konstantin Matskevich 450ea3131f samples 2014-01-24 12:59:19 +04:00
Alexander Smorkalov 086792ec06 Improvements in package build. 2014-01-24 12:00:44 +04:00
Elena Gvozdeva 07a88d48e9 fixed 2014-01-24 11:41:23 +04:00
Andrey Pavlenko 0a4a1d7526 temporary disabling hanging test 2014-01-24 10:07:21 +04:00
Roman Donchenko 078d49609e Merge pull request #2193 from apavlenko:2.4_lic_remove 2014-01-23 17:13:52 +04:00
Andrey Pavlenko dca5684145 removing duplicated legacy license, the actual instance is in 'opencv/LICENSE' 2014-01-23 17:05:20 +04:00
Elena Gvozdeva 4d86804f11 Fixed merge conflicts 2014-01-23 15:31:32 +04:00
Elena Gvozdeva 7bd8f9294d fixed 2014-01-23 14:50:30 +04:00
Elena Gvozdeva 8c5e19c270 fixed pref test 2014-01-23 14:50:29 +04:00
Elena Gvozdeva b4652e2cb3 Added perf test for ocl_matchTemplate 2014-01-23 14:50:29 +04:00
Elena Gvozdeva 2c0765b4d1 fixed trailing whitespace 2014-01-23 14:50:29 +04:00
Elena Gvozdeva 7e2bdb590f fixed 2014-01-23 14:50:29 +04:00
Elena Gvozdeva 4da1ba56b3 fixed 2014-01-23 14:50:29 +04:00
Elena Gvozdeva 47b572f99f fixed 2014-01-23 14:50:28 +04:00
Elena Gvozdeva da4d33ec26 Fixed test_match_template 2014-01-23 14:50:28 +04:00
Elena Gvozdeva 9de70c9a00 Fixed trailing whitespace 2014-01-23 14:50:28 +04:00
Elena Gvozdeva ba5d480f80 Fixed warnings 2014-01-23 14:50:28 +04:00
Elena Gvozdeva 86636dc265 Added ocl_matchTemplate( without dft) 2014-01-23 14:50:28 +04:00
Andrey Pavlenko ee88cc2c52 Merge pull request #2110 from hmax:master 2014-01-23 14:37:34 +04:00
Roman Donchenko 7ff9d7eb2d Merge pull request #2188 from jet47:gpumat-copyto-fix 2014-01-23 13:28:12 +04:00
Roman Donchenko 3715f71aaf Merge pull request #2175 from vrabaud:2.4 2014-01-23 13:27:38 +04:00
Konstantin Matskevich 133f91f3f2 added perf test 2014-01-23 07:51:19 +04:00
Andrey Pavlenko ba77719914 Merge pull request #2189 from ilya-lavrenov:tapi_sepFilter2D_fix 2014-01-22 19:13:05 +04:00
Andrey Pavlenko 7ce6c28bb4 Merge pull request #2186 from ilya-lavrenov:tapi_precornerdetect 2014-01-22 19:09:34 +04:00
Andrey Pavlenko 9aa4410509 Merge pull request #2134 from vbystricky:ocl_calcOpticalFlowFarneback 2014-01-22 18:57:34 +04:00
Vincent Rabaud 167a26642e fix message sent to user during cross_compilation 2014-01-22 15:26:14 +01:00
Konstantin Matskevich f90e41d54e dumpinfo 2014-01-22 17:04:44 +04:00
Konstantin Matskevich 2f8c29a1f0 removed unnecessary functions and variables 2014-01-22 15:31:27 +04:00
Konstantin Matskevich 3b7683e72f fixed docs 2014-01-22 15:31:26 +04:00
Konstantin Matskevich ca5689e0db BFMatcher
match

radiusMatch
2014-01-22 15:31:26 +04:00
Ilya Lavrenov d2ffd8ed21 implemented OpenCL version of cv::preCornerDetect 2014-01-22 13:46:26 +04:00
Ilya Lavrenov 059e6e4305 fixed cv::sepFilter2D 2014-01-22 13:40:48 +04:00
Roman Donchenko ee331001f5 Merge pull request #2161 from SpecLad:doc-req 2014-01-22 12:04:48 +04:00
Roman Donchenko a4b34e7ae1 Merge pull request #2181 from asmorkalov:ocv_packaging 2014-01-22 11:54:07 +04:00
Vladislav Vinogradov dda999545c fix GpuMat::copyTo method with mask:
fill destination matrix with zeros if it was reallocated
2014-01-22 10:40:14 +04:00
vbystricky e0c6377d58 Change the sanity checking type to ERROR_RELATIVE 2014-01-22 10:34:27 +04:00
Andrey Pavlenko 069bb9a929 Merge pull request #2185 from ilya-lavrenov:tapi_corners 2014-01-22 10:25:41 +04:00
Andrey Pavlenko 665d9cb29c Merge pull request #2168 from ilya-lavrenov:tapi_perf_stitching 2014-01-22 10:14:38 +04:00
Andrey Pavlenko 5d818c010e Merge pull request #2156 from ilya-lavrenov:tapi_reduce 2014-01-22 10:12:08 +04:00
Andrey Pavlenko 1400f53436 Merge pull request #2184 from ilya-lavrenov:bioinspired2contrib 2014-01-21 23:27:16 +04:00
Andrey Pavlenko 99942e8043 Merge pull request #2166 from ilya-lavrenov:tapi_gftt 2014-01-21 22:29:41 +04:00
Alexander Smorkalov 7821fe2bde Initial Linux packages build rools for CPack. 2014-01-21 20:34:36 +04:00
Alexander Smorkalov b75cbfde45 All installed files marked with component names for install customization. 2014-01-21 20:34:36 +04:00
Ilya Lavrenov 3177a683e9 ported corners to T-API 2014-01-21 20:13:55 +04:00
Roman Donchenko a548a08129 Merge pull request #2183 from jet47:cuda-hough-fix 2014-01-21 19:27:54 +04:00
Andrey Pavlenko c8afe7efc6 Merge pull request #1320 from mbarnach:svm_hog 2014-01-21 19:23:04 +04:00
Andrey Pavlenko 4fbd2ef87a Merge pull request #1290 from mbarnach:bow_desc 2014-01-21 19:22:47 +04:00
Andrey Pavlenko 32bc89f094 Merge pull request #2107 from nghiaho12:nn_doc 2014-01-21 19:11:12 +04:00
Ilya Lavrenov 303c37a175 removed TOC 2014-01-21 18:47:22 +04:00
vbystricky c1172b83dd Change epsilon value to 0.01 2014-01-21 18:46:26 +04:00
Ilya Lavrenov 5d206059a8 moved bioinspired to opencv_contrib 2014-01-21 18:02:53 +04:00
Andrey Pavlenko 9eca3ec8f6 Merge pull request #2177 from ilya-lavrenov:ocl_superres 2014-01-21 17:05:50 +04:00
Vladislav Vinogradov 33d42b740c disable CUDA generalized Hough Transform 2014-01-21 15:07:47 +04:00
Vladislav Vinogradov d847387694 split CUDA Hough sources 2014-01-21 15:07:47 +04:00
Ilya Lavrenov bfa382cf9d fixed copying UMat -> std::vector 2014-01-21 14:37:22 +04:00
Ilya Lavrenov ae4be413c3 added perf tests for cv::reduce 2014-01-21 14:18:38 +04:00
Vincent Rabaud eabcfa5652 reorder the if's for clarity 2014-01-21 10:27:37 +01:00
Ilya Lavrenov ac2e613975 skip OCL tests if OpenCL isn't available 2014-01-21 13:09:39 +04:00
Vincent Rabaud 6cb90c0e97 fix cross-compilation issue with Numpy 2014-01-21 10:07:19 +01:00
Andrey Pavlenko 494f7e3657 Merge pull request #2158 from KonstantinMatskevich:testdata_path_calib3d 2014-01-20 23:35:06 +04:00
Andrey Pavlenko 801d2d0a32 Merge pull request #2167 from ilya-lavrenov:tapi_kern_warn 2014-01-20 23:33:55 +04:00
Roman Donchenko 64244e160b Merge pull request #2171 from djetter99:fix_static_init_order 2014-01-20 19:30:29 +04:00
Roman Donchenko a509819b21 Merge pull request #2163 from ilya-lavrenov:tapi_channels 2014-01-20 18:48:52 +04:00
Ilya Lavrenov e5130cf83f enabled tests 2014-01-20 18:09:43 +04:00
Roman Donchenko 9710b25c7d Merge pull request #2173 from Nerei:viz 2014-01-20 18:05:11 +04:00
Roman Donchenko 9dc93ce328 Merge pull request #2176 from SpecLad:merge-2.4 2014-01-20 18:04:56 +04:00
Anatoly Baksheev ac035b9b8e review comments 2014-01-20 15:22:58 +04:00
Andrey Pavlenko 69ba0c53ad Merge pull request #2165 from ilya-lavrenov:tapi_upload 2014-01-20 15:18:56 +04:00
Roman Donchenko e45fd939c2 Merge remote-tracking branch 'origin/2.4' into merge-2.4
Conflicts:
	modules/ocl/src/cl_runtime/cl_runtime.cpp
	modules/ocl/src/cl_runtime/clamdblas_runtime.cpp
	modules/ocl/src/cl_runtime/clamdfft_runtime.cpp
	modules/ocl/src/cl_runtime/generator/template/clamdblas_runtime.cpp.in
	modules/ocl/src/cl_runtime/generator/template/clamdfft_runtime.cpp.in
2014-01-20 15:10:19 +04:00
Roman Donchenko 087371c021 Merge pull request #2164 from ilya-lavrenov:excess_commas_semicolons_v2 2014-01-20 14:15:05 +04:00
Ilya Lavrenov 5abfd40989 added perf test for cv::goodFeaturesToTrack 2014-01-20 13:57:53 +04:00
Ilya Lavrenov 52ed6d0d27 ported cv::goodFeaturesToTrack to T-API 2014-01-20 13:57:53 +04:00
Ilya Lavrenov 5d18cf9989 added cv::[extract|insert]Channel to T-API 2014-01-20 13:52:07 +04:00
Roman Donchenko 8386ce2b2f Merge pull request #2160 from SpecLad:norm-assert 2014-01-20 12:20:21 +04:00
Roman Donchenko d47f32581c Merge pull request #2174 from Nerei:yet_another_fix_for_pr2172 2014-01-20 12:06:44 +04:00
Anatoly Baksheev 4cc8f7012b closing window 2014-01-19 18:39:01 +04:00
Anatoly Baksheev 4e18007066 fixed white spaces 2014-01-19 18:39:01 +04:00
Anatoly Baksheev d29c3d2f0d fixed documentation warnings 2014-01-19 18:39:00 +04:00
Anatoly Baksheev 8f15a8abdb disabled Ubuntu workaround code for Windows 2014-01-19 18:39:00 +04:00
Anatoly Baksheev 0d12fb0346 implemented workaround of a problem with x-server for ubuntu 2014-01-19 18:39:00 +04:00
Anatoly Baksheev 7410593d55 fixed warnigns and compiler errors for Ubuntu 2014-01-19 18:39:00 +04:00
Anatoly Baksheev d7ca0bb757 merged background color with background gradient methods, updated tests to show description of scene 2014-01-19 18:38:59 +04:00
Anatoly Baksheev 16281027af resolved problem with multiple spin()/spinOnce() 2014-01-19 18:38:59 +04:00
Anatoly Baksheev 57d5ad5131 minor iteractor refactoring 2014-01-19 18:38:59 +04:00
Anatoly Baksheev ffad7b699c added test for textured mesh 2014-01-19 18:38:59 +04:00
Anatoly Baksheev 8d327fa497 updated for compatibility with VTK6.0 2014-01-19 18:38:58 +04:00
Anatoly Baksheev e472d45d99 updated mesh reading (texture support) 2014-01-19 18:38:58 +04:00
Anatoly Baksheev 625c35a9f9 added support of texture for mesh 2014-01-19 18:38:58 +04:00
Anatoly Baksheev 74206e0159 added painted cloud widget 2014-01-19 18:38:57 +04:00
Anatoly Baksheev 3086095837 improved background gradient 2014-01-19 18:38:57 +04:00
Anatoly Baksheev b0ca93b22c by default enabled tests vtk 2014-01-19 18:38:57 +04:00
Anatoly Baksheev d7c30281a5 set background texture method 2014-01-19 18:38:57 +04:00
Anatoly Baksheev e2ef558c8a refactored WGrid 2014-01-19 18:38:56 +04:00
Anatoly Baksheev 658f4a7d38 refactoed plane 2014-01-19 18:38:56 +04:00
Anatoly Baksheev 53b8218652 addeed test for text 2d/3d 2014-01-19 18:38:56 +04:00
Anatoly Baksheev bb891f0570 added cone implementation 2014-01-19 18:38:56 +04:00
Anatoly Baksheev 08f50314cb updated cylinder and cube 2014-01-19 18:38:55 +04:00
Anatoly Baksheev c0cc551228 refactored circle 2014-01-19 18:38:55 +04:00
Anatoly Baksheev dac27c9913 refactored arrow 2014-01-19 18:38:55 +04:00
Anatoly Baksheev 1449823bcd implemented showImage 2014-01-19 18:38:55 +04:00
Anatoly Baksheev d90a068e0e fixed bug with setImage 2014-01-19 18:38:54 +04:00
Anatoly Baksheev cad9a786c4 optimized Mat to vtkImageData conversion 2014-01-19 18:38:54 +04:00
Anatoly Baksheev e21f2a81ff factored camera postions with image 2014-01-19 18:38:54 +04:00
Anatoly Baksheev a23f1447a8 minor 2014-01-19 18:38:53 +04:00
Anatoly Baksheev f930f2f19d simplification of cloud collection 2014-01-19 18:38:53 +04:00
Anatoly Baksheev e3ff28dacc refactored WImage3D 2014-01-19 18:38:53 +04:00
Anatoly Baksheev f37c31742a created tests for images, created vtk/vtkImageMatSource, and switched all images to that class 2014-01-19 18:38:53 +04:00
Anatoly Baksheev 462d516743 added test for camera positions, slightly refactored the widgets 2014-01-19 18:38:52 +04:00
Anatoly Baksheev 8309d19f31 renamed Mesh3d -> Mesh 2014-01-19 18:38:52 +04:00
Anatoly Baksheev d591bd875b fixed crash in enabling shading for polydata widgets 2014-01-19 18:38:52 +04:00
Anatoly Baksheev e478d6b1e9 renamed cv::viz::get() to getWindowByName() 2014-01-19 18:38:52 +04:00
Anatoly Baksheev 25b417e8b2 added test for trajectories and fixed bug with float type 2014-01-19 18:38:51 +04:00
Anatoly Baksheev 64566e6178 minor 2014-01-19 18:38:51 +04:00
Anatoly Baksheev 0d702b83f4 updated code to use mapper->SetInput instead of SetInputConnection. All widgets except plane, images ans texts 2014-01-19 18:38:51 +04:00
Anatoly Baksheev a3b1f29d23 refactored spheres trajectory 2014-01-19 18:38:51 +04:00
Anatoly Baksheev 38c9fa4a92 more refactoring 2014-01-19 18:38:50 +04:00
Anatoly Baksheev 4833976a0c refactored frustum trajectory to use glyphs 2014-01-19 18:38:50 +04:00
Anatoly Baksheev 42dc90295d refactored camera position - simplified frustum creation 2014-01-19 18:38:50 +04:00
Anatoly Baksheev 45879fb9db more refactoring 2014-01-19 18:38:50 +04:00
Anatoly Baksheev a8556134ae refactored simple trajectory to use TensorGlyph 2014-01-19 18:38:49 +04:00
Anatoly Baksheev 771d9509a8 polyline now uses scalars for color data (for reuse by other widgets) 2014-01-19 18:38:49 +04:00
Anatoly Baksheev e94ee94be3 refactored WCoordinateSystem widget 2014-01-19 18:38:49 +04:00
Anatoly Baksheev 56819eaf19 switched completer API to doubles, updated docs 2014-01-19 18:38:48 +04:00
Anatoly Baksheev d264465422 more refactoring 2014-01-19 18:38:48 +04:00
Anatoly Baksheev 406444037d refactored polyline 2014-01-19 18:38:48 +04:00
Anatoly Baksheev b100299644 code beatification 2014-01-19 18:38:48 +04:00
Anatoly Baksheev e26b7e1e4f ported some trajectories functionality to InputArray style 2014-01-19 18:38:47 +04:00
Anatoly Baksheev 7b28f730f4 traits for Affine3 2014-01-19 18:38:47 +04:00
Anatoly Baksheev cd57c4e189 refactored CloudNormals and added test for it 2014-01-19 18:38:47 +04:00
Anatoly Baksheev b7cb3fe8e0 switched more to doubles 2014-01-19 18:38:47 +04:00
Anatoly Baksheev a76a34d28e added Affine3: 3x4 input Mat support 2014-01-19 18:38:46 +04:00
Anatoly Baksheev 3e071491c9 added Affine3 ctor from array 2014-01-19 18:38:46 +04:00
Anatoly Baksheev baee8c3aa5 refactored Mesh, added tests, added failing "twice spin()" test 2014-01-19 18:38:46 +04:00
Anatoly Baksheev 70a81db567 fixed bugs in cloud collection and added test 2014-01-19 18:38:46 +04:00
Anatoly Baksheev cb58061649 getViewerPose implementation simplified (and error seems to be fixed) 2014-01-19 18:38:45 +04:00
Anatoly Baksheev 186853a50f mass switch from Affine3f to Affine3d 2014-01-19 18:38:45 +04:00
Anatoly Baksheev b1c0bf1fee Affine::rotate(rvec) method 2014-01-19 18:38:45 +04:00
Anatoly Baksheev 1615527426 switched source to InputArrays 2014-01-19 18:38:45 +04:00
Anatoly Baksheev f610c295f2 more tests 2014-01-19 18:38:44 +04:00
Anatoly Baksheev e7791e1590 colors minor 2014-01-19 18:38:44 +04:00
Anatoly Baksheev c1b41caa7c added vtkCloudMatSink, reworked cloud IO functions, added normals support 2014-01-19 18:38:44 +04:00
Anatoly Baksheev 1c4cfd8eaf normals support for CloudMatSource 2014-01-19 18:38:43 +04:00
Anatoly Baksheev 7e952e2f10 removed incorrect and unnecessarily methods from Affine3f 2014-01-19 18:38:43 +04:00
Anatoly Baksheev bf30c33e6e getting data from opencv_extra 2014-01-19 18:38:43 +04:00
Anatoly Baksheev b131faa8f9 export scene to vrml and obj formats 2014-01-19 18:38:43 +04:00
Anatoly Baksheev b2cd526e6a removed extra code 2014-01-19 18:38:42 +04:00
Anatoly Baksheev 84d6fe397d reading/writing clouds functionality 2014-01-19 18:38:42 +04:00
Anatoly Baksheev 80ab6e889f refactoring 2014-01-19 18:38:42 +04:00
Anatoly Baksheev 7dbf6bc8df rewrote cloud widget in vtk filters style
Conflicts:
	modules/viz/src/clouds.cpp
2014-01-19 18:38:42 +04:00
Anatoly Baksheev 159de9cc47 fixed potential crash 2014-01-19 18:38:41 +04:00
Anatoly Baksheev 2705068290 refactored Keyboard and Mouse Events 2014-01-19 18:38:41 +04:00
Anatoly Baksheev cad2f98007 removed vizActor (since unnecessarily in new design concept with simplified widgets) 2014-01-19 18:38:41 +04:00
Anatoly Baksheev 45aeecb043 renaming 2014-01-19 18:38:41 +04:00
Anatoly Baksheev abc9465798 kinect camera CAD parameters 2014-01-19 18:38:40 +04:00
Anatoly Baksheev e990d5b999 reading/writing trajectories 2014-01-19 18:38:40 +04:00
Anatoly Baksheev e048df51ce for shapes switched vtkDataSetMapper to more efficient vtkPolyDataMapper 2014-01-19 18:38:40 +04:00
Anatoly Baksheev 4979f44cfa minor 2014-01-19 18:38:40 +04:00
Anatoly Baksheev 31d42ce18f refactored Trajectory: split into Trajectory and TrajectoryFrustums) 2014-01-19 18:38:39 +04:00
Anatoly Baksheev 54fa69cab2 renamed Spheres Trajectory, minor changes in Trajectory 2014-01-19 18:38:39 +04:00
Anatoly Baksheev c7ff13873d minor 2014-01-19 18:38:39 +04:00
Anatoly Baksheev f6e9b81188 reduced exported interface names (to make IntelliSense hints less littered) 2014-01-19 18:38:38 +04:00
Anatoly Baksheev 44c1d4dfdc allow fast switch between actors (except mesh, cloud, cloud collection) 2014-01-19 18:38:38 +04:00
Anatoly Baksheev 2d63f60d43 minor changes, opencv cross-branch code 2014-01-19 18:38:38 +04:00
Anatoly Baksheev 15fd3faa40 support gray color clouds 2014-01-19 18:38:38 +04:00
Anatoly Baksheev 2cbfb04144 viz: rich set of named colors 2014-01-19 18:38:37 +04:00
Anatoly Baksheev 5ea3ecdc3b horisontal mwhell support 2014-01-19 18:32:22 +04:00
Ilya Lavrenov 3db33979e1 added perf tests for stitching warpers 2014-01-19 12:01:01 +04:00
Ilya Lavrenov 5af2e6f1c9 removed useless CRC calculation 2014-01-19 11:57:50 +04:00
Andrey Pavlenko f60f8a7346 Merge pull request #2172 from Nerei:compilation_and_warnings 2014-01-19 11:44:37 +04:00
Drew Jetter 6bf599b1bc Fixed bug #3489: The code assumed that two global variables would be constructed in a particular order, but global variable initialization order is compiler-dependent. 2014-01-18 23:04:16 -07:00
Anatoly Baksheev 4e20e06ee7 warnings 2014-01-19 04:07:24 +04:00
Anatoly Baksheev 0fc4ac4f1f warnings and compilation with installed Windows 8.1 SDK 2014-01-19 04:07:17 +04:00
Ilya Lavrenov 6b8bee6e0b fixed kernel compilation warnings 2014-01-18 22:37:47 +04:00
Matthias Bady d270c9e8b6 Type conversions to fix warnings 2014-01-18 11:12:13 +01:00
Matthias Bady 67e2d7ec43 Merge branch 'master' of https://github.com/Itseez/opencv into brief_cl 2014-01-18 10:38:07 +01:00
Ilya Lavrenov 37789f015a deleted excess semicolons, commas 2014-01-18 01:31:33 +04:00
Roman Donchenko e965f3d3d4 Merge pull request #2157 from k0da:master 2014-01-17 19:00:19 +04:00
Roman Donchenko 0de799b3b0 Removed some duplicate assertions. 2014-01-17 18:25:28 +04:00
Roman Donchenko 088535fa56 Merge pull request #2159 from SpecLad:1xN 2014-01-17 18:23:53 +04:00
Roman Donchenko 79fcc06a4b Merge pull request #2146 from SpecLad:merge-2.4 2014-01-17 16:28:30 +04:00
vbystricky f1541b5287 Add perfomance test 2014-01-17 16:15:39 +04:00
vbystricky fc8b385ff6 Return false if ocl version not properly worked 2014-01-17 16:15:38 +04:00
vbystricky 3762036b08 Fix compiler warnings. Add additional test case for UseInitFlow 2014-01-17 16:15:38 +04:00
vbystricky 3b0fa68a97 Move OpticalFlowFarneback from ocl module to video module 2014-01-17 16:15:38 +04:00
Roman Donchenko 659c5345d9 Merge pull request #2122 from adishavit:feature-HandleMouseWheel 2014-01-17 14:58:28 +04:00
Roman Donchenko 58afe5dd17 Merge pull request #2140 from Daniil-Osokin:fix_saving_untrained_svm_model 2014-01-17 14:57:57 +04:00
Andrey Pavlenko 664c9b15cf Merge pull request #2152 from ilya-lavrenov:tapi_canny 2014-01-17 14:52:17 +04:00
Roman Donchenko a502ffbd2c Updated required CMake version in docs to match reality. 2014-01-17 14:50:40 +04:00
Roman Donchenko e9805e444f Fixed an overly-narrow assertion in cv::norm.
size() requires that the matrix is two-dimensional, and norm()
works on higher dimensions.
2014-01-17 14:49:42 +04:00
Roman Donchenko 5f8d8c0069 Added a test for matrix-to-vector copy and convert. 2014-01-17 14:18:31 +04:00
Roman Donchenko 4e4a7d0353 Removed an unnecessary workaround for matrix-to-vector copyTo. 2014-01-17 14:16:22 +04:00
Roman Donchenko ee97a5e757 Re-fix bug #3319 with less side effects. 2014-01-17 14:13:21 +04:00
Roman Donchenko f02204847a Revert "fixed bug #3319"
See 092f916 for explanation.

This reverts commit 4f9c081dc3.
2014-01-17 13:43:00 +04:00
Konstantin Matskevich e9e9e00d45 replaced sprintf with cv::format 2014-01-17 13:01:12 +04:00
Roman Donchenko 092f916db9 Revert 4f9c081
That commit introduces problems, as it breaks certain use cases of
OpenCV functions; for example, convertTo of an Nx1 matrix to an
std::vector.

Since vectors can't store separate width and height values, OpenCV
considers them to always be 1xN. So even though the vector is created with
.create(N, 1), the Mat passed to getContinousSize has dimensions 1xN,
and the size comparison fails, even though the operation itself is safe.

This is a use case we probably don't want to break, at the very least
for backwards compatibility. So I'm reverting the commit. This will also
unfix bug #3319; I'll submit a less intrusive solution as a PR to 2.4, which
will also revert 4f9c081 there.
2014-01-17 12:51:52 +04:00
Ilya Lavrenov 93a818684c ported cv::Canny to T-API 2014-01-17 11:13:28 +04:00
Andrey Pavlenko 8dbc96fed8 Merge pull request #2143 from Daniil-Osokin:fix_docs_cvt_color_alpha_channel 2014-01-17 10:43:40 +04:00
Dinar Valeev 711f07a34c Use __vector instead of vector as suggests Eigen
This fixes build on PowerPC where Eigen unsets vector, bool and pixel

Signed-off-by: Dinar Valeev <dvaleev@suse.com>
2014-01-16 21:53:49 +01:00
Ilya Lavrenov 63a5e39e2c added cv::reduce to T-API 2014-01-17 00:41:18 +04:00
Daniil Osokin 8ce691e679 Fixed cvtColor alpha channel docs 2014-01-16 18:36:06 +04:00
Adi Shavit 8fd0fd538d Doc fix. 2014-01-16 16:30:54 +02:00
Roman Donchenko 07e08f7a3d Merge pull request #2141 from ilya-lavrenov:perf_warp 2014-01-16 18:03:21 +04:00
Roman Donchenko 63c61b4b98 Revert "replaced sprintf with cv::format"
Fixing build breakage.

This reverts commit b83eff7ecf.
2014-01-16 17:58:26 +04:00
Roman Donchenko ddfd1854a7 Merge pull request #2151 from KonstantinMatskevich:testdata_path_calib3d 2014-01-16 16:44:24 +04:00
Konstantin Matskevich b83eff7ecf replaced sprintf with cv::format 2014-01-16 16:18:02 +04:00
Adi Shavit 46f06d82c9 Update docs. 2014-01-16 12:51:14 +02:00
Adi Shavit 8802d62cc5 Updated docs. 2014-01-16 11:25:57 +02:00
Adi Shavit 24333569aa Small fixes: typo, spacing and using ::ScreenToClient() instead of ::GetWindowRect() 2014-01-16 11:09:25 +02:00
Roman Donchenko b0af6a2b58 Merge pull request #2127 from apavlenko:perf_cascades 2014-01-16 12:37:02 +04:00
Scott Breyfogle 0ea454301f Added optional constraints to non-probablistic hough lines functions 2014-01-15 13:22:56 -08:00
Ilya Lavrenov 82d3efc6c0 added perf test for cv::Canny 2014-01-15 20:06:24 +04:00
Konstantin Matskevich ab18c2d132 changed testdata path for calib3d 2014-01-15 15:08:09 +04:00
Andrey Pavlenko a164381cc6 Merge pull request #2150 from ilya-lavrenov:tapi_cvtcolor 2014-01-15 13:45:28 +04:00
Seunghoon Park 2272a58769 fixing bug #3345. don't use BORDER_ISOLATED alone. it should be combined with some border type 2014-01-14 20:47:23 -05:00
Adi Shavit e45cf2173f [HighGUI] Updated mouse wheel delta to reside within the 'flags' variable. Updated C++ API. 2014-01-14 21:33:32 +02:00
Adi Shavit fecd5c994b Added support for mouse-wheel events on Windows.
To be used in the mouse callback like this:
    if (CV_EVENT_MOUSEWHEEL == CV_GET_MOUSEWHEEL_EVENT(event))
    {
       int delta= CV_GET_WHEEL_DELTA(event);
       // use delta...
    }
2014-01-14 21:20:05 +02:00
Adi Shavit 9dc0bfc755 Small fix for extracting mouse coordinates on Windows, in a way that will always work with multiple monitors.
This is the way recommended by Microsoft.
2014-01-14 21:20:04 +02:00
Andrey Pavlenko c7d90c8b32 adding old cascade 2014-01-14 23:15:50 +04:00
Andrey Pavlenko 9b7b360bf7 fixing compilation if WITH_OPENCL=OFF 2014-01-14 17:50:00 +04:00
Ilya Lavrenov 7ed692bf92 fixed cv::cvtColor 2014-01-14 16:16:35 +04:00
Roman Donchenko 2fde4d8a94 Merge pull request #2145 from andreasBihlmaier:2.4 2014-01-14 11:55:29 +04:00
Roman Donchenko fee2ed37fc Merge remote-tracking branch 'origin/2.4' into merge-2.4
Conflicts:
	modules/contrib/src/retina.cpp
	modules/core/include/opencv2/core/mat.hpp
	modules/core/src/algorithm.cpp
	modules/core/src/arithm.cpp
	modules/features2d/src/features2d_init.cpp
	modules/gpu/include/opencv2/gpu/gpu.hpp
	modules/gpu/perf/perf_imgproc.cpp
	modules/imgproc/src/generalized_hough.cpp
	modules/ocl/include/opencv2/ocl/ocl.hpp
	modules/video/src/tvl1flow.cpp
	modules/video/src/video_init.cpp
2014-01-14 11:53:59 +04:00
Andrey Pavlenko fdb1019b9e Merge pull request #2147 from ilya-lavrenov:tapi_sqrt 2014-01-14 11:34:03 +04:00
Matthias Bady 06fb073b8b Merge branch 'master' of https://github.com/Itseez/opencv into brief_cl 2014-01-13 18:14:56 +01:00
Ilya Lavrenov 09bff78d63 deleted extra arg in case of power=0.5 2014-01-13 19:59:10 +04:00
Roman Donchenko 2443e8090e Merge pull request #2133 from apavlenko:2.4-perf_haar 2014-01-13 19:28:09 +04:00
ahb 49dfa5a17f Fix the following error for ocl::getOpenCLPlatforms() on Ubuntu 12.04 with gcc 4.8
OpenCV Error: Unknown error code -6 (OpenCL function is not available: [clGetPlatformIDs]) in opencl_check_fn, file /home/ahb/software/opencv/modules/ocl/src/cl_runtime/cl_runtime.cpp, line 83

The issue results from modules/ocl/src/cl_runtime/cl_runtime.cpp checking for
"linux" instead of "__linux__" (cp.  http://sourceforge.net/p/predef/wiki/OperatingSystems/)

Adjust all other occurrences of "defined(linux)" as well.
2014-01-13 16:09:42 +01:00
Ilya Lavrenov 30b5234e9a added perf test for cv::sqrBoxFilter 2014-01-13 18:51:49 +04:00
Ilya Lavrenov 8702fceb4b fixed cv::integral perf test 2014-01-13 18:36:52 +04:00
Roman Donchenko c3bfe3f33e Merge pull request #2136 from SpecLad:python-ver 2014-01-13 18:17:00 +04:00
Andrey Pavlenko 4c99196399 adding finish() to flush CL queue, renaming the test to match 'master' branch 2014-01-13 18:12:30 +04:00
Ilya Lavrenov a7a7b80ff8 added perf test for cv::Moments 2014-01-13 17:50:14 +04:00
Andrey Pavlenko 520a692fda switching to CL_PERF_TEST_P, adding safeFinish() to flush CL queue 2014-01-13 16:58:36 +04:00
Roman Donchenko 9628abc786 Merge pull request #2137 from ilya-lavrenov:gitignore 2014-01-13 16:33:16 +04:00
Roman Donchenko 85c713b59e Merge pull request #2138 from alekcac:python_tutorial_fix 2014-01-13 16:32:42 +04:00
Roman Donchenko af9cd79e16 Merge pull request #2121 from ilya-lavrenov:tapi_perf 2014-01-13 16:30:33 +04:00
Roman Donchenko 87e0c26129 Merge pull request #2108 from pemmanuelviel:flannMemoryLeak 2014-01-13 16:26:02 +04:00
Ilya Lavrenov 6fb878a65f added perf tests for cv::medianBlur 2014-01-13 15:59:24 +04:00
Max Khardin d8e5f1611b Rewrite definition/declaration of variables to be more compact 2014-01-13 15:55:49 +04:00
Ilya Lavrenov 5e7fd8bd7e added perf tests for cv::morphologyEx 2014-01-13 15:43:09 +04:00
Ilya Lavrenov 5a2a0b326a added perf tests for cv::dilate 2014-01-13 15:30:35 +04:00
Ilya Lavrenov f61597dce8 added perf tests for filters 2014-01-13 15:26:50 +04:00
Ilya Lavrenov 04ae46e21c added perf tests to some imgproc functions 2014-01-13 15:01:52 +04:00
Ilya Lavrenov e76d51511e added perf test for cv::cvtColor, pyr operations 2014-01-13 14:40:42 +04:00
Ilya Lavrenov 4bd4c8d12a added perf tests for cv::blendLinear 2014-01-13 14:06:15 +04:00
Daniil Osokin 5d2edced26 Added throwing exception when saving untrained SVM model 2014-01-13 13:50:30 +04:00
Ilya Lavrenov 6fbaff6d83 added perf tests for T-API warp operations 2014-01-13 13:10:26 +04:00
Andrey Pavlenko a7821c60e5 refactoring the test as it should be in 2.4 2014-01-13 11:20:17 +04:00
Andrey Pavlenko 6071671bda Merge pull request #2135 from alalek:ocl_runtime_cleanup_2 2014-01-11 17:15:22 +04:00
Andrey Pavlenko d64f05cd59 Merge pull request #2112 from ilya-lavrenov:tapi_stitching 2014-01-11 16:39:22 +04:00
Alexander Shishkov e90d0b6e4c changed code in python tutorial, these functions don’t return image 2014-01-11 16:35:41 +04:00
Ilya Lavrenov f197d8b91c updated .gitignore 2014-01-10 18:59:06 +04:00
Ilya Lavrenov da2790249e added NORM_L2SQR type to cv::norm 2014-01-10 18:45:52 +04:00
Ilya Lavrenov 2e5e278271 added cv::PSNR performance test 2014-01-10 18:45:40 +04:00
Ilya Lavrenov a01e81c8f7 added some performance tests 2014-01-10 18:45:40 +04:00
Ilya Lavrenov 1592234f1a added mask support to cv::norm, cv::meanStdDev 2014-01-10 18:45:40 +04:00
Roman Donchenko 9e3673ef53 Don't use PYTHON_VERSION_STRING when searching for Python libraries
It may be an arbitrary string, and, for example, in Ubuntu 13.10
it's set to "2.7.5+", which breaks the find script.
2014-01-10 18:40:47 +04:00
Ilya Lavrenov 7852b2f155 updated docs according to the last changes 2014-01-10 18:19:26 +04:00
Ilya Lavrenov 8f9ccc099b replaced Mat by Input/Output arrays 2014-01-10 18:16:56 +04:00
Ilya Lavrenov 118709fd9f added OpenCL accelerated warpers 2014-01-10 18:16:56 +04:00
Roman Donchenko 5a9900481a Merge pull request #2105 from ilya-lavrenov:norm 2014-01-10 18:12:08 +04:00
Roman Donchenko 890f1baff0 Merge pull request #2132 from ComFreek:patch-2 2014-01-10 11:44:46 +04:00
Alexander Alekhin f7b0940d44 core/ocl: runtime, remove unused declarations 2014-01-10 11:42:02 +04:00
Andrey Pavlenko 4d28e8243c 'master'-like Haar perf test 2014-01-10 00:14:48 +04:00
Andrey Pavlenko 2c0e24e948 adding Haar & LBP cascades perf test using UMat, removing old incomplete test 2014-01-10 00:08:15 +04:00
ComFreek ae795e5797 Corrected package name in tutorial
See also #2101
2014-01-09 17:24:20 +01:00
Ilya Lavrenov dd302158e0 fixed case with zero mask 2014-01-09 19:26:09 +04:00
Andrey Pavlenko a75cfe13e7 Merge pull request #2128 from alalek:ocl_cleanup_runtime 2014-01-09 17:08:48 +04:00
Roman Donchenko 560cfa5672 Merge pull request #2129 from ilya-lavrenov:mix_fix 2014-01-09 17:04:03 +04:00
Roman Donchenko a13e32f5ab Merge pull request #2115 from nghiaho12:kmeans_sample 2014-01-09 16:58:29 +04:00
Roman Donchenko d509165d96 Merge pull request #2118 from ilya-lavrenov:semicolons 2014-01-09 16:21:49 +04:00
Roman Donchenko dfeba1e8dd Merge pull request #2119 from d-schmidt:patch-1 2014-01-09 14:44:07 +04:00
Ilya Lavrenov 9899cf7519 fixed cv::mixChannels perf test 2014-01-09 14:26:44 +04:00
Nghia Ho bf4994554d Removed unecessary initialisation of Mat centers. 2014-01-09 21:04:17 +11:00
Roman Donchenko b45bb60c8b Merge pull request #2126 from yinghau76:master 2014-01-09 14:00:53 +04:00
Ilya Lavrenov 6ee0b6eb56 added mask support to cv::norm, cv::meanStdDev 2014-01-09 13:49:42 +04:00
Alexander Alekhin 70a0327004 core/ocl: cleanup unused files 2014-01-09 13:47:04 +04:00
Roman Donchenko 7acea48788 Merge pull request #2106 from robbertkl:patch-2 2014-01-09 13:25:59 +04:00
Roman Donchenko 58882e5c22 Merge pull request #2114 from kazuki-ma:SparseMat_convertTo_typofix_24 2014-01-09 13:24:20 +04:00
Roman Donchenko cab67cd9ac Merge tag '3.0-ocl-tech-preview' (-s ours) 2014-01-09 12:42:58 +04:00
Roman Donchenko 6d84671e8b Merge pull request #2116 from ilya-lavrenov:tapi_mixchannels_fix 2014-01-09 12:41:57 +04:00
Roman Donchenko ea3dd9d5e7 Merge pull request #2103 from ilya-lavrenov:typo 2014-01-09 12:38:55 +04:00
Roman Donchenko 4e35ebb52f Merge pull request #2102 from Nerei:compilatin_for_windows 2014-01-09 12:35:30 +04:00
Patrick Tsai b24f7ee57c Fix compiler error with Android NDK r8e
Original error without the fix:

opencv/modules/objdetect/src/cascadedetect.cpp: In member function 'bool cv::CascadeClassifierImpl::ocl_detectSingleScale(const cv::_InputArray&, cv::Size, int, double, cv::Size)':
/opencv/modules/objdetect/src/cascadedetect.cpp:1215:
error: no matching function for call to 'cv::ocl::Kernel::args(cv::ocl::KernelArg, cv::ocl::KernelArg, cv::ocl::KernelArg, int, cv::ocl::KernelArg, cv::ocl::KernelArg, cv::ocl::KernelArg, cv::Size&, int&, float, cv::Rect&, cv::Size&, cv::CascadeClassifierImpl::<anonymous enum>)'
2014-01-09 14:49:20 +08:00
Bo Li d155639db5 grammar fix 2014-01-07 09:57:40 +08:00
Bo Li d444af5bb2 updated decomposeEssentialMat doc 2014-01-07 09:54:12 +08:00
David Schmidt ef61964768 Update py_face_detection.rst
bug in example
2014-01-07 00:11:33 +01:00
Ilya Lavrenov 6b9ebcbf3d deleted extra semicolons 2014-01-07 02:52:30 +04:00
Ilya Lavrenov 0119e8553c fixed cv::mixChannels OpenCL version 2014-01-06 14:41:57 +04:00
Nghia Ho 601b7d1dd3 Fixed a valgrind 'Conditional jump or move depends on uninitialised value(s)' on cv::kmeans(...). The original code used points(sampleCount, 1, CV_32FC2), which confused generateCentersPP into thinking it is a 1 dimensional center, instead of 2. As a result it would set only the x variable and leave y unitialised. 2014-01-06 20:19:07 +11:00
Matthias Bady e17da9a843 merge with upstream 2014-01-05 19:00:25 +01:00
Kazuki Matsuda 2ae20c74a2 Fix typo of SparseMat_<_Tp>::SparseMat_(const SparseMat& m)
Fix compilation erros when compiling this constructor.
First argument type of "convertTo" should be instance, not a pointer of instance.

First pull request was created for master branch.
But it should be marged for 2.4.
https://github.com/Itseez/opencv/pull/2113
2014-01-06 02:24:14 +09:00
Max Khardin 699eda46b6 Remove three sneaky tabs 2014-01-04 20:09:30 +08:00
Ilya Lavrenov 3a4d4080f4 fixed overflow for cv::norm NORM_L2 2014-01-04 15:20:50 +04:00
Max Khardin 34b05794d6 Fix source code indents 2014-01-04 19:01:32 +08:00
Max Khardin 214e9d4b12 Add performance tests for elementwise multiplication 2014-01-04 18:56:32 +08:00
Pierre-Emmanuel Viel 3f458c6eb1 Fix: freeing previous elements has to be done before loading new parameters to avoid trying to delete unexisting objects if arrays size was modified 2014-01-03 13:16:36 +01:00
Nghia Ho d3e24f3cbf Improved documentation for neural network 2014-01-03 14:18:07 +11:00
Robbert Klarenbeek e21c6e19db Fix algorithm setter argument validation for uchar 2014-01-02 21:17:55 +01:00
Ilya Lavrenov 0c49360318 fixed typo 2014-01-01 19:41:14 +04:00
Anatoly Baksheev c2dd7fd762 compilation for windows 2014-01-01 15:39:21 +04:00
Roman Donchenko 5327482b46 Merge pull request #2084 from ilya-lavrenov:cont 2013-12-31 16:51:30 +04:00
Vadim Pisarevsky 1c3bfae212 Merge pull request #1957 from Nerei:format_declaration_by_default 2013-12-31 15:55:00 +04:00
Ilya Lavrenov 4f9c081dc3 fixed bug #3319 2013-12-31 13:56:59 +04:00
Roman Donchenko 157202fc8d Merge pull request #2094 from SpecLad:multimon-be-gone 2013-12-31 11:40:44 +04:00
Seunghoon Park b036fc756a fixing bug #3345 2013-12-30 21:10:06 -05:00
Roman Donchenko 4ce684e61c Merge pull request #2087 from ilya-lavrenov:remap_sse2_cond 2013-12-30 18:18:42 +04:00
Roman Donchenko 795c108f2b Fixed MinGW build by declaring the minimal required Windows version.
Also deleted miscellaneous remaining multimon cruft.
Deleted #include <winuser.h>, because <windows.h> includes it
already.

This should have a nice side effect of preventing us from
accidentally using any Windows API that's too new.
2013-12-30 18:13:42 +04:00
Roman Donchenko 6811d2ab24 Merge pull request #2086 from ilya-lavrenov:mul_fix 2013-12-30 17:57:43 +04:00
Ilya Lavrenov 5db1754d49 SSE2 optimization of cv::remap doesn't work with big images 2013-12-30 17:13:40 +04:00
Ilya Lavrenov 09d25e11c6 fixed bug #3341 2013-12-30 16:47:54 +04:00
Roman Donchenko a0c98dcefa Merge pull request #2092 from alalek:fix_mingw_warn 2013-12-30 15:34:16 +04:00
Alexander Alekhin 44970ddf56 eliminate MINGW pragma warning 2013-12-30 12:31:00 +04:00
Matthias Bady 928924d248 Merge branch 'master' of https://github.com/Itseez/opencv into brief_cl 2013-12-23 19:47:06 +01:00
berak 2bb3de5aa0 core/utility.hpp missing in flann/timer.h 2013-12-20 14:58:21 +01:00
Matthias Bady a032d947b4 Fixed doc 2013-12-20 11:45:07 +01:00
Matthias Bady 9b0a9f2a24 moved documentation of BriefDescriptorExtractor to correct place 2013-12-20 10:57:48 +01:00
Matthias Bady 6e4715309b added documentation 2013-12-20 10:53:21 +01:00
Matthias Bady 74dfa668e2 added tests 2013-12-20 00:05:50 +01:00
Matthias Bady 545f02679a Optimized version. Faster than CPU 2013-12-19 01:54:57 +01:00
Matthias Bady 69d034ecdf Naive impl. Slower than CPU 2013-12-19 00:15:53 +01:00
Anatoly Baksheev 262f70f3ab cv::format declaration in default headers 2013-12-08 19:00:53 +04:00
Mathieu Barnachon fb9c59dd8d Fix default argument. 2013-11-27 18:14:37 +01:00
Mathieu Barnachon b413bcbba4 Fix shadow parameter. 2013-11-27 11:36:34 +01:00
Mathieu Barnachon 99c8b8c016 Fix parameter name to fit documentation. 2013-11-27 11:06:52 +01:00
Mathieu Barnachon 4f74e2509b Fix the documentation names. 2013-11-26 22:50:26 +01:00
Mathieu Barnachon c90fe65f22 Fix compilation issue related to previous commit. 2013-11-24 17:16:45 +01:00
Mathieu Barnachon e8b86c8663 Fix name of one parameter to fit the documentation. 2013-11-24 17:14:23 +01:00
Mathieu Barnachon 089b8e2f4a Suppress a space! 2013-11-24 17:10:06 +01:00
Mathieu Barnachon 9dc713eaba Fix name of parameter to have proper documentation. 2013-11-24 15:45:05 +01:00
Mathieu Barnachon bf84d476fc Fix useless space... 2013-11-24 15:38:48 +01:00
Mathieu Barnachon e015691b41 Fix warnings as errors. 2013-11-24 15:32:52 +01:00
Mathieu Barnachon 0c4da123e9 Remove duplicate functions. 2013-11-24 14:33:41 +01:00
Mathieu Barnachon 67525627db Merge remote-tracking branch 'upstream/master' into bow_desc
Conflicts:
	modules/features2d/src/bagofwords.cpp
2013-11-24 14:21:44 +01:00
Mathieu Barnachon 63c23cce65 Merge remote-tracking branch 'upstream/master' into svm_hog 2013-11-24 13:24:39 +01:00
Mathieu Barnachon e1955759af Fix some warning.
Adding missing credit for a function.
2013-11-24 13:22:10 +01:00
Mathieu Barnachon a4ceb7b6ee Fix compilation issues. 2013-11-11 19:29:39 +01:00
Mathieu Barnachon 0934344a3d Update sample and code with external computation of HOG detector. 2013-09-12 18:38:49 +02:00
Mathieu Barnachon 2fe340bf8a adding sample to train HOG and compare it with default people detector. 2013-09-05 17:33:08 +12:00
Mathieu Barnachon 464985205c Update PR after mdim review. 2013-09-05 16:05:54 +12:00
Mathieu Barnachon 4fbd5707f7 Fix warning on precision lost due to double to float conversion. 2013-08-22 17:34:31 +12:00
Mathieu Barnachon 7f3273c77f Adding an export for HOGDetector compatibility.
An SVM train with HOG could export a single vector for HOGDetector.
2013-08-22 15:00:32 +12:00
Mathieu Barnachon 43c9818895 Adding class for BOW image matcher (Feature #3005).
Same prototype as BOWImgDescriptorExtractor, but do only the matching.
If the feature is accepted, the BOWImgDescriptorExtractor and BOWImgDescriptorMatcher should probably refactor with inheritance.
Add a class to compute the keypoints, descriptors and matching from an image should be added to.
2013-08-18 11:32:04 +12:00
657 changed files with 21606 additions and 98282 deletions
+1
View File
@@ -1,6 +1,7 @@
*.autosave
*.pyc
*.user
*~
.*.swp
.DS_Store
.sw[a-z]
+1 -1
View File
@@ -210,7 +210,7 @@
#include <string>
#endif
#if defined(linux) || defined(__APPLE__) || defined(__MACOSX)
#if defined(__linux__) || defined(__APPLE__) || defined(__MACOSX)
#include <alloca.h>
#include <emmintrin.h>
+7 -7
View File
@@ -332,13 +332,13 @@ typedef unsigned int cl_GLenum;
/* Define basic vector types */
#if defined( __VEC__ )
#include <altivec.h> /* may be omitted depending on compiler. AltiVec spec provides no way to detect whether the header is required. */
typedef vector unsigned char __cl_uchar16;
typedef vector signed char __cl_char16;
typedef vector unsigned short __cl_ushort8;
typedef vector signed short __cl_short8;
typedef vector unsigned int __cl_uint4;
typedef vector signed int __cl_int4;
typedef vector float __cl_float4;
typedef __vector unsigned char __cl_uchar16;
typedef __vector signed char __cl_char16;
typedef __vector unsigned short __cl_ushort8;
typedef __vector signed short __cl_short8;
typedef __vector unsigned int __cl_uint4;
typedef __vector signed int __cl_int4;
typedef __vector float __cl_float4;
#define __CL_UCHAR16__ 1
#define __CL_CHAR16__ 1
#define __CL_USHORT8__ 1
+1 -1
View File
@@ -47,5 +47,5 @@ if(ENABLE_SOLUTION_FOLDERS)
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${JASPER_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main)
ocv_install_target(${JASPER_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
+1 -1
View File
@@ -46,5 +46,5 @@ if(ENABLE_SOLUTION_FOLDERS)
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${JPEG_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main)
ocv_install_target(${JPEG_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
+1 -1
View File
@@ -55,5 +55,5 @@ if(ENABLE_SOLUTION_FOLDERS)
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${PNG_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main)
ocv_install_target(${PNG_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
+1 -1
View File
@@ -115,5 +115,5 @@ if(ENABLE_SOLUTION_FOLDERS)
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${TIFF_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main)
ocv_install_target(${TIFF_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
+1 -1
View File
@@ -64,7 +64,7 @@ if(ENABLE_SOLUTION_FOLDERS)
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(IlmImf EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main)
ocv_install_target(IlmImf EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
set(OPENEXR_INCLUDE_PATHS ${OPENEXR_INCLUDE_PATHS} PARENT_SCOPE)
+3 -3
View File
@@ -232,9 +232,9 @@ if(ENABLE_SOLUTION_FOLDERS)
endif()
ocv_install_target(tbb EXPORT OpenCVModules
RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT main
LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT main
ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main
RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT libs
LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT libs
ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev
)
# get TBB version
+1 -1
View File
@@ -95,5 +95,5 @@ if(ENABLE_SOLUTION_FOLDERS)
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${ZLIB_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main)
ocv_install_target(${ZLIB_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
+27 -2
View File
@@ -116,7 +116,7 @@ endif()
OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON IF (NOT ANDROID AND NOT IOS) )
OCV_OPTION(WITH_AVFOUNDATION "Use AVFoundation for Video I/O" ON IF IOS)
OCV_OPTION(WITH_CARBON "Use Carbon for UI instead of Cocoa" OFF IF APPLE )
OCV_OPTION(WITH_VTK "Include VTK library support (and build opencv_viz module eiher)" OFF IF (NOT ANDROID AND NOT IOS) )
OCV_OPTION(WITH_VTK "Include VTK library support (and build opencv_viz module eiher)" ON IF (NOT ANDROID AND NOT IOS) )
OCV_OPTION(WITH_CUDA "Include NVidia Cuda Runtime support" ON IF (NOT IOS) )
OCV_OPTION(WITH_CUFFT "Include NVidia Cuda Fast Fourier Transform (FFT) library support" ON IF (NOT IOS) )
OCV_OPTION(WITH_CUBLAS "Include NVidia Cuda Basic Linear Algebra Subprograms (BLAS) library support" OFF IF (NOT IOS) )
@@ -191,7 +191,7 @@ OCV_OPTION(INSTALL_C_EXAMPLES "Install C examples" OFF )
OCV_OPTION(INSTALL_PYTHON_EXAMPLES "Install Python examples" OFF )
OCV_OPTION(INSTALL_ANDROID_EXAMPLES "Install Android examples" OFF IF ANDROID )
OCV_OPTION(INSTALL_TO_MANGLED_PATHS "Enables mangled install paths, that help with side by side installs." OFF IF (UNIX AND NOT ANDROID AND NOT IOS AND BUILD_SHARED_LIBS) )
OCV_OPTION(INSTALL_TESTS "Install accuracy and performance test binaries and test data" OFF)
# OpenCV build options
# ===================================================
@@ -260,6 +260,9 @@ endif()
set(OPENCV_SAMPLES_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}samples")
set(OPENCV_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}bin")
if(NOT OPENCV_TEST_INSTALL_PATH)
set(OPENCV_TEST_INSTALL_PATH "${OPENCV_BIN_INSTALL_PATH}")
endif()
if(ANDROID)
set(LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/lib/${ANDROID_NDK_ABI_NAME}")
@@ -268,6 +271,7 @@ if(ANDROID)
set(OPENCV_3P_LIB_INSTALL_PATH sdk/native/3rdparty/libs/${ANDROID_NDK_ABI_NAME})
set(OPENCV_CONFIG_INSTALL_PATH sdk/native/jni)
set(OPENCV_INCLUDE_INSTALL_PATH sdk/native/jni/include)
set(OPENCV_SAMPLES_SRC_INSTALL_PATH samples/native)
else()
set(LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/lib")
set(3P_LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/3rdparty/lib${LIB_SUFFIX}")
@@ -278,9 +282,11 @@ else()
set(OPENCV_LIB_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}lib${LIB_SUFFIX}")
endif()
set(OPENCV_3P_LIB_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}staticlib${LIB_SUFFIX}")
set(OPENCV_SAMPLES_SRC_INSTALL_PATH samples/native)
else()
set(OPENCV_LIB_INSTALL_PATH lib${LIB_SUFFIX})
set(OPENCV_3P_LIB_INSTALL_PATH share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH})
set(OPENCV_SAMPLES_SRC_INSTALL_PATH share/OpenCV/samples)
endif()
set(OPENCV_INCLUDE_INSTALL_PATH "include")
@@ -535,6 +541,19 @@ include(cmake/OpenCVGenConfig.cmake)
# Generate Info.plist for the IOS framework
include(cmake/OpenCVGenInfoPlist.cmake)
# Generate environment setup file
if(INSTALL_TESTS AND OPENCV_TEST_DATA_PATH AND UNIX AND NOT ANDROID)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/opencv_testing.sh.in"
"${CMAKE_BINARY_DIR}/unix-install/opencv_testing.sh" @ONLY)
install(FILES "${CMAKE_BINARY_DIR}/unix-install/opencv_testing.sh"
DESTINATION /etc/profile.d/ COMPONENT tests)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/opencv_run_all_tests.sh.in"
"${CMAKE_BINARY_DIR}/unix-install/opencv_run_all_tests.sh" @ONLY)
install(FILES "${CMAKE_BINARY_DIR}/unix-install/opencv_run_all_tests.sh"
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE
DESTINATION ${OPENCV_TEST_INSTALL_PATH} COMPONENT tests)
endif()
# ----------------------------------------------------------------------------
# Summary:
# ----------------------------------------------------------------------------
@@ -971,3 +990,9 @@ ocv_finalize_status()
if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
message(WARNING "The source directory is the same as binary directory. \"make clean\" may damage the source tree")
endif()
# ----------------------------------------------------------------------------
# CPack stuff
# ----------------------------------------------------------------------------
include(cmake/OpenCVPackaging.cmake)
+6 -6
View File
@@ -71,14 +71,14 @@ set_target_properties(opencv_performance PROPERTIES
if(INSTALL_CREATE_DISTRIB)
if(BUILD_SHARED_LIBS)
install(TARGETS opencv_haartraining RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT main)
install(TARGETS opencv_createsamples RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT main)
install(TARGETS opencv_performance RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT main)
install(TARGETS opencv_haartraining RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
install(TARGETS opencv_createsamples RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
install(TARGETS opencv_performance RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
endif()
else()
install(TARGETS opencv_haartraining RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT main)
install(TARGETS opencv_createsamples RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT main)
install(TARGETS opencv_performance RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT main)
install(TARGETS opencv_haartraining RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
install(TARGETS opencv_createsamples RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
install(TARGETS opencv_performance RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
endif()
if(ENABLE_SOLUTION_FOLDERS)
+1 -1
View File
@@ -340,7 +340,7 @@ typedef enum CvBoostType
CV_LKCLASS = 5, /* classification (K class problem) */
CV_LSREG = 6, /* least squares regression */
CV_LADREG = 7, /* least absolute deviation regression */
CV_MREG = 8, /* M-regression (Huber loss) */
CV_MREG = 8 /* M-regression (Huber loss) */
} CvBoostType;
/****************************************************************************************\
+2 -2
View File
@@ -35,8 +35,8 @@ endif()
if(INSTALL_CREATE_DISTRIB)
if(BUILD_SHARED_LIBS)
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT main)
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
endif()
else()
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT main)
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
endif()
+5 -5
View File
@@ -344,20 +344,20 @@ macro(add_android_project target path)
add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${android_proj_bin_dir}/bin/${target}-debug.apk" "${OpenCV_BINARY_DIR}/bin/${target}.apk")
if(INSTALL_ANDROID_EXAMPLES AND "${target}" MATCHES "^example-")
#apk
install(FILES "${OpenCV_BINARY_DIR}/bin/${target}.apk" DESTINATION "samples" COMPONENT main)
install(FILES "${OpenCV_BINARY_DIR}/bin/${target}.apk" DESTINATION "samples" COMPONENT samples)
get_filename_component(sample_dir "${path}" NAME)
#java part
list(REMOVE_ITEM android_proj_files ${ANDROID_MANIFEST_FILE})
foreach(f ${android_proj_files} ${ANDROID_MANIFEST_FILE})
get_filename_component(install_subdir "${f}" PATH)
install(FILES "${android_proj_bin_dir}/${f}" DESTINATION "samples/${sample_dir}/${install_subdir}" COMPONENT main)
install(FILES "${android_proj_bin_dir}/${f}" DESTINATION "samples/${sample_dir}/${install_subdir}" COMPONENT samples)
endforeach()
#jni part + eclipse files
file(GLOB_RECURSE jni_files RELATIVE "${path}" "${path}/jni/*" "${path}/.cproject")
ocv_list_filterout(jni_files "\\\\.svn")
foreach(f ${jni_files} ".classpath" ".project" ".settings/org.eclipse.jdt.core.prefs")
get_filename_component(install_subdir "${f}" PATH)
install(FILES "${path}/${f}" DESTINATION "samples/${sample_dir}/${install_subdir}" COMPONENT main)
install(FILES "${path}/${f}" DESTINATION "samples/${sample_dir}/${install_subdir}" COMPONENT samples)
endforeach()
#update proj
if(android_proj_lib_deps_commands)
@@ -365,9 +365,9 @@ macro(add_android_project target path)
endif()
install(CODE "EXECUTE_PROCESS(COMMAND ${ANDROID_EXECUTABLE} --silent update project --path . --target \"${android_proj_sdk_target}\" --name \"${target}\" ${inst_lib_opt}
WORKING_DIRECTORY \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/samples/${sample_dir}\"
)" COMPONENT main)
)" COMPONENT dev)
#empty 'gen'
install(CODE "MAKE_DIRECTORY(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/samples/${sample_dir}/gen\")" COMPONENT main)
install(CODE "MAKE_DIRECTORY(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/samples/${sample_dir}/gen\")" COMPONENT samples)
endif()
endif()
endmacro()
+29 -13
View File
@@ -24,7 +24,8 @@ if(PYTHONINTERP_FOUND)
if(NOT ANDROID AND NOT IOS)
ocv_check_environment_variables(PYTHON_LIBRARY PYTHON_INCLUDE_DIR)
find_host_package(PythonLibs "${PYTHON_VERSION_STRING}" EXACT)
# not using PYTHON_VERSION_STRING here, because it might not conform to the CMake version format
find_host_package(PythonLibs "${PYTHON_VERSION_MAJOR_MINOR}.${PYTHON_VERSION_PATCH}" EXACT)
endif()
if(NOT ANDROID AND NOT IOS)
@@ -59,23 +60,38 @@ if(PYTHONINTERP_FOUND)
SET(PYTHON_PACKAGES_PATH "${_PYTHON_PACKAGES_PATH}" CACHE PATH "Where to install the python packages.")
if(NOT PYTHON_NUMPY_INCLUDE_DIRS)
# Attempt to discover the NumPy include directory. If this succeeds, then build python API with NumPy
execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c
"import os; os.environ['DISTUTILS_USE_SDK']='1'; import numpy.distutils; print(os.pathsep.join(numpy.distutils.misc_util.get_numpy_include_dirs()))"
RESULT_VARIABLE PYTHON_NUMPY_PROCESS
OUTPUT_VARIABLE PYTHON_NUMPY_INCLUDE_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(CMAKE_CROSSCOMPILING)
message(STATUS "Cannot probe for Python/Numpy support (because we are cross-compiling OpenCV)")
message(STATUS "If you want to enable Python/Numpy support, set the following variables:")
message(STATUS " PYTHON_INCLUDE_PATH")
message(STATUS " PYTHON_LIBRARIES")
message(STATUS " PYTHON_NUMPY_INCLUDE_DIRS")
else()
# Attempt to discover the NumPy include directory. If this succeeds, then build python API with NumPy
execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import os; os.environ['DISTUTILS_USE_SDK']='1'; import numpy.distutils; print(os.pathsep.join(numpy.distutils.misc_util.get_numpy_include_dirs()))"
RESULT_VARIABLE PYTHON_NUMPY_PROCESS
OUTPUT_VARIABLE PYTHON_NUMPY_INCLUDE_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(PYTHON_NUMPY_PROCESS EQUAL 0)
file(TO_CMAKE_PATH "${PYTHON_NUMPY_INCLUDE_DIRS}" _PYTHON_NUMPY_INCLUDE_DIRS)
set(PYTHON_NUMPY_INCLUDE_DIRS "${_PYTHON_NUMPY_INCLUDE_DIRS}" CACHE PATH "Path to numpy headers")
if(NOT PYTHON_NUMPY_PROCESS EQUAL 0)
unset(PYTHON_NUMPY_INCLUDE_DIRS)
endif()
endif()
endif()
if(PYTHON_NUMPY_INCLUDE_DIRS)
execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import numpy; print(numpy.version.version)"
OUTPUT_VARIABLE PYTHON_NUMPY_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
file(TO_CMAKE_PATH "${PYTHON_NUMPY_INCLUDE_DIRS}" _PYTHON_NUMPY_INCLUDE_DIRS)
set(PYTHON_NUMPY_INCLUDE_DIRS ${_PYTHON_NUMPY_INCLUDE_DIRS} CACHE PATH "Path to numpy headers")
if(CMAKE_CROSSCOMPILING)
if(NOT PYTHON_NUMPY_VERSION)
set(PYTHON_NUMPY_VERSION "undefined - cannot be probed because of the cross-compilation")
endif()
else()
execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import numpy; print(numpy.version.version)"
RESULT_VARIABLE PYTHON_NUMPY_PROCESS
OUTPUT_VARIABLE PYTHON_NUMPY_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
endif()
endif(NOT ANDROID AND NOT IOS)
endif()
+2 -2
View File
@@ -2,7 +2,7 @@ if(NOT WITH_VTK OR ANDROID OR IOS)
return()
endif()
find_package(VTK 6.0 QUIET COMPONENTS vtkRenderingCore vtkInteractionWidgets vtkInteractionStyle vtkIOLegacy vtkIOPLY vtkRenderingFreeType vtkRenderingLOD vtkFiltersTexture NO_MODULE)
find_package(VTK 6.0 QUIET COMPONENTS vtkRenderingCore vtkInteractionWidgets vtkInteractionStyle vtkIOLegacy vtkIOPLY vtkRenderingFreeType vtkRenderingLOD vtkFiltersTexture vtkIOExport NO_MODULE)
if(NOT DEFINED VTK_FOUND OR NOT VTK_FOUND)
find_package(VTK 5.10 QUIET COMPONENTS vtkCommon vtkFiltering vtkRendering vtkWidgets vtkImaging NO_MODULE)
@@ -18,4 +18,4 @@ if(VTK_FOUND)
else()
set(HAVE_VTK OFF)
message(STATUS "VTK is not found. Please set -DVTK_DIR in CMake to VTK build directory, or set $VTK_DIR enviroment variable to VTK install subdirectory with VTKConfig.cmake file (for windows)")
endif()
endif()
+1 -1
View File
@@ -4,7 +4,7 @@
CONFIGURE_FILE(
"${OpenCV_SOURCE_DIR}/cmake/templates/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
@ONLY)
ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
if(ENABLE_SOLUTION_FOLDERS)
+3 -3
View File
@@ -91,7 +91,7 @@ if(ANDROID)
set(OPENCV_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/lib/\$(OPENCV_TARGET_ARCH_ABI)")
set(OPENCV_3RDPARTY_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/3rdparty/lib/\$(OPENCV_TARGET_ARCH_ABI)")
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV.mk.in" "${CMAKE_BINARY_DIR}/OpenCV.mk" IMMEDIATE @ONLY)
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV.mk.in" "${CMAKE_BINARY_DIR}/OpenCV.mk" @ONLY)
# -------------------------------------------------------------------------------------------
# Part 2/2: ${BIN_DIR}/unix-install/OpenCV.mk -> For use with "make install"
@@ -101,6 +101,6 @@ if(ANDROID)
set(OPENCV_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/../libs/\$(OPENCV_TARGET_ARCH_ABI)")
set(OPENCV_3RDPARTY_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/../3rdparty/libs/\$(OPENCV_TARGET_ARCH_ABI)")
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV.mk.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCV.mk" IMMEDIATE @ONLY)
install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCV.mk DESTINATION ${OPENCV_CONFIG_INSTALL_PATH})
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV.mk.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCV.mk" @ONLY)
install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCV.mk DESTINATION ${OPENCV_CONFIG_INSTALL_PATH} COMPONENT dev)
endif(ANDROID)
+19 -19
View File
@@ -83,9 +83,9 @@ endif()
export(TARGETS ${OpenCVModules_TARGETS} FILE "${CMAKE_BINARY_DIR}/OpenCVModules${modules_file_suffix}.cmake")
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig.cmake" IMMEDIATE @ONLY)
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig.cmake" @ONLY)
#support for version checking when finding opencv. find_package(OpenCV 2.3.1 EXACT) should now work.
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig-version.cmake" IMMEDIATE @ONLY)
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig-version.cmake" @ONLY)
# --------------------------------------------------------------------------------------------
# Part 2/3: ${BIN_DIR}/unix-install/OpenCVConfig.cmake -> For use *with* "make install"
@@ -98,8 +98,8 @@ if(INSTALL_TO_MANGLED_PATHS)
set(OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE}\"")
endif()
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig.cmake" IMMEDIATE @ONLY)
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig-version.cmake" IMMEDIATE @ONLY)
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig.cmake" @ONLY)
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig-version.cmake" @ONLY)
if(UNIX) # ANDROID configuration is created here also
#http://www.vtk.org/Wiki/CMake/Tutorials/Packaging reference
@@ -109,18 +109,18 @@ if(UNIX) # ANDROID configuration is created here also
# <prefix>/(share|lib)/<name>*/ (U)
# <prefix>/(share|lib)/<name>*/(cmake|CMake)/ (U)
if(INSTALL_TO_MANGLED_PATHS)
install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig.cmake DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}-${OPENCV_VERSION}/)
install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig-version.cmake DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}-${OPENCV_VERSION}/)
install(EXPORT OpenCVModules DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}-${OPENCV_VERSION}/ FILE OpenCVModules${modules_file_suffix}.cmake)
install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig.cmake DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}-${OPENCV_VERSION}/ COMPONENT dev)
install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig-version.cmake DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}-${OPENCV_VERSION}/ COMPONENT dev)
install(EXPORT OpenCVModules DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}-${OPENCV_VERSION}/ FILE OpenCVModules${modules_file_suffix}.cmake COMPONENT dev)
else()
install(FILES "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig.cmake" DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/)
install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig-version.cmake DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/)
install(EXPORT OpenCVModules DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/ FILE OpenCVModules${modules_file_suffix}.cmake)
install(FILES "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig.cmake" DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/ COMPONENT dev)
install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig-version.cmake DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/ COMPONENT dev)
install(EXPORT OpenCVModules DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/ FILE OpenCVModules${modules_file_suffix}.cmake COMPONENT dev)
endif()
endif()
if(ANDROID)
install(FILES "${OpenCV_SOURCE_DIR}/platforms/android/android.toolchain.cmake" DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/)
install(FILES "${OpenCV_SOURCE_DIR}/platforms/android/android.toolchain.cmake" DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/ COMPONENT dev)
endif()
# --------------------------------------------------------------------------------------------
@@ -131,15 +131,15 @@ if(WIN32)
set(OpenCV2_INCLUDE_DIRS_CONFIGCMAKE "\"\"")
exec_program(mkdir ARGS "-p \"${CMAKE_BINARY_DIR}/win-install/\"" OUTPUT_VARIABLE RET_VAL)
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" IMMEDIATE @ONLY)
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig-version.cmake" IMMEDIATE @ONLY)
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" @ONLY)
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig-version.cmake" @ONLY)
if(BUILD_SHARED_LIBS)
install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}lib")
install(EXPORT OpenCVModules DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}lib" FILE OpenCVModules${modules_file_suffix}.cmake)
install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}lib" COMPONENT dev)
install(EXPORT OpenCVModules DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}lib" FILE OpenCVModules${modules_file_suffix}.cmake COMPONENT dev)
else()
install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}staticlib")
install(EXPORT OpenCVModules DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}staticlib" FILE OpenCVModules${modules_file_suffix}.cmake)
install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}staticlib" COMPONENT dev)
install(EXPORT OpenCVModules DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}staticlib" FILE OpenCVModules${modules_file_suffix}.cmake COMPONENT dev)
endif()
install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig-version.cmake" DESTINATION "${CMAKE_INSTALL_PREFIX}")
install(FILES "${OpenCV_SOURCE_DIR}/cmake/OpenCVConfig.cmake" DESTINATION "${CMAKE_INSTALL_PREFIX}/")
install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig-version.cmake" DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT dev)
install(FILES "${OpenCV_SOURCE_DIR}/cmake/OpenCVConfig.cmake" DESTINATION "${CMAKE_INSTALL_PREFIX}/" COMPONENT dev)
endif()
+1 -1
View File
@@ -23,4 +23,4 @@ set(OPENCV_MODULE_DEFINITIONS_CONFIGMAKE "${OPENCV_MODULE_DEFINITIONS_CONFIGMAKE
#endforeach()
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/opencv_modules.hpp.in" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp")
install(FILES "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp" DESTINATION ${OPENCV_INCLUDE_INSTALL_PATH}/opencv2 COMPONENT main)
install(FILES "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp" DESTINATION ${OPENCV_INCLUDE_INSTALL_PATH}/opencv2 COMPONENT dev)
+2 -2
View File
@@ -78,8 +78,8 @@ else()
endif()
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/opencv-XXX.pc.in"
"${CMAKE_BINARY_DIR}/unix-install/${OPENCV_PC_FILE_NAME}"
@ONLY IMMEDIATE)
@ONLY)
if(UNIX AND NOT ANDROID)
install(FILES ${CMAKE_BINARY_DIR}/unix-install/${OPENCV_PC_FILE_NAME} DESTINATION ${OPENCV_LIB_INSTALL_PATH}/pkgconfig)
install(FILES ${CMAKE_BINARY_DIR}/unix-install/${OPENCV_PC_FILE_NAME} DESTINATION ${OPENCV_LIB_INSTALL_PATH}/pkgconfig COMPONENT dev)
endif()
+14 -7
View File
@@ -583,9 +583,9 @@ macro(ocv_create_module)
endif()
ocv_install_target(${the_module} EXPORT OpenCVModules
RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT main
LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT main
ARCHIVE DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT main
RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT libs
LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT libs
ARCHIVE DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT dev
)
# only "public" headers need to be installed
@@ -593,7 +593,7 @@ macro(ocv_create_module)
foreach(hdr ${OPENCV_MODULE_${the_module}_HEADERS})
string(REGEX REPLACE "^.*opencv2/" "opencv2/" hdr2 "${hdr}")
if(NOT hdr2 MATCHES "opencv2/${the_module}/private.*" AND hdr2 MATCHES "^(opencv2/?.*)/[^/]+.h(..)?$" )
install(FILES ${hdr} DESTINATION "${OPENCV_INCLUDE_INSTALL_PATH}/${CMAKE_MATCH_1}" COMPONENT main)
install(FILES ${hdr} DESTINATION "${OPENCV_INCLUDE_INSTALL_PATH}/${CMAKE_MATCH_1}" COMPONENT dev)
endif()
endforeach()
endif()
@@ -717,6 +717,9 @@ function(ocv_add_perf_tests)
else(OCV_DEPENDENCIES_FOUND)
# TODO: warn about unsatisfied dependencies
endif(OCV_DEPENDENCIES_FOUND)
if(INSTALL_TESTS)
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_TEST_INSTALL_PATH} COMPONENT tests)
endif()
endif()
endfunction()
@@ -770,6 +773,10 @@ function(ocv_add_accuracy_tests)
else(OCV_DEPENDENCIES_FOUND)
# TODO: warn about unsatisfied dependencies
endif(OCV_DEPENDENCIES_FOUND)
if(INSTALL_TESTS)
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_TEST_INSTALL_PATH} COMPONENT tests)
endif()
endif()
endfunction()
@@ -801,7 +808,7 @@ function(ocv_add_samples)
endif()
if(WIN32)
install(TARGETS ${the_target} RUNTIME DESTINATION "samples/${module_id}" COMPONENT main)
install(TARGETS ${the_target} RUNTIME DESTINATION "samples/${module_id}" COMPONENT samples)
endif()
endforeach()
endif()
@@ -810,8 +817,8 @@ function(ocv_add_samples)
if(INSTALL_C_EXAMPLES AND NOT WIN32 AND EXISTS "${samples_path}")
file(GLOB sample_files "${samples_path}/*")
install(FILES ${sample_files}
DESTINATION share/OpenCV/samples/${module_id}
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ)
DESTINATION ${OPENCV_SAMPLES_SRC_INSTALL_PATH}/${module_id}
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT samples)
endif()
endfunction()
+110
View File
@@ -0,0 +1,110 @@
if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
set(CPACK_set_DESTDIR "on")
if(NOT OPENCV_CUSTOM_PACKAGE_INFO)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Open Computer Vision Library")
set(CPACK_PACKAGE_DESCRIPTION
"OpenCV (Open Source Computer Vision Library) is an open source computer vision
and machine learning software library. OpenCV was built to provide a common
infrastructure for computer vision applications and to accelerate the use of
machine perception in the commercial products. Being a BSD-licensed product,
OpenCV makes it easy for businesses to utilize and modify the code.")
set(CPACK_PACKAGE_VENDOR "OpenCV Foundation")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_CONTACT "admin@opencv.org")
set(CPACK_PACKAGE_VERSION_MAJOR "${OPENCV_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${OPENCV_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${OPENCV_VERSION_PATCH}")
set(CPACK_PACKAGE_VERSION "${OPENCV_VCSVERSION}")
endif(NOT OPENCV_CUSTOM_PACKAGE_INFO)
#arch
if(X86)
set(CPACK_DEBIAN_ARCHITECTURE "i386")
set(CPACK_RPM_PACKAGE_ARCHITECTURE "i686")
elseif(X86_64)
set(CPACK_DEBIAN_ARCHITECTURE "amd64")
set(CPACK_RPM_PACKAGE_ARCHITECTURE "x86_64")
elseif(ARM)
set(CPACK_DEBIAN_ARCHITECTURE "armhf")
set(CPACK_RPM_PACKAGE_ARCHITECTURE "armhf")
else()
set(CPACK_DEBIAN_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
set(CPACK_RPM_PACKAGE_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
endif()
if(CPACK_GENERATOR STREQUAL "DEB")
set(OPENCV_PACKAGE_ARCH_SUFFIX ${CPACK_DEBIAN_ARCHITECTURE})
elseif(CPACK_GENERATOR STREQUAL "RPM")
set(OPENCV_PACKAGE_ARCH_SUFFIX ${CPACK_RPM_PACKAGE_ARCHITECTURE})
else()
set(OPENCV_PACKAGE_ARCH_SUFFIX ${CMAKE_SYSTEM_PROCESSOR})
endif()
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${OPENCV_VCSVERSION}-${OPENCV_PACKAGE_ARCH_SUFFIX}")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${OPENCV_VCSVERSION}-${OPENCV_PACKAGE_ARCH_SUFFIX}")
#rpm options
set(CPACK_RPM_COMPONENT_INSTALL TRUE)
set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_PACKAGE_DESCRIPTION_SUMMARY})
set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION})
set(CPACK_RPM_PACKAGE_URL "http://opencv.org")
set(CPACK_RPM_PACKAGE_LICENSE "BSD")
#deb options
set(CPACK_DEB_COMPONENT_INSTALL TRUE)
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
set(CPACK_DEBIAN_PACKAGE_SECTION "libs")
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://opencv.org")
#depencencies
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS TRUE)
set(CPACK_COMPONENT_samples_DEPENDS libs)
set(CPACK_COMPONENT_dev_DEPENDS libs)
set(CPACK_COMPONENT_docs_DEPENDS libs)
set(CPACK_COMPONENT_java_DEPENDS libs)
set(CPACK_COMPONENT_python_DEPENDS libs)
set(CPACK_COMPONENT_tests_DEPENDS libs)
if(HAVE_CUDA)
string(REPLACE "." "-" cuda_version_suffix ${CUDA_VERSION})
set(CPACK_DEB_libs_PACKAGE_DEPENDS "cuda-core-libs-${cuda_version_suffix}, cuda-extra-libs-${cuda_version_suffix}")
set(CPACK_COMPONENT_dev_DEPENDS libs)
set(CPACK_DEB_dev_PACKAGE_DEPENDS "cuda-headers-${cuda_version_suffix}")
endif()
if(NOT OPENCV_CUSTOM_PACKAGE_INFO)
set(CPACK_COMPONENT_libs_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}")
set(CPACK_COMPONENT_libs_DESCRIPTION "Open Computer Vision Library")
set(CPACK_COMPONENT_python_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}-python")
set(CPACK_COMPONENT_python_DESCRIPTION "Python bindings for Open Source Computer Vision Library")
set(CPACK_COMPONENT_java_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}-java")
set(CPACK_COMPONENT_java_DESCRIPTION "Java bindings for Open Source Computer Vision Library")
set(CPACK_COMPONENT_dev_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}-dev")
set(CPACK_COMPONENT_dev_DESCRIPTION "Development files for Open Source Computer Vision Library")
set(CPACK_COMPONENT_docs_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}-docs")
set(CPACK_COMPONENT_docs_DESCRIPTION "Documentation for Open Source Computer Vision Library")
set(CPACK_COMPONENT_samples_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}-samples")
set(CPACK_COMPONENT_samples_DESCRIPTION "Samples for Open Source Computer Vision Library")
set(CPACK_COMPONENT_tests_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}-tests")
set(CPACK_COMPONENT_tests_DESCRIPTION "Accuracy and performance tests for Open Source Computer Vision Library")
endif(NOT OPENCV_CUSTOM_PACKAGE_INFO)
if(NOT OPENCV_CUSTOM_PACKAGE_LAYOUT)
set(CPACK_libs_COMPONENT_INSTALL TRUE)
set(CPACK_dev_COMPONENT_INSTALL TRUE)
set(CPACK_docs_COMPONENT_INSTALL TRUE)
set(CPACK_python_COMPONENT_INSTALL TRUE)
set(CPACK_java_COMPONENT_INSTALL TRUE)
set(CPACK_samples_COMPONENT_INSTALL TRUE)
endif(NOT OPENCV_CUSTOM_PACKAGE_LAYOUT)
include(CPack)
ENDif(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
+3 -2
View File
@@ -29,6 +29,7 @@ ${nested_namespace_start}
set(STR_HPP "// This file is auto-generated. Do not edit!
#include \"opencv2/core/ocl_genbase.hpp\"
#include \"opencv2/core/opencl/ocl_defs.hpp\"
namespace cv
{
@@ -64,8 +65,8 @@ foreach(cl ${cl_list})
set(STR_CPP_DECL "const struct ProgramEntry ${cl_filename}={\"${cl_filename}\",\n\"${lines}, \"${hash}\"};\n")
set(STR_HPP_DECL "extern const struct ProgramEntry ${cl_filename};\n")
if(new_mode)
set(STR_CPP_DECL "${STR_CPP_DECL}ProgramSource2 ${cl_filename}_oclsrc(${cl_filename}.programStr);\n")
set(STR_HPP_DECL "${STR_HPP_DECL}extern ProgramSource2 ${cl_filename}_oclsrc;\n")
set(STR_CPP_DECL "${STR_CPP_DECL}ProgramSource ${cl_filename}_oclsrc(${cl_filename}.programStr);\n")
set(STR_HPP_DECL "${STR_HPP_DECL}extern ProgramSource ${cl_filename}_oclsrc;\n")
endif()
set(STR_CPP "${STR_CPP}${STR_CPP_DECL}")
@@ -0,0 +1,25 @@
#!/bin/sh
OPENCV_TEST_PATH=@OPENCV_TEST_INSTALL_PATH@
export OPENCV_TEST_DATA_PATH=@CMAKE_INSTALL_PREFIX@/share/OpenCV/testdata
SUMMARY_STATUS=0
for t in "$OPENCV_TEST_PATH/"opencv_test_* "$OPENCV_TEST_PATH/"opencv_perf_*;
do
report="`basename "$t"`-`date --rfc-3339=date`.xml"
"$t" --perf_min_samples=1 --perf_force_samples=1 --gtest_output=xml:"$report"
TEST_STATUS=$?
if [ $TEST_STATUS -ne 0 ]; then
SUMMARY_STATUS=$TEST_STATUS
fi
done
rm -f /tmp/__opencv_temp.*
if [ $SUMMARY_STATUS -eq 0 ]; then
echo "All OpenCV tests finished successfully"
else
echo "OpenCV tests finished with status $SUMMARY_STATUS"
fi
return $SUMMARY_STATUS
+2
View File
@@ -0,0 +1,2 @@
# Environment setup for OpenCV testing
export OPENCV_TEST_DATA_PATH=@CMAKE_INSTALL_PREFIX@/share/OpenCV/testdata
+12 -4
View File
@@ -2,9 +2,17 @@ file(GLOB HAAR_CASCADES haarcascades/*.xml)
file(GLOB LBP_CASCADES lbpcascades/*.xml)
if(ANDROID)
install(FILES ${HAAR_CASCADES} DESTINATION sdk/etc/haarcascades COMPONENT main)
install(FILES ${LBP_CASCADES} DESTINATION sdk/etc/lbpcascades COMPONENT main)
install(FILES ${HAAR_CASCADES} DESTINATION sdk/etc/haarcascades COMPONENT libs)
install(FILES ${LBP_CASCADES} DESTINATION sdk/etc/lbpcascades COMPONENT libs)
elseif(NOT WIN32)
install(FILES ${HAAR_CASCADES} DESTINATION share/OpenCV/haarcascades COMPONENT main)
install(FILES ${LBP_CASCADES} DESTINATION share/OpenCV/lbpcascades COMPONENT main)
install(FILES ${HAAR_CASCADES} DESTINATION share/OpenCV/haarcascades COMPONENT libs)
install(FILES ${LBP_CASCADES} DESTINATION share/OpenCV/lbpcascades COMPONENT libs)
endif()
if(INSTALL_TESTS AND OPENCV_TEST_DATA_PATH)
if(ANDROID)
install(DIRECTORY ${OPENCV_TEST_DATA_PATH} DESTINATION sdk/etc/testdata COMPONENT tests)
elseif(NOT WIN32)
install(DIRECTORY ${OPENCV_TEST_DATA_PATH} DESTINATION share/OpenCV/testdata COMPONENT tests)
endif()
endif()
+3 -3
View File
@@ -33,7 +33,7 @@ if(BUILD_DOCS AND HAVE_SPHINX)
endif()
endforeach()
set(FIXED_ORDER_MODULES core imgproc highgui video calib3d features2d objdetect ml flann photo stitching nonfree contrib legacy bioinspired)
set(FIXED_ORDER_MODULES core imgproc highgui video calib3d features2d objdetect ml flann photo stitching nonfree contrib legacy)
list(REMOVE_ITEM BASE_MODULES ${FIXED_ORDER_MODULES})
@@ -148,11 +148,11 @@ if(BUILD_DOCS AND HAVE_SPHINX)
endif()
foreach(f ${DOC_LIST})
install(FILES "${f}" DESTINATION "${OPENCV_DOC_INSTALL_PATH}" COMPONENT main)
install(FILES "${f}" DESTINATION "${OPENCV_DOC_INSTALL_PATH}" COMPONENT docs)
endforeach()
foreach(f ${OPTIONAL_DOC_LIST})
install(FILES "${f}" DESTINATION "${OPENCV_DOC_INSTALL_PATH}" OPTIONAL)
install(FILES "${f}" DESTINATION "${OPENCV_DOC_INSTALL_PATH}" OPTIONAL COMPONENT docs)
endforeach()
endif()
-37
View File
@@ -1,37 +0,0 @@
IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* 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.
@@ -33,21 +33,21 @@ To draw a line, you need to pass starting and ending coordinates of line. We wil
img = np.zeros((512,512,3), np.uint8)
# Draw a diagonal blue line with thickness of 5 px
img = cv2.line(img,(0,0),(511,511),(255,0,0),5)
cv2.line(img,(0,0),(511,511),(255,0,0),5)
Drawing Rectangle
-------------------
To draw a rectangle, you need top-left corner and bottom-right corner of rectangle. This time we will draw a green rectangle at the top-right corner of image.
::
img = cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)
cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)
Drawing Circle
----------------
To draw a circle, you need its center coordinates and radius. We will draw a circle inside the rectangle drawn above.
::
img = cv2.circle(img,(447,63), 63, (0,0,255), -1)
cv2.circle(img,(447,63), 63, (0,0,255), -1)
Drawing Ellipse
--------------------
@@ -55,7 +55,7 @@ Drawing Ellipse
To draw the ellipse, we need to pass several arguments. One argument is the center location (x,y). Next argument is axes lengths (major axis length, minor axis length). ``angle`` is the angle of rotation of ellipse in anti-clockwise direction. ``startAngle`` and ``endAngle`` denotes the starting and ending of ellipse arc measured in clockwise direction from major axis. i.e. giving values 0 and 360 gives the full ellipse. For more details, check the documentation of **cv2.ellipse()**. Below example draws a half ellipse at the center of the image.
::
img = cv2.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
cv2.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
Drawing Polygon
@@ -65,7 +65,7 @@ To draw a polygon, first you need coordinates of vertices. Make those points int
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
img = cv2.polylines(img,[pts],True,(0,255,255))
cv2.polylines(img,[pts],True,(0,255,255))
.. Note:: If third argument is ``False``, you will get a polylines joining all the points, not a closed shape.
@@ -103,4 +103,4 @@ Additional Resources
Exercises
==============
#. Try to create the logo of OpenCV using drawing functions available in OpenCV
#. Try to create the logo of OpenCV using drawing functions available in OpenCV.
@@ -73,7 +73,7 @@ Now we find the faces in the image. If faces are found, it returns the positions
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(roi_gray)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

@@ -1,418 +0,0 @@
.. _Retina_Model:
Discovering the human retina and its use for image processing
*************************************************************
Goal
=====
I present here a model of human retina that shows some interesting properties for image preprocessing and enhancement.
In this tutorial you will learn how to:
.. container:: enumeratevisibleitemswithsquare
+ discover the main two channels outing from your retina
+ see the basics to use the retina model
+ discover some parameters tweaks
General overview
================
The proposed model originates from Jeanny Herault's research [herault2010]_ at `Gipsa <http://www.gipsa-lab.inpg.fr>`_. It is involved in image processing applications with `Listic <http://www.listic.univ-savoie.fr>`_ (code maintainer and user) lab. This is not a complete model but it already present interesting properties that can be involved for enhanced image processing experience. The model allows the following human retina properties to be used :
* spectral whitening that has 3 important effects: high spatio-temporal frequency signals canceling (noise), mid-frequencies details enhancement and low frequencies luminance energy reduction. This *all in one* property directly allows visual signals cleaning of classical undesired distortions introduced by image sensors and input luminance range.
* local logarithmic luminance compression allows details to be enhanced even in low light conditions.
* decorrelation of the details information (Parvocellular output channel) and transient information (events, motion made available at the Magnocellular output channel).
The first two points are illustrated below :
In the figure below, the OpenEXR image sample *CrissyField.exr*, a High Dynamic Range image is shown. In order to make it visible on this web-page, the original input image is linearly rescaled to the classical image luminance range [0-255] and is converted to 8bit/channel format. Such strong conversion hides many details because of too strong local contrasts. Furthermore, noise energy is also strong and pollutes visual information.
.. image:: images/retina_TreeHdr_small.jpg
:alt: A High dynamic range image linearly rescaled within range [0-255].
:align: center
In the following image, applying the ideas proposed in [benoit2010]_, as your retina does, local luminance adaptation, spatial noise removal and spectral whitening work together and transmit accurate information on lower range 8bit data channels. On this picture, noise in significantly removed, local details hidden by strong luminance contrasts are enhanced. Output image keeps its naturalness and visual content is enhanced. Color processing is based on the color multiplexing/demultiplexing method proposed in [chaix2007]_.
.. image:: images/retina_TreeHdr_retina.jpg
:alt: A High dynamic range image compressed within range [0-255] using the retina.
:align: center
*Note :* image sample can be downloaded from the `OpenEXR website <http://www.openexr.com>`_. Regarding this demonstration, before retina processing, input image has been linearly rescaled within 0-255 keeping its channels float format. 5% of its histogram ends has been cut (mostly removes wrong HDR pixels). Check out the sample *opencv/samples/cpp/OpenEXRimages_HighDynamicRange_Retina_toneMapping.cpp* for similar processing. The following demonstration will only consider classical 8bit/channel images.
The retina model output channels
================================
The retina model presents two outputs that benefit from the above cited behaviors.
* The first one is called the Parvocellular channel. It is mainly active in the foveal retina area (high resolution central vision with color sensitive photo-receptors), its aim is to provide accurate color vision for visual details remaining static on the retina. On the other hand objects moving on the retina projection are blurred.
* The second well known channel is the Magnocellular channel. It is mainly active in the retina peripheral vision and send signals related to change events (motion, transient events, etc.). These outing signals also help visual system to focus/center retina on 'transient'/moving areas for more detailed analysis thus improving visual scene context and object classification.
**NOTE :** regarding the proposed model, contrary to the real retina, we apply these two channels on the entire input images using the same resolution. This allows enhanced visual details and motion information to be extracted on all the considered images... but remember, that these two channels are complementary. For example, if Magnocellular channel gives strong energy in an area, then, the Parvocellular channel is certainly blurred there since there is a transient event.
As an illustration, we apply in the following the retina model on a webcam video stream of a dark visual scene. In this visual scene, captured in an amphitheater of the university, some students are moving while talking to the teacher.
In this video sequence, because of the dark ambiance, signal to noise ratio is low and color artifacts are present on visual features edges because of the low quality image capture tool-chain.
.. image:: images/studentsSample_input.jpg
:alt: an input video stream extract sample
:align: center
Below is shown the retina foveal vision applied on the entire image. In the used retina configuration, global luminance is preserved and local contrasts are enhanced. Also, signal to noise ratio is improved : since high frequency spatio-temporal noise is reduced, enhanced details are not corrupted by any enhanced noise.
.. image:: images/studentsSample_parvo.jpg
:alt: the retina Parvocellular output. Enhanced details, luminance adaptation and noise removal. A processing tool for image analysis.
:align: center
Below is the output of the Magnocellular output of the retina model. Its signals are strong where transient events occur. Here, a student is moving at the bottom of the image thus generating high energy. The remaining of the image is static however, it is corrupted by a strong noise. Here, the retina filters out most of the noise thus generating low false motion area 'alarms'. This channel can be used as a transient/moving areas detector : it would provide relevant information for a low cost segmentation tool that would highlight areas in which an event is occurring.
.. image:: images/studentsSample_magno.jpg
:alt: the retina Magnocellular output. Enhanced transient signals (motion, etc.). A preprocessing tool for event detection.
:align: center
Retina use case
===============
This model can be used basically for spatio-temporal video effects but also in the aim of :
* performing texture analysis with enhanced signal to noise ratio and enhanced details robust against input images luminance ranges (check out the Parvocellular retina channel output)
* performing motion analysis also taking benefit of the previously cited properties.
Literature
==========
For more information, refer to the following papers :
.. [benoit2010] Benoit A., Caplier A., Durette B., Herault, J., "Using Human Visual System Modeling For Bio-Inspired Low Level Image Processing", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773. DOI <http://dx.doi.org/10.1016/j.cviu.2010.01.011>
* Please have a look at the reference work of Jeanny Herault that you can read in his book :
.. [herault2010] Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
This retina filter code includes the research contributions of phd/research collegues from which code has been redrawn by the author :
* take a look at the *retinacolor.hpp* module to discover Brice Chaix de Lavarene phD color mosaicing/demosaicing and his reference paper:
.. [chaix2007] B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
* take a look at *imagelogpolprojection.hpp* to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions. More informations in the above cited Jeanny Heraults's book.
Code tutorial
=============
Please refer to the original tutorial source code in file *opencv_folder/samples/cpp/tutorial_code/bioinspired/retina_tutorial.cpp*.
**Note :** do not forget that the retina model is included in the following namespace : *cv::bioinspired*.
To compile it, assuming OpenCV is correctly installed, use the following command. It requires the opencv_core *(cv::Mat and friends objects management)*, opencv_highgui *(display and image/video read)* and opencv_bioinspired *(Retina description)* libraries to compile.
.. code-block:: cpp
// compile
gcc retina_tutorial.cpp -o Retina_tuto -lopencv_core -lopencv_highgui -lopencv_bioinspired
// Run commands : add 'log' as a last parameter to apply a spatial log sampling (simulates retina sampling)
// run on webcam
./Retina_tuto -video
// run on video file
./Retina_tuto -video myVideo.avi
// run on an image
./Retina_tuto -image myPicture.jpg
// run on an image with log sampling
./Retina_tuto -image myPicture.jpg log
Here is a code explanation :
Retina definition is present in the bioinspired package and a simple include allows to use it. You can rather use the specific header : *opencv2/bioinspired.hpp* if you prefer but then include the other required openv modules : *opencv2/core.hpp* and *opencv2/highgui.hpp*
.. code-block:: cpp
#include "opencv2/opencv.hpp"
Provide user some hints to run the program with a help function
.. code-block:: cpp
// the help procedure
static void help(std::string errorMessage)
{
std::cout<<"Program init error : "<<errorMessage<<std::endl;
std::cout<<"\nProgram call procedure : retinaDemo [processing mode] [Optional : media target] [Optional LAST parameter: \"log\" to activate retina log sampling]"<<std::endl;
std::cout<<"\t[processing mode] :"<<std::endl;
std::cout<<"\t -image : for still image processing"<<std::endl;
std::cout<<"\t -video : for video stream processing"<<std::endl;
std::cout<<"\t[Optional : media target] :"<<std::endl;
std::cout<<"\t if processing an image or video file, then, specify the path and filename of the target to process"<<std::endl;
std::cout<<"\t leave empty if processing video stream coming from a connected video device"<<std::endl;
std::cout<<"\t[Optional : activate retina log sampling] : an optional last parameter can be specified for retina spatial log sampling"<<std::endl;
std::cout<<"\t set \"log\" without quotes to activate this sampling, output frame size will be divided by 4"<<std::endl;
std::cout<<"\nExamples:"<<std::endl;
std::cout<<"\t-Image processing : ./retinaDemo -image lena.jpg"<<std::endl;
std::cout<<"\t-Image processing with log sampling : ./retinaDemo -image lena.jpg log"<<std::endl;
std::cout<<"\t-Video processing : ./retinaDemo -video myMovie.mp4"<<std::endl;
std::cout<<"\t-Live video processing : ./retinaDemo -video"<<std::endl;
std::cout<<"\nPlease start again with new parameters"<<std::endl;
std::cout<<"****************************************************"<<std::endl;
std::cout<<" NOTE : this program generates the default retina parameters file 'RetinaDefaultParameters.xml'"<<std::endl;
std::cout<<" => you can use this to fine tune parameters and load them if you save to file 'RetinaSpecificParameters.xml'"<<std::endl;
}
Then, start the main program and first declare a *cv::Mat* matrix in which input images will be loaded. Also allocate a *cv::VideoCapture* object ready to load video streams (if necessary)
.. code-block:: cpp
int main(int argc, char* argv[]) {
// declare the retina input buffer... that will be fed differently in regard of the input media
cv::Mat inputFrame;
cv::VideoCapture videoCapture; // in case a video media is used, its manager is declared here
In the main program, before processing, first check input command parameters. Here it loads a first input image coming from a single loaded image (if user chose command *-image*) or from a video stream (if user chose command *-video*). Also, if the user added *log* command at the end of its program call, the spatial logarithmic image sampling performed by the retina is taken into account by the Boolean flag *useLogSampling*.
.. code-block:: cpp
// welcome message
std::cout<<"****************************************************"<<std::endl;
std::cout<<"* Retina demonstration : demonstrates the use of is a wrapper class of the Gipsa/Listic Labs retina model."<<std::endl;
std::cout<<"* This demo will try to load the file 'RetinaSpecificParameters.xml' (if exists).\nTo create it, copy the autogenerated template 'RetinaDefaultParameters.xml'.\nThen twaek it with your own retina parameters."<<std::endl;
// basic input arguments checking
if (argc<2)
{
help("bad number of parameter");
return -1;
}
bool useLogSampling = !strcmp(argv[argc-1], "log"); // check if user wants retina log sampling processing
std::string inputMediaType=argv[1];
//////////////////////////////////////////////////////////////////////////////
// checking input media type (still image, video file, live video acquisition)
if (!strcmp(inputMediaType.c_str(), "-image") && argc >= 3)
{
std::cout<<"RetinaDemo: processing image "<<argv[2]<<std::endl;
// image processing case
inputFrame = cv::imread(std::string(argv[2]), 1); // load image in RGB mode
}else
if (!strcmp(inputMediaType.c_str(), "-video"))
{
if (argc == 2 || (argc == 3 && useLogSampling)) // attempt to grab images from a video capture device
{
videoCapture.open(0);
}else// attempt to grab images from a video filestream
{
std::cout<<"RetinaDemo: processing video stream "<<argv[2]<<std::endl;
videoCapture.open(argv[2]);
}
// grab a first frame to check if everything is ok
videoCapture>>inputFrame;
}else
{
// bad command parameter
help("bad command parameter");
return -1;
}
Once all input parameters are processed, a first image should have been loaded, if not, display error and stop program :
.. code-block:: cpp
if (inputFrame.empty())
{
help("Input media could not be loaded, aborting");
return -1;
}
Now, everything is ready to run the retina model. I propose here to allocate a retina instance and to manage the eventual log sampling option. The Retina constructor expects at least a cv::Size object that shows the input data size that will have to be managed. One can activate other options such as color and its related color multiplexing strategy (here Bayer multiplexing is chosen using *enum cv::bioinspired::RETINA_COLOR_BAYER*). If using log sampling, the image reduction factor (smaller output images) and log sampling strengh can be adjusted.
.. code-block:: cpp
// pointer to a retina object
cv::Ptr<cv::bioinspired::Retina> myRetina;
// if the last parameter is 'log', then activate log sampling (favour foveal vision and subsamples peripheral vision)
if (useLogSampling)
{
myRetina = cv::bioinspired::createRetina(inputFrame.size(), true, cv::bioinspired::RETINA_COLOR_BAYER, true, 2.0, 10.0);
}
else// -> else allocate "classical" retina :
myRetina = cv::bioinspired::createRetina(inputFrame.size());
Once done, the proposed code writes a default xml file that contains the default parameters of the retina. This is useful to make your own config using this template. Here generated template xml file is called *RetinaDefaultParameters.xml*.
.. code-block:: cpp
// save default retina parameters file in order to let you see this and maybe modify it and reload using method "setup"
myRetina->write("RetinaDefaultParameters.xml");
In the following line, the retina attempts to load another xml file called *RetinaSpecificParameters.xml*. If you created it and introduced your own setup, it will be loaded, in the other case, default retina parameters are used.
.. code-block:: cpp
// load parameters if file exists
myRetina->setup("RetinaSpecificParameters.xml");
It is not required here but just to show it is possible, you can reset the retina buffers to zero to force it to forget past events.
.. code-block:: cpp
// reset all retina buffers (imagine you close your eyes for a long time)
myRetina->clearBuffers();
Now, it is time to run the retina ! First create some output buffers ready to receive the two retina channels outputs
.. code-block:: cpp
// declare retina output buffers
cv::Mat retinaOutput_parvo;
cv::Mat retinaOutput_magno;
Then, run retina in a loop, load new frames from video sequence if necessary and get retina outputs back to dedicated buffers.
.. code-block:: cpp
// processing loop with no stop condition
while(true)
{
// if using video stream, then, grabbing a new frame, else, input remains the same
if (videoCapture.isOpened())
videoCapture>>inputFrame;
// run retina filter on the loaded input frame
myRetina->run(inputFrame);
// Retrieve and display retina output
myRetina->getParvo(retinaOutput_parvo);
myRetina->getMagno(retinaOutput_magno);
cv::imshow("retina input", inputFrame);
cv::imshow("Retina Parvo", retinaOutput_parvo);
cv::imshow("Retina Magno", retinaOutput_magno);
cv::waitKey(10);
}
That's done ! But if you want to secure the system, take care and manage Exceptions. The retina can throw some when it sees irrelevant data (no input frame, wrong setup, etc.).
Then, i recommend to surround all the retina code by a try/catch system like this :
.. code-block:: cpp
try{
// pointer to a retina object
cv::Ptr<cv::Retina> myRetina;
[---]
// processing loop with no stop condition
while(true)
{
[---]
}
}catch(cv::Exception e)
{
std::cerr<<"Error using Retina : "<<e.what()<<std::endl;
}
Retina parameters, what to do ?
===============================
First, it is recommended to read the reference paper :
* Benoit A., Caplier A., Durette B., Herault, J., *"Using Human Visual System Modeling For Bio-Inspired Low Level Image Processing"*, Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773. DOI <http://dx.doi.org/10.1016/j.cviu.2010.01.011>
Once done open the configuration file *RetinaDefaultParameters.xml* generated by the demo and let's have a look at it.
.. code-block:: cpp
<?xml version="1.0"?>
<opencv_storage>
<OPLandIPLparvo>
<colorMode>1</colorMode>
<normaliseOutput>1</normaliseOutput>
<photoreceptorsLocalAdaptationSensitivity>7.5e-01</photoreceptorsLocalAdaptationSensitivity>
<photoreceptorsTemporalConstant>9.0e-01</photoreceptorsTemporalConstant>
<photoreceptorsSpatialConstant>5.7e-01</photoreceptorsSpatialConstant>
<horizontalCellsGain>0.01</horizontalCellsGain>
<hcellsTemporalConstant>0.5</hcellsTemporalConstant>
<hcellsSpatialConstant>7.</hcellsSpatialConstant>
<ganglionCellsSensitivity>7.5e-01</ganglionCellsSensitivity></OPLandIPLparvo>
<IPLmagno>
<normaliseOutput>1</normaliseOutput>
<parasolCells_beta>0.</parasolCells_beta>
<parasolCells_tau>0.</parasolCells_tau>
<parasolCells_k>7.</parasolCells_k>
<amacrinCellsTemporalCutFrequency>2.0e+00</amacrinCellsTemporalCutFrequency>
<V0CompressionParameter>9.5e-01</V0CompressionParameter>
<localAdaptintegration_tau>0.</localAdaptintegration_tau>
<localAdaptintegration_k>7.</localAdaptintegration_k></IPLmagno>
</opencv_storage>
Here are some hints but actually, the best parameter setup depends more on what you want to do with the retina rather than the images input that you give to retina. Apart from the more specific case of High Dynamic Range images (HDR) that require more specific setup for specific luminance compression objective, the retina behaviors should be rather stable from content to content. Note that OpenCV is able to manage such HDR format thanks to the OpenEXR images compatibility.
Then, if the application target requires details enhancement prior to specific image processing, you need to know if mean luminance information is required or not. If not, the the retina can cancel or significantly reduce its energy thus giving more visibility to higher spatial frequency details.
Basic parameters
----------------
The most simple parameters are the following :
* **colorMode** : let the retina process color information (if 1) or gray scale images (if 0). In this last case, only the first channel of the input will be processed.
* **normaliseOutput** : each channel has this parameter, if value is 1, then the considered channel output is rescaled between 0 and 255. Take care in this case at the Magnocellular output level (motion/transient channel detection). Residual noise will also be rescaled !
**Note :** using color requires color channels multiplexing/demultipexing which requires more processing. You can expect much faster processing using gray levels : it would require around 30 product per pixel for all the retina processes and it has recently been parallelized for multicore architectures.
Photo-receptors parameters
--------------------------
The following parameters act on the entry point of the retina - photo-receptors - and impact all the following processes. These sensors are low pass spatio-temporal filters that smooth temporal and spatial data and also adjust there sensitivity to local luminance thus improving details extraction and high frequency noise canceling.
* **photoreceptorsLocalAdaptationSensitivity** between 0 and 1. Values close to 1 allow high luminance log compression effect at the photo-receptors level. Values closer to 0 give a more linear sensitivity. Increased alone, it can burn the *Parvo (details channel)* output image. If adjusted in collaboration with **ganglionCellsSensitivity** images can be very contrasted whatever the local luminance there is... at the price of a naturalness decrease.
* **photoreceptorsTemporalConstant** this setups the temporal constant of the low pass filter effect at the entry of the retina. High value lead to strong temporal smoothing effect : moving objects are blurred and can disappear while static object are favored. But when starting the retina processing, stable state is reached lately.
* **photoreceptorsSpatialConstant** specifies the spatial constant related to photo-receptors low pass filter effect. This parameters specify the minimum allowed spatial signal period allowed in the following. Typically, this filter should cut high frequency noise. Then a 0 value doesn't cut anything noise while higher values start to cut high spatial frequencies and more and more lower frequencies... Then, do not go to high if you wanna see some details of the input images ! A good compromise for color images is 0.53 since this won't affect too much the color spectrum. Higher values would lead to gray and blurred output images.
Horizontal cells parameters
---------------------------
This parameter set tunes the neural network connected to the photo-receptors, the horizontal cells. It modulates photo-receptors sensitivity and completes the processing for final spectral whitening (part of the spatial band pass effect thus favoring visual details enhancement).
* **horizontalCellsGain** here is a critical parameter ! If you are not interested by the mean luminance and focus on details enhancement, then, set to zero. But if you want to keep some environment luminance data, let some low spatial frequencies pass into the system and set a higher value (<1).
* **hcellsTemporalConstant** similar to photo-receptors, this acts on the temporal constant of a low pass temporal filter that smooths input data. Here, a high value generates a high retina after effect while a lower value makes the retina more reactive. This value should be lower than **photoreceptorsTemporalConstant** to limit strong retina after effects.
* **hcellsSpatialConstant** is the spatial constant of the low pass filter of these cells filter. It specifies the lowest spatial frequency allowed in the following. Visually, a high value leads to very low spatial frequencies processing and leads to salient halo effects. Lower values reduce this effect but the limit is : do not go lower than the value of **photoreceptorsSpatialConstant**. Those 2 parameters actually specify the spatial band-pass of the retina.
**NOTE** after the processing managed by the previous parameters, input data is cleaned from noise and luminance in already partly enhanced. The following parameters act on the last processing stages of the two outing retina signals.
Parvo (details channel) dedicated parameter
-------------------------------------------
* **ganglionCellsSensitivity** specifies the strength of the final local adaptation occurring at the output of this details dedicated channel. Parameter values remain between 0 and 1. Low value tend to give a linear response while higher values enforces the remaining low contrasted areas.
**Note :** this parameter can correct eventual burned images by favoring low energetic details of the visual scene, even in bright areas.
IPL Magno (motion/transient channel) parameters
-----------------------------------------------
Once image information is cleaned, this channel acts as a high pass temporal filter that only selects signals related to transient signals (events, motion, etc.). A low pass spatial filter smooths extracted transient data and a final logarithmic compression enhances low transient events thus enhancing event sensitivity.
* **parasolCells_beta** generally set to zero, can be considered as an amplifier gain at the entry point of this processing stage. Generally set to 0.
* **parasolCells_tau** the temporal smoothing effect that can be added
* **parasolCells_k** the spatial constant of the spatial filtering effect, set it at a high value to favor low spatial frequency signals that are lower subject to residual noise.
* **amacrinCellsTemporalCutFrequency** specifies the temporal constant of the high pass filter. High values let slow transient events to be selected.
* **V0CompressionParameter** specifies the strength of the log compression. Similar behaviors to previous description but here it enforces sensitivity of transient events.
* **localAdaptintegration_tau** generally set to 0, no real use here actually
* **localAdaptintegration_k** specifies the size of the area on which local adaptation is performed. Low values lead to short range local adaptation (higher sensitivity to noise), high values secure log compression.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

@@ -1,36 +0,0 @@
.. _Table-Of-Content-Bioinspired:
*bioinspired* module. Algorithms inspired from biological models
----------------------------------------------------------------
Here you will learn how to use additional modules of OpenCV defined in the "bioinspired" module.
.. include:: ../../definitions/tocDefinitions.rst
+
.. tabularcolumns:: m{100pt} m{300pt}
.. cssclass:: toctableopencv
=============== ======================================================
|RetinaDemoImg| **Title:** :ref:`Retina_Model`
*Compatibility:* > OpenCV 2.4
*Author:* |Author_AlexB|
You will learn how to process images and video streams with a model of retina filter for details enhancement, spatio-temporal noise removal, luminance correction and spatio-temporal events detection.
=============== ======================================================
.. |RetinaDemoImg| image:: images/retina_TreeHdr_small.jpg
:height: 90pt
:width: 90pt
.. raw:: latex
\pagebreak
.. toctree::
:hidden:
../retina_model/retina_model
@@ -1,36 +0,0 @@
.. _Table-Of-Content-Contrib:
*contrib* module. The additional contributions made available !
----------------------------------------------------------------
Here you will learn how to use additional modules of OpenCV defined in the "contrib" module.
.. include:: ../../definitions/tocDefinitions.rst
+
.. tabularcolumns:: m{100pt} m{300pt}
.. cssclass:: toctableopencv
=============== ======================================================
|RetinaDemoImg| **Title:** :ref:`Retina_Model`
*Compatibility:* > OpenCV 2.4
*Author:* |Author_AlexB|
You will learn how to process images and video streams with a model of retina filter for details enhancement, spatio-temporal noise removal, luminance correction and spatio-temporal events detection.
=============== ======================================================
.. |RetinaDemoImg| image:: images/retina_TreeHdr_small.jpg
:height: 90pt
:width: 90pt
.. raw:: latex
\pagebreak
.. toctree::
:hidden:
../retina_model/retina_model
@@ -66,7 +66,7 @@ The structure of package contents looks as follows:
| |_ armeabi-v7a
| |_ x86
|
|_ license.txt
|_ LICENSE
|_ README.android
* :file:`sdk` folder contains OpenCV API and libraries for Android:
@@ -13,10 +13,10 @@ Required Packages
sudo apt-get install build-essential
* CMake 2.6 or higher;
* CMake 2.8.7 or higher;
* Git;
* GTK+2.x or higher, including headers (libgtk2.0-dev);
* pkgconfig;
* pkg-config;
* Python 2.6 or later and Numpy 1.5 or later with developer packages (python-dev, python-numpy);
* ffmpeg or libav development packages: libavcodec-dev, libavformat-dev, libswscale-dev;
* [optional] libdc1394 2.x;
-16
View File
@@ -171,21 +171,6 @@ As always, we would be happy to hear your comments and receive your contribution
:width: 80pt
:alt: gpu icon
* :ref:`Table-Of-Content-Bioinspired`
.. tabularcolumns:: m{100pt} m{300pt}
.. cssclass:: toctableopencv
============= =======================================================
|Bioinspired| Algorithms inspired from biological models.
============= =======================================================
.. |Bioinspired| image:: images/retina.jpg
:height: 80pt
:width: 80pt
:alt: gpu icon
* :ref:`Table-Of-Content-iOS`
.. tabularcolumns:: m{100pt} m{300pt}
@@ -250,7 +235,6 @@ As always, we would be happy to hear your comments and receive your contribution
ml/table_of_content_ml/table_of_content_ml
photo/table_of_content_photo/table_of_content_photo
gpu/table_of_content_gpu/table_of_content_gpu
bioinspired/table_of_content_bioinspired/table_of_content_bioinspired
ios/table_of_content_ios/table_of_content_ios
viz/table_of_content_viz/table_of_content_viz
general/table_of_content_general/table_of_content_general
@@ -43,7 +43,7 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial
cout << "First event loop is over" << endl;
/// Access window via its name
viz::Viz3d sameWindow = viz::get("Viz Demo");
viz::Viz3d sameWindow = viz::getWindowByName("Viz Demo");
/// Start event loop
sameWindow.spin();
+2 -2
View File
@@ -1,7 +1,7 @@
file(GLOB old_hdrs "opencv/*.h*")
install(FILES ${old_hdrs}
DESTINATION ${OPENCV_INCLUDE_INSTALL_PATH}/opencv
COMPONENT main)
COMPONENT dev)
install(FILES "opencv2/opencv.hpp"
DESTINATION ${OPENCV_INCLUDE_INSTALL_PATH}/opencv2
COMPONENT main)
COMPONENT dev)
-1
View File
@@ -52,7 +52,6 @@
#include "opencv2/calib3d.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/contrib.hpp"
#include "opencv2/bioinspired.hpp"
#include "opencv2/ml.hpp"
#endif
+1 -1
View File
@@ -40,6 +40,6 @@ else()
get_filename_component(wrapper_name "${wrapper}" NAME)
install(FILES "${LIBRARY_OUTPUT_PATH}/${wrapper_name}"
DESTINATION ${OPENCV_LIB_INSTALL_PATH}
COMPONENT main)
COMPONENT libs)
endforeach()
endif()
@@ -63,4 +63,4 @@ if (NOT (CMAKE_BUILD_TYPE MATCHES "debug"))
endif()
install(TARGETS ${the_target} LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT main)
install(TARGETS ${the_target} LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT libs)
-3
View File
@@ -1,3 +0,0 @@
set(the_description "Biologically inspired algorithms")
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef)
ocv_define_module(bioinspired opencv_core OPTIONAL opencv_highgui opencv_ocl)
-10
View File
@@ -1,10 +0,0 @@
********************************************************************
bioinspired. Biologically inspired vision models and derivated tools
********************************************************************
The module provides biological visual systems models (human visual system and others). It also provides derivated objects that take advantage of those bio-inspired models.
.. toctree::
:maxdepth: 2
Human retina documentation <retina/index>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

-493
View File
@@ -1,493 +0,0 @@
Retina : a Bio mimetic human retina model
*****************************************
.. highlight:: cpp
Retina
======
.. ocv:class:: Retina : public Algorithm
**Note** : do not forget that the retina model is included in the following namespace : *cv::bioinspired*.
Introduction
++++++++++++
Class which provides the main controls to the Gipsa/Listic labs human retina model. This is a non separable spatio-temporal filter modelling the two main retina information channels :
* foveal vision for detailled color vision : the parvocellular pathway.
* peripheral vision for sensitive transient signals detection (motion and events) : the magnocellular pathway.
From a general point of view, this filter whitens the image spectrum and corrects luminance thanks to local adaptation. An other important property is its hability to filter out spatio-temporal noise while enhancing details.
This model originates from Jeanny Herault work [Herault2010]_. It has been involved in Alexandre Benoit phd and his current research [Benoit2010]_, [Strat2013]_ (he currently maintains this module within OpenCV). It includes the work of other Jeanny's phd student such as [Chaix2007]_ and the log polar transformations of Barthelemy Durette described in Jeanny's book.
**NOTES :**
* For ease of use in computer vision applications, the two retina channels are applied homogeneously on all the input images. This does not follow the real retina topology but this can still be done using the log sampling capabilities proposed within the class.
* Extend the retina description and code use in the tutorial/contrib section for complementary explanations.
Preliminary illustration
++++++++++++++++++++++++
As a preliminary presentation, let's start with a visual example. We propose to apply the filter on a low quality color jpeg image with backlight problems. Here is the considered input... *"Well, my eyes were able to see more that this strange black shadow..."*
.. image:: images/retinaInput.jpg
:alt: a low quality color jpeg image with backlight problems.
:align: center
Below, the retina foveal model applied on the entire image with default parameters. Here contours are enforced, halo effects are voluntary visible with this configuration. See parameters discussion below and increase horizontalCellsGain near 1 to remove them.
.. image:: images/retinaOutput_default.jpg
:alt: the retina foveal model applied on the entire image with default parameters. Here contours are enforced, luminance is corrected and halo effects are voluntary visible with this configuration, increase horizontalCellsGain near 1 to remove them.
:align: center
Below, a second retina foveal model output applied on the entire image with a parameters setup focused on naturalness perception. *"Hey, i now recognize my cat, looking at the mountains at the end of the day !"*. Here contours are enforced, luminance is corrected but halos are avoided with this configuration. The backlight effect is corrected and highlight details are still preserved. Then, even on a low quality jpeg image, if some luminance information remains, the retina is able to reconstruct a proper visual signal. Such configuration is also usefull for High Dynamic Range (*HDR*) images compression to 8bit images as discussed in [benoit2010]_ and in the demonstration codes discussed below.
As shown at the end of the page, parameters change from defaults are :
* horizontalCellsGain=0.3
* photoreceptorsLocalAdaptationSensitivity=ganglioncellsSensitivity=0.89.
.. image:: images/retinaOutput_realistic.jpg
:alt: the retina foveal model applied on the entire image with 'naturalness' parameters. Here contours are enforced but are avoided with this configuration, horizontalCellsGain is 0.3 and photoreceptorsLocalAdaptationSensitivity=ganglioncellsSensitivity=0.89.
:align: center
As observed in this preliminary demo, the retina can be settled up with various parameters, by default, as shown on the figure above, the retina strongly reduces mean luminance energy and enforces all details of the visual scene. Luminance energy and halo effects can be modulated (exagerated to cancelled as shown on the two examples). In order to use your own parameters, you can use at least one time the *write(String fs)* method which will write a proper XML file with all default parameters. Then, tweak it on your own and reload them at any time using method *setup(String fs)*. These methods update a *Retina::RetinaParameters* member structure that is described hereafter. XML parameters file samples are shown at the end of the page.
Here is an overview of the abstract Retina interface, allocate one instance with the *createRetina* functions.::
namespace cv{namespace bioinspired{
class Retina : public Algorithm
{
public:
// parameters setup instance
struct RetinaParameters; // this class is detailled later
// main method for input frame processing (all use method, can also perform High Dynamic Range tone mapping)
void run (InputArray inputImage);
// specific method aiming at correcting luminance only (faster High Dynamic Range tone mapping)
void applyFastToneMapping(InputArray inputImage, OutputArray outputToneMappedImage)
// output buffers retreival methods
// -> foveal color vision details channel with luminance and noise correction
void getParvo (OutputArray retinaOutput_parvo);
void getParvoRAW (OutputArray retinaOutput_parvo);// retreive original output buffers without any normalisation
const Mat getParvoRAW () const;// retreive original output buffers without any normalisation
// -> peripheral monochrome motion and events (transient information) channel
void getMagno (OutputArray retinaOutput_magno);
void getMagnoRAW (OutputArray retinaOutput_magno); // retreive original output buffers without any normalisation
const Mat getMagnoRAW () const;// retreive original output buffers without any normalisation
// reset retina buffers... equivalent to closing your eyes for some seconds
void clearBuffers ();
// retreive input and output buffers sizes
Size getInputSize ();
Size getOutputSize ();
// setup methods with specific parameters specification of global xml config file loading/write
void setup (String retinaParameterFile="", const bool applyDefaultSetupOnFailure=true);
void setup (FileStorage &fs, const bool applyDefaultSetupOnFailure=true);
void setup (RetinaParameters newParameters);
struct Retina::RetinaParameters getParameters ();
const String printSetup ();
virtual void write (String fs) const;
virtual void write (FileStorage &fs) const;
void setupOPLandIPLParvoChannel (const bool colorMode=true, const bool normaliseOutput=true, const float photoreceptorsLocalAdaptationSensitivity=0.7, const float photoreceptorsTemporalConstant=0.5, const float photoreceptorsSpatialConstant=0.53, const float horizontalCellsGain=0, const float HcellsTemporalConstant=1, const float HcellsSpatialConstant=7, const float ganglionCellsSensitivity=0.7);
void setupIPLMagnoChannel (const bool normaliseOutput=true, const float parasolCells_beta=0, const float parasolCells_tau=0, const float parasolCells_k=7, const float amacrinCellsTemporalCutFrequency=1.2, const float V0CompressionParameter=0.95, const float localAdaptintegration_tau=0, const float localAdaptintegration_k=7);
void setColorSaturation (const bool saturateColors=true, const float colorSaturationValue=4.0);
void activateMovingContoursProcessing (const bool activate);
void activateContoursProcessing (const bool activate);
};
// Allocators
cv::Ptr<Retina> createRetina (Size inputSize);
cv::Ptr<Retina> createRetina (Size inputSize, const bool colorMode, RETINA_COLORSAMPLINGMETHOD colorSamplingMethod=RETINA_COLOR_BAYER, const bool useRetinaLogSampling=false, const double reductionFactor=1.0, const double samplingStrenght=10.0);
}} // cv and bioinspired namespaces end
.. Sample code::
* An example on retina tone mapping can be found at opencv_source_code/samples/cpp/OpenEXRimages_HDR_Retina_toneMapping.cpp
* An example on retina tone mapping on video input can be found at opencv_source_code/samples/cpp/OpenEXRimages_HDR_Retina_toneMapping.cpp
* A complete example illustrating the retina interface can be found at opencv_source_code/samples/cpp/retinaDemo.cpp
Description
+++++++++++
Class which allows the `Gipsa <http://www.gipsa-lab.inpg.fr>`_ (preliminary work) / `Listic <http://www.listic.univ-savoie.fr>`_ (code maintainer and user) labs retina model to be used. This class allows human retina spatio-temporal image processing to be applied on still images, images sequences and video sequences. Briefly, here are the main human retina model properties:
* spectral whithening (mid-frequency details enhancement)
* high frequency spatio-temporal noise reduction (temporal noise and high frequency spatial noise are minimized)
* low frequency luminance reduction (luminance range compression) : high luminance regions do not hide details in darker regions anymore
* local logarithmic luminance compression allows details to be enhanced even in low light conditions
Use : this model can be used basically for spatio-temporal video effects but also in the aim of :
* performing texture analysis with enhanced signal to noise ratio and enhanced details robust against input images luminance ranges (check out the parvocellular retina channel output, by using the provided **getParvo** methods)
* performing motion analysis also taking benefit of the previously cited properties (check out the magnocellular retina channel output, by using the provided **getMagno** methods)
* general image/video sequence description using either one or both channels. An example of the use of Retina in a Bag of Words approach is given in [Strat2013]_.
Literature
==========
For more information, refer to the following papers :
* Model description :
.. [Benoit2010] Benoit A., Caplier A., Durette B., Herault, J., "Using Human Visual System Modeling For Bio-Inspired Low Level Image Processing", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773. DOI <http://dx.doi.org/10.1016/j.cviu.2010.01.011>
* Model use in a Bag of Words approach :
.. [Strat2013] Strat S., Benoit A., Lambert P., "Retina enhanced SIFT descriptors for video indexing", CBMI2013, Veszprém, Hungary, 2013.
* Please have a look at the reference work of Jeanny Herault that you can read in his book :
.. [Herault2010] Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
This retina filter code includes the research contributions of phd/research collegues from which code has been redrawn by the author :
* take a look at the *retinacolor.hpp* module to discover Brice Chaix de Lavarene phD color mosaicing/demosaicing and his reference paper:
.. [Chaix2007] B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
* take a look at *imagelogpolprojection.hpp* to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions. More informations in the above cited Jeanny Heraults's book.
* Meylan&al work on HDR tone mapping that is implemented as a specific method within the model :
.. [Meylan2007] L. Meylan , D. Alleysson, S. Susstrunk, "A Model of Retinal Local Adaptation for the Tone Mapping of Color Filter Array Images", Journal of Optical Society of America, A, Vol. 24, N 9, September, 1st, 2007, pp. 2807-2816
Demos and experiments !
=======================
**NOTE : Complementary to the following examples, have a look at the Retina tutorial in the tutorial/contrib section for complementary explanations.**
Take a look at the provided C++ examples provided with OpenCV :
* **samples/cpp/retinademo.cpp** shows how to use the retina module for details enhancement (Parvo channel output) and transient maps observation (Magno channel output). You can play with images, video sequences and webcam video.
Typical uses are (provided your OpenCV installation is situated in folder *OpenCVReleaseFolder*)
* image processing : **OpenCVReleaseFolder/bin/retinademo -image myPicture.jpg**
* video processing : **OpenCVReleaseFolder/bin/retinademo -video myMovie.avi**
* webcam processing: **OpenCVReleaseFolder/bin/retinademo -video**
**Note :** This demo generates the file *RetinaDefaultParameters.xml* which contains the default parameters of the retina. Then, rename this as *RetinaSpecificParameters.xml*, adjust the parameters the way you want and reload the program to check the effect.
* **samples/cpp/OpenEXRimages_HDR_Retina_toneMapping.cpp** shows how to use the retina to perform High Dynamic Range (HDR) luminance compression
Then, take a HDR image using bracketing with your camera and generate an OpenEXR image and then process it using the demo.
Typical use, supposing that you have the OpenEXR image such as *memorial.exr* (present in the samples/cpp/ folder)
**OpenCVReleaseFolder/bin/OpenEXRimages_HDR_Retina_toneMapping memorial.exr [optional: 'fast']**
Note that some sliders are made available to allow you to play with luminance compression.
If not using the 'fast' option, then, tone mapping is performed using the full retina model [Benoit2010]_. It includes spectral whitening that allows luminance energy to be reduced. When using the 'fast' option, then, a simpler method is used, it is an adaptation of the algorithm presented in [Meylan2007]_. This method gives also good results and is faster to process but it sometimes requires some more parameters adjustement.
Methods description
===================
Here are detailled the main methods to control the retina model
Ptr<Retina>::createRetina
+++++++++++++++++++++++++
.. ocv:function:: Ptr<cv::bioinspired::Retina> createRetina(Size inputSize)
.. ocv:function:: Ptr<cv::bioinspired::Retina> createRetina(Size inputSize, const bool colorMode, cv::bioinspired::RETINA_COLORSAMPLINGMETHOD colorSamplingMethod = cv::bioinspired::RETINA_COLOR_BAYER, const bool useRetinaLogSampling = false, const double reductionFactor = 1.0, const double samplingStrenght = 10.0 )
Constructors from standardized interfaces : retreive a smart pointer to a Retina instance
:param inputSize: the input frame size
:param colorMode: the chosen processing mode : with or without color processing
:param colorSamplingMethod: specifies which kind of color sampling will be used :
* cv::bioinspired::RETINA_COLOR_RANDOM: each pixel position is either R, G or B in a random choice
* cv::bioinspired::RETINA_COLOR_DIAGONAL: color sampling is RGBRGBRGB..., line 2 BRGBRGBRG..., line 3, GBRGBRGBR...
* cv::bioinspired::RETINA_COLOR_BAYER: standard bayer sampling
:param useRetinaLogSampling: activate retina log sampling, if true, the 2 following parameters can be used
:param reductionFactor: only usefull if param useRetinaLogSampling=true, specifies the reduction factor of the output frame (as the center (fovea) is high resolution and corners can be underscaled, then a reduction of the output is allowed without precision leak
:param samplingStrenght: only usefull if param useRetinaLogSampling=true, specifies the strenght of the log scale that is applied
Retina::activateContoursProcessing
++++++++++++++++++++++++++++++++++
.. ocv:function:: void Retina::activateContoursProcessing(const bool activate)
Activate/desactivate the Parvocellular pathway processing (contours information extraction), by default, it is activated
:param activate: true if Parvocellular (contours information extraction) output should be activated, false if not... if activated, the Parvocellular output can be retrieved using the **getParvo** methods
Retina::activateMovingContoursProcessing
++++++++++++++++++++++++++++++++++++++++
.. ocv:function:: void Retina::activateMovingContoursProcessing(const bool activate)
Activate/desactivate the Magnocellular pathway processing (motion information extraction), by default, it is activated
:param activate: true if Magnocellular output should be activated, false if not... if activated, the Magnocellular output can be retrieved using the **getMagno** methods
Retina::clearBuffers
++++++++++++++++++++
.. ocv:function:: void Retina::clearBuffers()
Clears all retina buffers (equivalent to opening the eyes after a long period of eye close ;o) whatchout the temporal transition occuring just after this method call.
Retina::getParvo
++++++++++++++++
.. ocv:function:: void Retina::getParvo( OutputArray retinaOutput_parvo )
.. ocv:function:: void Retina::getParvoRAW( OutputArray retinaOutput_parvo )
.. ocv:function:: const Mat Retina::getParvoRAW() const
Accessor of the details channel of the retina (models foveal vision). Warning, getParvoRAW methods return buffers that are not rescaled within range [0;255] while the non RAW method allows a normalized matrix to be retrieved.
:param retinaOutput_parvo: the output buffer (reallocated if necessary), format can be :
* a Mat, this output is rescaled for standard 8bits image processing use in OpenCV
* RAW methods actually return a 1D matrix (encoding is R1, R2, ... Rn, G1, G2, ..., Gn, B1, B2, ...Bn), this output is the original retina filter model output, without any quantification or rescaling.
Retina::getMagno
++++++++++++++++
.. ocv:function:: void Retina::getMagno( OutputArray retinaOutput_magno )
.. ocv:function:: void Retina::getMagnoRAW( OutputArray retinaOutput_magno )
.. ocv:function:: const Mat Retina::getMagnoRAW() const
Accessor of the motion channel of the retina (models peripheral vision). Warning, getMagnoRAW methods return buffers that are not rescaled within range [0;255] while the non RAW method allows a normalized matrix to be retrieved.
:param retinaOutput_magno: the output buffer (reallocated if necessary), format can be :
* a Mat, this output is rescaled for standard 8bits image processing use in OpenCV
* RAW methods actually return a 1D matrix (encoding is M1, M2,... Mn), this output is the original retina filter model output, without any quantification or rescaling.
Retina::getInputSize
++++++++++++++++++++
.. ocv:function:: Size Retina::getInputSize()
Retreive retina input buffer size
:return: the retina input buffer size
Retina::getOutputSize
+++++++++++++++++++++
.. ocv:function:: Size Retina::getOutputSize()
Retreive retina output buffer size that can be different from the input if a spatial log transformation is applied
:return: the retina output buffer size
Retina::printSetup
++++++++++++++++++
.. ocv:function:: const String Retina::printSetup()
Outputs a string showing the used parameters setup
:return: a string which contains formated parameters information
Retina::run
+++++++++++
.. ocv:function:: void Retina::run(InputArray inputImage)
Method which allows retina to be applied on an input image, after run, encapsulated retina module is ready to deliver its outputs using dedicated acccessors, see getParvo and getMagno methods
:param inputImage: the input Mat image to be processed, can be gray level or BGR coded in any format (from 8bit to 16bits)
Retina::applyFastToneMapping
++++++++++++++++++++++++++++
.. ocv:function:: void Retina::applyFastToneMapping(InputArray inputImage, OutputArray outputToneMappedImage)
Method which processes an image in the aim to correct its luminance : correct backlight problems, enhance details in shadows. This method is designed to perform High Dynamic Range image tone mapping (compress >8bit/pixel images to 8bit/pixel). This is a simplified version of the Retina Parvocellular model (simplified version of the run/getParvo methods call) since it does not include the spatio-temporal filter modelling the Outer Plexiform Layer of the retina that performs spectral whitening and many other stuff. However, it works great for tone mapping and in a faster way.
Check the demos and experiments section to see examples and the way to perform tone mapping using the original retina model and the method.
:param inputImage: the input image to process (should be coded in float format : CV_32F, CV_32FC1, CV_32F_C3, CV_32F_C4, the 4th channel won't be considered).
:param outputToneMappedImage: the output 8bit/channel tone mapped image (CV_8U or CV_8UC3 format).
Retina::setColorSaturation
++++++++++++++++++++++++++
.. ocv:function:: void Retina::setColorSaturation(const bool saturateColors = true, const float colorSaturationValue = 4.0 )
Activate color saturation as the final step of the color demultiplexing process -> this saturation is a sigmoide function applied to each channel of the demultiplexed image.
:param saturateColors: boolean that activates color saturation (if true) or desactivate (if false)
:param colorSaturationValue: the saturation factor : a simple factor applied on the chrominance buffers
Retina::setup
+++++++++++++
.. ocv:function:: void Retina::setup(String retinaParameterFile = "", const bool applyDefaultSetupOnFailure = true )
.. ocv:function:: void Retina::setup(FileStorage & fs, const bool applyDefaultSetupOnFailure = true )
.. ocv:function:: void Retina::setup(RetinaParameters newParameters)
Try to open an XML retina parameters file to adjust current retina instance setup => if the xml file does not exist, then default setup is applied => warning, Exceptions are thrown if read XML file is not valid
:param retinaParameterFile: the parameters filename
:param applyDefaultSetupOnFailure: set to true if an error must be thrown on error
:param fs: the open Filestorage which contains retina parameters
:param newParameters: a parameters structures updated with the new target configuration. You can retreive the current parameers structure using method *Retina::RetinaParameters Retina::getParameters()* and update it before running method *setup*.
Retina::write
+++++++++++++
.. ocv:function:: void Retina::write( String fs ) const
.. ocv:function:: void Retina::write( FileStorage& fs ) const
Write xml/yml formated parameters information
:param fs: the filename of the xml file that will be open and writen with formatted parameters information
Retina::setupIPLMagnoChannel
++++++++++++++++++++++++++++
.. ocv:function:: void Retina::setupIPLMagnoChannel(const bool normaliseOutput = true, const float parasolCells_beta = 0, const float parasolCells_tau = 0, const float parasolCells_k = 7, const float amacrinCellsTemporalCutFrequency = 1.2, const float V0CompressionParameter = 0.95, const float localAdaptintegration_tau = 0, const float localAdaptintegration_k = 7 )
Set parameters values for the Inner Plexiform Layer (IPL) magnocellular channel this channel processes signals output from OPL processing stage in peripheral vision, it allows motion information enhancement. It is decorrelated from the details channel. See reference papers for more details.
:param normaliseOutput: specifies if (true) output is rescaled between 0 and 255 of not (false)
:param parasolCells_beta: the low pass filter gain used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), typical value is 0
:param parasolCells_tau: the low pass filter time constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is frame, typical value is 0 (immediate response)
:param parasolCells_k: the low pass filter spatial constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is pixels, typical value is 5
:param amacrinCellsTemporalCutFrequency: the time constant of the first order high pass fiter of the magnocellular way (motion information channel), unit is frames, typical value is 1.2
:param V0CompressionParameter: the compression strengh of the ganglion cells local adaptation output, set a value between 0.6 and 1 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 0.95
:param localAdaptintegration_tau: specifies the temporal constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
:param localAdaptintegration_k: specifies the spatial constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
Retina::setupOPLandIPLParvoChannel
++++++++++++++++++++++++++++++++++
.. ocv:function:: void Retina::setupOPLandIPLParvoChannel(const bool colorMode = true, const bool normaliseOutput = true, const float photoreceptorsLocalAdaptationSensitivity = 0.7, const float photoreceptorsTemporalConstant = 0.5, const float photoreceptorsSpatialConstant = 0.53, const float horizontalCellsGain = 0, const float HcellsTemporalConstant = 1, const float HcellsSpatialConstant = 7, const float ganglionCellsSensitivity = 0.7 )
Setup the OPL and IPL parvo channels (see biologocal model) OPL is referred as Outer Plexiform Layer of the retina, it allows the spatio-temporal filtering which withens the spectrum and reduces spatio-temporal noise while attenuating global luminance (low frequency energy) IPL parvo is the OPL next processing stage, it refers to a part of the Inner Plexiform layer of the retina, it allows high contours sensitivity in foveal vision. See reference papers for more informations.
:param colorMode: specifies if (true) color is processed of not (false) to then processing gray level image
:param normaliseOutput: specifies if (true) output is rescaled between 0 and 255 of not (false)
:param photoreceptorsLocalAdaptationSensitivity: the photoreceptors sensitivity renage is 0-1 (more log compression effect when value increases)
:param photoreceptorsTemporalConstant: the time constant of the first order low pass filter of the photoreceptors, use it to cut high temporal frequencies (noise or fast motion), unit is frames, typical value is 1 frame
:param photoreceptorsSpatialConstant: the spatial constant of the first order low pass filter of the photoreceptors, use it to cut high spatial frequencies (noise or thick contours), unit is pixels, typical value is 1 pixel
:param horizontalCellsGain: gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, then, the luminance is not filtered and is still reachable at the output, typicall value is 0
:param HcellsTemporalConstant: the time constant of the first order low pass filter of the horizontal cells, use it to cut low temporal frequencies (local luminance variations), unit is frames, typical value is 1 frame, as the photoreceptors
:param HcellsSpatialConstant: the spatial constant of the first order low pass filter of the horizontal cells, use it to cut low spatial frequencies (local luminance), unit is pixels, typical value is 5 pixel, this value is also used for local contrast computing when computing the local contrast adaptation at the ganglion cells level (Inner Plexiform Layer parvocellular channel model)
:param ganglionCellsSensitivity: the compression strengh of the ganglion cells local adaptation output, set a value between 0.6 and 1 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 0.7
Retina::RetinaParameters
========================
.. ocv:struct:: Retina::RetinaParameters
This structure merges all the parameters that can be adjusted threw the **Retina::setup()**, **Retina::setupOPLandIPLParvoChannel** and **Retina::setupIPLMagnoChannel** setup methods
Parameters structure for better clarity, check explenations on the comments of methods : setupOPLandIPLParvoChannel and setupIPLMagnoChannel. ::
class RetinaParameters{
struct OPLandIplParvoParameters{ // Outer Plexiform Layer (OPL) and Inner Plexiform Layer Parvocellular (IplParvo) parameters
OPLandIplParvoParameters():colorMode(true),
normaliseOutput(true), // specifies if (true) output is rescaled between 0 and 255 of not (false)
photoreceptorsLocalAdaptationSensitivity(0.7f), // the photoreceptors sensitivity renage is 0-1 (more log compression effect when value increases)
photoreceptorsTemporalConstant(0.5f),// the time constant of the first order low pass filter of the photoreceptors, use it to cut high temporal frequencies (noise or fast motion), unit is frames, typical value is 1 frame
photoreceptorsSpatialConstant(0.53f),// the spatial constant of the first order low pass filter of the photoreceptors, use it to cut high spatial frequencies (noise or thick contours), unit is pixels, typical value is 1 pixel
horizontalCellsGain(0.0f),//gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, then, the luminance is not filtered and is still reachable at the output, typicall value is 0
hcellsTemporalConstant(1.f),// the time constant of the first order low pass filter of the horizontal cells, use it to cut low temporal frequencies (local luminance variations), unit is frames, typical value is 1 frame, as the photoreceptors. Reduce to 0.5 to limit retina after effects.
hcellsSpatialConstant(7.f),//the spatial constant of the first order low pass filter of the horizontal cells, use it to cut low spatial frequencies (local luminance), unit is pixels, typical value is 5 pixel, this value is also used for local contrast computing when computing the local contrast adaptation at the ganglion cells level (Inner Plexiform Layer parvocellular channel model)
ganglionCellsSensitivity(0.7f)//the compression strengh of the ganglion cells local adaptation output, set a value between 0.6 and 1 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 0.7
{};// default setup
bool colorMode, normaliseOutput;
float photoreceptorsLocalAdaptationSensitivity, photoreceptorsTemporalConstant, photoreceptorsSpatialConstant, horizontalCellsGain, hcellsTemporalConstant, hcellsSpatialConstant, ganglionCellsSensitivity;
};
struct IplMagnoParameters{ // Inner Plexiform Layer Magnocellular channel (IplMagno)
IplMagnoParameters():
normaliseOutput(true), //specifies if (true) output is rescaled between 0 and 255 of not (false)
parasolCells_beta(0.f), // the low pass filter gain used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), typical value is 0
parasolCells_tau(0.f), //the low pass filter time constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is frame, typical value is 0 (immediate response)
parasolCells_k(7.f), //the low pass filter spatial constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is pixels, typical value is 5
amacrinCellsTemporalCutFrequency(1.2f), //the time constant of the first order high pass fiter of the magnocellular way (motion information channel), unit is frames, typical value is 1.2
V0CompressionParameter(0.95f), the compression strengh of the ganglion cells local adaptation output, set a value between 0.6 and 1 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 0.95
localAdaptintegration_tau(0.f), // specifies the temporal constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
localAdaptintegration_k(7.f) // specifies the spatial constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
{};// default setup
bool normaliseOutput;
float parasolCells_beta, parasolCells_tau, parasolCells_k, amacrinCellsTemporalCutFrequency, V0CompressionParameter, localAdaptintegration_tau, localAdaptintegration_k;
};
struct OPLandIplParvoParameters OPLandIplParvo;
struct IplMagnoParameters IplMagno;
};
Retina parameters files examples
++++++++++++++++++++++++++++++++
Here is the default configuration file of the retina module. It gives results such as the first retina output shown on the top of this page.
.. code-block:: cpp
<?xml version="1.0"?>
<opencv_storage>
<OPLandIPLparvo>
<colorMode>1</colorMode>
<normaliseOutput>1</normaliseOutput>
<photoreceptorsLocalAdaptationSensitivity>7.5e-01</photoreceptorsLocalAdaptationSensitivity>
<photoreceptorsTemporalConstant>9.0e-01</photoreceptorsTemporalConstant>
<photoreceptorsSpatialConstant>5.3e-01</photoreceptorsSpatialConstant>
<horizontalCellsGain>0.01</horizontalCellsGain>
<hcellsTemporalConstant>0.5</hcellsTemporalConstant>
<hcellsSpatialConstant>7.</hcellsSpatialConstant>
<ganglionCellsSensitivity>7.5e-01</ganglionCellsSensitivity></OPLandIPLparvo>
<IPLmagno>
<normaliseOutput>1</normaliseOutput>
<parasolCells_beta>0.</parasolCells_beta>
<parasolCells_tau>0.</parasolCells_tau>
<parasolCells_k>7.</parasolCells_k>
<amacrinCellsTemporalCutFrequency>2.0e+00</amacrinCellsTemporalCutFrequency>
<V0CompressionParameter>9.5e-01</V0CompressionParameter>
<localAdaptintegration_tau>0.</localAdaptintegration_tau>
<localAdaptintegration_k>7.</localAdaptintegration_k></IPLmagno>
</opencv_storage>
Here is the 'realistic" setup used to obtain the second retina output shown on the top of this page.
.. code-block:: cpp
<?xml version="1.0"?>
<opencv_storage>
<OPLandIPLparvo>
<colorMode>1</colorMode>
<normaliseOutput>1</normaliseOutput>
<photoreceptorsLocalAdaptationSensitivity>8.9e-01</photoreceptorsLocalAdaptationSensitivity>
<photoreceptorsTemporalConstant>9.0e-01</photoreceptorsTemporalConstant>
<photoreceptorsSpatialConstant>5.3e-01</photoreceptorsSpatialConstant>
<horizontalCellsGain>0.3</horizontalCellsGain>
<hcellsTemporalConstant>0.5</hcellsTemporalConstant>
<hcellsSpatialConstant>7.</hcellsSpatialConstant>
<ganglionCellsSensitivity>8.9e-01</ganglionCellsSensitivity></OPLandIPLparvo>
<IPLmagno>
<normaliseOutput>1</normaliseOutput>
<parasolCells_beta>0.</parasolCells_beta>
<parasolCells_tau>0.</parasolCells_tau>
<parasolCells_k>7.</parasolCells_k>
<amacrinCellsTemporalCutFrequency>2.0e+00</amacrinCellsTemporalCutFrequency>
<V0CompressionParameter>9.5e-01</V0CompressionParameter>
<localAdaptintegration_tau>0.</localAdaptintegration_tau>
<localAdaptintegration_k>7.</localAdaptintegration_k></IPLmagno>
</opencv_storage>
@@ -1,50 +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*/
#ifndef __OPENCV_BIOINSPIRED_HPP__
#define __OPENCV_BIOINSPIRED_HPP__
#include "opencv2/core.hpp"
#include "opencv2/bioinspired/retina.hpp"
#include "opencv2/bioinspired/retinafasttonemapping.hpp"
#endif
@@ -1,311 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2013
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
#ifndef __OPENCV_BIOINSPIRED_RETINA_HPP__
#define __OPENCV_BIOINSPIRED_RETINA_HPP__
/*
* Retina.hpp
*
* Created on: Jul 19, 2011
* Author: Alexandre Benoit
*/
#include "opencv2/core.hpp" // for all OpenCV core functionalities access, including cv::Exception support
namespace cv{
namespace bioinspired{
enum {
RETINA_COLOR_RANDOM, //!< each pixel position is either R, G or B in a random choice
RETINA_COLOR_DIAGONAL,//!< color sampling is RGBRGBRGB..., line 2 BRGBRGBRG..., line 3, GBRGBRGBR...
RETINA_COLOR_BAYER//!< standard bayer sampling
};
/**
* @class Retina a wrapper class which allows the Gipsa/Listic Labs model to be used with OpenCV.
* This retina model allows spatio-temporal image processing (applied on still images, video sequences).
* As a summary, these are the retina model properties:
* => It applies a spectral whithening (mid-frequency details enhancement)
* => high frequency spatio-temporal noise reduction
* => low frequency luminance to be reduced (luminance range compression)
* => local logarithmic luminance compression allows details to be enhanced in low light conditions
*
* USE : this model can be used basically for spatio-temporal video effects but also for :
* _using the getParvo method output matrix : texture analysiswith enhanced signal to noise ratio and enhanced details robust against input images luminance ranges
* _using the getMagno method output matrix : motion analysis also with the previously cited properties
*
* for more information, reer to the following papers :
* Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
* Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
*
* The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
* _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
* ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
* _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
* ====> more informations in the above cited Jeanny Heraults's book.
*/
class CV_EXPORTS Retina : public Algorithm {
public:
// parameters structure for better clarity, check explenations on the comments of methods : setupOPLandIPLParvoChannel and setupIPLMagnoChannel
struct RetinaParameters{
struct OPLandIplParvoParameters{ // Outer Plexiform Layer (OPL) and Inner Plexiform Layer Parvocellular (IplParvo) parameters
OPLandIplParvoParameters():colorMode(true),
normaliseOutput(true),
photoreceptorsLocalAdaptationSensitivity(0.75f),
photoreceptorsTemporalConstant(0.9f),
photoreceptorsSpatialConstant(0.53f),
horizontalCellsGain(0.01f),
hcellsTemporalConstant(0.5f),
hcellsSpatialConstant(7.f),
ganglionCellsSensitivity(0.75f){};// default setup
bool colorMode, normaliseOutput;
float photoreceptorsLocalAdaptationSensitivity, photoreceptorsTemporalConstant, photoreceptorsSpatialConstant, horizontalCellsGain, hcellsTemporalConstant, hcellsSpatialConstant, ganglionCellsSensitivity;
};
struct IplMagnoParameters{ // Inner Plexiform Layer Magnocellular channel (IplMagno)
IplMagnoParameters():
normaliseOutput(true),
parasolCells_beta(0.f),
parasolCells_tau(0.f),
parasolCells_k(7.f),
amacrinCellsTemporalCutFrequency(2.0f),
V0CompressionParameter(0.95f),
localAdaptintegration_tau(0.f),
localAdaptintegration_k(7.f){};// default setup
bool normaliseOutput;
float parasolCells_beta, parasolCells_tau, parasolCells_k, amacrinCellsTemporalCutFrequency, V0CompressionParameter, localAdaptintegration_tau, localAdaptintegration_k;
};
struct OPLandIplParvoParameters OPLandIplParvo;
struct IplMagnoParameters IplMagno;
};
/**
* retreive retina input buffer size
*/
virtual Size getInputSize()=0;
/**
* retreive retina output buffer size
*/
virtual Size getOutputSize()=0;
/**
* try to open an XML retina parameters file to adjust current retina instance setup
* => if the xml file does not exist, then default setup is applied
* => warning, Exceptions are thrown if read XML file is not valid
* @param retinaParameterFile : the parameters filename
* @param applyDefaultSetupOnFailure : set to true if an error must be thrown on error
*/
virtual void setup(String retinaParameterFile="", const bool applyDefaultSetupOnFailure=true)=0;
/**
* try to open an XML retina parameters file to adjust current retina instance setup
* => if the xml file does not exist, then default setup is applied
* => warning, Exceptions are thrown if read XML file is not valid
* @param fs : the open Filestorage which contains retina parameters
* @param applyDefaultSetupOnFailure : set to true if an error must be thrown on error
*/
virtual void setup(cv::FileStorage &fs, const bool applyDefaultSetupOnFailure=true)=0;
/**
* try to open an XML retina parameters file to adjust current retina instance setup
* => if the xml file does not exist, then default setup is applied
* => warning, Exceptions are thrown if read XML file is not valid
* @param newParameters : a parameters structures updated with the new target configuration
* @param applyDefaultSetupOnFailure : set to true if an error must be thrown on error
*/
virtual void setup(RetinaParameters newParameters)=0;
/**
* @return the current parameters setup
*/
virtual struct Retina::RetinaParameters getParameters()=0;
/**
* parameters setup display method
* @return a string which contains formatted parameters information
*/
virtual const String printSetup()=0;
/**
* write xml/yml formated parameters information
* @rparam fs : the filename of the xml file that will be open and writen with formatted parameters information
*/
virtual void write( String fs ) const=0;
/**
* write xml/yml formated parameters information
* @param fs : a cv::Filestorage object ready to be filled
*/
virtual void write( FileStorage& fs ) const=0;
/**
* setup the OPL and IPL parvo channels (see biologocal model)
* OPL is referred as Outer Plexiform Layer of the retina, it allows the spatio-temporal filtering which withens the spectrum and reduces spatio-temporal noise while attenuating global luminance (low frequency energy)
* IPL parvo is the OPL next processing stage, it refers to Inner Plexiform layer of the retina, it allows high contours sensitivity in foveal vision.
* for more informations, please have a look at the paper Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
* @param colorMode : specifies if (true) color is processed of not (false) to then processing gray level image
* @param normaliseOutput : specifies if (true) output is rescaled between 0 and 255 of not (false)
* @param photoreceptorsLocalAdaptationSensitivity: the photoreceptors sensitivity renage is 0-1 (more log compression effect when value increases)
* @param photoreceptorsTemporalConstant: the time constant of the first order low pass filter of the photoreceptors, use it to cut high temporal frequencies (noise or fast motion), unit is frames, typical value is 1 frame
* @param photoreceptorsSpatialConstant: the spatial constant of the first order low pass filter of the photoreceptors, use it to cut high spatial frequencies (noise or thick contours), unit is pixels, typical value is 1 pixel
* @param horizontalCellsGain: gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, then, the luminance is not filtered and is still reachable at the output, typicall value is 0
* @param HcellsTemporalConstant: the time constant of the first order low pass filter of the horizontal cells, use it to cut low temporal frequencies (local luminance variations), unit is frames, typical value is 1 frame, as the photoreceptors
* @param HcellsSpatialConstant: the spatial constant of the first order low pass filter of the horizontal cells, use it to cut low spatial frequencies (local luminance), unit is pixels, typical value is 5 pixel, this value is also used for local contrast computing when computing the local contrast adaptation at the ganglion cells level (Inner Plexiform Layer parvocellular channel model)
* @param ganglionCellsSensitivity: the compression strengh of the ganglion cells local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 230
*/
virtual void setupOPLandIPLParvoChannel(const bool colorMode=true, const bool normaliseOutput = true, const float photoreceptorsLocalAdaptationSensitivity=0.7, const float photoreceptorsTemporalConstant=0.5, const float photoreceptorsSpatialConstant=0.53, const float horizontalCellsGain=0, const float HcellsTemporalConstant=1, const float HcellsSpatialConstant=7, const float ganglionCellsSensitivity=0.7)=0;
/**
* set parameters values for the Inner Plexiform Layer (IPL) magnocellular channel
* this channel processes signals outpint from OPL processing stage in peripheral vision, it allows motion information enhancement. It is decorrelated from the details channel. See reference paper for more details.
* @param normaliseOutput : specifies if (true) output is rescaled between 0 and 255 of not (false)
* @param parasolCells_beta: the low pass filter gain used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), typical value is 0
* @param parasolCells_tau: the low pass filter time constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is frame, typical value is 0 (immediate response)
* @param parasolCells_k: the low pass filter spatial constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is pixels, typical value is 5
* @param amacrinCellsTemporalCutFrequency: the time constant of the first order high pass fiter of the magnocellular way (motion information channel), unit is frames, tipicall value is 5
* @param V0CompressionParameter: the compression strengh of the ganglion cells local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 200
* @param localAdaptintegration_tau: specifies the temporal constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
* @param localAdaptintegration_k: specifies the spatial constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
*/
virtual void setupIPLMagnoChannel(const bool normaliseOutput = true, const float parasolCells_beta=0, const float parasolCells_tau=0, const float parasolCells_k=7, const float amacrinCellsTemporalCutFrequency=1.2, const float V0CompressionParameter=0.95, const float localAdaptintegration_tau=0, const float localAdaptintegration_k=7)=0;
/**
* method which allows retina to be applied on an input image, after run, encapsulated retina module is ready to deliver its outputs using dedicated acccessors, see getParvo and getMagno methods
* @param inputImage : the input cv::Mat image to be processed, can be gray level or BGR coded in any format (from 8bit to 16bits)
*/
virtual void run(InputArray inputImage)=0;
/**
* method that applies a luminance correction (initially High Dynamic Range (HDR) tone mapping) using only the 2 local adaptation stages of the retina parvo channel : photoreceptors level and ganlion cells level. Spatio temporal filtering is applied but limited to temporal smoothing and eventually high frequencies attenuation. This is a lighter method than the one available using the regular run method. It is then faster but it does not include complete temporal filtering nor retina spectral whitening. Then, it can have a more limited effect on images with a very high dynamic range. This is an adptation of the original still image HDR tone mapping algorithm of David Alleyson, Sabine Susstruck and Laurence Meylan's work, please cite:
* -> Meylan L., Alleysson D., and Susstrunk S., A Model of Retinal Local Adaptation for the Tone Mapping of Color Filter Array Images, Journal of Optical Society of America, A, Vol. 24, N 9, September, 1st, 2007, pp. 2807-2816
@param inputImage the input image to process RGB or gray levels
@param outputToneMappedImage the output tone mapped image
*/
virtual void applyFastToneMapping(InputArray inputImage, OutputArray outputToneMappedImage)=0;
/**
* accessor of the details channel of the retina (models foveal vision)
* @param retinaOutput_parvo : the output buffer (reallocated if necessary), this output is rescaled for standard 8bits image processing use in OpenCV
*/
virtual void getParvo(OutputArray retinaOutput_parvo)=0;
/**
* accessor of the details channel of the retina (models foveal vision)
* @param retinaOutput_parvo : a cv::Mat header filled with the internal parvo buffer of the retina module. This output is the original retina filter model output, without any quantification or rescaling
*/
virtual void getParvoRAW(OutputArray retinaOutput_parvo)=0;
/**
* accessor of the motion channel of the retina (models peripheral vision)
* @param retinaOutput_magno : the output buffer (reallocated if necessary), this output is rescaled for standard 8bits image processing use in OpenCV
*/
virtual void getMagno(OutputArray retinaOutput_magno)=0;
/**
* accessor of the motion channel of the retina (models peripheral vision)
* @param retinaOutput_magno : a cv::Mat header filled with the internal retina magno buffer of the retina module. This output is the original retina filter model output, without any quantification or rescaling
*/
virtual void getMagnoRAW(OutputArray retinaOutput_magno)=0;
// original API level data accessors : get buffers addresses from a Mat header, similar to getParvoRAW and getMagnoRAW...
virtual const Mat getMagnoRAW() const=0;
virtual const Mat getParvoRAW() const=0;
/**
* activate color saturation as the final step of the color demultiplexing process
* -> this saturation is a sigmoide function applied to each channel of the demultiplexed image.
* @param saturateColors: boolean that activates color saturation (if true) or desactivate (if false)
* @param colorSaturationValue: the saturation factor
*/
virtual void setColorSaturation(const bool saturateColors=true, const float colorSaturationValue=4.0)=0;
/**
* clear all retina buffers (equivalent to opening the eyes after a long period of eye close ;o)
*/
virtual void clearBuffers()=0;
/**
* Activate/desactivate the Magnocellular pathway processing (motion information extraction), by default, it is activated
* @param activate: true if Magnocellular output should be activated, false if not
*/
virtual void activateMovingContoursProcessing(const bool activate)=0;
/**
* Activate/desactivate the Parvocellular pathway processing (contours information extraction), by default, it is activated
* @param activate: true if Parvocellular (contours information extraction) output should be activated, false if not
*/
virtual void activateContoursProcessing(const bool activate)=0;
};
CV_EXPORTS Ptr<Retina> createRetina(Size inputSize);
CV_EXPORTS Ptr<Retina> createRetina(Size inputSize, const bool colorMode, int colorSamplingMethod=RETINA_COLOR_BAYER, const bool useRetinaLogSampling=false, const double reductionFactor=1.0, const double samplingStrenght=10.0);
CV_EXPORTS Ptr<Retina> createRetina_OCL(Size inputSize);
CV_EXPORTS Ptr<Retina> createRetina_OCL(Size inputSize, const bool colorMode, int colorSamplingMethod=RETINA_COLOR_BAYER, const bool useRetinaLogSampling=false, const double reductionFactor=1.0, const double samplingStrenght=10.0);
}
}
#endif /* __OPENCV_BIOINSPIRED_RETINA_HPP__ */
@@ -1,121 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2013
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
**
**
**
**
** This class is based on image processing tools of the author and already used within the Retina class (this is the same code as method retina::applyFastToneMapping, but in an independent class, it is ligth from a memory requirement point of view). It implements an adaptation of the efficient tone mapping algorithm propose by David Alleyson, Sabine Susstruck and Laurence Meylan's work, please cite:
** -> Meylan L., Alleysson D., and Susstrunk S., A Model of Retinal Local Adaptation for the Tone Mapping of Color Filter Array Images, Journal of Optical Society of America, A, Vol. 24, N 9, September, 1st, 2007, pp. 2807-2816
**
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
#ifndef __OPENCV_BIOINSPIRED_RETINAFASTTONEMAPPING_HPP__
#define __OPENCV_BIOINSPIRED_RETINAFASTTONEMAPPING_HPP__
/*
* retinafasttonemapping.hpp
*
* Created on: May 26, 2013
* Author: Alexandre Benoit
*/
#include "opencv2/core.hpp" // for all OpenCV core functionalities access, including cv::Exception support
namespace cv{
namespace bioinspired{
/**
* @class RetinaFastToneMappingImpl a wrapper class which allows the tone mapping algorithm of Meylan&al(2007) to be used with OpenCV.
* This algorithm is already implemented in thre Retina class (retina::applyFastToneMapping) but used it does not require all the retina model to be allocated. This allows a light memory use for low memory devices (smartphones, etc.
* As a summary, these are the model properties:
* => 2 stages of local luminance adaptation with a different local neighborhood for each.
* => first stage models the retina photorecetors local luminance adaptation
* => second stage models th ganglion cells local information adaptation
* => compared to the initial publication, this class uses spatio-temporal low pass filters instead of spatial only filters.
* ====> this can help noise robustness and temporal stability for video sequence use cases.
* for more information, read to the following papers :
* Meylan L., Alleysson D., and Susstrunk S., A Model of Retinal Local Adaptation for the Tone Mapping of Color Filter Array Images, Journal of Optical Society of America, A, Vol. 24, N 9, September, 1st, 2007, pp. 2807-2816Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
* regarding spatio-temporal filter and the bigger retina model :
* Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
*/
class CV_EXPORTS RetinaFastToneMapping : public Algorithm
{
public:
/**
* method that applies a luminance correction (initially High Dynamic Range (HDR) tone mapping) using only the 2 local adaptation stages of the retina parvocellular channel : photoreceptors level and ganlion cells level. Spatio temporal filtering is applied but limited to temporal smoothing and eventually high frequencies attenuation. This is a lighter method than the one available using the regular retina::run method. It is then faster but it does not include complete temporal filtering nor retina spectral whitening. Then, it can have a more limited effect on images with a very high dynamic range. This is an adptation of the original still image HDR tone mapping algorithm of David Alleyson, Sabine Susstruck and Laurence Meylan's work, please cite:
* -> Meylan L., Alleysson D., and Susstrunk S., A Model of Retinal Local Adaptation for the Tone Mapping of Color Filter Array Images, Journal of Optical Society of America, A, Vol. 24, N 9, September, 1st, 2007, pp. 2807-2816
@param inputImage the input image to process RGB or gray levels
@param outputToneMappedImage the output tone mapped image
*/
virtual void applyFastToneMapping(InputArray inputImage, OutputArray outputToneMappedImage)=0;
/**
* setup method that updates tone mapping behaviors by adjusing the local luminance computation area
* @param photoreceptorsNeighborhoodRadius the first stage local adaptation area
* @param ganglioncellsNeighborhoodRadius the second stage local adaptation area
* @param meanLuminanceModulatorK the factor applied to modulate the meanLuminance information (default is 1, see reference paper)
*/
virtual void setup(const float photoreceptorsNeighborhoodRadius=3.f, const float ganglioncellsNeighborhoodRadius=1.f, const float meanLuminanceModulatorK=1.f)=0;
};
CV_EXPORTS Ptr<RetinaFastToneMapping> createRetinaFastToneMapping(Size inputSize);
}
}
#endif /* __OPENCV_BIOINSPIRED_RETINAFASTTONEMAPPING_HPP__ */
@@ -1,888 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
#include "precomp.hpp"
#include <iostream>
#include <cstdlib>
#include "basicretinafilter.hpp"
#include <cmath>
namespace cv
{
namespace bioinspired
{
// @author Alexandre BENOIT, benoit.alexandre.vision@gmail.com, LISTIC : www.listic.univ-savoie.fr Gipsa-Lab, France: www.gipsa-lab.inpg.fr/
//////////////////////////////////////////////////////////
// BASIC RETINA FILTER
//////////////////////////////////////////////////////////
// Constructor and Desctructor of the basic retina filter
BasicRetinaFilter::BasicRetinaFilter(const unsigned int NBrows, const unsigned int NBcolumns, const unsigned int parametersListSize, const bool useProgressiveFilter)
:_filterOutput(NBrows, NBcolumns),
_localBuffer(NBrows*NBcolumns),
_filteringCoeficientsTable(3*parametersListSize),
_progressiveSpatialConstant(0),// pointer to a local table containing local spatial constant (allocated with the object)
_progressiveGain(0)
{
#ifdef T_BASIC_RETINA_ELEMENT_DEBUG
std::cout<<"BasicRetinaFilter::BasicRetinaFilter: new filter, size="<<NBrows<<", "<<NBcolumns<<std::endl;
#endif
_halfNBrows=_filterOutput.getNBrows()/2;
_halfNBcolumns=_filterOutput.getNBcolumns()/2;
if (useProgressiveFilter)
{
#ifdef T_BASIC_RETINA_ELEMENT_DEBUG
std::cout<<"BasicRetinaFilter::BasicRetinaFilter: _progressiveSpatialConstant_Tbuffer"<<std::endl;
#endif
_progressiveSpatialConstant.resize(_filterOutput.size());
#ifdef T_BASIC_RETINA_ELEMENT_DEBUG
std::cout<<"BasicRetinaFilter::BasicRetinaFilter: new _progressiveGain_Tbuffer"<<NBrows<<", "<<NBcolumns<<std::endl;
#endif
_progressiveGain.resize(_filterOutput.size());
}
#ifdef T_BASIC_RETINA_ELEMENT_DEBUG
std::cout<<"BasicRetinaFilter::BasicRetinaFilter: new filter, size="<<NBrows<<", "<<NBcolumns<<std::endl;
#endif
// set default values
_maxInputValue=256.0;
// reset all buffers
clearAllBuffers();
#ifdef T_BASIC_RETINA_ELEMENT_DEBUG
std::cout<<"BasicRetinaFilter::Init BasicRetinaElement at specified frame size OK, size="<<this->size()<<std::endl;
#endif
}
BasicRetinaFilter::~BasicRetinaFilter()
{
#ifdef BASIC_RETINA_ELEMENT_DEBUG
std::cout<<"BasicRetinaFilter::BasicRetinaElement Deleted OK"<<std::endl;
#endif
}
////////////////////////////////////
// functions of the basic filter
////////////////////////////////////
// resize all allocated buffers
void BasicRetinaFilter::resize(const unsigned int NBrows, const unsigned int NBcolumns)
{
std::cout<<"BasicRetinaFilter::resize( "<<NBrows<<", "<<NBcolumns<<")"<<std::endl;
// resizing buffers
_filterOutput.resizeBuffer(NBrows, NBcolumns);
// updating variables
_halfNBrows=_filterOutput.getNBrows()/2;
_halfNBcolumns=_filterOutput.getNBcolumns()/2;
_localBuffer.resize(_filterOutput.size());
// in case of spatial adapted filter
if (_progressiveSpatialConstant.size()>0)
{
_progressiveSpatialConstant.resize(_filterOutput.size());
_progressiveGain.resize(_filterOutput.size());
}
// reset buffers
clearAllBuffers();
}
// Change coefficients table
void BasicRetinaFilter::setLPfilterParameters(const float beta, const float tau, const float desired_k, const unsigned int filterIndex)
{
float _beta = beta+tau;
float k=desired_k;
// check if the spatial constant is correct (avoid 0 value to avoid division by 0)
if (desired_k<=0)
{
k=0.001f;
std::cerr<<"BasicRetinaFilter::spatial constant of the low pass filter must be superior to zero !!! correcting parameter setting to 0,001"<<std::endl;
}
float _alpha = k*k;
float _mu = 0.8f;
unsigned int tableOffset=filterIndex*3;
if (k<=0)
{
std::cerr<<"BasicRetinaFilter::spatial filtering coefficient must be superior to zero, correcting value to 0.01"<<std::endl;
_alpha=0.0001f;
}
float _temp = (1.0f+_beta)/(2.0f*_mu*_alpha);
float a = _filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)std::sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f);
_filteringCoeficientsTable[1+tableOffset]=(1.0f-a)*(1.0f-a)*(1.0f-a)*(1.0f-a)/(1.0f+_beta);
_filteringCoeficientsTable[2+tableOffset] =tau;
//std::cout<<"BasicRetinaFilter::normal:"<<(1.0-a)*(1.0-a)*(1.0-a)*(1.0-a)/(1.0+_beta)<<" -> old:"<<(1-a)*(1-a)*(1-a)*(1-a)/(1+_beta)<<std::endl;
//std::cout<<"BasicRetinaFilter::a="<<a<<", gain="<<_filteringCoeficientsTable[1+tableOffset]<<", tau="<<tau<<std::endl;
}
void BasicRetinaFilter::setProgressiveFilterConstants_CentredAccuracy(const float beta, const float tau, const float alpha0, const unsigned int filterIndex)
{
// check if dedicated buffers are already allocated, if not create them
if (_progressiveSpatialConstant.size()!=_filterOutput.size())
{
_progressiveSpatialConstant.resize(_filterOutput.size());
_progressiveGain.resize(_filterOutput.size());
}
float _beta = beta+tau;
float _mu=0.8f;
if (alpha0<=0)
{
std::cerr<<"BasicRetinaFilter::spatial filtering coefficient must be superior to zero, correcting value to 0.01"<<std::endl;
//alpha0=0.0001;
}
unsigned int tableOffset=filterIndex*3;
float _alpha=0.8f;
float _temp = (1.0f+_beta)/(2.0f*_mu*_alpha);
float a=_filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)std::sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f);
_filteringCoeficientsTable[tableOffset+1]=(1.0f-a)*(1.0f-a)*(1.0f-a)*(1.0f-a)/(1.0f+_beta);
_filteringCoeficientsTable[tableOffset+2] =tau;
float commonFactor=alpha0/(float)std::sqrt(_halfNBcolumns*_halfNBcolumns+_halfNBrows*_halfNBrows+1.0f);
//memset(_progressiveSpatialConstant, 255, _filterOutput.getNBpixels());
for (unsigned int idColumn=0;idColumn<_halfNBcolumns; ++idColumn)
for (unsigned int idRow=0;idRow<_halfNBrows; ++idRow)
{
// computing local spatial constant
float localSpatialConstantValue=commonFactor*std::sqrt((float)(idColumn*idColumn)+(float)(idRow*idRow));
if (localSpatialConstantValue>1.0f)
localSpatialConstantValue=1.0f;
_progressiveSpatialConstant[_halfNBcolumns-1+idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1+idRow)]=localSpatialConstantValue;
_progressiveSpatialConstant[_halfNBcolumns-1-idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1+idRow)]=localSpatialConstantValue;
_progressiveSpatialConstant[_halfNBcolumns-1+idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1-idRow)]=localSpatialConstantValue;
_progressiveSpatialConstant[_halfNBcolumns-1-idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1-idRow)]=localSpatialConstantValue;
// computing local gain
float localGain=(1-localSpatialConstantValue)*(1-localSpatialConstantValue)*(1-localSpatialConstantValue)*(1-localSpatialConstantValue)/(1+_beta);
_progressiveGain[_halfNBcolumns-1+idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1+idRow)]=localGain;
_progressiveGain[_halfNBcolumns-1-idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1+idRow)]=localGain;
_progressiveGain[_halfNBcolumns-1+idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1-idRow)]=localGain;
_progressiveGain[_halfNBcolumns-1-idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1-idRow)]=localGain;
//std::cout<<commonFactor<<", "<<std::sqrt((_halfNBcolumns-1-idColumn)+(_halfNBrows-idRow-1))<<", "<<(_halfNBcolumns-1-idColumn)<<", "<<(_halfNBrows-idRow-1)<<", "<<localSpatialConstantValue<<std::endl;
}
}
void BasicRetinaFilter::setProgressiveFilterConstants_CustomAccuracy(const float beta, const float tau, const float k, const std::valarray<float> &accuracyMap, const unsigned int filterIndex)
{
if (accuracyMap.size()!=_filterOutput.size())
{
std::cerr<<"BasicRetinaFilter::setProgressiveFilterConstants_CustomAccuracy: error: input accuracy map does not match filter size, init skept"<<std::endl;
return ;
}
// check if dedicated buffers are already allocated, if not create them
if (_progressiveSpatialConstant.size()!=_filterOutput.size())
{
_progressiveSpatialConstant.resize(accuracyMap.size());
_progressiveGain.resize(accuracyMap.size());
}
float _beta = beta+tau;
float _alpha=k*k;
float _mu=0.8f;
if (k<=0)
{
std::cerr<<"BasicRetinaFilter::spatial filtering coefficient must be superior to zero, correcting value to 0.01"<<std::endl;
//alpha0=0.0001;
}
unsigned int tableOffset=filterIndex*3;
float _temp = (1.0f+_beta)/(2.0f*_mu*_alpha);
float a=_filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)std::sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f);
_filteringCoeficientsTable[tableOffset+1]=(1.0f-a)*(1.0f-a)*(1.0f-a)*(1.0f-a)/(1.0f+_beta);
_filteringCoeficientsTable[tableOffset+2] =tau;
//memset(_progressiveSpatialConstant, 255, _filterOutput.getNBpixels());
for (unsigned int idColumn=0;idColumn<_filterOutput.getNBcolumns(); ++idColumn)
for (unsigned int idRow=0;idRow<_filterOutput.getNBrows(); ++idRow)
{
// computing local spatial constant
unsigned int index=idColumn+idRow*_filterOutput.getNBcolumns();
float localSpatialConstantValue=_a*accuracyMap[index];
if (localSpatialConstantValue>1)
localSpatialConstantValue=1;
_progressiveSpatialConstant[index]=localSpatialConstantValue;
// computing local gain
float localGain=(1.0f-localSpatialConstantValue)*(1.0f-localSpatialConstantValue)*(1.0f-localSpatialConstantValue)*(1.0f-localSpatialConstantValue)/(1.0f+_beta);
_progressiveGain[index]=localGain;
//std::cout<<commonFactor<<", "<<std::sqrt((_halfNBcolumns-1-idColumn)+(_halfNBrows-idRow-1))<<", "<<(_halfNBcolumns-1-idColumn)<<", "<<(_halfNBrows-idRow-1)<<", "<<localSpatialConstantValue<<std::endl;
}
}
///////////////////////////////////////////////////////////////////////
/// Local luminance adaptation functions
// run local adaptation filter and save result in _filterOutput
const std::valarray<float> &BasicRetinaFilter::runFilter_LocalAdapdation(const std::valarray<float> &inputFrame, const std::valarray<float> &localLuminance)
{
_localLuminanceAdaptation(get_data(inputFrame), get_data(localLuminance), &_filterOutput[0]);
return _filterOutput;
}
// run local adaptation filter at a specific output adress
void BasicRetinaFilter::runFilter_LocalAdapdation(const std::valarray<float> &inputFrame, const std::valarray<float> &localLuminance, std::valarray<float> &outputFrame)
{
_localLuminanceAdaptation(get_data(inputFrame), get_data(localLuminance), &outputFrame[0]);
}
// run local adaptation filter and save result in _filterOutput with autonomous low pass filtering before adaptation
const std::valarray<float> &BasicRetinaFilter::runFilter_LocalAdapdation_autonomous(const std::valarray<float> &inputFrame)
{
_spatiotemporalLPfilter(get_data(inputFrame), &_filterOutput[0]);
_localLuminanceAdaptation(get_data(inputFrame), &_filterOutput[0], &_filterOutput[0]);
return _filterOutput;
}
// run local adaptation filter at a specific output adress with autonomous low pass filtering before adaptation
void BasicRetinaFilter::runFilter_LocalAdapdation_autonomous(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame)
{
_spatiotemporalLPfilter(get_data(inputFrame), &_filterOutput[0]);
_localLuminanceAdaptation(get_data(inputFrame), &_filterOutput[0], &outputFrame[0]);
}
// local luminance adaptation of the input in regard of localLuminance buffer, the input is rewrited and becomes the output
void BasicRetinaFilter::_localLuminanceAdaptation(float *inputOutputFrame, const float *localLuminance)
{
_localLuminanceAdaptation(inputOutputFrame, localLuminance, inputOutputFrame, false);
/* const float *localLuminancePTR=localLuminance;
float *inputOutputFramePTR=inputOutputFrame;
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel, ++inputOutputFramePTR)
{
float X0=*(localLuminancePTR++)*_localLuminanceFactor+_localLuminanceAddon;
*(inputOutputFramePTR) = (_maxInputValue+X0)**inputOutputFramePTR/(*inputOutputFramePTR +X0+0.00000000001);
}
*/
}
// local luminance adaptation of the input in regard of localLuminance buffer
void BasicRetinaFilter::_localLuminanceAdaptation(const float *inputFrame, const float *localLuminance, float *outputFrame, const bool updateLuminanceMean)
{
if (updateLuminanceMean)
{ float meanLuminance=0;
const float *luminancePTR=inputFrame;
for (unsigned int i=0;i<_filterOutput.getNBpixels();++i)
meanLuminance+=*(luminancePTR++);
meanLuminance/=_filterOutput.getNBpixels();
//float tempMeanValue=meanLuminance+_meanInputValue*_tau;
updateCompressionParameter(meanLuminance);
}
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(0,_filterOutput.getNBpixels()), Parallel_localAdaptation(localLuminance, inputFrame, outputFrame, _localLuminanceFactor, _localLuminanceAddon, _maxInputValue));
#else
//std::cout<<meanLuminance<<std::endl;
const float *localLuminancePTR=localLuminance;
const float *inputFramePTR=inputFrame;
float *outputFramePTR=outputFrame;
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel, ++inputFramePTR, ++outputFramePTR)
{
float X0=*(localLuminancePTR++)*_localLuminanceFactor+_localLuminanceAddon;
// TODO : the following line can lead to a divide by zero ! A small offset is added, take care if the offset is too large in case of High Dynamic Range images which can use very small values...
*(outputFramePTR) = (_maxInputValue+X0)**inputFramePTR/(*inputFramePTR +X0+0.00000000001);
//std::cout<<"BasicRetinaFilter::inputFrame[IDpixel]=%f, X0=%f, outputFrame[IDpixel]=%f\n", inputFrame[IDpixel], X0, outputFrame[IDpixel]);
}
#endif
}
// local adaptation applied on a range of values which can be positive and negative
void BasicRetinaFilter::_localLuminanceAdaptationPosNegValues(const float *inputFrame, const float *localLuminance, float *outputFrame)
{
const float *localLuminancePTR=localLuminance;
const float *inputFramePTR=inputFrame;
float *outputFramePTR=outputFrame;
float factor=_maxInputValue*2.0f/(float)CV_PI;
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel, ++inputFramePTR)
{
float X0=*(localLuminancePTR++)*_localLuminanceFactor+_localLuminanceAddon;
*(outputFramePTR++) = factor*atan(*inputFramePTR/X0);//(_maxInputValue+X0)**inputFramePTR/(*inputFramePTR +X0);
//std::cout<<"BasicRetinaFilter::inputFrame[IDpixel]=%f, X0=%f, outputFrame[IDpixel]=%f\n", inputFrame[IDpixel], X0, outputFrame[IDpixel]);
}
}
///////////////////////////////////////////////////////////////////////
/// Spatio temporal Low Pass filter functions
// run LP filter and save result in the basic retina element buffer
const std::valarray<float> &BasicRetinaFilter::runFilter_LPfilter(const std::valarray<float> &inputFrame, const unsigned int filterIndex)
{
_spatiotemporalLPfilter(get_data(inputFrame), &_filterOutput[0], filterIndex);
return _filterOutput;
}
// run LP filter for a new frame input and save result at a specific output adress
void BasicRetinaFilter::runFilter_LPfilter(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame, const unsigned int filterIndex)
{
_spatiotemporalLPfilter(get_data(inputFrame), &outputFrame[0], filterIndex);
}
// run LP filter on the input data and rewrite it
void BasicRetinaFilter::runFilter_LPfilter_Autonomous(std::valarray<float> &inputOutputFrame, const unsigned int filterIndex)
{
unsigned int coefTableOffset=filterIndex*3;
/**********/
_a=_filteringCoeficientsTable[coefTableOffset];
_gain=_filteringCoeficientsTable[1+coefTableOffset];
_tau=_filteringCoeficientsTable[2+coefTableOffset];
// launch the serie of 1D directional filters in order to compute the 2D low pass filter
_horizontalCausalFilter(&inputOutputFrame[0], 0, _filterOutput.getNBrows());
_horizontalAnticausalFilter(&inputOutputFrame[0], 0, _filterOutput.getNBrows());
_verticalCausalFilter(&inputOutputFrame[0], 0, _filterOutput.getNBcolumns());
_verticalAnticausalFilter_multGain(&inputOutputFrame[0], 0, _filterOutput.getNBcolumns());
}
// run LP filter for a new frame input and save result at a specific output adress
void BasicRetinaFilter::_spatiotemporalLPfilter(const float *inputFrame, float *outputFrame, const unsigned int filterIndex)
{
unsigned int coefTableOffset=filterIndex*3;
/**********/
_a=_filteringCoeficientsTable[coefTableOffset];
_gain=_filteringCoeficientsTable[1+coefTableOffset];
_tau=_filteringCoeficientsTable[2+coefTableOffset];
// launch the serie of 1D directional filters in order to compute the 2D low pass filter
_horizontalCausalFilter_addInput(inputFrame, outputFrame, 0,_filterOutput.getNBrows());
_horizontalAnticausalFilter(outputFrame, 0, _filterOutput.getNBrows());
_verticalCausalFilter(outputFrame, 0, _filterOutput.getNBcolumns());
_verticalAnticausalFilter_multGain(outputFrame, 0, _filterOutput.getNBcolumns());
}
// run SQUARING LP filter for a new frame input and save result at a specific output adress
float BasicRetinaFilter::_squaringSpatiotemporalLPfilter(const float *inputFrame, float *outputFrame, const unsigned int filterIndex)
{
unsigned int coefTableOffset=filterIndex*3;
/**********/
_a=_filteringCoeficientsTable[coefTableOffset];
_gain=_filteringCoeficientsTable[1+coefTableOffset];
_tau=_filteringCoeficientsTable[2+coefTableOffset];
// launch the serie of 1D directional filters in order to compute the 2D low pass filter
_squaringHorizontalCausalFilter(inputFrame, outputFrame, 0, _filterOutput.getNBrows());
_horizontalAnticausalFilter(outputFrame, 0, _filterOutput.getNBrows());
_verticalCausalFilter(outputFrame, 0, _filterOutput.getNBcolumns());
return _verticalAnticausalFilter_returnMeanValue(outputFrame, 0, _filterOutput.getNBcolumns());
}
/////////////////////////////////////////////////
// standard version of the 1D low pass filters
// horizontal causal filter which adds the input inside
void BasicRetinaFilter::_horizontalCausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{
//#pragma omp parallel for
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{
register float* outputPTR=outputFrame+(IDrowStart+IDrow)*_filterOutput.getNBcolumns();
register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{
result = *(outputPTR)+ _a* result;
*(outputPTR++) = result;
}
}
}
// horizontal causal filter which adds the input inside
void BasicRetinaFilter::_horizontalCausalFilter_addInput(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDrowStart,IDrowEnd), Parallel_horizontalCausalFilter_addInput(inputFrame, outputFrame, IDrowStart, _filterOutput.getNBcolumns(), _a, _tau));
#else
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{
register float* outputPTR=outputFrame+(IDrowStart+IDrow)*_filterOutput.getNBcolumns();
register const float* inputPTR=inputFrame+(IDrowStart+IDrow)*_filterOutput.getNBcolumns();
register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{
result = *(inputPTR++) + _tau**(outputPTR)+ _a* result;
*(outputPTR++) = result;
}
}
#endif
}
// horizontal anticausal filter (basic way, no add on)
void BasicRetinaFilter::_horizontalAnticausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDrowStart,IDrowEnd), Parallel_horizontalAnticausalFilter(outputFrame, IDrowEnd, _filterOutput.getNBcolumns(), _a ));
#else
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{
register float* outputPTR=outputFrame+(IDrowEnd-IDrow)*(_filterOutput.getNBcolumns())-1;
register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{
result = *(outputPTR)+ _a* result;
*(outputPTR--) = result;
}
}
#endif
}
// horizontal anticausal filter which multiplies the output by _gain
void BasicRetinaFilter::_horizontalAnticausalFilter_multGain(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{
//#pragma omp parallel for
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{
register float* outputPTR=outputFrame+(IDrowEnd-IDrow)*(_filterOutput.getNBcolumns())-1;
register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{
result = *(outputPTR)+ _a* result;
*(outputPTR--) = _gain*result;
}
}
}
// vertical anticausal filter
void BasicRetinaFilter::_verticalCausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDcolumnStart,IDcolumnEnd), Parallel_verticalCausalFilter(outputFrame, _filterOutput.getNBrows(), _filterOutput.getNBcolumns(), _a ));
#else
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{
register float result=0;
register float *outputPTR=outputFrame+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{
result = *(outputPTR) + _a * result;
*(outputPTR) = result;
outputPTR+=_filterOutput.getNBcolumns();
}
}
#endif
}
// vertical anticausal filter (basic way, no add on)
void BasicRetinaFilter::_verticalAnticausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{
float* offset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
//#pragma omp parallel for
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{
register float result=0;
register float *outputPTR=offset+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{
result = *(outputPTR) + _a * result;
*(outputPTR) = result;
outputPTR-=_filterOutput.getNBcolumns();
}
}
}
// vertical anticausal filter which multiplies the output by _gain
void BasicRetinaFilter::_verticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDcolumnStart,IDcolumnEnd), Parallel_verticalAnticausalFilter_multGain(outputFrame, _filterOutput.getNBrows(), _filterOutput.getNBcolumns(), _a, _gain ));
#else
float* offset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
//#pragma omp parallel for
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{
register float result=0;
register float *outputPTR=offset+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{
result = *(outputPTR) + _a * result;
*(outputPTR) = _gain*result;
outputPTR-=_filterOutput.getNBcolumns();
}
}
#endif
}
/////////////////////////////////////////
// specific modifications of 1D filters
// -> squaring horizontal causal filter
void BasicRetinaFilter::_squaringHorizontalCausalFilter(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{
register float* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns();
register const float* inputPTR=inputFrame+IDrowStart*_filterOutput.getNBcolumns();
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{
register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{
result = *(inputPTR)**(inputPTR) + _tau**(outputPTR)+ _a* result;
*(outputPTR++) = result;
++inputPTR;
}
}
}
// vertical anticausal filter that returns the mean value of its result
float BasicRetinaFilter::_verticalAnticausalFilter_returnMeanValue(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{
register float meanValue=0;
float* offset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{
register float result=0;
register float *outputPTR=offset+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{
result = *(outputPTR) + _a * result;
*(outputPTR) = _gain*result;
meanValue+=*(outputPTR);
outputPTR-=_filterOutput.getNBcolumns();
}
}
return meanValue/(float)_filterOutput.getNBpixels();
}
// LP filter with integration in specific areas (regarding true values of a binary parameters image)
void BasicRetinaFilter::_localSquaringSpatioTemporalLPfilter(const float *inputFrame, float *LPfilterOutput, const unsigned int *integrationAreas, const unsigned int filterIndex)
{
unsigned int coefTableOffset=filterIndex*3;
_a=_filteringCoeficientsTable[coefTableOffset+0];
_gain=_filteringCoeficientsTable[coefTableOffset+1];
_tau=_filteringCoeficientsTable[coefTableOffset+2];
// launch the serie of 1D directional filters in order to compute the 2D low pass filter
_local_squaringHorizontalCausalFilter(inputFrame, LPfilterOutput, 0, _filterOutput.getNBrows(), integrationAreas);
_local_horizontalAnticausalFilter(LPfilterOutput, 0, _filterOutput.getNBrows(), integrationAreas);
_local_verticalCausalFilter(LPfilterOutput, 0, _filterOutput.getNBcolumns(), integrationAreas);
_local_verticalAnticausalFilter_multGain(LPfilterOutput, 0, _filterOutput.getNBcolumns(), integrationAreas);
}
// LP filter on specific parts of the picture instead of all the image
// same functions (some of them) but take a binary flag to allow integration, false flag means, no data change at the output...
// this function take an image in input and squares it befor computing
void BasicRetinaFilter::_local_squaringHorizontalCausalFilter(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const unsigned int *integrationAreas)
{
register float* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns();
register const float* inputPTR=inputFrame+IDrowStart*_filterOutput.getNBcolumns();
const unsigned int *integrationAreasPTR=integrationAreas;
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{
register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{
if (*(integrationAreasPTR++))
result = *(inputPTR)**(inputPTR) + _tau**(outputPTR)+ _a* result;
else
result=0;
*(outputPTR++) = result;
++inputPTR;
}
}
}
void BasicRetinaFilter::_local_horizontalAnticausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const unsigned int *integrationAreas)
{
register float* outputPTR=outputFrame+IDrowEnd*(_filterOutput.getNBcolumns())-1;
const unsigned int *integrationAreasPTR=integrationAreas;
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{
register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{
if (*(integrationAreasPTR++))
result = *(outputPTR)+ _a* result;
else
result=0;
*(outputPTR--) = result;
}
}
}
void BasicRetinaFilter::_local_verticalCausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas)
{
const unsigned int *integrationAreasPTR=integrationAreas;
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{
register float result=0;
register float *outputPTR=outputFrame+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{
if (*(integrationAreasPTR++))
result = *(outputPTR)+ _a* result;
else
result=0;
*(outputPTR) = result;
outputPTR+=_filterOutput.getNBcolumns();
}
}
}
// this functions affects _gain at the output
void BasicRetinaFilter::_local_verticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas)
{
const unsigned int *integrationAreasPTR=integrationAreas;
float* offset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{
register float result=0;
register float *outputPTR=offset+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{
if (*(integrationAreasPTR++))
result = *(outputPTR)+ _a* result;
else
result=0;
*(outputPTR) = _gain*result;
outputPTR-=_filterOutput.getNBcolumns();
}
}
}
////////////////////////////////////////////////////
// run LP filter for a new frame input and save result at a specific output adress
// -> USE IRREGULAR SPATIAL CONSTANT
// irregular filter computed from a buffer and rewrites it
void BasicRetinaFilter::_spatiotemporalLPfilter_Irregular(float *inputOutputFrame, const unsigned int filterIndex)
{
if (_progressiveGain.size()==0)
{
std::cerr<<"BasicRetinaFilter::runProgressiveFilter: cannot perform filtering, no progressive filter settled up"<<std::endl;
return;
}
unsigned int coefTableOffset=filterIndex*3;
/**********/
//_a=_filteringCoeficientsTable[coefTableOffset];
_tau=_filteringCoeficientsTable[2+coefTableOffset];
// launch the serie of 1D directional filters in order to compute the 2D low pass filter
_horizontalCausalFilter_Irregular(inputOutputFrame, 0, (int)_filterOutput.getNBrows());
_horizontalAnticausalFilter_Irregular(inputOutputFrame, 0, (int)_filterOutput.getNBrows(), &_progressiveSpatialConstant[0]);
_verticalCausalFilter_Irregular(inputOutputFrame, 0, (int)_filterOutput.getNBcolumns(), &_progressiveSpatialConstant[0]);
_verticalAnticausalFilter_Irregular_multGain(inputOutputFrame, 0, (int)_filterOutput.getNBcolumns());
}
// irregular filter computed from a buffer and puts result on another
void BasicRetinaFilter::_spatiotemporalLPfilter_Irregular(const float *inputFrame, float *outputFrame, const unsigned int filterIndex)
{
if (_progressiveGain.size()==0)
{
std::cerr<<"BasicRetinaFilter::runProgressiveFilter: cannot perform filtering, no progressive filter settled up"<<std::endl;
return;
}
unsigned int coefTableOffset=filterIndex*3;
/**********/
//_a=_filteringCoeficientsTable[coefTableOffset];
_tau=_filteringCoeficientsTable[2+coefTableOffset];
// launch the serie of 1D directional filters in order to compute the 2D low pass filter
_horizontalCausalFilter_Irregular_addInput(inputFrame, outputFrame, 0, (int)_filterOutput.getNBrows());
_horizontalAnticausalFilter_Irregular(outputFrame, 0, (int)_filterOutput.getNBrows(), &_progressiveSpatialConstant[0]);
_verticalCausalFilter_Irregular(outputFrame, 0, (int)_filterOutput.getNBcolumns(), &_progressiveSpatialConstant[0]);
_verticalAnticausalFilter_Irregular_multGain(outputFrame, 0, (int)_filterOutput.getNBcolumns());
}
// 1D filters with irregular spatial constant
// horizontal causal filter wich runs on its input buffer
void BasicRetinaFilter::_horizontalCausalFilter_Irregular(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{
register float* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns();
register const float* spatialConstantPTR=&_progressiveSpatialConstant[0]+IDrowStart*_filterOutput.getNBcolumns();
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{
register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{
result = *(outputPTR)+ *(spatialConstantPTR++)* result;
*(outputPTR++) = result;
}
}
}
// horizontal causal filter with add input
void BasicRetinaFilter::_horizontalCausalFilter_Irregular_addInput(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{
register float* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns();
register const float* inputPTR=inputFrame+IDrowStart*_filterOutput.getNBcolumns();
register const float* spatialConstantPTR=&_progressiveSpatialConstant[0]+IDrowStart*_filterOutput.getNBcolumns();
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{
register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{
result = *(inputPTR++) + _tau**(outputPTR)+ *(spatialConstantPTR++)* result;
*(outputPTR++) = result;
}
}
}
// horizontal anticausal filter (basic way, no add on)
void BasicRetinaFilter::_horizontalAnticausalFilter_Irregular(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const float *spatialConstantBuffer)
{
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDrowStart,IDrowEnd), Parallel_horizontalAnticausalFilter_Irregular(outputFrame, spatialConstantBuffer, IDrowEnd, _filterOutput.getNBcolumns()));
#else
register float* outputPTR=outputFrame+IDrowEnd*(_filterOutput.getNBcolumns())-1;
register const float* spatialConstantPTR=spatialConstantBuffer+IDrowEnd*(_filterOutput.getNBcolumns())-1;
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{
register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{
result = *(outputPTR)+ *(spatialConstantPTR--)* result;
*(outputPTR--) = result;
}
}
#endif
}
// vertical anticausal filter
void BasicRetinaFilter::_verticalCausalFilter_Irregular(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const float *spatialConstantBuffer)
{
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDcolumnStart,IDcolumnEnd), Parallel_verticalCausalFilter_Irregular(outputFrame, spatialConstantBuffer, _filterOutput.getNBrows(), _filterOutput.getNBcolumns()));
#else
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{
register float result=0;
register float *outputPTR=outputFrame+IDcolumn;
register const float *spatialConstantPTR=spatialConstantBuffer+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{
result = *(outputPTR) + *(spatialConstantPTR) * result;
*(outputPTR) = result;
outputPTR+=_filterOutput.getNBcolumns();
spatialConstantPTR+=_filterOutput.getNBcolumns();
}
}
#endif
}
// vertical anticausal filter which multiplies the output by _gain
void BasicRetinaFilter::_verticalAnticausalFilter_Irregular_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{
float* outputOffset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
const float* constantOffset=&_progressiveSpatialConstant[0]+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
const float* gainOffset=&_progressiveGain[0]+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{
register float result=0;
register float *outputPTR=outputOffset+IDcolumn;
register const float *spatialConstantPTR=constantOffset+IDcolumn;
register const float *progressiveGainPTR=gainOffset+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{
result = *(outputPTR) + *(spatialConstantPTR) * result;
*(outputPTR) = *(progressiveGainPTR)*result;
outputPTR-=_filterOutput.getNBcolumns();
spatialConstantPTR-=_filterOutput.getNBcolumns();
progressiveGainPTR-=_filterOutput.getNBcolumns();
}
}
}
}// end of namespace bioinspired
}// end of namespace cv
@@ -1,657 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
#ifndef BASICRETINAELEMENT_HPP_
#define BASICRETINAELEMENT_HPP_
#include <cstring>
/**
* @class BasicRetinaFilter
* @brief Brief overview, this class provides tools for low level image processing:
* --> this class is able to perform:
* -> first order Low pass optimized filtering
* -> local luminance adaptation (able to correct back light problems and contrast enhancement)
* -> progressive low pass filter filtering (higher filtering on the borders than on the center)
* -> image data between 0 and 255 resampling with different options, linear rescaling, sigmoide)
*
* NOTE : initially the retina model was based on double format scalar values but
* a good memory/precision compromise is float...
* also the double format precision does not make so much sense from a biological point of view (neurons value coding is not so precise)
*
* TYPICAL USE:
*
* // create object at a specified picture size
* BasicRetinaFilter *_photoreceptorsPrefilter;
* _photoreceptorsPrefilter =new BasicRetinaFilter(sizeRows, sizeWindows);
*
* // init gain, spatial and temporal parameters:
* _photoreceptorsPrefilter->setCoefficientsTable(gain,temporalConstant, spatialConstant);
*
* // during program execution, call the filter for local luminance correction or low pass filtering for an input picture called "FrameBuffer":
* _photoreceptorsPrefilter->runFilter_LocalAdapdation(FrameBuffer);
* // or (Low pass first order filter)
* _photoreceptorsPrefilter->runFilter_LPfilter(FrameBuffer);
* // get output frame and its size:
* const unsigned int output_nbRows=_photoreceptorsPrefilter->getNBrows();
* const unsigned int output_nbColumns=_photoreceptorsPrefilter->getNBcolumns();
* const double *outputFrame=_photoreceptorsPrefilter->getOutput();
*
* // at the end of the program, destroy object:
* delete _photoreceptorsPrefilter;
* @author Alexandre BENOIT, benoit.alexandre.vision@gmail.com, LISTIC : www.listic.univ-savoie.fr, Gipsa-Lab, France: www.gipsa-lab.inpg.fr/
* Creation date 2007
* synthesis of the work described in Alexandre BENOIT thesis: "Le systeme visuel humain au secours de la vision par ordinateur"
*/
#include <iostream>
#include "templatebuffer.hpp"
//#define __BASIC_RETINA_ELEMENT_DEBUG
namespace cv
{
namespace bioinspired
{
class BasicRetinaFilter
{
public:
/**
* constructor of the base bio-inspired toolbox, parameters are only linked to imae input size and number of filtering capabilities of the object
* @param NBrows: number of rows of the input image
* @param NBcolumns: number of columns of the input image
* @param parametersListSize: specifies the number of parameters set (each parameters set represents a specific low pass spatio-temporal filter)
* @param useProgressiveFilter: specifies if the filter has irreguar (progressive) filtering capabilities (this can be activated later using setProgressiveFilterConstants_xxx methods)
*/
BasicRetinaFilter(const unsigned int NBrows, const unsigned int NBcolumns, const unsigned int parametersListSize=1, const bool useProgressiveFilter=false);
/**
* standrad destructore
*/
~BasicRetinaFilter();
/**
* function which clears the output buffer of the object
*/
inline void clearOutputBuffer(){_filterOutput=0;};
/**
* function which clears the secondary buffer of the object
*/
inline void clearSecondaryBuffer(){_localBuffer=0;};
/**
* function which clears the output and the secondary buffer of the object
*/
inline void clearAllBuffers(){clearOutputBuffer();clearSecondaryBuffer();};
/**
* resize basic retina filter object (resize all allocated buffers
* @param NBrows: the new height size
* @param NBcolumns: the new width size
*/
void resize(const unsigned int NBrows, const unsigned int NBcolumns);
/**
* forbiden method inherited from parent std::valarray
* prefer not to use this method since the filter matrix become vectors
*/
void resize(const unsigned int){std::cerr<<"error, not accessible method"<<std::endl;};
/**
* low pass filter call and run (models the homogeneous cells network at the retina level, for example horizontal cells or photoreceptors)
* @param inputFrame: the input image to be processed
* @param filterIndex: the offset which specifies the parameter set that should be used for the filtering
* @return the processed image, the output is reachable later by using function getOutput()
*/
const std::valarray<float> &runFilter_LPfilter(const std::valarray<float> &inputFrame, const unsigned int filterIndex=0); // run the LP filter for a new frame input and save result in _filterOutput
/**
* low pass filter call and run (models the homogeneous cells network at the retina level, for example horizontal cells or photoreceptors)
* @param inputFrame: the input image to be processed
* @param outputFrame: the output buffer in which the result is writed
* @param filterIndex: the offset which specifies the parameter set that should be used for the filtering
*/
void runFilter_LPfilter(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame, const unsigned int filterIndex=0); // run LP filter on a specific output adress
/**
* low pass filter call and run (models the homogeneous cells network at the retina level, for example horizontal cells or photoreceptors)
* @param inputOutputFrame: the input image to be processed on which the result is rewrited
* @param filterIndex: the offset which specifies the parameter set that should be used for the filtering
*/
void runFilter_LPfilter_Autonomous(std::valarray<float> &inputOutputFrame, const unsigned int filterIndex=0);// run LP filter on the input data and rewrite it
/**
* local luminance adaptation call and run (contrast enhancement property of the photoreceptors)
* @param inputOutputFrame: the input image to be processed
* @param localLuminance: an image which represents the local luminance of the inputFrame parameter, in general, it is its low pass spatial filtering
* @return the processed image, the output is reachable later by using function getOutput()
*/
const std::valarray<float> &runFilter_LocalAdapdation(const std::valarray<float> &inputOutputFrame, const std::valarray<float> &localLuminance);// run local adaptation filter and save result in _filterOutput
/**
* local luminance adaptation call and run (contrast enhancement property of the photoreceptors)
* @param inputFrame: the input image to be processed
* @param localLuminance: an image which represents the local luminance of the inputFrame parameter, in general, it is its low pass spatial filtering
* @param outputFrame: the output buffer in which the result is writed
*/
void runFilter_LocalAdapdation(const std::valarray<float> &inputFrame, const std::valarray<float> &localLuminance, std::valarray<float> &outputFrame); // run local adaptation filter on a specific output adress
/**
* local luminance adaptation call and run (contrast enhancement property of the photoreceptors)
* @param inputFrame: the input image to be processed
* @return the processed image, the output is reachable later by using function getOutput()
*/
const std::valarray<float> &runFilter_LocalAdapdation_autonomous(const std::valarray<float> &inputFrame);// run local adaptation filter and save result in _filterOutput
/**
* local luminance adaptation call and run (contrast enhancement property of the photoreceptors)
* @param inputFrame: the input image to be processed
* @param outputFrame: the output buffer in which the result is writen
*/
void runFilter_LocalAdapdation_autonomous(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame); // run local adaptation filter on a specific output adress
/**
* run low pass filtering with progressive parameters (models the retina log sampling of the photoreceptors and its low pass filtering effect consequence: more powerfull low pass filtering effect on the corners)
* @param inputFrame: the input image to be processed
* @param filterIndex: the index which specifies the parameter set that should be used for the filtering
* @return the processed image, the output is reachable later by using function getOutput() if outputFrame is NULL
*/
inline void runProgressiveFilter(std::valarray<float> &inputFrame, const unsigned int filterIndex=0){_spatiotemporalLPfilter_Irregular(&inputFrame[0], filterIndex);};
/**
* run low pass filtering with progressive parameters (models the retina log sampling of the photoreceptors and its low pass filtering effect consequence: more powerfull low pass filtering effect on the corners)
* @param inputFrame: the input image to be processed
* @param outputFrame: the output buffer in which the result is writen
* @param filterIndex: the index which specifies the parameter set that should be used for the filtering
*/
inline void runProgressiveFilter(const std::valarray<float> &inputFrame,
std::valarray<float> &outputFrame,
const unsigned int filterIndex=0)
{_spatiotemporalLPfilter_Irregular(get_data(inputFrame), &outputFrame[0], filterIndex);};
/**
* first order spatio-temporal low pass filter setup function
* @param beta: gain of the filter (generally set to zero)
* @param tau: time constant of the filter (unit is frame for video processing)
* @param k: spatial constant of the filter (unit is pixels)
* @param filterIndex: the index which specifies the parameter set that should be used for the filtering
*/
void setLPfilterParameters(const float beta, const float tau, const float k, const unsigned int filterIndex=0); // change the parameters of the filter
/**
* first order spatio-temporal low pass filter setup function
* @param beta: gain of the filter (generally set to zero)
* @param tau: time constant of the filter (unit is frame for video processing)
* @param alpha0: spatial constant of the filter (unit is pixels) on the border of the image
* @param filterIndex: the index which specifies the parameter set that should be used for the filtering
*/
void setProgressiveFilterConstants_CentredAccuracy(const float beta, const float tau, const float alpha0, const unsigned int filterIndex=0);
/**
* first order spatio-temporal low pass filter setup function
* @param beta: gain of the filter (generally set to zero)
* @param tau: time constant of the filter (unit is frame for video processing)
* @param alpha0: spatial constant of the filter (unit is pixels) on the border of the image
* @param accuracyMap an image (float format) which values range is between 0 and 1, where 0 means, apply no filtering and 1 means apply the filtering as specified in the parameters set, intermediate values allow to smooth variations of the filtering strenght
* @param filterIndex: the index which specifies the parameter set that should be used for the filtering
*/
void setProgressiveFilterConstants_CustomAccuracy(const float beta, const float tau, const float alpha0, const std::valarray<float> &accuracyMap, const unsigned int filterIndex=0);
/**
* local luminance adaptation setup, this function should be applied for normal local adaptation (not for tone mapping operation)
* @param v0: compression effect for the local luminance adaptation processing, set a value between 0.6 and 0.9 for best results, a high value yields to a high compression effect
* @param maxInputValue: the maximum amplitude value measured after local adaptation processing (c.f. function runFilter_LocalAdapdation & runFilter_LocalAdapdation_autonomous)
* @param meanLuminance: the a priori meann luminance of the input data (should be 128 for 8bits images but can vary greatly in case of High Dynamic Range Images (HDRI)
*/
void setV0CompressionParameter(const float v0, const float maxInputValue, const float){ _v0=v0*maxInputValue; _localLuminanceFactor=v0; _localLuminanceAddon=maxInputValue*(1.0f-v0); _maxInputValue=maxInputValue;};
/**
* update local luminance adaptation setup, initial maxInputValue is kept. This function should be applied for normal local adaptation (not for tone mapping operation)
* @param v0: compression effect for the local luminance adaptation processing, set a value between 0.6 and 0.9 for best results, a high value yields to a high compression effect
* @param meanLuminance: the a priori meann luminance of the input data (should be 128 for 8bits images but can vary greatly in case of High Dynamic Range Images (HDRI)
*/
void setV0CompressionParameter(const float v0, const float meanLuminance){ this->setV0CompressionParameter(v0, _maxInputValue, meanLuminance);};
/**
* local luminance adaptation setup, this function should be applied for normal local adaptation (not for tone mapping operation)
* @param v0: compression effect for the local luminance adaptation processing, set a value between 0.6 and 0.9 for best results, a high value yields to a high compression effect
*/
void setV0CompressionParameter(const float v0){ _v0=v0*_maxInputValue; _localLuminanceFactor=v0; _localLuminanceAddon=_maxInputValue*(1.0f-v0);};
/**
* local luminance adaptation setup, this function should be applied for local adaptation applied to tone mapping operation
* @param v0: compression effect for the local luminance adaptation processing, set a value between 0.6 and 0.9 for best results, a high value yields to a high compression effect
* @param maxInputValue: the maximum amplitude value measured after local adaptation processing (c.f. function runFilter_LocalAdapdation & runFilter_LocalAdapdation_autonomous)
* @param meanLuminance: the a priori meann luminance of the input data (should be 128 for 8bits images but can vary greatly in case of High Dynamic Range Images (HDRI)
*/
void setV0CompressionParameterToneMapping(const float v0, const float maxInputValue, const float meanLuminance=128.0f){ _v0=v0*maxInputValue; _localLuminanceFactor=1.0f; _localLuminanceAddon=meanLuminance*v0; _maxInputValue=maxInputValue;};
/**
* update compression parameters while keeping v0 parameter value
* @param meanLuminance the input frame mean luminance
*/
inline void updateCompressionParameter(const float meanLuminance){_localLuminanceFactor=1; _localLuminanceAddon=meanLuminance*_v0;};
/**
* @return the v0 compression parameter used to compute the local adaptation
*/
float getV0CompressionParameter(){ return _v0/_maxInputValue;};
/**
* @return the output result of the object
*/
inline const std::valarray<float> &getOutput() const {return _filterOutput;};
/**
* @return number of rows of the filter
*/
inline unsigned int getNBrows(){return _filterOutput.getNBrows();};
/**
* @return number of columns of the filter
*/
inline unsigned int getNBcolumns(){return _filterOutput.getNBcolumns();};
/**
* @return number of pixels of the filter
*/
inline unsigned int getNBpixels(){return _filterOutput.getNBpixels();};
/**
* force filter output to be normalized between 0 and maxValue
* @param maxValue: the maximum output value that is required
*/
inline void normalizeGrayOutput_0_maxOutputValue(const float maxValue){_filterOutput.normalizeGrayOutput_0_maxOutputValue(maxValue);};
/**
* force filter output to be normalized around 0 and rescaled with a sigmoide effect (extrem values saturation)
* @param maxValue: the maximum output value that is required
*/
inline void normalizeGrayOutputCentredSigmoide(){_filterOutput.normalizeGrayOutputCentredSigmoide();};
/**
* force filter output to be normalized : data centering and std normalisation
* @param maxValue: the maximum output value that is required
*/
inline void centerReductImageLuminance(){_filterOutput.centerReductImageLuminance();};
/**
* @return the maximum input buffer value
*/
inline float getMaxInputValue(){return this->_maxInputValue;};
/**
* @return the maximum input buffer value
*/
inline void setMaxInputValue(const float newMaxInputValue){this->_maxInputValue=newMaxInputValue;};
protected:
/////////////////////////
// data buffers
TemplateBuffer<float> _filterOutput; // primary buffer (contains processing outputs)
std::valarray<float> _localBuffer; // local secondary buffer
/////////////////////////
// PARAMETERS
unsigned int _halfNBrows;
unsigned int _halfNBcolumns;
// parameters buffers
std::valarray <float>_filteringCoeficientsTable;
std::valarray <float>_progressiveSpatialConstant;// pointer to a local table containing local spatial constant (allocated with the object)
std::valarray <float>_progressiveGain;// pointer to a local table containing local spatial constant (allocated with the object)
// local adaptation filtering parameters
float _v0; //value used for local luminance adaptation function
float _maxInputValue;
float _meanInputValue;
float _localLuminanceFactor;
float _localLuminanceAddon;
// protected data related to standard low pass filters parameters
float _a;
float _tau;
float _gain;
/////////////////////////
// FILTERS METHODS
// Basic low pass spation temporal low pass filter used by each retina filters
void _spatiotemporalLPfilter(const float *inputFrame, float *LPfilterOutput, const unsigned int coefTableOffset=0);
float _squaringSpatiotemporalLPfilter(const float *inputFrame, float *outputFrame, const unsigned int filterIndex=0);
// LP filter with an irregular spatial filtering
// -> rewrites the input buffer
void _spatiotemporalLPfilter_Irregular(float *inputOutputFrame, const unsigned int filterIndex=0);
// writes the output on another buffer
void _spatiotemporalLPfilter_Irregular(const float *inputFrame, float *outputFrame, const unsigned int filterIndex=0);
// LP filter that squares the input and computes the output ONLY on the areas where the integrationAreas map are TRUE
void _localSquaringSpatioTemporalLPfilter(const float *inputFrame, float *LPfilterOutput, const unsigned int *integrationAreas, const unsigned int filterIndex=0);
// local luminance adaptation of the input in regard of localLuminance buffer
void _localLuminanceAdaptation(const float *inputFrame, const float *localLuminance, float *outputFrame, const bool updateLuminanceMean=true);
// local luminance adaptation of the input in regard of localLuminance buffer, the input is rewrited and becomes the output
void _localLuminanceAdaptation(float *inputOutputFrame, const float *localLuminance);
// local adaptation applied on a range of values which can be positive and negative
void _localLuminanceAdaptationPosNegValues(const float *inputFrame, const float *localLuminance, float *outputFrame);
//////////////////////////////////////////////////////////////
// 1D directional filters used for the 2D low pass filtering
// 1D filters with image input
void _horizontalCausalFilter_addInput(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd);
// 1D filters with image input that is squared in the function // parallelized with TBB
void _squaringHorizontalCausalFilter(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd);
// vertical anticausal filter that returns the mean value of its result
float _verticalAnticausalFilter_returnMeanValue(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd);
// most simple functions: only perform 1D filtering with output=input (no add on)
void _horizontalCausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd);
void _horizontalAnticausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd); // parallelized with TBB
void _verticalCausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); // parallelized with TBB
void _verticalAnticausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd);
// perform 1D filtering with output with varrying spatial coefficient
void _horizontalCausalFilter_Irregular(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd);
void _horizontalCausalFilter_Irregular_addInput(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd);
void _horizontalAnticausalFilter_Irregular(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const float *spatialConstantBuffer); // parallelized with TBB
void _verticalCausalFilter_Irregular(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const float *spatialConstantBuffer); // parallelized with TBB
void _verticalAnticausalFilter_Irregular_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd);
// 1D filters in which the output is multiplied by _gain
void _verticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); // this functions affects _gain at the output // parallelized with TBB
void _horizontalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); // this functions affects _gain at the output
// LP filter on specific parts of the picture instead of all the image
// same functions (some of them) but take a binary flag to allow integration, false flag means, 0 at the output...
void _local_squaringHorizontalCausalFilter(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const unsigned int *integrationAreas);
void _local_horizontalAnticausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const unsigned int *integrationAreas);
void _local_verticalCausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas);
void _local_verticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas); // this functions affects _gain at the output
#ifdef MAKE_PARALLEL
/******************************************************
** IF some parallelizing thread methods are available, then, main loops are parallelized using these functors
** ==> main idea paralellise main filters loops, then, only the most used methods are parallelized... TODO : increase the number of parallelised methods as necessary
** ==> functors names = Parallel_$$$ where $$$= the name of the serial method that is parallelised
** ==> functors constructors can differ from the parameters used with their related serial functions
*/
#define _DEBUG_TBB // define DEBUG_TBB in order to display additionnal data on stdout
class Parallel_horizontalAnticausalFilter: public cv::ParallelLoopBody
{
private:
float *outputFrame;
unsigned int IDrowEnd, nbColumns;
float filterParam_a;
public:
// constructor which takes the input image pointer reference reference and limits
Parallel_horizontalAnticausalFilter(float *bufferToProcess, const unsigned int idEnd, const unsigned int nbCols, const float a )
:outputFrame(bufferToProcess), IDrowEnd(idEnd), nbColumns(nbCols), filterParam_a(a)
{
#ifdef DEBUG_TBB
std::cout<<"Parallel_horizontalAnticausalFilter::Parallel_horizontalAnticausalFilter :"
<<"\n\t idEnd="<<IDrowEnd
<<"\n\t nbCols="<<nbColumns
<<"\n\t filterParam="<<filterParam_a
<<std::endl;
#endif
}
virtual void operator()( const Range& r ) const {
#ifdef DEBUG_TBB
std::cout<<"Parallel_horizontalAnticausalFilter::operator() :"
<<"\n\t range size="<<r.size()
<<"\n\t first index="<<r.start
//<<"\n\t last index="<<filterParam
<<std::endl;
#endif
for (int IDrow=r.start; IDrow!=r.end; ++IDrow)
{
register float* outputPTR=outputFrame+(IDrowEnd-IDrow)*(nbColumns)-1;
register float result=0;
for (unsigned int index=0; index<nbColumns; ++index)
{
result = *(outputPTR)+ filterParam_a* result;
*(outputPTR--) = result;
}
}
}
};
class Parallel_horizontalCausalFilter_addInput: public cv::ParallelLoopBody
{
private:
const float *inputFrame;
float *outputFrame;
unsigned int IDrowStart, nbColumns;
float filterParam_a, filterParam_tau;
public:
Parallel_horizontalCausalFilter_addInput(const float *bufferToAddAsInputProcess, float *bufferToProcess, const unsigned int idStart, const unsigned int nbCols, const float a, const float tau)
:inputFrame(bufferToAddAsInputProcess), outputFrame(bufferToProcess), IDrowStart(idStart), nbColumns(nbCols), filterParam_a(a), filterParam_tau(tau){}
virtual void operator()( const Range& r ) const {
for (int IDrow=r.start; IDrow!=r.end; ++IDrow)
{
register float* outputPTR=outputFrame+(IDrowStart+IDrow)*nbColumns;
register const float* inputPTR=inputFrame+(IDrowStart+IDrow)*nbColumns;
register float result=0;
for (unsigned int index=0; index<nbColumns; ++index)
{
result = *(inputPTR++) + filterParam_tau**(outputPTR)+ filterParam_a* result;
*(outputPTR++) = result;
}
}
}
};
class Parallel_verticalCausalFilter: public cv::ParallelLoopBody
{
private:
float *outputFrame;
unsigned int nbRows, nbColumns;
float filterParam_a;
public:
Parallel_verticalCausalFilter(float *bufferToProcess, const unsigned int nbRws, const unsigned int nbCols, const float a )
:outputFrame(bufferToProcess), nbRows(nbRws), nbColumns(nbCols), filterParam_a(a){}
virtual void operator()( const Range& r ) const {
for (int IDcolumn=r.start; IDcolumn!=r.end; ++IDcolumn)
{
register float result=0;
register float *outputPTR=outputFrame+IDcolumn;
for (unsigned int index=0; index<nbRows; ++index)
{
result = *(outputPTR) + filterParam_a * result;
*(outputPTR) = result;
outputPTR+=nbColumns;
}
}
}
};
class Parallel_verticalAnticausalFilter_multGain: public cv::ParallelLoopBody
{
private:
float *outputFrame;
unsigned int nbRows, nbColumns;
float filterParam_a, filterParam_gain;
public:
Parallel_verticalAnticausalFilter_multGain(float *bufferToProcess, const unsigned int nbRws, const unsigned int nbCols, const float a, const float gain)
:outputFrame(bufferToProcess), nbRows(nbRws), nbColumns(nbCols), filterParam_a(a), filterParam_gain(gain){}
virtual void operator()( const Range& r ) const {
float* offset=outputFrame+nbColumns*nbRows-nbColumns;
for (int IDcolumn=r.start; IDcolumn!=r.end; ++IDcolumn)
{
register float result=0;
register float *outputPTR=offset+IDcolumn;
for (unsigned int index=0; index<nbRows; ++index)
{
result = *(outputPTR) + filterParam_a * result;
*(outputPTR) = filterParam_gain*result;
outputPTR-=nbColumns;
}
}
}
};
class Parallel_localAdaptation: public cv::ParallelLoopBody
{
private:
const float *localLuminance, *inputFrame;
float *outputFrame;
float localLuminanceFactor, localLuminanceAddon, maxInputValue;
public:
Parallel_localAdaptation(const float *localLum, const float *inputImg, float *bufferToProcess, const float localLuminanceFact, const float localLuminanceAdd, const float maxInputVal)
:localLuminance(localLum), inputFrame(inputImg),outputFrame(bufferToProcess), localLuminanceFactor(localLuminanceFact), localLuminanceAddon(localLuminanceAdd), maxInputValue(maxInputVal) {};
virtual void operator()( const Range& r ) const {
const float *localLuminancePTR=localLuminance+r.start;
const float *inputFramePTR=inputFrame+r.start;
float *outputFramePTR=outputFrame+r.start;
for (register int IDpixel=r.start ; IDpixel!=r.end ; ++IDpixel, ++inputFramePTR, ++outputFramePTR)
{
float X0=*(localLuminancePTR++)*localLuminanceFactor+localLuminanceAddon;
// TODO : the following line can lead to a divide by zero ! A small offset is added, take care if the offset is too large in case of High Dynamic Range images which can use very small values...
*(outputFramePTR) = (maxInputValue+X0)**inputFramePTR/(*inputFramePTR +X0+0.00000000001f);
//std::cout<<"BasicRetinaFilter::inputFrame[IDpixel]=%f, X0=%f, outputFrame[IDpixel]=%f\n", inputFrame[IDpixel], X0, outputFrame[IDpixel]);
}
}
};
//////////////////////////////////////////
/// Specific filtering methods which manage non const spatial filtering parameter (used By retinacolor and LogProjectors)
class Parallel_horizontalAnticausalFilter_Irregular: public cv::ParallelLoopBody
{
private:
float *outputFrame;
const float *spatialConstantBuffer;
unsigned int IDrowEnd, nbColumns;
public:
Parallel_horizontalAnticausalFilter_Irregular(float *bufferToProcess, const float *spatialConst, const unsigned int idEnd, const unsigned int nbCols)
:outputFrame(bufferToProcess), spatialConstantBuffer(spatialConst), IDrowEnd(idEnd), nbColumns(nbCols){}
virtual void operator()( const Range& r ) const {
for (int IDrow=r.start; IDrow!=r.end; ++IDrow)
{
register float* outputPTR=outputFrame+(IDrowEnd-IDrow)*(nbColumns)-1;
register const float* spatialConstantPTR=spatialConstantBuffer+(IDrowEnd-IDrow)*(nbColumns)-1;
register float result=0;
for (unsigned int index=0; index<nbColumns; ++index)
{
result = *(outputPTR)+ *(spatialConstantPTR--)* result;
*(outputPTR--) = result;
}
}
}
};
class Parallel_verticalCausalFilter_Irregular: public cv::ParallelLoopBody
{
private:
float *outputFrame;
const float *spatialConstantBuffer;
unsigned int nbRows, nbColumns;
public:
Parallel_verticalCausalFilter_Irregular(float *bufferToProcess, const float *spatialConst, const unsigned int nbRws, const unsigned int nbCols)
:outputFrame(bufferToProcess), spatialConstantBuffer(spatialConst), nbRows(nbRws), nbColumns(nbCols){}
virtual void operator()( const Range& r ) const {
for (int IDcolumn=r.start; IDcolumn!=r.end; ++IDcolumn)
{
register float result=0;
register float *outputPTR=outputFrame+IDcolumn;
register const float* spatialConstantPTR=spatialConstantBuffer+IDcolumn;
for (unsigned int index=0; index<nbRows; ++index)
{
result = *(outputPTR) + *(spatialConstantPTR) * result;
*(outputPTR) = result;
outputPTR+=nbColumns;
spatialConstantPTR+=nbColumns;
}
}
}
};
#endif
};
}// end of namespace bioinspired
}// end of namespace cv
#endif
@@ -1,451 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
#include "precomp.hpp"
#include "imagelogpolprojection.hpp"
#include <cmath>
#include <iostream>
// @author Alexandre BENOIT, benoit.alexandre.vision@gmail.com, LISTIC : www.listic.univ-savoie.fr, Gipsa-Lab, France: www.gipsa-lab.inpg.fr/
namespace cv
{
namespace bioinspired
{
// constructor
ImageLogPolProjection::ImageLogPolProjection(const unsigned int nbRows, const unsigned int nbColumns, const PROJECTIONTYPE projection, const bool colorModeCapable)
:BasicRetinaFilter(nbRows, nbColumns),
_sampledFrame(0),
_tempBuffer(_localBuffer),
_transformTable(0),
_irregularLPfilteredFrame(_filterOutput)
{
_inputDoubleNBpixels=nbRows*nbColumns*2;
_selectedProjection = projection;
_reductionFactor=0;
_initOK=false;
_usefullpixelIndex=0;
_colorModeCapable=colorModeCapable;
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"ImageLogPolProjection::allocating"<<std::endl;
#endif
if (_colorModeCapable)
{
_tempBuffer.resize(nbRows*nbColumns*3);
}
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"ImageLogPolProjection::done"<<std::endl;
#endif
clearAllBuffers();
}
// destructor
ImageLogPolProjection::~ImageLogPolProjection()
{
}
// reset buffers method
void ImageLogPolProjection::clearAllBuffers()
{
_sampledFrame=0;
_tempBuffer=0;
BasicRetinaFilter::clearAllBuffers();
}
/**
* resize retina color filter object (resize all allocated buffers)
* @param NBrows: the new height size
* @param NBcolumns: the new width size
*/
void ImageLogPolProjection::resize(const unsigned int NBrows, const unsigned int NBcolumns)
{
BasicRetinaFilter::resize(NBrows, NBcolumns);
initProjection(_reductionFactor, _samplingStrenght);
// reset buffers method
clearAllBuffers();
}
// init functions depending on the projection type
bool ImageLogPolProjection::initProjection(const double reductionFactor, const double samplingStrenght)
{
switch(_selectedProjection)
{
case RETINALOGPROJECTION:
return _initLogRetinaSampling(reductionFactor, samplingStrenght);
break;
case CORTEXLOGPOLARPROJECTION:
return _initLogPolarCortexSampling(reductionFactor, samplingStrenght);
break;
default:
std::cout<<"ImageLogPolProjection::no projection setted up... performing default retina projection... take care"<<std::endl;
return _initLogRetinaSampling(reductionFactor, samplingStrenght);
break;
}
}
// -> private init functions dedicated to each projection
bool ImageLogPolProjection::_initLogRetinaSampling(const double reductionFactor, const double samplingStrenght)
{
_initOK=false;
if (_selectedProjection!=RETINALOGPROJECTION)
{
std::cerr<<"ImageLogPolProjection::initLogRetinaSampling: could not initialize logPolar projection for a log projection system\n -> you probably chose the wrong init function, use initLogPolarCortexSampling() instead"<<std::endl;
return false;
}
if (reductionFactor<1.0)
{
std::cerr<<"ImageLogPolProjection::initLogRetinaSampling: reduction factor must be superior to 0, skeeping initialisation..."<<std::endl;
return false;
}
// compute image output size
_outputNBrows=predictOutputSize(this->getNBrows(), reductionFactor);
_outputNBcolumns=predictOutputSize(this->getNBcolumns(), reductionFactor);
_outputNBpixels=_outputNBrows*_outputNBcolumns;
_outputDoubleNBpixels=_outputNBrows*_outputNBcolumns*2;
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: Log resampled image resampling factor: "<<reductionFactor<<", strenght:"<<samplingStrenght<<std::endl;
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: Log resampled image size: "<<_outputNBrows<<"*"<<_outputNBcolumns<<std::endl;
#endif
// setup progressive prefilter that will be applied BEFORE log sampling
setProgressiveFilterConstants_CentredAccuracy(0.f, 0.f, 0.99f);
// (re)create the image output buffer and transform table if the reduction factor changed
_sampledFrame.resize(_outputNBpixels*(1+(unsigned int)_colorModeCapable*2));
// specifiying new reduction factor after preliminar checks
_reductionFactor=reductionFactor;
_samplingStrenght=samplingStrenght;
// compute the rlim for symetric rows/columns sampling, then, the rlim is based on the smallest dimension
_minDimension=(double)(_filterOutput.getNBrows() < _filterOutput.getNBcolumns() ? _filterOutput.getNBrows() : _filterOutput.getNBcolumns());
// input frame dimensions dependent log sampling:
//double rlim=1.0/reductionFactor*(minDimension/2.0+samplingStrenght);
// input frame dimensions INdependent log sampling:
_azero=(1.0+reductionFactor*std::sqrt(samplingStrenght))/(reductionFactor*reductionFactor*samplingStrenght-1.0);
_alim=(1.0+_azero)/reductionFactor;
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: rlim= "<<rlim<<std::endl;
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: alim= "<<alim<<std::endl;
#endif
// get half frame size
unsigned int halfOutputRows = _outputNBrows/2-1;
unsigned int halfOutputColumns = _outputNBcolumns/2-1;
unsigned int halfInputRows = _filterOutput.getNBrows()/2-1;
unsigned int halfInputColumns = _filterOutput.getNBcolumns()/2-1;
// computing log sampling matrix by computing quarters of images
// the original new image center (_filterOutput.getNBrows()/2, _filterOutput.getNBcolumns()/2) being at coordinate (_filterOutput.getNBrows()/(2*_reductionFactor), _filterOutput.getNBcolumns()/(2*_reductionFactor))
// -> use a temporary transform table which is bigger than the final one, we only report pixels coordinates that are included in the sampled picture
std::valarray<unsigned int> tempTransformTable(2*_outputNBpixels); // the structure would be: (pixelInputCoordinate n)(pixelOutputCoordinate n)(pixelInputCoordinate n+1)(pixelOutputCoordinate n+1)
_usefullpixelIndex=0;
double rMax=0;
halfInputRows<halfInputColumns ? rMax=(double)(halfInputRows*halfInputRows):rMax=(double)(halfInputColumns*halfInputColumns);
for (unsigned int idRow=0;idRow<halfOutputRows; ++idRow)
{
for (unsigned int idColumn=0;idColumn<halfOutputColumns; ++idColumn)
{
// get the pixel position in the original picture
// -> input frame dimensions dependent log sampling:
//double scale = samplingStrenght/(rlim-(double)std::sqrt(idRow*idRow+idColumn*idColumn));
// -> input frame dimensions INdependent log sampling:
double scale=getOriginalRadiusLength((double)std::sqrt((double)(idRow*idRow+idColumn*idColumn)));
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: scale= "<<scale<<std::endl;
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: scale2= "<<scale2<<std::endl;
#endif
if (scale < 0) ///check it later
scale = 10000;
#ifdef IMAGELOGPOLPROJECTION_DEBUG
// std::cout<<"ImageLogPolProjection::initLogRetinaSampling: scale= "<<scale<<std::endl;
#endif
unsigned int u=(unsigned int)floor((double)idRow*scale);
unsigned int v=(unsigned int)floor((double)idColumn*scale);
// manage border effects
double length=u*u+v*v;
double radiusRatio=std::sqrt(rMax/length);
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"ImageLogPolProjection::(inputH, inputW)="<<halfInputRows<<", "<<halfInputColumns<<", Rmax2="<<rMax<<std::endl;
std::cout<<"before ==> ImageLogPolProjection::(u, v)="<<u<<", "<<v<<", r="<<u*u+v*v<<std::endl;
std::cout<<"ratio ="<<radiusRatio<<std::endl;
#endif
if (radiusRatio < 1.0)
{
u=(unsigned int)floor(radiusRatio*double(u));
v=(unsigned int)floor(radiusRatio*double(v));
}
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"after ==> ImageLogPolProjection::(u, v)="<<u<<", "<<v<<", r="<<u*u+v*v<<std::endl;
std::cout<<"ImageLogPolProjection::("<<(halfOutputRows-idRow)<<", "<<idColumn+halfOutputColumns<<") <- ("<<halfInputRows-u<<", "<<v+halfInputColumns<<")"<<std::endl;
std::cout<<(halfOutputRows-idRow)+(halfOutputColumns+idColumn)*_outputNBrows<<" -> "<<(halfInputRows-u)+_filterOutput.getNBrows()*(halfInputColumns+v)<<std::endl;
#endif
if ((u<halfInputRows)&&(v<halfInputColumns))
{
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"*** VALID ***"<<std::endl;
#endif
// set pixel coordinate of the input picture in the transform table at the current log sampled pixel
// 1st quadrant
tempTransformTable[_usefullpixelIndex++]=(halfOutputColumns+idColumn)+(halfOutputRows-idRow)*_outputNBcolumns;
tempTransformTable[_usefullpixelIndex++]=_filterOutput.getNBcolumns()*(halfInputRows-u)+(halfInputColumns+v);
// 2nd quadrant
tempTransformTable[_usefullpixelIndex++]=(halfOutputColumns+idColumn)+(halfOutputRows+idRow)*_outputNBcolumns;
tempTransformTable[_usefullpixelIndex++]=_filterOutput.getNBcolumns()*(halfInputRows+u)+(halfInputColumns+v);
// 3rd quadrant
tempTransformTable[_usefullpixelIndex++]=(halfOutputColumns-idColumn)+(halfOutputRows-idRow)*_outputNBcolumns;
tempTransformTable[_usefullpixelIndex++]=_filterOutput.getNBcolumns()*(halfInputRows-u)+(halfInputColumns-v);
// 4td quadrant
tempTransformTable[_usefullpixelIndex++]=(halfOutputColumns-idColumn)+(halfOutputRows+idRow)*_outputNBcolumns;
tempTransformTable[_usefullpixelIndex++]=_filterOutput.getNBcolumns()*(halfInputRows+u)+(halfInputColumns-v);
}
}
}
// (re)creating and filling the transform table
_transformTable.resize(_usefullpixelIndex);
memcpy(&_transformTable[0], &tempTransformTable[0], sizeof(unsigned int)*_usefullpixelIndex);
// reset all buffers
clearAllBuffers();
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: init done successfully"<<std::endl;
#endif
_initOK=true;
return _initOK;
}
bool ImageLogPolProjection::_initLogPolarCortexSampling(const double reductionFactor, const double)
{
_initOK=false;
if (_selectedProjection!=CORTEXLOGPOLARPROJECTION)
{
std::cerr<<"ImageLogPolProjection::could not initialize log projection for a logPolar projection system\n -> you probably chose the wrong init function, use initLogRetinaSampling() instead"<<std::endl;
return false;
}
if (reductionFactor<1.0)
{
std::cerr<<"ImageLogPolProjection::reduction factor must be superior to 0, skeeping initialisation..."<<std::endl;
return false;
}
// compute the smallest image size
unsigned int minDimension=(_filterOutput.getNBrows() < _filterOutput.getNBcolumns() ? _filterOutput.getNBrows() : _filterOutput.getNBcolumns());
// specifiying new reduction factor after preliminar checks
_reductionFactor=reductionFactor;
// compute image output size
_outputNBrows=(unsigned int)((double)minDimension/reductionFactor);
_outputNBcolumns=(unsigned int)((double)minDimension/reductionFactor);
_outputNBpixels=_outputNBrows*_outputNBcolumns;
_outputDoubleNBpixels=_outputNBrows*_outputNBcolumns*2;
// get half frame size
//unsigned int halfOutputRows = _outputNBrows/2-1;
//unsigned int halfOutputColumns = _outputNBcolumns/2-1;
unsigned int halfInputRows = _filterOutput.getNBrows()/2-1;
unsigned int halfInputColumns = _filterOutput.getNBcolumns()/2-1;
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"ImageLogPolProjection::Log resampled image size: "<<_outputNBrows<<"*"<<_outputNBcolumns<<std::endl;
#endif
// setup progressive prefilter that will be applied BEFORE log sampling
setProgressiveFilterConstants_CentredAccuracy(0.f, 0.f, 0.99f);
// (re)create the image output buffer and transform table if the reduction factor changed
_sampledFrame.resize(_outputNBpixels*(1+(unsigned int)_colorModeCapable*2));
// create the radius and orientation axis and fill them, radius E [0;1], orientation E[-pi, pi]
std::valarray<double> radiusAxis(_outputNBcolumns);
double radiusStep=2.30/(double)_outputNBcolumns;
for (unsigned int i=0;i<_outputNBcolumns;++i)
{
radiusAxis[i]=i*radiusStep;
}
std::valarray<double> orientationAxis(_outputNBrows);
double orientationStep=-2.0*CV_PI/(double)_outputNBrows;
for (unsigned int io=0;io<_outputNBrows;++io)
{
orientationAxis[io]=io*orientationStep;
}
// -> use a temporay transform table which is bigger than the final one, we only report pixels coordinates that are included in the sampled picture
std::valarray<unsigned int> tempTransformTable(2*_outputNBpixels); // the structure would be: (pixelInputCoordinate n)(pixelOutputCoordinate n)(pixelInputCoordinate n+1)(pixelOutputCoordinate n+1)
_usefullpixelIndex=0;
//std::cout<<"ImageLogPolProjection::Starting cortex projection"<<std::endl;
// compute transformation, get theta and Radius in reagrd of the output sampled pixel
double diagonalLenght=std::sqrt((double)(_outputNBcolumns*_outputNBcolumns+_outputNBrows*_outputNBrows));
for (unsigned int radiusIndex=0;radiusIndex<_outputNBcolumns;++radiusIndex)
for(unsigned int orientationIndex=0;orientationIndex<_outputNBrows;++orientationIndex)
{
double x=1.0+sinh(radiusAxis[radiusIndex])*cos(orientationAxis[orientationIndex]);
double y=sinh(radiusAxis[radiusIndex])*sin(orientationAxis[orientationIndex]);
// get the input picture coordinate
double R=diagonalLenght*std::sqrt(x*x+y*y)/(5.0+std::sqrt(x*x+y*y));
double theta=atan2(y,x);
// convert input polar coord into cartesian/C compatble coordinate
unsigned int columnIndex=(unsigned int)(cos(theta)*R)+halfInputColumns;
unsigned int rowIndex=(unsigned int)(sin(theta)*R)+halfInputRows;
//std::cout<<"ImageLogPolProjection::R="<<R<<" / Theta="<<theta<<" / (x, y)="<<columnIndex<<", "<<rowIndex<<std::endl;
if ((columnIndex<_filterOutput.getNBcolumns())&&(columnIndex>0)&&(rowIndex<_filterOutput.getNBrows())&&(rowIndex>0))
{
// set coordinate
tempTransformTable[_usefullpixelIndex++]=radiusIndex+orientationIndex*_outputNBcolumns;
tempTransformTable[_usefullpixelIndex++]= columnIndex+rowIndex*_filterOutput.getNBcolumns();
}
}
// (re)creating and filling the transform table
_transformTable.resize(_usefullpixelIndex);
memcpy(&_transformTable[0], &tempTransformTable[0], sizeof(unsigned int)*_usefullpixelIndex);
// reset all buffers
clearAllBuffers();
_initOK=true;
return true;
}
// action function
std::valarray<float> &ImageLogPolProjection::runProjection(const std::valarray<float> &inputFrame, const bool colorMode)
{
if (_colorModeCapable&&colorMode)
{
// progressive filtering and storage of the result in _tempBuffer
_spatiotemporalLPfilter_Irregular(get_data(inputFrame), &_irregularLPfilteredFrame[0]);
_spatiotemporalLPfilter_Irregular(&_irregularLPfilteredFrame[0], &_tempBuffer[0]); // warning, temporal issue may occur, if the temporal constant is not NULL !!!
_spatiotemporalLPfilter_Irregular(get_data(inputFrame)+_filterOutput.getNBpixels(), &_irregularLPfilteredFrame[0]);
_spatiotemporalLPfilter_Irregular(&_irregularLPfilteredFrame[0], &_tempBuffer[0]+_filterOutput.getNBpixels());
_spatiotemporalLPfilter_Irregular(get_data(inputFrame)+_filterOutput.getNBpixels()*2, &_irregularLPfilteredFrame[0]);
_spatiotemporalLPfilter_Irregular(&_irregularLPfilteredFrame[0], &_tempBuffer[0]+_filterOutput.getNBpixels()*2);
// applying image projection/resampling
register unsigned int *transformTablePTR=&_transformTable[0];
for (unsigned int i=0 ; i<_usefullpixelIndex ; i+=2, transformTablePTR+=2)
{
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"ImageLogPolProjection::i:"<<i<<"output(max="<<_outputNBpixels<<")="<<_transformTable[i]<<" / intput(max="<<_filterOutput.getNBpixels()<<")="<<_transformTable[i+1]<<std::endl;
#endif
_sampledFrame[*(transformTablePTR)]=_tempBuffer[*(transformTablePTR+1)];
_sampledFrame[*(transformTablePTR)+_outputNBpixels]=_tempBuffer[*(transformTablePTR+1)+_filterOutput.getNBpixels()];
_sampledFrame[*(transformTablePTR)+_outputDoubleNBpixels]=_tempBuffer[*(transformTablePTR+1)+_inputDoubleNBpixels];
}
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"ImageLogPolProjection::runProjection: color image projection OK"<<std::endl;
#endif
//normalizeGrayOutput_0_maxOutputValue(_sampledFrame, _outputNBpixels);
}else
{
_spatiotemporalLPfilter_Irregular(get_data(inputFrame), &_irregularLPfilteredFrame[0]);
_spatiotemporalLPfilter_Irregular(&_irregularLPfilteredFrame[0], &_irregularLPfilteredFrame[0]);
// applying image projection/resampling
register unsigned int *transformTablePTR=&_transformTable[0];
for (unsigned int i=0 ; i<_usefullpixelIndex ; i+=2, transformTablePTR+=2)
{
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"i:"<<i<<"output(max="<<_outputNBpixels<<")="<<_transformTable[i]<<" / intput(max="<<_filterOutput.getNBpixels()<<")="<<_transformTable[i+1]<<std::endl;
#endif
_sampledFrame[*(transformTablePTR)]=_irregularLPfilteredFrame[*(transformTablePTR+1)];
}
//normalizeGrayOutput_0_maxOutputValue(_sampledFrame, _outputNBpixels);
#ifdef IMAGELOGPOLPROJECTION_DEBUG
std::cout<<"ImageLogPolProjection::runProjection: gray level image projection OK"<<std::endl;
#endif
}
return _sampledFrame;
}
}// end of namespace bioinspired
}// end of namespace cv
@@ -1,243 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
#ifndef IMAGELOGPOLPROJECTION_H_
#define IMAGELOGPOLPROJECTION_H_
/**
* @class ImageLogPolProjection
* @brief class able to perform a log sampling of an image input (models the log sampling of the photoreceptors of the retina)
* or a log polar projection which models the retina information projection on the primary visual cortex: a linear projection in the center for detail analysis and a log projection of the borders (low spatial frequency motion information in general)
*
* collaboration: Barthelemy DURETTE who experimented the retina log projection
-> "Traitement visuels Bio mimtiques pour la supplance perceptive", internal technical report, May 2005, Gipsa-lab/DIS, Grenoble, FRANCE
*
* * TYPICAL USE:
*
* // create object, here for a log sampling (keyword:RETINALOGPROJECTION): (dynamic object allocation sample)
* ImageLogPolProjection *imageSamplingTool;
* imageSamplingTool = new ImageLogPolProjection(frameSizeRows, frameSizeColumns, RETINALOGPROJECTION);
*
* // init log projection:
* imageSamplingTool->initProjection(1.0, 15.0);
*
* // during program execution, call the log transform applied to a frame called "FrameBuffer" :
* imageSamplingTool->runProjection(FrameBuffer);
* // get output frame and its size:
* const unsigned int logSampledFrame_nbRows=imageSamplingTool->getOutputNBrows();
* const unsigned int logSampledFrame_nbColumns=imageSamplingTool->getOutputNBcolumns();
* const double *logSampledFrame=imageSamplingTool->getSampledFrame();
*
* // at the end of the program, destroy object:
* delete imageSamplingTool;
*
* @author Alexandre BENOIT, benoit.alexandre.vision@gmail.com, LISTIC : www.listic.univ-savoie.fr, Gipsa-Lab, France: www.gipsa-lab.inpg.fr/
* Creation date 2007
*/
//#define __IMAGELOGPOLPROJECTION_DEBUG // used for std output debug information
#include "basicretinafilter.hpp"
namespace cv
{
namespace bioinspired
{
class ImageLogPolProjection:public BasicRetinaFilter
{
public:
enum PROJECTIONTYPE{RETINALOGPROJECTION, CORTEXLOGPOLARPROJECTION};
/**
* constructor, just specifies the image input size and the projection type, no projection initialisation is done
* -> use initLogRetinaSampling() or initLogPolarCortexSampling() for that
* @param nbRows: number of rows of the input image
* @param nbColumns: number of columns of the input image
* @param projection: the type of projection, RETINALOGPROJECTION or CORTEXLOGPOLARPROJECTION
* @param colorMode: specifies if the projection is applied on a grayscale image (false) or color images (3 layers) (true)
*/
ImageLogPolProjection(const unsigned int nbRows, const unsigned int nbColumns, const PROJECTIONTYPE projection, const bool colorMode=false);
/**
* standard destructor
*/
virtual ~ImageLogPolProjection();
/**
* function that clears all buffers of the object
*/
void clearAllBuffers();
/**
* resize retina color filter object (resize all allocated buffers)
* @param NBrows: the new height size
* @param NBcolumns: the new width size
*/
void resize(const unsigned int NBrows, const unsigned int NBcolumns);
/**
* init function depending on the projection type
* @param reductionFactor: the size reduction factor of the ouptup image in regard of the size of the input image, must be superior to 1
* @param samplingStrenght: specifies the strenght of the log compression effect (magnifying coefficient)
* @return true if the init was performed without any errors
*/
bool initProjection(const double reductionFactor, const double samplingStrenght);
/**
* main funtion of the class: run projection function
* @param inputFrame: the input frame to be processed
* @param colorMode: the input buffer color mode: false=gray levels, true = 3 color channels mode
* @return the output frame
*/
std::valarray<float> &runProjection(const std::valarray<float> &inputFrame, const bool colorMode=false);
/**
* @return the numbers of rows (height) of the images OUTPUTS of the object
*/
inline unsigned int getOutputNBrows(){return _outputNBrows;};
/**
* @return the numbers of columns (width) of the images OUTPUTS of the object
*/
inline unsigned int getOutputNBcolumns(){return _outputNBcolumns;};
/**
* main funtion of the class: run projection function
* @param size: one of the input frame initial dimensions to be processed
* @return the output frame dimension
*/
inline static unsigned int predictOutputSize(const unsigned int size, const double reductionFactor){return (unsigned int)((double)size/reductionFactor);};
/**
* @return the output of the filter which applies an irregular Low Pass spatial filter to the imag input (see function
*/
inline const std::valarray<float> &getIrregularLPfilteredInputFrame() const {return _irregularLPfilteredFrame;};
/**
* function which allows to retrieve the output frame which was updated after the "runProjection(...) function BasicRetinaFilter::runProgressiveFilter(...)
* @return the projection result
*/
inline const std::valarray<float> &getSampledFrame() const {return _sampledFrame;};
/**
* function which allows gives the tranformation table, its size is (getNBrows()*getNBcolumns()*2)
* @return the transformation matrix [outputPixIndex_i, inputPixIndex_i, outputPixIndex_i+1, inputPixIndex_i+1....]
*/
inline const std::valarray<unsigned int> &getSamplingMap() const {return _transformTable;};
inline double getOriginalRadiusLength(const double projectedRadiusLength){return _azero/(_alim-projectedRadiusLength*2.0/_minDimension);};
// unsigned int getInputPixelIndex(const unsigned int ){ return _transformTable[index*2+1]};
private:
PROJECTIONTYPE _selectedProjection;
// size of the image output
unsigned int _outputNBrows;
unsigned int _outputNBcolumns;
unsigned int _outputNBpixels;
unsigned int _outputDoubleNBpixels;
unsigned int _inputDoubleNBpixels;
// is the object able to manage color flag
bool _colorModeCapable;
// sampling strenght factor
double _samplingStrenght;
// sampling reduction factor
double _reductionFactor;
// log sampling parameters
double _azero;
double _alim;
double _minDimension;
// template buffers
std::valarray<float>_sampledFrame;
std::valarray<float>&_tempBuffer;
std::valarray<unsigned int>_transformTable;
std::valarray<float> &_irregularLPfilteredFrame; // just a reference for easier understanding
unsigned int _usefullpixelIndex;
// init transformation tables
bool _computeLogProjection();
bool _computeLogPolarProjection();
// specifies if init was done correctly
bool _initOK;
// private init projections functions called by "initProjection(...)" function
bool _initLogRetinaSampling(const double reductionFactor, const double samplingStrenght);
bool _initLogPolarCortexSampling(const double reductionFactor, const double samplingStrenght);
ImageLogPolProjection(const ImageLogPolProjection&);
ImageLogPolProjection& operator=(const ImageLogPolProjection&);
};
}// end of namespace bioinspired
}// end of namespace cv
#endif /*IMAGELOGPOLPROJECTION_H_*/
@@ -1,212 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
#include "precomp.hpp"
#include <iostream>
#include "magnoretinafilter.hpp"
#include <cmath>
namespace cv
{
namespace bioinspired
{
// Constructor and Desctructor of the OPL retina filter
MagnoRetinaFilter::MagnoRetinaFilter(const unsigned int NBrows, const unsigned int NBcolumns)
:BasicRetinaFilter(NBrows, NBcolumns, 2),
_previousInput_ON(NBrows*NBcolumns),
_previousInput_OFF(NBrows*NBcolumns),
_amacrinCellsTempOutput_ON(NBrows*NBcolumns),
_amacrinCellsTempOutput_OFF(NBrows*NBcolumns),
_magnoXOutputON(NBrows*NBcolumns),
_magnoXOutputOFF(NBrows*NBcolumns),
_localProcessBufferON(NBrows*NBcolumns),
_localProcessBufferOFF(NBrows*NBcolumns)
{
_magnoYOutput=&_filterOutput;
_magnoYsaturated=&_localBuffer;
clearAllBuffers();
#ifdef IPL_RETINA_ELEMENT_DEBUG
std::cout<<"MagnoRetinaFilter::Init IPL retina filter at specified frame size OK"<<std::endl;
#endif
}
MagnoRetinaFilter::~MagnoRetinaFilter()
{
#ifdef IPL_RETINA_ELEMENT_DEBUG
std::cout<<"MagnoRetinaFilter::Delete IPL retina filter OK"<<std::endl;
#endif
}
// function that clears all buffers of the object
void MagnoRetinaFilter::clearAllBuffers()
{
BasicRetinaFilter::clearAllBuffers();
_previousInput_ON=0;
_previousInput_OFF=0;
_amacrinCellsTempOutput_ON=0;
_amacrinCellsTempOutput_OFF=0;
_magnoXOutputON=0;
_magnoXOutputOFF=0;
_localProcessBufferON=0;
_localProcessBufferOFF=0;
}
/**
* resize retina magno filter object (resize all allocated buffers
* @param NBrows: the new height size
* @param NBcolumns: the new width size
*/
void MagnoRetinaFilter::resize(const unsigned int NBrows, const unsigned int NBcolumns)
{
BasicRetinaFilter::resize(NBrows, NBcolumns);
_previousInput_ON.resize(NBrows*NBcolumns);
_previousInput_OFF.resize(NBrows*NBcolumns);
_amacrinCellsTempOutput_ON.resize(NBrows*NBcolumns);
_amacrinCellsTempOutput_OFF.resize(NBrows*NBcolumns);
_magnoXOutputON.resize(NBrows*NBcolumns);
_magnoXOutputOFF.resize(NBrows*NBcolumns);
_localProcessBufferON.resize(NBrows*NBcolumns);
_localProcessBufferOFF.resize(NBrows*NBcolumns);
// to be sure, relink buffers
_magnoYOutput=&_filterOutput;
_magnoYsaturated=&_localBuffer;
// reset all buffers
clearAllBuffers();
}
void MagnoRetinaFilter::setCoefficientsTable(const float parasolCells_beta, const float parasolCells_tau, const float parasolCells_k, const float amacrinCellsTemporalCutFrequency, const float localAdaptIntegration_tau, const float localAdaptIntegration_k )
{
_temporalCoefficient=(float)std::exp(-1.0f/amacrinCellsTemporalCutFrequency);
// the first set of parameters is dedicated to the low pass filtering property of the ganglion cells
BasicRetinaFilter::setLPfilterParameters(parasolCells_beta, parasolCells_tau, parasolCells_k, 0);
// the second set of parameters is dedicated to the ganglion cells output intergartion for their local adaptation property
BasicRetinaFilter::setLPfilterParameters(0, localAdaptIntegration_tau, localAdaptIntegration_k, 1);
}
void MagnoRetinaFilter::_amacrineCellsComputing(const float *OPL_ON, const float *OPL_OFF)
{
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(0,_filterOutput.getNBpixels()), Parallel_amacrineCellsComputing(OPL_ON, OPL_OFF, &_previousInput_ON[0], &_previousInput_OFF[0], &_amacrinCellsTempOutput_ON[0], &_amacrinCellsTempOutput_OFF[0], _temporalCoefficient));
#else
register const float *OPL_ON_PTR=OPL_ON;
register const float *OPL_OFF_PTR=OPL_OFF;
register float *previousInput_ON_PTR= &_previousInput_ON[0];
register float *previousInput_OFF_PTR= &_previousInput_OFF[0];
register float *amacrinCellsTempOutput_ON_PTR= &_amacrinCellsTempOutput_ON[0];
register float *amacrinCellsTempOutput_OFF_PTR= &_amacrinCellsTempOutput_OFF[0];
for (unsigned int IDpixel=0 ; IDpixel<this->getNBpixels(); ++IDpixel)
{
/* Compute ON and OFF amacrin cells high pass temporal filter */
float magnoXonPixelResult = _temporalCoefficient*(*amacrinCellsTempOutput_ON_PTR+ *OPL_ON_PTR-*previousInput_ON_PTR);
*(amacrinCellsTempOutput_ON_PTR++)=((float)(magnoXonPixelResult>0))*magnoXonPixelResult;
float magnoXoffPixelResult = _temporalCoefficient*(*amacrinCellsTempOutput_OFF_PTR+ *OPL_OFF_PTR-*previousInput_OFF_PTR);
*(amacrinCellsTempOutput_OFF_PTR++)=((float)(magnoXoffPixelResult>0))*magnoXoffPixelResult;
/* prepare next loop */
*(previousInput_ON_PTR++)=*(OPL_ON_PTR++);
*(previousInput_OFF_PTR++)=*(OPL_OFF_PTR++);
}
#endif
}
// launch filter that runs all the IPL filter
const std::valarray<float> &MagnoRetinaFilter::runFilter(const std::valarray<float> &OPL_ON, const std::valarray<float> &OPL_OFF)
{
// Compute the high pass temporal filter
_amacrineCellsComputing(get_data(OPL_ON), get_data(OPL_OFF));
// apply low pass filtering on ON and OFF ways after temporal high pass filtering
_spatiotemporalLPfilter(&_amacrinCellsTempOutput_ON[0], &_magnoXOutputON[0], 0);
_spatiotemporalLPfilter(&_amacrinCellsTempOutput_OFF[0], &_magnoXOutputOFF[0], 0);
// local adaptation of the ganglion cells to the local contrast of the moving contours
_spatiotemporalLPfilter(&_magnoXOutputON[0], &_localProcessBufferON[0], 1);
_localLuminanceAdaptation(&_magnoXOutputON[0], &_localProcessBufferON[0]);
_spatiotemporalLPfilter(&_magnoXOutputOFF[0], &_localProcessBufferOFF[0], 1);
_localLuminanceAdaptation(&_magnoXOutputOFF[0], &_localProcessBufferOFF[0]);
/* Compute MagnoY */
register float *magnoYOutput= &(*_magnoYOutput)[0];
register float *magnoXOutputON_PTR= &_magnoXOutputON[0];
register float *magnoXOutputOFF_PTR= &_magnoXOutputOFF[0];
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel)
*(magnoYOutput++)=*(magnoXOutputON_PTR++)+*(magnoXOutputOFF_PTR++);
return (*_magnoYOutput);
}
}// end of namespace bioinspired
}// end of namespace cv
@@ -1,245 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
#ifndef MagnoRetinaFilter_H_
#define MagnoRetinaFilter_H_
/**
* @class MagnoRetinaFilter
* @brief class which describes the magnocellular channel of the retina:
* -> performs a moving contours extraction with powerfull local data enhancement
*
* TYPICAL USE:
*
* // create object at a specified picture size
* MagnoRetinaFilter *movingContoursExtractor;
* movingContoursExtractor =new MagnoRetinaFilter(frameSizeRows, frameSizeColumns);
*
* // init gain, spatial and temporal parameters:
* movingContoursExtractor->setCoefficientsTable(0, 0.7, 5, 3);
*
* // during program execution, call the filter for contours extraction for an input picture called "FrameBuffer":
* movingContoursExtractor->runfilter(FrameBuffer);
*
* // get the output frame, check in the class description below for more outputs:
* const float *movingContours=movingContoursExtractor->getMagnoYsaturated();
*
* // at the end of the program, destroy object:
* delete movingContoursExtractor;
* @author Alexandre BENOIT, benoit.alexandre.vision@gmail.com, LISTIC : www.listic.univ-savoie.fr, Gipsa-Lab, France: www.gipsa-lab.inpg.fr/
* Creation date 2007
* Based on Alexandre BENOIT thesis: "Le système visuel humain au secours de la vision par ordinateur"
*/
#include "basicretinafilter.hpp"
//#define _IPL_RETINA_ELEMENT_DEBUG
namespace cv
{
namespace bioinspired
{
class MagnoRetinaFilter: public BasicRetinaFilter
{
public:
/**
* constructor parameters are only linked to image input size
* @param NBrows: number of rows of the input image
* @param NBcolumns: number of columns of the input image
*/
MagnoRetinaFilter(const unsigned int NBrows, const unsigned int NBcolumns);
/**
* destructor
*/
virtual ~MagnoRetinaFilter();
/**
* function that clears all buffers of the object
*/
void clearAllBuffers();
/**
* resize retina magno filter object (resize all allocated buffers)
* @param NBrows: the new height size
* @param NBcolumns: the new width size
*/
void resize(const unsigned int NBrows, const unsigned int NBcolumns);
/**
* set parameters values
* @param parasolCells_beta: the low pass filter gain used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), typical value is 0
* @param parasolCells_tau: the low pass filter time constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is frame, typical value is 0 (immediate response)
* @param parasolCells_k: the low pass filter spatial constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is pixels, typical value is 5
* @param amacrinCellsTemporalCutFrequency: the time constant of the first order high pass fiter of the magnocellular way (motion information channel), unit is frames, tipicall value is 5
* @param localAdaptIntegration_tau: specifies the temporal constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
* @param localAdaptIntegration_k: specifies the spatial constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
*/
void setCoefficientsTable(const float parasolCells_beta, const float parasolCells_tau, const float parasolCells_k, const float amacrinCellsTemporalCutFrequency, const float localAdaptIntegration_tau, const float localAdaptIntegration_k);
/**
* launch filter that runs all the IPL magno filter (model of the magnocellular channel of the Inner Plexiform Layer of the retina)
* @param OPL_ON: the output of the bipolar ON cells of the retina (available from the ParvoRetinaFilter class (getBipolarCellsON() function)
* @param OPL_OFF: the output of the bipolar OFF cells of the retina (available from the ParvoRetinaFilter class (getBipolarCellsOFF() function)
* @return the processed result without post-processing
*/
const std::valarray<float> &runFilter(const std::valarray<float> &OPL_ON, const std::valarray<float> &OPL_OFF);
/**
* @return the Magnocellular ON channel filtering output
*/
inline const std::valarray<float> &getMagnoON() const {return _magnoXOutputON;};
/**
* @return the Magnocellular OFF channel filtering output
*/
inline const std::valarray<float> &getMagnoOFF() const {return _magnoXOutputOFF;};
/**
* @return the Magnocellular Y (sum of the ON and OFF magno channels) filtering output
*/
inline const std::valarray<float> &getMagnoYsaturated() const {return *_magnoYsaturated;};
/**
* applies an image normalization which saturates the high output values by the use of an assymetric sigmoide
*/
inline void normalizeGrayOutputNearZeroCentreredSigmoide(){_filterOutput.normalizeGrayOutputNearZeroCentreredSigmoide(&(*_magnoYOutput)[0], &(*_magnoYsaturated)[0]);};
/**
* @return the horizontal cells' temporal constant
*/
inline float getTemporalConstant(){return this->_filteringCoeficientsTable[2];};
private:
// related pointers to these buffers
std::valarray<float> _previousInput_ON;
std::valarray<float> _previousInput_OFF;
std::valarray<float> _amacrinCellsTempOutput_ON;
std::valarray<float> _amacrinCellsTempOutput_OFF;
std::valarray<float> _magnoXOutputON;
std::valarray<float> _magnoXOutputOFF;
std::valarray<float> _localProcessBufferON;
std::valarray<float> _localProcessBufferOFF;
// reference to parent buffers and allow better readability
TemplateBuffer<float> *_magnoYOutput;
std::valarray<float> *_magnoYsaturated;
// varialbles
float _temporalCoefficient;
// amacrine cells filter : high pass temporal filter
void _amacrineCellsComputing(const float *ONinput, const float *OFFinput);
#ifdef MAKE_PARALLEL
/******************************************************
** IF some parallelizing thread methods are available, then, main loops are parallelized using these functors
** ==> main idea paralellise main filters loops, then, only the most used methods are parallelized... TODO : increase the number of parallelised methods as necessary
** ==> functors names = Parallel_$$$ where $$$= the name of the serial method that is parallelised
** ==> functors constructors can differ from the parameters used with their related serial functions
*/
class Parallel_amacrineCellsComputing: public cv::ParallelLoopBody
{
private:
const float *OPL_ON, *OPL_OFF;
float *previousInput_ON, *previousInput_OFF, *amacrinCellsTempOutput_ON, *amacrinCellsTempOutput_OFF;
float temporalCoefficient;
public:
Parallel_amacrineCellsComputing(const float *OPL_ON_PTR, const float *OPL_OFF_PTR, float *previousInput_ON_PTR, float *previousInput_OFF_PTR, float *amacrinCellsTempOutput_ON_PTR, float *amacrinCellsTempOutput_OFF_PTR, float temporalCoefficientVal)
:OPL_ON(OPL_ON_PTR), OPL_OFF(OPL_OFF_PTR), previousInput_ON(previousInput_ON_PTR), previousInput_OFF(previousInput_OFF_PTR), amacrinCellsTempOutput_ON(amacrinCellsTempOutput_ON_PTR), amacrinCellsTempOutput_OFF(amacrinCellsTempOutput_OFF_PTR), temporalCoefficient(temporalCoefficientVal) {}
virtual void operator()( const Range& r ) const {
register const float *OPL_ON_PTR=OPL_ON+r.start;
register const float *OPL_OFF_PTR=OPL_OFF+r.start;
register float *previousInput_ON_PTR= previousInput_ON+r.start;
register float *previousInput_OFF_PTR= previousInput_OFF+r.start;
register float *amacrinCellsTempOutput_ON_PTR= amacrinCellsTempOutput_ON+r.start;
register float *amacrinCellsTempOutput_OFF_PTR= amacrinCellsTempOutput_OFF+r.start;
for (int IDpixel=r.start ; IDpixel!=r.end; ++IDpixel)
{
/* Compute ON and OFF amacrin cells high pass temporal filter */
float magnoXonPixelResult = temporalCoefficient*(*amacrinCellsTempOutput_ON_PTR+ *OPL_ON_PTR-*previousInput_ON_PTR);
*(amacrinCellsTempOutput_ON_PTR++)=((float)(magnoXonPixelResult>0))*magnoXonPixelResult;
float magnoXoffPixelResult = temporalCoefficient*(*amacrinCellsTempOutput_OFF_PTR+ *OPL_OFF_PTR-*previousInput_OFF_PTR);
*(amacrinCellsTempOutput_OFF_PTR++)=((float)(magnoXoffPixelResult>0))*magnoXoffPixelResult;
/* prepare next loop */
*(previousInput_ON_PTR++)=*(OPL_ON_PTR++);
*(previousInput_OFF_PTR++)=*(OPL_OFF_PTR++);
}
}
};
#endif
};
}// end of namespace bioinspired
}// end of namespace cv
#endif /*MagnoRetinaFilter_H_*/
@@ -1,779 +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) 2010-2013, Multicoreware, Inc., all rights reserved.
// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
// Peng Xiao, pengxiao@multicorewareinc.com
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other oclMaterials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors as is and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
//data (which is float) is aligend in 32 bytes
#define WIDTH_MULTIPLE (32 >> 2)
/////////////////////////////////////////////////////////
//*******************************************************
// basicretinafilter
//////////////// _spatiotemporalLPfilter ////////////////
//_horizontalCausalFilter_addInput
kernel void horizontalCausalFilter_addInput(
global const float * input,
global float * output,
const int cols,
const int rows,
const int elements_per_row,
const int in_offset,
const int out_offset,
const float _tau,
const float _a
)
{
int gid = get_global_id(0);
if(gid >= rows)
{
return;
}
global const float * iptr =
input + mad24(gid, elements_per_row, in_offset / 4);
global float * optr =
output + mad24(gid, elements_per_row, out_offset / 4);
float res;
float4 in_v4, out_v4, res_v4 = (float4)(0);
//vectorize to increase throughput
for(int i = 0; i < cols / 4; ++i, iptr += 4, optr += 4)
{
in_v4 = vload4(0, iptr);
out_v4 = vload4(0, optr);
res_v4.x = in_v4.x + _tau * out_v4.x + _a * res_v4.w;
res_v4.y = in_v4.y + _tau * out_v4.y + _a * res_v4.x;
res_v4.z = in_v4.z + _tau * out_v4.z + _a * res_v4.y;
res_v4.w = in_v4.w + _tau * out_v4.w + _a * res_v4.z;
vstore4(res_v4, 0, optr);
}
res = res_v4.w;
// there may be left some
for(int i = 0; i < cols % 4; ++i, ++iptr, ++optr)
{
res = *iptr + _tau * *optr + _a * res;
*optr = res;
}
}
//_horizontalAnticausalFilter
kernel void horizontalAnticausalFilter(
global float * output,
const int cols,
const int rows,
const int elements_per_row,
const int out_offset,
const float _a
)
{
int gid = get_global_id(0);
if(gid >= rows)
{
return;
}
global float * optr = output +
mad24(gid + 1, elements_per_row, - 1 + out_offset / 4);
float4 result_v4 = (float4)(0), out_v4;
float result = 0;
// we assume elements_per_row is multple of WIDTH_MULTIPLE
for(int i = 0; i < WIDTH_MULTIPLE; ++ i, -- optr)
{
if(i >= elements_per_row - cols)
{
result = *optr + _a * result;
}
*optr = result;
}
result_v4.x = result;
optr -= 3;
for(int i = WIDTH_MULTIPLE / 4; i < elements_per_row / 4; ++i, optr -= 4)
{
// shift left, `offset` is type `size_t` so it cannot be negative
out_v4 = vload4(0, optr);
result_v4.w = out_v4.w + _a * result_v4.x;
result_v4.z = out_v4.z + _a * result_v4.w;
result_v4.y = out_v4.y + _a * result_v4.z;
result_v4.x = out_v4.x + _a * result_v4.y;
vstore4(result_v4, 0, optr);
}
}
//_verticalCausalFilter
kernel void verticalCausalFilter(
global float * output,
const int cols,
const int rows,
const int elements_per_row,
const int out_offset,
const float _a
)
{
int gid = get_global_id(0);
if(gid >= cols)
{
return;
}
global float * optr = output + gid + out_offset / 4;
float result = 0;
for(int i = 0; i < rows; ++i, optr += elements_per_row)
{
result = *optr + _a * result;
*optr = result;
}
}
//_verticalCausalFilter
kernel void verticalAnticausalFilter_multGain(
global float * output,
const int cols,
const int rows,
const int elements_per_row,
const int out_offset,
const float _a,
const float _gain
)
{
int gid = get_global_id(0);
if(gid >= cols)
{
return;
}
global float * optr = output + (rows - 1) * elements_per_row + gid + out_offset / 4;
float result = 0;
for(int i = 0; i < rows; ++i, optr -= elements_per_row)
{
result = *optr + _a * result;
*optr = _gain * result;
}
}
//
// end of _spatiotemporalLPfilter
/////////////////////////////////////////////////////////////////////
//////////////// horizontalAnticausalFilter_Irregular ////////////////
kernel void horizontalAnticausalFilter_Irregular(
global float * output,
global float * buffer,
const int cols,
const int rows,
const int elements_per_row,
const int out_offset,
const int buffer_offset
)
{
int gid = get_global_id(0);
if(gid >= rows)
{
return;
}
global float * optr =
output + mad24(rows - gid, elements_per_row, -1 + out_offset / 4);
global float * bptr =
buffer + mad24(rows - gid, elements_per_row, -1 + buffer_offset / 4);
float4 buf_v4, out_v4, res_v4 = (float4)(0);
float result = 0;
// we assume elements_per_row is multple of WIDTH_MULTIPLE
for(int i = 0; i < WIDTH_MULTIPLE; ++ i, -- optr, -- bptr)
{
if(i >= elements_per_row - cols)
{
result = *optr + *bptr * result;
}
*optr = result;
}
res_v4.x = result;
optr -= 3;
bptr -= 3;
for(int i = WIDTH_MULTIPLE / 4; i < elements_per_row / 4; ++i, optr -= 4, bptr -= 4)
{
buf_v4 = vload4(0, bptr);
out_v4 = vload4(0, optr);
res_v4.w = out_v4.w + buf_v4.w * res_v4.x;
res_v4.z = out_v4.z + buf_v4.z * res_v4.w;
res_v4.y = out_v4.y + buf_v4.y * res_v4.z;
res_v4.x = out_v4.x + buf_v4.x * res_v4.y;
vstore4(res_v4, 0, optr);
}
}
//////////////// verticalCausalFilter_Irregular ////////////////
kernel void verticalCausalFilter_Irregular(
global float * output,
global float * buffer,
const int cols,
const int rows,
const int elements_per_row,
const int out_offset,
const int buffer_offset
)
{
int gid = get_global_id(0);
if(gid >= cols)
{
return;
}
global float * optr = output + gid + out_offset / 4;
global float * bptr = buffer + gid + buffer_offset / 4;
float result = 0;
for(int i = 0; i < rows; ++i, optr += elements_per_row, bptr += elements_per_row)
{
result = *optr + *bptr * result;
*optr = result;
}
}
//////////////// _adaptiveHorizontalCausalFilter_addInput ////////////////
kernel void adaptiveHorizontalCausalFilter_addInput(
global const float * input,
global const float * gradient,
global float * output,
const int cols,
const int rows,
const int elements_per_row,
const int in_offset,
const int grad_offset,
const int out_offset
)
{
int gid = get_global_id(0);
if(gid >= rows)
{
return;
}
global const float * iptr =
input + mad24(gid, elements_per_row, in_offset / 4);
global const float * gptr =
gradient + mad24(gid, elements_per_row, grad_offset / 4);
global float * optr =
output + mad24(gid, elements_per_row, out_offset / 4);
float4 in_v4, grad_v4, out_v4, res_v4 = (float4)(0);
for(int i = 0; i < cols / 4; ++i, iptr += 4, gptr += 4, optr += 4)
{
in_v4 = vload4(0, iptr);
grad_v4 = vload4(0, gptr);
res_v4.x = in_v4.x + grad_v4.x * res_v4.w;
res_v4.y = in_v4.y + grad_v4.y * res_v4.x;
res_v4.z = in_v4.z + grad_v4.z * res_v4.y;
res_v4.w = in_v4.w + grad_v4.w * res_v4.z;
vstore4(res_v4, 0, optr);
}
for(int i = 0; i < cols % 4; ++i, ++iptr, ++gptr, ++optr)
{
res_v4.w = *iptr + *gptr * res_v4.w;
*optr = res_v4.w;
}
}
//////////////// _adaptiveVerticalAnticausalFilter_multGain ////////////////
kernel void adaptiveVerticalAnticausalFilter_multGain(
global const float * gradient,
global float * output,
const int cols,
const int rows,
const int elements_per_row,
const int grad_offset,
const int out_offset,
const float gain
)
{
int gid = get_global_id(0);
if(gid >= cols)
{
return;
}
int start_idx = mad24(rows - 1, elements_per_row, gid);
global const float * gptr = gradient + start_idx + grad_offset / 4;
global float * optr = output + start_idx + out_offset / 4;
float result = 0;
for(int i = 0; i < rows; ++i, gptr -= elements_per_row, optr -= elements_per_row)
{
result = *optr + *gptr * result;
*optr = gain * result;
}
}
//////////////// _localLuminanceAdaptation ////////////////
// FIXME:
// This kernel seems to have precision problem on GPU
kernel void localLuminanceAdaptation(
global const float * luma,
global const float * input,
global float * output,
const int cols,
const int rows,
const int elements_per_row,
const float _localLuminanceAddon,
const float _localLuminanceFactor,
const float _maxInputValue
)
{
int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx >= cols || gidy >= rows)
{
return;
}
int offset = mad24(gidy, elements_per_row, gidx);
float X0 = luma[offset] * _localLuminanceFactor + _localLuminanceAddon;
float input_val = input[offset];
// output of the following line may be different between GPU and CPU
output[offset] = (_maxInputValue + X0) * input_val / (input_val + X0 + 0.00000000001f);
}
// end of basicretinafilter
//*******************************************************
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//******************************************************
// magno
// TODO: this kernel has too many buffer accesses, better to make it
// vector read/write for fetch efficiency
kernel void amacrineCellsComputing(
global const float * opl_on,
global const float * opl_off,
global float * prev_in_on,
global float * prev_in_off,
global float * out_on,
global float * out_off,
const int cols,
const int rows,
const int elements_per_row,
const float coeff
)
{
int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx >= cols || gidy >= rows)
{
return;
}
int offset = mad24(gidy, elements_per_row, gidx);
opl_on += offset;
opl_off += offset;
prev_in_on += offset;
prev_in_off += offset;
out_on += offset;
out_off += offset;
float magnoXonPixelResult = coeff * (*out_on + *opl_on - *prev_in_on);
*out_on = fmax(magnoXonPixelResult, 0);
float magnoXoffPixelResult = coeff * (*out_off + *opl_off - *prev_in_off);
*out_off = fmax(magnoXoffPixelResult, 0);
*prev_in_on = *opl_on;
*prev_in_off = *opl_off;
}
/////////////////////////////////////////////////////////
//******************************************************
// parvo
// TODO: this kernel has too many buffer accesses, needs optimization
kernel void OPL_OnOffWaysComputing(
global float4 * photo_out,
global float4 * horiz_out,
global float4 * bipol_on,
global float4 * bipol_off,
global float4 * parvo_on,
global float4 * parvo_off,
const int cols,
const int rows,
const int elements_per_row
)
{
int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx * 4 >= cols || gidy >= rows)
{
return;
}
// we assume elements_per_row must be multiples of 4
int offset = mad24(gidy, elements_per_row >> 2, gidx);
photo_out += offset;
horiz_out += offset;
bipol_on += offset;
bipol_off += offset;
parvo_on += offset;
parvo_off += offset;
float4 diff = *photo_out - *horiz_out;
float4 isPositive;// = convert_float4(diff > (float4)(0.0f, 0.0f, 0.0f, 0.0f));
isPositive.x = diff.x > 0.0f;
isPositive.y = diff.y > 0.0f;
isPositive.z = diff.z > 0.0f;
isPositive.w = diff.w > 0.0f;
float4 res_on = isPositive * diff;
float4 res_off = (isPositive - (float4)(1.0f)) * diff;
*bipol_on = res_on;
*parvo_on = res_on;
*bipol_off = res_off;
*parvo_off = res_off;
}
/////////////////////////////////////////////////////////
//******************************************************
// retinacolor
inline int bayerSampleOffset(int step, int rows, int x, int y)
{
return mad24(y, step, x) +
((y % 2) + (x % 2)) * rows * step;
}
/////// colorMultiplexing //////
kernel void runColorMultiplexingBayer(
global const float * input,
global float * output,
const int cols,
const int rows,
const int elements_per_row
)
{
int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx >= cols || gidy >= rows)
{
return;
}
int offset = mad24(gidy, elements_per_row, gidx);
output[offset] = input[bayerSampleOffset(elements_per_row, rows, gidx, gidy)];
}
kernel void runColorDemultiplexingBayer(
global const float * input,
global float * output,
const int cols,
const int rows,
const int elements_per_row
)
{
int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx >= cols || gidy >= rows)
{
return;
}
int offset = mad24(gidy, elements_per_row, gidx);
output[bayerSampleOffset(elements_per_row, rows, gidx, gidy)] = input[offset];
}
kernel void demultiplexAssign(
global const float * input,
global float * output,
const int cols,
const int rows,
const int elements_per_row
)
{
int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx >= cols || gidy >= rows)
{
return;
}
int offset = bayerSampleOffset(elements_per_row, rows, gidx, gidy);
output[offset] = input[offset];
}
//// normalizeGrayOutputCentredSigmoide
kernel void normalizeGrayOutputCentredSigmoide(
global const float * input,
global float * output,
const int cols,
const int rows,
const int elements_per_row,
const float meanval,
const float X0
)
{
int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx >= cols || gidy >= rows)
{
return;
}
int offset = mad24(gidy, elements_per_row, gidx);
float input_val = input[offset];
output[offset] = meanval +
(meanval + X0) * (input_val - meanval) / (fabs(input_val - meanval) + X0);
}
//// normalize by photoreceptors density
kernel void normalizePhotoDensity(
global const float * chroma,
global const float * colorDensity,
global const float * multiplex,
global float * luma,
global float * demultiplex,
const int cols,
const int rows,
const int elements_per_row,
const float pG
)
{
const int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx >= cols || gidy >= rows)
{
return;
}
const int offset = mad24(gidy, elements_per_row, gidx);
int index = offset;
float Cr = chroma[index] * colorDensity[index];
index += elements_per_row * rows;
float Cg = chroma[index] * colorDensity[index];
index += elements_per_row * rows;
float Cb = chroma[index] * colorDensity[index];
const float luma_res = (Cr + Cg + Cb) * pG;
luma[offset] = luma_res;
demultiplex[bayerSampleOffset(elements_per_row, rows, gidx, gidy)] =
multiplex[offset] - luma_res;
}
//////// computeGradient ///////
// TODO:
// this function maybe accelerated by image2d_t or lds
kernel void computeGradient(
global const float * luma,
global float * gradient,
const int cols,
const int rows,
const int elements_per_row
)
{
int gidx = get_global_id(0) + 2, gidy = get_global_id(1) + 2;
if(gidx >= cols - 2 || gidy >= rows - 2)
{
return;
}
int offset = mad24(gidy, elements_per_row, gidx);
luma += offset;
// horizontal and vertical local gradients
const float v_grad = fabs(luma[elements_per_row] - luma[- elements_per_row]);
const float h_grad = fabs(luma[1] - luma[-1]);
// neighborhood horizontal and vertical gradients
const float cur_val = luma[0];
const float v_grad_p = fabs(cur_val - luma[- 2 * elements_per_row]);
const float h_grad_p = fabs(cur_val - luma[- 2]);
const float v_grad_n = fabs(cur_val - luma[2 * elements_per_row]);
const float h_grad_n = fabs(cur_val - luma[2]);
const float horiz_grad = 0.5f * h_grad + 0.25f * (h_grad_p + h_grad_n);
const float verti_grad = 0.5f * v_grad + 0.25f * (v_grad_p + v_grad_n);
const bool is_vertical_greater = horiz_grad < verti_grad;
gradient[offset + elements_per_row * rows] = is_vertical_greater ? 0.06f : 0.57f;
gradient[offset ] = is_vertical_greater ? 0.57f : 0.06f;
}
/////// substractResidual ///////
kernel void substractResidual(
global float * input,
const int cols,
const int rows,
const int elements_per_row,
const float pR,
const float pG,
const float pB
)
{
const int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx >= cols || gidy >= rows)
{
return;
}
int indices [3] =
{
mad24(gidy, elements_per_row, gidx),
mad24(gidy + rows, elements_per_row, gidx),
mad24(gidy + 2 * rows, elements_per_row, gidx)
};
float vals[3] = {input[indices[0]], input[indices[1]], input[indices[2]]};
float residu = pR * vals[0] + pG * vals[1] + pB * vals[2];
input[indices[0]] = vals[0] - residu;
input[indices[1]] = vals[1] - residu;
input[indices[2]] = vals[2] - residu;
}
///// clipRGBOutput_0_maxInputValue /////
kernel void clipRGBOutput_0_maxInputValue(
global float * input,
const int cols,
const int rows,
const int elements_per_row,
const float maxVal
)
{
const int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx >= cols || gidy >= rows)
{
return;
}
const int offset = mad24(gidy, elements_per_row, gidx);
float val = input[offset];
val = clamp(val, 0.0f, maxVal);
input[offset] = val;
}
//// normalizeGrayOutputNearZeroCentreredSigmoide ////
kernel void normalizeGrayOutputNearZeroCentreredSigmoide(
global float * input,
global float * output,
const int cols,
const int rows,
const int elements_per_row,
const float maxVal,
const float X0cube
)
{
const int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx >= cols || gidy >= rows)
{
return;
}
const int offset = mad24(gidy, elements_per_row, gidx);
float currentCubeLuminance = input[offset];
currentCubeLuminance = currentCubeLuminance * currentCubeLuminance * currentCubeLuminance;
output[offset] = currentCubeLuminance * X0cube / (X0cube + currentCubeLuminance);
}
//// centerReductImageLuminance ////
kernel void centerReductImageLuminance(
global float * input,
const int cols,
const int rows,
const int elements_per_row,
const float mean,
const float std_dev
)
{
const int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx >= cols || gidy >= rows)
{
return;
}
const int offset = mad24(gidy, elements_per_row, gidx);
float val = input[offset];
input[offset] = (val - mean) / std_dev;
}
//// inverseValue ////
kernel void inverseValue(
global float * input,
const int cols,
const int rows,
const int elements_per_row
)
{
const int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx >= cols || gidy >= rows)
{
return;
}
const int offset = mad24(gidy, elements_per_row, gidx);
input[offset] = 1.f / input[offset];
}
#define CV_PI 3.1415926535897932384626433832795
//// _processRetinaParvoMagnoMapping ////
kernel void processRetinaParvoMagnoMapping(
global float * parvo,
global float * magno,
global float * output,
const int cols,
const int rows,
const int halfCols,
const int halfRows,
const int elements_per_row,
const float minDistance
)
{
const int gidx = get_global_id(0), gidy = get_global_id(1);
if(gidx >= cols || gidy >= rows)
{
return;
}
const int offset = mad24(gidy, elements_per_row, gidx);
float distanceToCenter =
sqrt(((float)(gidy - halfRows) * (gidy - halfRows) + (gidx - halfCols) * (gidx - halfCols)));
float a = distanceToCenter < minDistance ?
(0.5f + 0.5f * (float)cos(CV_PI * distanceToCenter / minDistance)) : 0;
float b = 1.f - a;
output[offset] = parvo[offset] * a + magno[offset] * b;
}
@@ -1,233 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
#include "precomp.hpp"
#include "parvoretinafilter.hpp"
// @author Alexandre BENOIT, benoit.alexandre.vision@gmail.com, LISTIC : www.listic.univ-savoie.fr, Gipsa-Lab, France: www.gipsa-lab.inpg.fr/
#include <iostream>
#include <cmath>
namespace cv
{
namespace bioinspired
{
//////////////////////////////////////////////////////////
// OPL RETINA FILTER
//////////////////////////////////////////////////////////
// Constructor and Desctructor of the OPL retina filter
ParvoRetinaFilter::ParvoRetinaFilter(const unsigned int NBrows, const unsigned int NBcolumns)
:BasicRetinaFilter(NBrows, NBcolumns, 3),
_photoreceptorsOutput(NBrows*NBcolumns),
_horizontalCellsOutput(NBrows*NBcolumns),
_parvocellularOutputON(NBrows*NBcolumns),
_parvocellularOutputOFF(NBrows*NBcolumns),
_bipolarCellsOutputON(NBrows*NBcolumns),
_bipolarCellsOutputOFF(NBrows*NBcolumns),
_localAdaptationOFF(NBrows*NBcolumns)
{
// link to the required local parent adaptation buffers
_localAdaptationON=&_localBuffer;
_parvocellularOutputONminusOFF=&_filterOutput;
// (*_localAdaptationON)=&_localBuffer;
// (*_parvocellularOutputONminusOFF)=&(BasicRetinaFilter::TemplateBuffer);
// init: set all the values to 0
clearAllBuffers();
#ifdef OPL_RETINA_ELEMENT_DEBUG
std::cout<<"ParvoRetinaFilter::Init OPL retina filter at specified frame size OK\n"<<std::endl;
#endif
}
ParvoRetinaFilter::~ParvoRetinaFilter()
{
#ifdef OPL_RETINA_ELEMENT_DEBUG
std::cout<<"ParvoRetinaFilter::Delete OPL retina filter OK"<<std::endl;
#endif
}
////////////////////////////////////
// functions of the PARVO filter
////////////////////////////////////
// function that clears all buffers of the object
void ParvoRetinaFilter::clearAllBuffers()
{
BasicRetinaFilter::clearAllBuffers();
_photoreceptorsOutput=0;
_horizontalCellsOutput=0;
_parvocellularOutputON=0;
_parvocellularOutputOFF=0;
_bipolarCellsOutputON=0;
_bipolarCellsOutputOFF=0;
_localAdaptationOFF=0;
}
/**
* resize parvo retina filter object (resize all allocated buffers
* @param NBrows: the new height size
* @param NBcolumns: the new width size
*/
void ParvoRetinaFilter::resize(const unsigned int NBrows, const unsigned int NBcolumns)
{
BasicRetinaFilter::resize(NBrows, NBcolumns);
_photoreceptorsOutput.resize(NBrows*NBcolumns);
_horizontalCellsOutput.resize(NBrows*NBcolumns);
_parvocellularOutputON.resize(NBrows*NBcolumns);
_parvocellularOutputOFF.resize(NBrows*NBcolumns);
_bipolarCellsOutputON.resize(NBrows*NBcolumns);
_bipolarCellsOutputOFF.resize(NBrows*NBcolumns);
_localAdaptationOFF.resize(NBrows*NBcolumns);
// link to the required local parent adaptation buffers
_localAdaptationON=&_localBuffer;
_parvocellularOutputONminusOFF=&_filterOutput;
// clean buffers
clearAllBuffers();
}
// change the parameters of the filter
void ParvoRetinaFilter::setOPLandParvoFiltersParameters(const float beta1, const float tau1, const float k1, const float beta2, const float tau2, const float k2)
{
// init photoreceptors low pass filter
setLPfilterParameters(beta1, tau1, k1);
// init horizontal cells low pass filter
setLPfilterParameters(beta2, tau2, k2, 1);
// init parasol ganglion cells low pass filter (default parameters)
setLPfilterParameters(0, tau1, k1, 2);
}
// update/set size of the frames
// run filter for a new frame input
// output return is (*_parvocellularOutputONminusOFF)
const std::valarray<float> &ParvoRetinaFilter::runFilter(const std::valarray<float> &inputFrame, const bool useParvoOutput)
{
_spatiotemporalLPfilter(get_data(inputFrame), &_photoreceptorsOutput[0]);
_spatiotemporalLPfilter(&_photoreceptorsOutput[0], &_horizontalCellsOutput[0], 1);
_OPL_OnOffWaysComputing();
if (useParvoOutput)
{
// local adaptation processes on ON and OFF ways
_spatiotemporalLPfilter(&_bipolarCellsOutputON[0], &(*_localAdaptationON)[0], 2);
_localLuminanceAdaptation(&_parvocellularOutputON[0], &(*_localAdaptationON)[0]);
_spatiotemporalLPfilter(&_bipolarCellsOutputOFF[0], &_localAdaptationOFF[0], 2);
_localLuminanceAdaptation(&_parvocellularOutputOFF[0], &_localAdaptationOFF[0]);
//// Final loop that computes the main output of this filter
//
//// loop that makes the difference between photoreceptor cells output and horizontal cells
//// positive part goes on the ON way, negative pat goes on the OFF way
register float *parvocellularOutputONminusOFF_PTR=&(*_parvocellularOutputONminusOFF)[0];
register float *parvocellularOutputON_PTR=&_parvocellularOutputON[0];
register float *parvocellularOutputOFF_PTR=&_parvocellularOutputOFF[0];
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel)
*(parvocellularOutputONminusOFF_PTR++)= (*(parvocellularOutputON_PTR++)-*(parvocellularOutputOFF_PTR++));
}
return (*_parvocellularOutputONminusOFF);
}
void ParvoRetinaFilter::_OPL_OnOffWaysComputing() // WARNING : this method requires many buffer accesses, parallelizing can increase bandwith & core efficacy
{
// loop that makes the difference between photoreceptor cells output and horizontal cells
// positive part goes on the ON way, negative pat goes on the OFF way
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(0,_filterOutput.getNBpixels()), Parallel_OPL_OnOffWaysComputing(&_photoreceptorsOutput[0], &_horizontalCellsOutput[0], &_bipolarCellsOutputON[0], &_bipolarCellsOutputOFF[0], &_parvocellularOutputON[0], &_parvocellularOutputOFF[0]));
#else
float *photoreceptorsOutput_PTR= &_photoreceptorsOutput[0];
float *horizontalCellsOutput_PTR= &_horizontalCellsOutput[0];
float *bipolarCellsON_PTR = &_bipolarCellsOutputON[0];
float *bipolarCellsOFF_PTR = &_bipolarCellsOutputOFF[0];
float *parvocellularOutputON_PTR= &_parvocellularOutputON[0];
float *parvocellularOutputOFF_PTR= &_parvocellularOutputOFF[0];
// compute bipolar cells response equal to photoreceptors minus horizontal cells response
// and copy the result on parvo cellular outputs... keeping time before their local contrast adaptation for final result
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel)
{
float pixelDifference = *(photoreceptorsOutput_PTR++) -*(horizontalCellsOutput_PTR++);
// test condition to allow write pixelDifference in ON or OFF buffer and 0 in the over
float isPositive=(float) (pixelDifference>0.0f);
// ON and OFF channels writing step
*(parvocellularOutputON_PTR++)=*(bipolarCellsON_PTR++) = isPositive*pixelDifference;
*(parvocellularOutputOFF_PTR++)=*(bipolarCellsOFF_PTR++)= (isPositive-1.0f)*pixelDifference;
}
#endif
}
}// end of namespace bioinspired
}// end of namespace cv
@@ -1,263 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
#ifndef ParvoRetinaFilter_H_
#define ParvoRetinaFilter_H_
/**
* @class ParvoRetinaFilter
* @brief class which describes the OPL retina model and the Inner Plexiform Layer parvocellular channel of the retina:
* -> performs a contours extraction with powerfull local data enhancement as at the retina level
* -> spectrum whitening occurs at the OPL (Outer Plexiform Layer) of the retina: corrects the 1/f spectrum tendancy of natural images
* ---> enhances details with mid spatial frequencies, attenuates low spatial frequencies (luminance), attenuates high temporal frequencies and high spatial frequencies, etc.
*
* TYPICAL USE:
*
* // create object at a specified picture size
* ParvoRetinaFilter *contoursExtractor;
* contoursExtractor =new ParvoRetinaFilter(frameSizeRows, frameSizeColumns);
*
* // init gain, spatial and temporal parameters:
* contoursExtractor->setCoefficientsTable(0, 0.7, 1, 0, 7, 1);
*
* // during program execution, call the filter for contours extraction for an input picture called "FrameBuffer":
* contoursExtractor->runfilter(FrameBuffer);
*
* // get the output frame, check in the class description below for more outputs:
* const float *contours=contoursExtractor->getParvoONminusOFF();
*
* // at the end of the program, destroy object:
* delete contoursExtractor;
* @author Alexandre BENOIT, benoit.alexandre.vision@gmail.com, LISTIC : www.listic.univ-savoie.fr, Gipsa-Lab, France: www.gipsa-lab.inpg.fr/
* Creation date 2007
* Based on Alexandre BENOIT thesis: "Le système visuel humain au secours de la vision par ordinateur"
*
*/
#include "basicretinafilter.hpp"
//#define _OPL_RETINA_ELEMENT_DEBUG
namespace cv
{
namespace bioinspired
{
//retina classes that derivate from the Basic Retrina class
class ParvoRetinaFilter: public BasicRetinaFilter
{
public:
/**
* constructor parameters are only linked to image input size
* @param NBrows: number of rows of the input image
* @param NBcolumns: number of columns of the input image
*/
ParvoRetinaFilter(const unsigned int NBrows=480, const unsigned int NBcolumns=640);
/**
* standard desctructor
*/
virtual ~ParvoRetinaFilter();
/**
* resize method, keeps initial parameters, all buffers are flushed
* @param NBrows: number of rows of the input image
* @param NBcolumns: number of columns of the input image
*/
void resize(const unsigned int NBrows, const unsigned int NBcolumns);
/**
* function that clears all buffers of the object
*/
void clearAllBuffers();
/**
* setup the OPL and IPL parvo channels
* @param beta1: gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, the amplitude is boosted but it should only be used for values rescaling... if needed
* @param tau1: the time constant of the first order low pass filter of the photoreceptors, use it to cut high temporal frequencies (noise or fast motion), unit is frames, typical value is 1 frame
* @param k1: the spatial constant of the first order low pass filter of the photoreceptors, use it to cut high spatial frequencies (noise or thick contours), unit is pixels, typical value is 1 pixel
* @param beta2: gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, then, the luminance is not filtered and is still reachable at the output, typicall value is 0
* @param tau2: the time constant of the first order low pass filter of the horizontal cells, use it to cut low temporal frequencies (local luminance variations), unit is frames, typical value is 1 frame, as the photoreceptors
* @param k2: the spatial constant of the first order low pass filter of the horizontal cells, use it to cut low spatial frequencies (local luminance), unit is pixels, typical value is 5 pixel, this value is also used for local contrast computing when computing the local contrast adaptation at the ganglion cells level (Inner Plexiform Layer parvocellular channel model)
*/
void setOPLandParvoFiltersParameters(const float beta1, const float tau1, const float k1, const float beta2, const float tau2, const float k2);
/**
* setup more precisely the low pass filter used for the ganglion cells low pass filtering (used for local luminance adaptation)
* @param tau: time constant of the filter (unit is frame for video processing)
* @param k: spatial constant of the filter (unit is pixels)
*/
void setGanglionCellsLocalAdaptationLPfilterParameters(const float tau, const float k){BasicRetinaFilter::setLPfilterParameters(0, tau, k, 2);}; // change the parameters of the filter
/**
* launch filter that runs the OPL spatiotemporal filtering and optionally finalizes IPL Pagno filter (model of the Parvocellular channel of the Inner Plexiform Layer of the retina)
* @param inputFrame: the input image to be processed, this can be the direct gray level input frame, but a better efficacy is expected if the input is preliminary processed by the photoreceptors local adaptation possible to acheive with the help of a BasicRetinaFilter object
* @param useParvoOutput: set true if the final IPL filtering step has to be computed (local contrast enhancement)
* @return the processed Parvocellular channel output (updated only if useParvoOutput is true)
* @details: in any case, after this function call, photoreceptors and horizontal cells output are updated, use getPhotoreceptorsLPfilteringOutput() and getHorizontalCellsOutput() to get them
* also, bipolar cells output are accessible (difference between photoreceptors and horizontal cells, ON output has positive values, OFF ouput has negative values), use the following access methods: getBipolarCellsON() and getBipolarCellsOFF()if useParvoOutput is true,
* if useParvoOutput is true, the complete Parvocellular channel is computed, more outputs are updated and can be accessed threw: getParvoON(), getParvoOFF() and their difference with getOutput()
*/
const std::valarray<float> &runFilter(const std::valarray<float> &inputFrame, const bool useParvoOutput=true); // output return is _parvocellularOutputONminusOFF
/**
* @return the output of the photoreceptors filtering step (high cut frequency spatio-temporal low pass filter)
*/
inline const std::valarray<float> &getPhotoreceptorsLPfilteringOutput() const {return _photoreceptorsOutput;};
/**
* @return the output of the photoreceptors filtering step (low cut frequency spatio-temporal low pass filter)
*/
inline const std::valarray<float> &getHorizontalCellsOutput() const { return _horizontalCellsOutput;};
/**
* @return the output Parvocellular ON channel of the retina model
*/
inline const std::valarray<float> &getParvoON() const {return _parvocellularOutputON;};
/**
* @return the output Parvocellular OFF channel of the retina model
*/
inline const std::valarray<float> &getParvoOFF() const {return _parvocellularOutputOFF;};
/**
* @return the output of the Bipolar cells of the ON channel of the retina model same as function getParvoON() but without luminance local adaptation
*/
inline const std::valarray<float> &getBipolarCellsON() const {return _bipolarCellsOutputON;};
/**
* @return the output of the Bipolar cells of the OFF channel of the retina model same as function getParvoON() but without luminance local adaptation
*/
inline const std::valarray<float> &getBipolarCellsOFF() const {return _bipolarCellsOutputOFF;};
/**
* @return the photoreceptors's temporal constant
*/
inline float getPhotoreceptorsTemporalConstant(){return this->_filteringCoeficientsTable[2];};
/**
* @return the horizontal cells' temporal constant
*/
inline float getHcellsTemporalConstant(){return this->_filteringCoeficientsTable[5];};
private:
// template buffers
std::valarray <float>_photoreceptorsOutput;
std::valarray <float>_horizontalCellsOutput;
std::valarray <float>_parvocellularOutputON;
std::valarray <float>_parvocellularOutputOFF;
std::valarray <float>_bipolarCellsOutputON;
std::valarray <float>_bipolarCellsOutputOFF;
std::valarray <float>_localAdaptationOFF;
std::valarray <float> *_localAdaptationON;
TemplateBuffer<float> *_parvocellularOutputONminusOFF;
// private functions
void _OPL_OnOffWaysComputing();
#ifdef MAKE_PARALLEL
/******************************************************
** IF some parallelizing thread methods are available, then, main loops are parallelized using these functors
** ==> main idea paralellise main filters loops, then, only the most used methods are parallelized... TODO : increase the number of parallelised methods as necessary
** ==> functors names = Parallel_$$$ where $$$= the name of the serial method that is parallelised
** ==> functors constructors can differ from the parameters used with their related serial functions
*/
class Parallel_OPL_OnOffWaysComputing: public cv::ParallelLoopBody
{
private:
float *photoreceptorsOutput, *horizontalCellsOutput, *bipolarCellsON, *bipolarCellsOFF, *parvocellularOutputON, *parvocellularOutputOFF;
public:
Parallel_OPL_OnOffWaysComputing(float *photoreceptorsOutput_PTR, float *horizontalCellsOutput_PTR, float *bipolarCellsON_PTR, float *bipolarCellsOFF_PTR, float *parvocellularOutputON_PTR, float *parvocellularOutputOFF_PTR)
:photoreceptorsOutput(photoreceptorsOutput_PTR), horizontalCellsOutput(horizontalCellsOutput_PTR), bipolarCellsON(bipolarCellsON_PTR), bipolarCellsOFF(bipolarCellsOFF_PTR), parvocellularOutputON(parvocellularOutputON_PTR), parvocellularOutputOFF(parvocellularOutputOFF_PTR) {}
virtual void operator()( const Range& r ) const {
// compute bipolar cells response equal to photoreceptors minus horizontal cells response
// and copy the result on parvo cellular outputs... keeping time before their local contrast adaptation for final result
float *photoreceptorsOutput_PTR= photoreceptorsOutput+r.start;
float *horizontalCellsOutput_PTR= horizontalCellsOutput+r.start;
float *bipolarCellsON_PTR = bipolarCellsON+r.start;
float *bipolarCellsOFF_PTR = bipolarCellsOFF+r.start;
float *parvocellularOutputON_PTR= parvocellularOutputON+r.start;
float *parvocellularOutputOFF_PTR= parvocellularOutputOFF+r.start;
for (register int IDpixel=r.start ; IDpixel!=r.end ; ++IDpixel)
{
float pixelDifference = *(photoreceptorsOutput_PTR++) -*(horizontalCellsOutput_PTR++);
// test condition to allow write pixelDifference in ON or OFF buffer and 0 in the over
float isPositive=(float) (pixelDifference>0.0f);
// ON and OFF channels writing step
*(parvocellularOutputON_PTR++)=*(bipolarCellsON_PTR++) = isPositive*pixelDifference;
*(parvocellularOutputOFF_PTR++)=*(bipolarCellsOFF_PTR++)= (isPositive-1.0f)*pixelDifference;
}
}
};
#endif
};
}// end of namespace bioinspired
}// end of namespace cv
#endif
-68
View File
@@ -1,68 +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*/
#ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__
#include "opencv2/opencv_modules.hpp"
#include "opencv2/bioinspired.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
#include "opencv2/core/ocl.hpp"
#include <valarray>
#ifdef HAVE_OPENCV_OCL
#include "opencv2/ocl/private/util.hpp"
#endif
namespace cv
{
// special function to get pointer to constant valarray elements, since
// simple &arr[0] does not compile on VS2005/VS2008.
template<typename T> inline const T* get_data(const std::valarray<T>& arr)
{ return &((std::valarray<T>&)arr)[0]; }
}
#endif
-743
View File
@@ -1,743 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
/*
* Retina.cpp
*
* Created on: Jul 19, 2011
* Author: Alexandre Benoit
*/
#include "precomp.hpp"
#include "retinafilter.hpp"
#include <cstdio>
#include <sstream>
#include <valarray>
namespace cv
{
namespace bioinspired
{
class RetinaImpl : public Retina
{
public:
/**
* Main constructor with most commun use setup : create an instance of color ready retina model
* @param inputSize : the input frame size
*/
RetinaImpl(Size inputSize);
/**
* Complete Retina filter constructor which allows all basic structural parameters definition
* @param inputSize : the input frame size
* @param colorMode : the chosen processing mode : with or without color processing
* @param colorSamplingMethod: specifies which kind of color sampling will be used
* @param useRetinaLogSampling: activate retina log sampling, if true, the 2 following parameters can be used
* @param reductionFactor: only usefull if param useRetinaLogSampling=true, specifies the reduction factor of the output frame (as the center (fovea) is high resolution and corners can be underscaled, then a reduction of the output is allowed without precision leak
* @param samplingStrenght: only usefull if param useRetinaLogSampling=true, specifies the strenght of the log scale that is applied
*/
RetinaImpl(Size inputSize, const bool colorMode, int colorSamplingMethod=RETINA_COLOR_BAYER, const bool useRetinaLogSampling=false, const double reductionFactor=1.0, const double samplingStrenght=10.0);
virtual ~RetinaImpl();
/**
* retreive retina input buffer size
*/
Size getInputSize();
/**
* retreive retina output buffer size
*/
Size getOutputSize();
/**
* try to open an XML retina parameters file to adjust current retina instance setup
* => if the xml file does not exist, then default setup is applied
* => warning, Exceptions are thrown if read XML file is not valid
* @param retinaParameterFile : the parameters filename
* @param applyDefaultSetupOnFailure : set to true if an error must be thrown on error
*/
void setup(String retinaParameterFile="", const bool applyDefaultSetupOnFailure=true);
/**
* try to open an XML retina parameters file to adjust current retina instance setup
* => if the xml file does not exist, then default setup is applied
* => warning, Exceptions are thrown if read XML file is not valid
* @param fs : the open Filestorage which contains retina parameters
* @param applyDefaultSetupOnFailure : set to true if an error must be thrown on error
*/
void setup(cv::FileStorage &fs, const bool applyDefaultSetupOnFailure=true);
/**
* try to open an XML retina parameters file to adjust current retina instance setup
* => if the xml file does not exist, then default setup is applied
* => warning, Exceptions are thrown if read XML file is not valid
* @param newParameters : a parameters structures updated with the new target configuration
* @param applyDefaultSetupOnFailure : set to true if an error must be thrown on error
*/
void setup(Retina::RetinaParameters newParameters);
/**
* @return the current parameters setup
*/
struct Retina::RetinaParameters getParameters();
/**
* parameters setup display method
* @return a string which contains formatted parameters information
*/
const String printSetup();
/**
* write xml/yml formated parameters information
* @rparam fs : the filename of the xml file that will be open and writen with formatted parameters information
*/
virtual void write( String fs ) const;
/**
* write xml/yml formated parameters information
* @param fs : a cv::Filestorage object ready to be filled
*/
virtual void write( FileStorage& fs ) const;
/**
* setup the OPL and IPL parvo channels (see biologocal model)
* OPL is referred as Outer Plexiform Layer of the retina, it allows the spatio-temporal filtering which withens the spectrum and reduces spatio-temporal noise while attenuating global luminance (low frequency energy)
* IPL parvo is the OPL next processing stage, it refers to Inner Plexiform layer of the retina, it allows high contours sensitivity in foveal vision.
* for more informations, please have a look at the paper Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
* @param colorMode : specifies if (true) color is processed of not (false) to then processing gray level image
* @param normaliseOutput : specifies if (true) output is rescaled between 0 and 255 of not (false)
* @param photoreceptorsLocalAdaptationSensitivity: the photoreceptors sensitivity renage is 0-1 (more log compression effect when value increases)
* @param photoreceptorsTemporalConstant: the time constant of the first order low pass filter of the photoreceptors, use it to cut high temporal frequencies (noise or fast motion), unit is frames, typical value is 1 frame
* @param photoreceptorsSpatialConstant: the spatial constant of the first order low pass filter of the photoreceptors, use it to cut high spatial frequencies (noise or thick contours), unit is pixels, typical value is 1 pixel
* @param horizontalCellsGain: gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, then, the luminance is not filtered and is still reachable at the output, typicall value is 0
* @param HcellsTemporalConstant: the time constant of the first order low pass filter of the horizontal cells, use it to cut low temporal frequencies (local luminance variations), unit is frames, typical value is 1 frame, as the photoreceptors
* @param HcellsSpatialConstant: the spatial constant of the first order low pass filter of the horizontal cells, use it to cut low spatial frequencies (local luminance), unit is pixels, typical value is 5 pixel, this value is also used for local contrast computing when computing the local contrast adaptation at the ganglion cells level (Inner Plexiform Layer parvocellular channel model)
* @param ganglionCellsSensitivity: the compression strengh of the ganglion cells local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 230
*/
void setupOPLandIPLParvoChannel(const bool colorMode=true, const bool normaliseOutput = true, const float photoreceptorsLocalAdaptationSensitivity=0.7, const float photoreceptorsTemporalConstant=0.5, const float photoreceptorsSpatialConstant=0.53, const float horizontalCellsGain=0, const float HcellsTemporalConstant=1, const float HcellsSpatialConstant=7, const float ganglionCellsSensitivity=0.7);
/**
* set parameters values for the Inner Plexiform Layer (IPL) magnocellular channel
* this channel processes signals outpint from OPL processing stage in peripheral vision, it allows motion information enhancement. It is decorrelated from the details channel. See reference paper for more details.
* @param normaliseOutput : specifies if (true) output is rescaled between 0 and 255 of not (false)
* @param parasolCells_beta: the low pass filter gain used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), typical value is 0
* @param parasolCells_tau: the low pass filter time constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is frame, typical value is 0 (immediate response)
* @param parasolCells_k: the low pass filter spatial constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is pixels, typical value is 5
* @param amacrinCellsTemporalCutFrequency: the time constant of the first order high pass fiter of the magnocellular way (motion information channel), unit is frames, tipicall value is 5
* @param V0CompressionParameter: the compression strengh of the ganglion cells local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 200
* @param localAdaptintegration_tau: specifies the temporal constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
* @param localAdaptintegration_k: specifies the spatial constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
*/
void setupIPLMagnoChannel(const bool normaliseOutput = true, const float parasolCells_beta=0, const float parasolCells_tau=0, const float parasolCells_k=7, const float amacrinCellsTemporalCutFrequency=1.2, const float V0CompressionParameter=0.95, const float localAdaptintegration_tau=0, const float localAdaptintegration_k=7);
/**
* method which allows retina to be applied on an input image, after run, encapsulated retina module is ready to deliver its outputs using dedicated acccessors, see getParvo and getMagno methods
* @param inputImage : the input cv::Mat image to be processed, can be gray level or BGR coded in any format (from 8bit to 16bits)
*/
void run(InputArray inputImage);
/**
* method that applies a luminance correction (initially High Dynamic Range (HDR) tone mapping) using only the 2 local adaptation stages of the retina parvo channel : photoreceptors level and ganlion cells level. Spatio temporal filtering is applied but limited to temporal smoothing and eventually high frequencies attenuation. This is a lighter method than the one available using the regular run method. It is then faster but it does not include complete temporal filtering nor retina spectral whitening. This is an adptation of the original still image HDR tone mapping algorithm of David Alleyson, Sabine Susstruck and Laurence Meylan's work, please cite:
* -> Meylan L., Alleysson D., and Susstrunk S., A Model of Retinal Local Adaptation for the Tone Mapping of Color Filter Array Images, Journal of Optical Society of America, A, Vol. 24, N 9, September, 1st, 2007, pp. 2807-2816
@param inputImage the input image to process RGB or gray levels
@param outputToneMappedImage the output tone mapped image
*/
void applyFastToneMapping(InputArray inputImage, OutputArray outputToneMappedImage);
/**
* accessor of the details channel of the retina (models foveal vision)
* @param retinaOutput_parvo : the output buffer (reallocated if necessary), this output is rescaled for standard 8bits image processing use in OpenCV
*/
void getParvo(OutputArray retinaOutput_parvo);
/**
* accessor of the details channel of the retina (models foveal vision)
* @param retinaOutput_parvo : a cv::Mat header filled with the internal parvo buffer of the retina module. This output is the original retina filter model output, without any quantification or rescaling
*/
void getParvoRAW(OutputArray retinaOutput_parvo);
/**
* accessor of the motion channel of the retina (models peripheral vision)
* @param retinaOutput_magno : the output buffer (reallocated if necessary), this output is rescaled for standard 8bits image processing use in OpenCV
*/
void getMagno(OutputArray retinaOutput_magno);
/**
* accessor of the motion channel of the retina (models peripheral vision)
* @param retinaOutput_magno : a cv::Mat header filled with the internal retina magno buffer of the retina module. This output is the original retina filter model output, without any quantification or rescaling
*/
void getMagnoRAW(OutputArray retinaOutput_magno);
// original API level data accessors : get buffers addresses from a Mat header, similar to getParvoRAW and getMagnoRAW...
const Mat getMagnoRAW() const;
const Mat getParvoRAW() const;
/**
* activate color saturation as the final step of the color demultiplexing process
* -> this saturation is a sigmoide function applied to each channel of the demultiplexed image.
* @param saturateColors: boolean that activates color saturation (if true) or desactivate (if false)
* @param colorSaturationValue: the saturation factor
*/
void setColorSaturation(const bool saturateColors=true, const float colorSaturationValue=4.0);
/**
* clear all retina buffers (equivalent to opening the eyes after a long period of eye close ;o)
*/
void clearBuffers();
/**
* Activate/desactivate the Magnocellular pathway processing (motion information extraction), by default, it is activated
* @param activate: true if Magnocellular output should be activated, false if not
*/
void activateMovingContoursProcessing(const bool activate);
/**
* Activate/desactivate the Parvocellular pathway processing (contours information extraction), by default, it is activated
* @param activate: true if Parvocellular (contours information extraction) output should be activated, false if not
*/
void activateContoursProcessing(const bool activate);
private:
// Parameteres setup members
RetinaParameters _retinaParameters; // structure of parameters
// Retina model related modules
std::valarray<float> _inputBuffer; //!< buffer used to convert input cv::Mat to internal retina buffers format (valarrays)
// pointer to retina model
RetinaFilter* _retinaFilter; //!< the pointer to the retina module, allocated with instance construction
//! private method called by constructors, gathers their parameters and use them in a unified way
void _init(const Size inputSize, const bool colorMode, int colorSamplingMethod=RETINA_COLOR_BAYER, const bool useRetinaLogSampling=false, const double reductionFactor=1.0, const double samplingStrenght=10.0);
/**
* exports a valarray buffer outing from bioinspired objects to a cv::Mat in CV_8UC1 (gray level picture) or CV_8UC3 (color) format
* @param grayMatrixToConvert the valarray to export to OpenCV
* @param nbRows : the number of rows of the valarray flatten matrix
* @param nbColumns : the number of rows of the valarray flatten matrix
* @param colorMode : a flag which mentions if matrix is color (true) or graylevel (false)
* @param outBuffer : the output matrix which is reallocated to satisfy Retina output buffer dimensions
*/
void _convertValarrayBuffer2cvMat(const std::valarray<float> &grayMatrixToConvert, const unsigned int nbRows, const unsigned int nbColumns, const bool colorMode, OutputArray outBuffer);
/**
* convert a cv::Mat to a valarray buffer in float format
* @param inputMatToConvert : the OpenCV cv::Mat that has to be converted to gray or RGB valarray buffer that will be processed by the retina model
* @param outputValarrayMatrix : the output valarray
* @return the input image color mode (color=true, gray levels=false)
*/
bool _convertCvMat2ValarrayBuffer(InputArray inputMatToConvert, std::valarray<float> &outputValarrayMatrix);
};
// smart pointers allocation :
Ptr<Retina> createRetina(Size inputSize){ return makePtr<RetinaImpl>(inputSize); }
Ptr<Retina> createRetina(Size inputSize, const bool colorMode, int colorSamplingMethod, const bool useRetinaLogSampling, const double reductionFactor, const double samplingStrenght){
return makePtr<RetinaImpl>(inputSize, colorMode, colorSamplingMethod, useRetinaLogSampling, reductionFactor, samplingStrenght);
}
// RetinaImpl code
RetinaImpl::RetinaImpl(const cv::Size inputSz)
{
_retinaFilter = 0;
_init(inputSz, true, RETINA_COLOR_BAYER, false);
}
RetinaImpl::RetinaImpl(const cv::Size inputSz, const bool colorMode, int colorSamplingMethod, const bool useRetinaLogSampling, const double reductionFactor, const double samplingStrenght)
{
_retinaFilter = 0;
_init(inputSz, colorMode, colorSamplingMethod, useRetinaLogSampling, reductionFactor, samplingStrenght);
};
RetinaImpl::~RetinaImpl()
{
if (_retinaFilter)
delete _retinaFilter;
}
/**
* retreive retina input buffer size
*/
Size RetinaImpl::getInputSize(){return cv::Size(_retinaFilter->getInputNBcolumns(), _retinaFilter->getInputNBrows());}
/**
* retreive retina output buffer size
*/
Size RetinaImpl::getOutputSize(){return cv::Size(_retinaFilter->getOutputNBcolumns(), _retinaFilter->getOutputNBrows());}
void RetinaImpl::setColorSaturation(const bool saturateColors, const float colorSaturationValue)
{
_retinaFilter->setColorSaturation(saturateColors, colorSaturationValue);
}
struct Retina::RetinaParameters RetinaImpl::getParameters(){return _retinaParameters;}
void RetinaImpl::setup(String retinaParameterFile, const bool applyDefaultSetupOnFailure)
{
try
{
// opening retinaParameterFile in read mode
cv::FileStorage fs(retinaParameterFile, cv::FileStorage::READ);
setup(fs, applyDefaultSetupOnFailure);
}
catch(Exception &e)
{
printf("Retina::setup: wrong/unappropriate xml parameter file : error report :`n=>%s\n", e.what());
if (applyDefaultSetupOnFailure)
{
printf("Retina::setup: resetting retina with default parameters\n");
setupOPLandIPLParvoChannel();
setupIPLMagnoChannel();
}
else
{
printf("=> keeping current parameters\n");
}
}
}
void RetinaImpl::setup(cv::FileStorage &fs, const bool applyDefaultSetupOnFailure)
{
try
{
// read parameters file if it exists or apply default setup if asked for
if (!fs.isOpened())
{
printf("Retina::setup: provided parameters file could not be open... skeeping configuration\n");
return;
// implicit else case : retinaParameterFile could be open (it exists at least)
}
// OPL and Parvo init first... update at the same time the parameters structure and the retina core
cv::FileNode rootFn = fs.root(), currFn=rootFn["OPLandIPLparvo"];
currFn["colorMode"]>>_retinaParameters.OPLandIplParvo.colorMode;
currFn["normaliseOutput"]>>_retinaParameters.OPLandIplParvo.normaliseOutput;
currFn["photoreceptorsLocalAdaptationSensitivity"]>>_retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity;
currFn["photoreceptorsTemporalConstant"]>>_retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant;
currFn["photoreceptorsSpatialConstant"]>>_retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant;
currFn["horizontalCellsGain"]>>_retinaParameters.OPLandIplParvo.horizontalCellsGain;
currFn["hcellsTemporalConstant"]>>_retinaParameters.OPLandIplParvo.hcellsTemporalConstant;
currFn["hcellsSpatialConstant"]>>_retinaParameters.OPLandIplParvo.hcellsSpatialConstant;
currFn["ganglionCellsSensitivity"]>>_retinaParameters.OPLandIplParvo.ganglionCellsSensitivity;
setupOPLandIPLParvoChannel(_retinaParameters.OPLandIplParvo.colorMode, _retinaParameters.OPLandIplParvo.normaliseOutput, _retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity, _retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant, _retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant, _retinaParameters.OPLandIplParvo.horizontalCellsGain, _retinaParameters.OPLandIplParvo.hcellsTemporalConstant, _retinaParameters.OPLandIplParvo.hcellsSpatialConstant, _retinaParameters.OPLandIplParvo.ganglionCellsSensitivity);
// init retina IPL magno setup... update at the same time the parameters structure and the retina core
currFn=rootFn["IPLmagno"];
currFn["normaliseOutput"]>>_retinaParameters.IplMagno.normaliseOutput;
currFn["parasolCells_beta"]>>_retinaParameters.IplMagno.parasolCells_beta;
currFn["parasolCells_tau"]>>_retinaParameters.IplMagno.parasolCells_tau;
currFn["parasolCells_k"]>>_retinaParameters.IplMagno.parasolCells_k;
currFn["amacrinCellsTemporalCutFrequency"]>>_retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency;
currFn["V0CompressionParameter"]>>_retinaParameters.IplMagno.V0CompressionParameter;
currFn["localAdaptintegration_tau"]>>_retinaParameters.IplMagno.localAdaptintegration_tau;
currFn["localAdaptintegration_k"]>>_retinaParameters.IplMagno.localAdaptintegration_k;
setupIPLMagnoChannel(_retinaParameters.IplMagno.normaliseOutput, _retinaParameters.IplMagno.parasolCells_beta, _retinaParameters.IplMagno.parasolCells_tau, _retinaParameters.IplMagno.parasolCells_k, _retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency,_retinaParameters.IplMagno.V0CompressionParameter, _retinaParameters.IplMagno.localAdaptintegration_tau, _retinaParameters.IplMagno.localAdaptintegration_k);
}catch(Exception &e)
{
printf("RetinaImpl::setup: resetting retina with default parameters\n");
if (applyDefaultSetupOnFailure)
{
setupOPLandIPLParvoChannel();
setupIPLMagnoChannel();
}
printf("Retina::setup: wrong/unappropriate xml parameter file : error report :`n=>%s\n", e.what());
printf("=> keeping current parameters\n");
}
// report current configuration
printf("%s\n", printSetup().c_str());
}
void RetinaImpl::setup(Retina::RetinaParameters newConfiguration)
{
// simply copy structures
memcpy(&_retinaParameters, &newConfiguration, sizeof(Retina::RetinaParameters));
// apply setup
setupOPLandIPLParvoChannel(_retinaParameters.OPLandIplParvo.colorMode, _retinaParameters.OPLandIplParvo.normaliseOutput, _retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity, _retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant, _retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant, _retinaParameters.OPLandIplParvo.horizontalCellsGain, _retinaParameters.OPLandIplParvo.hcellsTemporalConstant, _retinaParameters.OPLandIplParvo.hcellsSpatialConstant, _retinaParameters.OPLandIplParvo.ganglionCellsSensitivity);
setupIPLMagnoChannel(_retinaParameters.IplMagno.normaliseOutput, _retinaParameters.IplMagno.parasolCells_beta, _retinaParameters.IplMagno.parasolCells_tau, _retinaParameters.IplMagno.parasolCells_k, _retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency,_retinaParameters.IplMagno.V0CompressionParameter, _retinaParameters.IplMagno.localAdaptintegration_tau, _retinaParameters.IplMagno.localAdaptintegration_k);
}
const String RetinaImpl::printSetup()
{
std::stringstream outmessage;
// displaying OPL and IPL parvo setup
outmessage<<"Current Retina instance setup :"
<<"\nOPLandIPLparvo"<<"{"
<< "\n\t colorMode : " << _retinaParameters.OPLandIplParvo.colorMode
<< "\n\t normalizeParvoOutput :" << _retinaParameters.OPLandIplParvo.normaliseOutput
<< "\n\t photoreceptorsLocalAdaptationSensitivity : " << _retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity
<< "\n\t photoreceptorsTemporalConstant : " << _retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant
<< "\n\t photoreceptorsSpatialConstant : " << _retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant
<< "\n\t horizontalCellsGain : " << _retinaParameters.OPLandIplParvo.horizontalCellsGain
<< "\n\t hcellsTemporalConstant : " << _retinaParameters.OPLandIplParvo.hcellsTemporalConstant
<< "\n\t hcellsSpatialConstant : " << _retinaParameters.OPLandIplParvo.hcellsSpatialConstant
<< "\n\t parvoGanglionCellsSensitivity : " << _retinaParameters.OPLandIplParvo.ganglionCellsSensitivity
<<"}\n";
// displaying IPL magno setup
outmessage<<"Current Retina instance setup :"
<<"\nIPLmagno"<<"{"
<< "\n\t normaliseOutput : " << _retinaParameters.IplMagno.normaliseOutput
<< "\n\t parasolCells_beta : " << _retinaParameters.IplMagno.parasolCells_beta
<< "\n\t parasolCells_tau : " << _retinaParameters.IplMagno.parasolCells_tau
<< "\n\t parasolCells_k : " << _retinaParameters.IplMagno.parasolCells_k
<< "\n\t amacrinCellsTemporalCutFrequency : " << _retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency
<< "\n\t V0CompressionParameter : " << _retinaParameters.IplMagno.V0CompressionParameter
<< "\n\t localAdaptintegration_tau : " << _retinaParameters.IplMagno.localAdaptintegration_tau
<< "\n\t localAdaptintegration_k : " << _retinaParameters.IplMagno.localAdaptintegration_k
<<"}";
return outmessage.str().c_str();
}
void RetinaImpl::write( String fs ) const
{
FileStorage parametersSaveFile(fs, cv::FileStorage::WRITE );
write(parametersSaveFile);
}
void RetinaImpl::write( FileStorage& fs ) const
{
if (!fs.isOpened())
return; // basic error case
fs<<"OPLandIPLparvo"<<"{";
fs << "colorMode" << _retinaParameters.OPLandIplParvo.colorMode;
fs << "normaliseOutput" << _retinaParameters.OPLandIplParvo.normaliseOutput;
fs << "photoreceptorsLocalAdaptationSensitivity" << _retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity;
fs << "photoreceptorsTemporalConstant" << _retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant;
fs << "photoreceptorsSpatialConstant" << _retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant;
fs << "horizontalCellsGain" << _retinaParameters.OPLandIplParvo.horizontalCellsGain;
fs << "hcellsTemporalConstant" << _retinaParameters.OPLandIplParvo.hcellsTemporalConstant;
fs << "hcellsSpatialConstant" << _retinaParameters.OPLandIplParvo.hcellsSpatialConstant;
fs << "ganglionCellsSensitivity" << _retinaParameters.OPLandIplParvo.ganglionCellsSensitivity;
fs << "}";
fs<<"IPLmagno"<<"{";
fs << "normaliseOutput" << _retinaParameters.IplMagno.normaliseOutput;
fs << "parasolCells_beta" << _retinaParameters.IplMagno.parasolCells_beta;
fs << "parasolCells_tau" << _retinaParameters.IplMagno.parasolCells_tau;
fs << "parasolCells_k" << _retinaParameters.IplMagno.parasolCells_k;
fs << "amacrinCellsTemporalCutFrequency" << _retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency;
fs << "V0CompressionParameter" << _retinaParameters.IplMagno.V0CompressionParameter;
fs << "localAdaptintegration_tau" << _retinaParameters.IplMagno.localAdaptintegration_tau;
fs << "localAdaptintegration_k" << _retinaParameters.IplMagno.localAdaptintegration_k;
fs<<"}";
}
void RetinaImpl::setupOPLandIPLParvoChannel(const bool colorMode, const bool normaliseOutput, const float photoreceptorsLocalAdaptationSensitivity, const float photoreceptorsTemporalConstant, const float photoreceptorsSpatialConstant, const float horizontalCellsGain, const float HcellsTemporalConstant, const float HcellsSpatialConstant, const float ganglionCellsSensitivity)
{
// retina core parameters setup
_retinaFilter->setColorMode(colorMode);
_retinaFilter->setPhotoreceptorsLocalAdaptationSensitivity(photoreceptorsLocalAdaptationSensitivity);
_retinaFilter->setOPLandParvoParameters(0, photoreceptorsTemporalConstant, photoreceptorsSpatialConstant, horizontalCellsGain, HcellsTemporalConstant, HcellsSpatialConstant, ganglionCellsSensitivity);
_retinaFilter->setParvoGanglionCellsLocalAdaptationSensitivity(ganglionCellsSensitivity);
_retinaFilter->activateNormalizeParvoOutput_0_maxOutputValue(normaliseOutput);
// update parameters struture
_retinaParameters.OPLandIplParvo.colorMode = colorMode;
_retinaParameters.OPLandIplParvo.normaliseOutput = normaliseOutput;
_retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity = photoreceptorsLocalAdaptationSensitivity;
_retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant = photoreceptorsTemporalConstant;
_retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant = photoreceptorsSpatialConstant;
_retinaParameters.OPLandIplParvo.horizontalCellsGain = horizontalCellsGain;
_retinaParameters.OPLandIplParvo.hcellsTemporalConstant = HcellsTemporalConstant;
_retinaParameters.OPLandIplParvo.hcellsSpatialConstant = HcellsSpatialConstant;
_retinaParameters.OPLandIplParvo.ganglionCellsSensitivity = ganglionCellsSensitivity;
}
void RetinaImpl::setupIPLMagnoChannel(const bool normaliseOutput, const float parasolCells_beta, const float parasolCells_tau, const float parasolCells_k, const float amacrinCellsTemporalCutFrequency, const float V0CompressionParameter, const float localAdaptintegration_tau, const float localAdaptintegration_k)
{
_retinaFilter->setMagnoCoefficientsTable(parasolCells_beta, parasolCells_tau, parasolCells_k, amacrinCellsTemporalCutFrequency, V0CompressionParameter, localAdaptintegration_tau, localAdaptintegration_k);
_retinaFilter->activateNormalizeMagnoOutput_0_maxOutputValue(normaliseOutput);
// update parameters struture
_retinaParameters.IplMagno.normaliseOutput = normaliseOutput;
_retinaParameters.IplMagno.parasolCells_beta = parasolCells_beta;
_retinaParameters.IplMagno.parasolCells_tau = parasolCells_tau;
_retinaParameters.IplMagno.parasolCells_k = parasolCells_k;
_retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency = amacrinCellsTemporalCutFrequency;
_retinaParameters.IplMagno.V0CompressionParameter = V0CompressionParameter;
_retinaParameters.IplMagno.localAdaptintegration_tau = localAdaptintegration_tau;
_retinaParameters.IplMagno.localAdaptintegration_k = localAdaptintegration_k;
}
void RetinaImpl::run(InputArray inputMatToConvert)
{
// first convert input image to the compatible format : std::valarray<float>
const bool colorMode = _convertCvMat2ValarrayBuffer(inputMatToConvert.getMat(), _inputBuffer);
// process the retina
if (!_retinaFilter->runFilter(_inputBuffer, colorMode, false, _retinaParameters.OPLandIplParvo.colorMode && colorMode, false))
throw cv::Exception(-1, "RetinaImpl cannot be applied, wrong input buffer size", "RetinaImpl::run", "RetinaImpl.h", 0);
}
void RetinaImpl::applyFastToneMapping(InputArray inputImage, OutputArray outputToneMappedImage)
{
// first convert input image to the compatible format :
const bool colorMode = _convertCvMat2ValarrayBuffer(inputImage.getMat(), _inputBuffer);
const unsigned int nbPixels=_retinaFilter->getOutputNBrows()*_retinaFilter->getOutputNBcolumns();
// process tone mapping
if (colorMode)
{
std::valarray<float> imageOutput(nbPixels*3);
_retinaFilter->runRGBToneMapping(_inputBuffer, imageOutput, true, _retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity, _retinaParameters.OPLandIplParvo.ganglionCellsSensitivity);
_convertValarrayBuffer2cvMat(imageOutput, _retinaFilter->getOutputNBrows(), _retinaFilter->getOutputNBcolumns(), true, outputToneMappedImage);
}else
{
std::valarray<float> imageOutput(nbPixels);
_retinaFilter->runGrayToneMapping(_inputBuffer, imageOutput, _retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity, _retinaParameters.OPLandIplParvo.ganglionCellsSensitivity);
_convertValarrayBuffer2cvMat(imageOutput, _retinaFilter->getOutputNBrows(), _retinaFilter->getOutputNBcolumns(), false, outputToneMappedImage);
}
}
void RetinaImpl::getParvo(OutputArray retinaOutput_parvo)
{
if (_retinaFilter->getColorMode())
{
// reallocate output buffer (if necessary)
_convertValarrayBuffer2cvMat(_retinaFilter->getColorOutput(), _retinaFilter->getOutputNBrows(), _retinaFilter->getOutputNBcolumns(), true, retinaOutput_parvo);
}else
{
// reallocate output buffer (if necessary)
_convertValarrayBuffer2cvMat(_retinaFilter->getContours(), _retinaFilter->getOutputNBrows(), _retinaFilter->getOutputNBcolumns(), false, retinaOutput_parvo);
}
//retinaOutput_parvo/=255.0;
}
void RetinaImpl::getMagno(OutputArray retinaOutput_magno)
{
// reallocate output buffer (if necessary)
_convertValarrayBuffer2cvMat(_retinaFilter->getMovingContours(), _retinaFilter->getOutputNBrows(), _retinaFilter->getOutputNBcolumns(), false, retinaOutput_magno);
//retinaOutput_magno/=255.0;
}
// original API level data accessors : copy buffers if size matches, reallocate if required
void RetinaImpl::getMagnoRAW(OutputArray magnoOutputBufferCopy){
// get magno channel header
const cv::Mat magnoChannel=cv::Mat(getMagnoRAW());
// copy data
magnoChannel.copyTo(magnoOutputBufferCopy);
}
void RetinaImpl::getParvoRAW(OutputArray parvoOutputBufferCopy){
// get parvo channel header
const cv::Mat parvoChannel=cv::Mat(getMagnoRAW());
// copy data
parvoChannel.copyTo(parvoOutputBufferCopy);
}
// original API level data accessors : get buffers addresses...
const Mat RetinaImpl::getMagnoRAW() const {
// create a cv::Mat header for the valarray
return Mat((int)_retinaFilter->getMovingContours().size(),1, CV_32F, (void*)get_data(_retinaFilter->getMovingContours()));
}
const Mat RetinaImpl::getParvoRAW() const {
if (_retinaFilter->getColorMode()) // check if color mode is enabled
{
// create a cv::Mat table (for RGB planes as a single vector)
return Mat((int)_retinaFilter->getColorOutput().size(), 1, CV_32F, (void*)get_data(_retinaFilter->getColorOutput()));
}
// otherwise, output is gray level
// create a cv::Mat header for the valarray
return Mat((int)_retinaFilter->getContours().size(), 1, CV_32F, (void*)get_data(_retinaFilter->getContours()));
}
// private method called by constructirs
void RetinaImpl::_init(const cv::Size inputSz, const bool colorMode, int colorSamplingMethod, const bool useRetinaLogSampling, const double reductionFactor, const double samplingStrenght)
{
// basic error check
if (inputSz.height*inputSz.width <= 0)
throw cv::Exception(-1, "Bad retina size setup : size height and with must be superior to zero", "RetinaImpl::setup", "Retina.cpp", 0);
unsigned int nbPixels=inputSz.height*inputSz.width;
// resize buffers if size does not match
_inputBuffer.resize(nbPixels*3); // buffer supports gray images but also 3 channels color buffers... (larger is better...)
// allocate the retina model
if (_retinaFilter)
delete _retinaFilter;
_retinaFilter = new RetinaFilter(inputSz.height, inputSz.width, colorMode, colorSamplingMethod, useRetinaLogSampling, reductionFactor, samplingStrenght);
_retinaParameters.OPLandIplParvo.colorMode = colorMode;
// prepare the default parameter XML file with default setup
setup(_retinaParameters);
// init retina
_retinaFilter->clearAllBuffers();
// report current configuration
printf("%s\n", printSetup().c_str());
}
void RetinaImpl::_convertValarrayBuffer2cvMat(const std::valarray<float> &grayMatrixToConvert, const unsigned int nbRows, const unsigned int nbColumns, const bool colorMode, OutputArray outBuffer)
{
// fill output buffer with the valarray buffer
const float *valarrayPTR=get_data(grayMatrixToConvert);
if (!colorMode)
{
outBuffer.create(cv::Size(nbColumns, nbRows), CV_8U);
Mat outMat = outBuffer.getMat();
for (unsigned int i=0;i<nbRows;++i)
{
for (unsigned int j=0;j<nbColumns;++j)
{
cv::Point2d pixel(j,i);
outMat.at<unsigned char>(pixel)=(unsigned char)*(valarrayPTR++);
}
}
}else
{
const unsigned int nbPixels=nbColumns*nbRows;
const unsigned int doubleNBpixels=nbColumns*nbRows*2;
outBuffer.create(cv::Size(nbColumns, nbRows), CV_8UC3);
Mat outMat = outBuffer.getMat();
for (unsigned int i=0;i<nbRows;++i)
{
for (unsigned int j=0;j<nbColumns;++j,++valarrayPTR)
{
cv::Point2d pixel(j,i);
cv::Vec3b pixelValues;
pixelValues[2]=(unsigned char)*(valarrayPTR);
pixelValues[1]=(unsigned char)*(valarrayPTR+nbPixels);
pixelValues[0]=(unsigned char)*(valarrayPTR+doubleNBpixels);
outMat.at<cv::Vec3b>(pixel)=pixelValues;
}
}
}
}
bool RetinaImpl::_convertCvMat2ValarrayBuffer(InputArray inputMat, std::valarray<float> &outputValarrayMatrix)
{
const Mat inputMatToConvert=inputMat.getMat();
// first check input consistency
if (inputMatToConvert.empty())
throw cv::Exception(-1, "RetinaImpl cannot be applied, input buffer is empty", "RetinaImpl::run", "RetinaImpl.h", 0);
// retreive color mode from image input
int imageNumberOfChannels = inputMatToConvert.channels();
// convert to float AND fill the valarray buffer
typedef float T; // define here the target pixel format, here, float
const int dsttype = DataType<T>::depth; // output buffer is float format
const unsigned int nbPixels=inputMat.getMat().rows*inputMat.getMat().cols;
const unsigned int doubleNBpixels=inputMat.getMat().rows*inputMat.getMat().cols*2;
if(imageNumberOfChannels==4)
{
// create a cv::Mat table (for RGBA planes)
cv::Mat planes[4] =
{
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[doubleNBpixels]),
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[nbPixels]),
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0])
};
planes[3] = cv::Mat(inputMatToConvert.size(), dsttype); // last channel (alpha) does not point on the valarray (not usefull in our case)
// split color cv::Mat in 4 planes... it fills valarray directely
cv::split(Mat_<Vec<T, 4> >(inputMatToConvert), planes);
}
else if (imageNumberOfChannels==3)
{
// create a cv::Mat table (for RGB planes)
cv::Mat planes[] =
{
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[doubleNBpixels]),
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[nbPixels]),
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0])
};
// split color cv::Mat in 3 planes... it fills valarray directely
cv::split(cv::Mat_<Vec<T, 3> >(inputMatToConvert), planes);
}
else if(imageNumberOfChannels==1)
{
// create a cv::Mat header for the valarray
cv::Mat dst(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0]);
inputMatToConvert.convertTo(dst, dsttype);
}
else
CV_Error(Error::StsUnsupportedFormat, "input image must be single channel (gray levels), bgr format (color) or bgra (color with transparency which won't be considered");
return imageNumberOfChannels>1; // return bool : false for gray level image processing, true for color mode
}
void RetinaImpl::clearBuffers() {_retinaFilter->clearAllBuffers();}
void RetinaImpl::activateMovingContoursProcessing(const bool activate){_retinaFilter->activateMovingContoursProcessing(activate);}
void RetinaImpl::activateContoursProcessing(const bool activate){_retinaFilter->activateContoursProcessing(activate);}
}// end of namespace bioinspired
}// end of namespace cv
File diff suppressed because it is too large Load Diff
-634
View File
@@ -1,634 +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) 2010-2013, Multicoreware, Inc., all rights reserved.
// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
// Peng Xiao, pengxiao@multicorewareinc.com
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other oclMaterials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors as is and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OCL_RETINA_HPP__
#define __OCL_RETINA_HPP__
#include "precomp.hpp"
#ifdef HAVE_OPENCV_OCL
// please refer to c++ headers for API comments
namespace cv
{
namespace bioinspired
{
namespace ocl
{
void normalizeGrayOutputCentredSigmoide(const float meanValue, const float sensitivity, cv::ocl::oclMat &in, cv::ocl::oclMat &out, const float maxValue = 255.f);
void normalizeGrayOutput_0_maxOutputValue(cv::ocl::oclMat &inputOutputBuffer, const float maxOutputValue = 255.0);
void normalizeGrayOutputNearZeroCentreredSigmoide(cv::ocl::oclMat &inputPicture, cv::ocl::oclMat &outputBuffer, const float sensitivity = 40, const float maxOutputValue = 255.0f);
void centerReductImageLuminance(cv::ocl::oclMat &inputOutputBuffer);
class BasicRetinaFilter
{
public:
BasicRetinaFilter(const unsigned int NBrows, const unsigned int NBcolumns, const unsigned int parametersListSize = 1, const bool useProgressiveFilter = false);
~BasicRetinaFilter();
inline void clearOutputBuffer()
{
_filterOutput = 0;
};
inline void clearSecondaryBuffer()
{
_localBuffer = 0;
};
inline void clearAllBuffers()
{
clearOutputBuffer();
clearSecondaryBuffer();
};
void resize(const unsigned int NBrows, const unsigned int NBcolumns);
const cv::ocl::oclMat &runFilter_LPfilter(const cv::ocl::oclMat &inputFrame, const unsigned int filterIndex = 0);
void runFilter_LPfilter(const cv::ocl::oclMat &inputFrame, cv::ocl::oclMat &outputFrame, const unsigned int filterIndex = 0);
void runFilter_LPfilter_Autonomous(cv::ocl::oclMat &inputOutputFrame, const unsigned int filterIndex = 0);
const cv::ocl::oclMat &runFilter_LocalAdapdation(const cv::ocl::oclMat &inputOutputFrame, const cv::ocl::oclMat &localLuminance);
void runFilter_LocalAdapdation(const cv::ocl::oclMat &inputFrame, const cv::ocl::oclMat &localLuminance, cv::ocl::oclMat &outputFrame);
const cv::ocl::oclMat &runFilter_LocalAdapdation_autonomous(const cv::ocl::oclMat &inputFrame);
void runFilter_LocalAdapdation_autonomous(const cv::ocl::oclMat &inputFrame, cv::ocl::oclMat &outputFrame);
void setLPfilterParameters(const float beta, const float tau, const float k, const unsigned int filterIndex = 0);
inline void setV0CompressionParameter(const float v0, const float maxInputValue, const float)
{
_v0 = v0 * maxInputValue;
_localLuminanceFactor = v0;
_localLuminanceAddon = maxInputValue * (1.0f - v0);
_maxInputValue = maxInputValue;
};
inline void setV0CompressionParameter(const float v0, const float meanLuminance)
{
this->setV0CompressionParameter(v0, _maxInputValue, meanLuminance);
};
inline void setV0CompressionParameter(const float v0)
{
_v0 = v0 * _maxInputValue;
_localLuminanceFactor = v0;
_localLuminanceAddon = _maxInputValue * (1.0f - v0);
};
inline void setV0CompressionParameterToneMapping(const float v0, const float maxInputValue, const float meanLuminance = 128.0f)
{
_v0 = v0 * maxInputValue;
_localLuminanceFactor = 1.0f;
_localLuminanceAddon = meanLuminance * _v0;
_maxInputValue = maxInputValue;
};
inline void updateCompressionParameter(const float meanLuminance)
{
_localLuminanceFactor = 1;
_localLuminanceAddon = meanLuminance * _v0;
};
inline float getV0CompressionParameter()
{
return _v0 / _maxInputValue;
};
inline const cv::ocl::oclMat &getOutput() const
{
return _filterOutput;
};
inline unsigned int getNBrows()
{
return _filterOutput.rows;
};
inline unsigned int getNBcolumns()
{
return _filterOutput.cols;
};
inline unsigned int getNBpixels()
{
return _filterOutput.size().area();
};
inline void normalizeGrayOutput_0_maxOutputValue(const float maxValue)
{
ocl::normalizeGrayOutput_0_maxOutputValue(_filterOutput, maxValue);
};
inline void normalizeGrayOutputCentredSigmoide()
{
ocl::normalizeGrayOutputCentredSigmoide(0.0, 2.0, _filterOutput, _filterOutput);
};
inline void centerReductImageLuminance()
{
ocl::centerReductImageLuminance(_filterOutput);
};
inline float getMaxInputValue()
{
return this->_maxInputValue;
};
inline void setMaxInputValue(const float newMaxInputValue)
{
this->_maxInputValue = newMaxInputValue;
};
protected:
int _NBrows;
int _NBcols;
unsigned int _halfNBrows;
unsigned int _halfNBcolumns;
cv::ocl::oclMat _filterOutput;
cv::ocl::oclMat _localBuffer;
std::valarray <float>_filteringCoeficientsTable;
float _v0;
float _maxInputValue;
float _meanInputValue;
float _localLuminanceFactor;
float _localLuminanceAddon;
float _a;
float _tau;
float _gain;
void _spatiotemporalLPfilter(const cv::ocl::oclMat &inputFrame, cv::ocl::oclMat &LPfilterOutput, const unsigned int coefTableOffset = 0);
float _squaringSpatiotemporalLPfilter(const cv::ocl::oclMat &inputFrame, cv::ocl::oclMat &outputFrame, const unsigned int filterIndex = 0);
void _spatiotemporalLPfilter_Irregular(const cv::ocl::oclMat &inputFrame, cv::ocl::oclMat &outputFrame, const unsigned int filterIndex = 0);
void _localSquaringSpatioTemporalLPfilter(const cv::ocl::oclMat &inputFrame, cv::ocl::oclMat &LPfilterOutput, const unsigned int *integrationAreas, const unsigned int filterIndex = 0);
void _localLuminanceAdaptation(const cv::ocl::oclMat &inputFrame, const cv::ocl::oclMat &localLuminance, cv::ocl::oclMat &outputFrame, const bool updateLuminanceMean = true);
void _localLuminanceAdaptation(cv::ocl::oclMat &inputOutputFrame, const cv::ocl::oclMat &localLuminance);
void _localLuminanceAdaptationPosNegValues(const cv::ocl::oclMat &inputFrame, const cv::ocl::oclMat &localLuminance, float *outputFrame);
void _horizontalCausalFilter_addInput(const cv::ocl::oclMat &inputFrame, cv::ocl::oclMat &outputFrame);
void _horizontalAnticausalFilter(cv::ocl::oclMat &outputFrame);
void _verticalCausalFilter(cv::ocl::oclMat &outputFrame);
void _horizontalAnticausalFilter_Irregular(cv::ocl::oclMat &outputFrame, const cv::ocl::oclMat &spatialConstantBuffer);
void _verticalCausalFilter_Irregular(cv::ocl::oclMat &outputFrame, const cv::ocl::oclMat &spatialConstantBuffer);
void _verticalAnticausalFilter_multGain(cv::ocl::oclMat &outputFrame);
};
class MagnoRetinaFilter: public BasicRetinaFilter
{
public:
MagnoRetinaFilter(const unsigned int NBrows, const unsigned int NBcolumns);
virtual ~MagnoRetinaFilter();
void clearAllBuffers();
void resize(const unsigned int NBrows, const unsigned int NBcolumns);
void setCoefficientsTable(const float parasolCells_beta, const float parasolCells_tau, const float parasolCells_k, const float amacrinCellsTemporalCutFrequency, const float localAdaptIntegration_tau, const float localAdaptIntegration_k);
const cv::ocl::oclMat &runFilter(const cv::ocl::oclMat &OPL_ON, const cv::ocl::oclMat &OPL_OFF);
inline const cv::ocl::oclMat &getMagnoON() const
{
return _magnoXOutputON;
};
inline const cv::ocl::oclMat &getMagnoOFF() const
{
return _magnoXOutputOFF;
};
inline const cv::ocl::oclMat &getMagnoYsaturated() const
{
return _magnoYsaturated;
};
inline void normalizeGrayOutputNearZeroCentreredSigmoide()
{
ocl::normalizeGrayOutputNearZeroCentreredSigmoide(_magnoYOutput, _magnoYsaturated);
};
inline float getTemporalConstant()
{
return this->_filteringCoeficientsTable[2];
};
private:
cv::ocl::oclMat _previousInput_ON;
cv::ocl::oclMat _previousInput_OFF;
cv::ocl::oclMat _amacrinCellsTempOutput_ON;
cv::ocl::oclMat _amacrinCellsTempOutput_OFF;
cv::ocl::oclMat _magnoXOutputON;
cv::ocl::oclMat _magnoXOutputOFF;
cv::ocl::oclMat _localProcessBufferON;
cv::ocl::oclMat _localProcessBufferOFF;
cv::ocl::oclMat _magnoYOutput;
cv::ocl::oclMat _magnoYsaturated;
float _temporalCoefficient;
void _amacrineCellsComputing(const cv::ocl::oclMat &OPL_ON, const cv::ocl::oclMat &OPL_OFF);
};
class ParvoRetinaFilter: public BasicRetinaFilter
{
public:
ParvoRetinaFilter(const unsigned int NBrows = 480, const unsigned int NBcolumns = 640);
virtual ~ParvoRetinaFilter();
void resize(const unsigned int NBrows, const unsigned int NBcolumns);
void clearAllBuffers();
void setOPLandParvoFiltersParameters(const float beta1, const float tau1, const float k1, const float beta2, const float tau2, const float k2);
inline void setGanglionCellsLocalAdaptationLPfilterParameters(const float tau, const float k)
{
BasicRetinaFilter::setLPfilterParameters(0, tau, k, 2);
};
const cv::ocl::oclMat &runFilter(const cv::ocl::oclMat &inputFrame, const bool useParvoOutput = true);
inline const cv::ocl::oclMat &getPhotoreceptorsLPfilteringOutput() const
{
return _photoreceptorsOutput;
};
inline const cv::ocl::oclMat &getHorizontalCellsOutput() const
{
return _horizontalCellsOutput;
};
inline const cv::ocl::oclMat &getParvoON() const
{
return _parvocellularOutputON;
};
inline const cv::ocl::oclMat &getParvoOFF() const
{
return _parvocellularOutputOFF;
};
inline const cv::ocl::oclMat &getBipolarCellsON() const
{
return _bipolarCellsOutputON;
};
inline const cv::ocl::oclMat &getBipolarCellsOFF() const
{
return _bipolarCellsOutputOFF;
};
inline float getPhotoreceptorsTemporalConstant()
{
return this->_filteringCoeficientsTable[2];
};
inline float getHcellsTemporalConstant()
{
return this->_filteringCoeficientsTable[5];
};
private:
cv::ocl::oclMat _photoreceptorsOutput;
cv::ocl::oclMat _horizontalCellsOutput;
cv::ocl::oclMat _parvocellularOutputON;
cv::ocl::oclMat _parvocellularOutputOFF;
cv::ocl::oclMat _bipolarCellsOutputON;
cv::ocl::oclMat _bipolarCellsOutputOFF;
cv::ocl::oclMat _localAdaptationOFF;
cv::ocl::oclMat _localAdaptationON;
cv::ocl::oclMat _parvocellularOutputONminusOFF;
void _OPL_OnOffWaysComputing();
};
class RetinaColor: public BasicRetinaFilter
{
public:
RetinaColor(const unsigned int NBrows, const unsigned int NBcolumns, const int samplingMethod = RETINA_COLOR_DIAGONAL);
virtual ~RetinaColor();
void clearAllBuffers();
void resize(const unsigned int NBrows, const unsigned int NBcolumns);
inline void runColorMultiplexing(const cv::ocl::oclMat &inputRGBFrame)
{
runColorMultiplexing(inputRGBFrame, _multiplexedFrame);
};
void runColorMultiplexing(const cv::ocl::oclMat &demultiplexedInputFrame, cv::ocl::oclMat &multiplexedFrame);
void runColorDemultiplexing(const cv::ocl::oclMat &multiplexedColorFrame, const bool adaptiveFiltering = false, const float maxInputValue = 255.0);
void setColorSaturation(const bool saturateColors = true, const float colorSaturationValue = 4.0)
{
_saturateColors = saturateColors;
_colorSaturationValue = colorSaturationValue;
};
void setChrominanceLPfilterParameters(const float beta, const float tau, const float k)
{
setLPfilterParameters(beta, tau, k);
};
bool applyKrauskopfLMS2Acr1cr2Transform(cv::ocl::oclMat &result);
bool applyLMS2LabTransform(cv::ocl::oclMat &result);
inline const cv::ocl::oclMat &getMultiplexedFrame() const
{
return _multiplexedFrame;
};
inline const cv::ocl::oclMat &getDemultiplexedColorFrame() const
{
return _demultiplexedColorFrame;
};
inline const cv::ocl::oclMat &getLuminance() const
{
return _luminance;
};
inline const cv::ocl::oclMat &getChrominance() const
{
return _chrominance;
};
void clipRGBOutput_0_maxInputValue(cv::ocl::oclMat &inputOutputBuffer, const float maxOutputValue = 255.0);
void normalizeRGBOutput_0_maxOutputValue(const float maxOutputValue = 255.0);
inline void setDemultiplexedColorFrame(const cv::ocl::oclMat &demultiplexedImage)
{
_demultiplexedColorFrame = demultiplexedImage;
};
protected:
inline unsigned int bayerSampleOffset(unsigned int index)
{
return index + ((index / getNBcolumns()) % 2) * getNBpixels() + ((index % getNBcolumns()) % 2) * getNBpixels();
}
inline Rect getROI(int idx)
{
return Rect(0, idx * _NBrows, _NBcols, _NBrows);
}
int _samplingMethod;
bool _saturateColors;
float _colorSaturationValue;
cv::ocl::oclMat _luminance;
cv::ocl::oclMat _multiplexedFrame;
cv::ocl::oclMat _RGBmosaic;
cv::ocl::oclMat _tempMultiplexedFrame;
cv::ocl::oclMat _demultiplexedTempBuffer;
cv::ocl::oclMat _demultiplexedColorFrame;
cv::ocl::oclMat _chrominance;
cv::ocl::oclMat _colorLocalDensity;
cv::ocl::oclMat _imageGradient;
float _pR, _pG, _pB;
bool _objectInit;
void _initColorSampling();
void _adaptiveSpatialLPfilter(const cv::ocl::oclMat &inputFrame, const cv::ocl::oclMat &gradient, cv::ocl::oclMat &outputFrame);
void _adaptiveHorizontalCausalFilter_addInput(const cv::ocl::oclMat &inputFrame, const cv::ocl::oclMat &gradient, cv::ocl::oclMat &outputFrame);
void _adaptiveVerticalAnticausalFilter_multGain(const cv::ocl::oclMat &gradient, cv::ocl::oclMat &outputFrame);
void _computeGradient(const cv::ocl::oclMat &luminance, cv::ocl::oclMat &gradient);
void _normalizeOutputs_0_maxOutputValue(void);
void _applyImageColorSpaceConversion(const cv::ocl::oclMat &inputFrame, cv::ocl::oclMat &outputFrame, const float *transformTable);
};
class RetinaFilter
{
public:
RetinaFilter(const unsigned int sizeRows, const unsigned int sizeColumns, const bool colorMode = false, const int samplingMethod = RETINA_COLOR_BAYER, const bool useRetinaLogSampling = false, const double reductionFactor = 1.0, const double samplingStrenght = 10.0);
~RetinaFilter();
void clearAllBuffers();
void resize(const unsigned int NBrows, const unsigned int NBcolumns);
bool checkInput(const cv::ocl::oclMat &input, const bool colorMode);
bool runFilter(const cv::ocl::oclMat &imageInput, const bool useAdaptiveFiltering = true, const bool processRetinaParvoMagnoMapping = false, const bool useColorMode = false, const bool inputIsColorMultiplexed = false);
void setGlobalParameters(const float OPLspatialResponse1 = 0.7, const float OPLtemporalresponse1 = 1, const float OPLassymetryGain = 0, const float OPLspatialResponse2 = 5, const float OPLtemporalresponse2 = 1, const float LPfilterSpatialResponse = 5, const float LPfilterGain = 0, const float LPfilterTemporalresponse = 0, const float MovingContoursExtractorCoefficient = 5, const bool normalizeParvoOutput_0_maxOutputValue = false, const bool normalizeMagnoOutput_0_maxOutputValue = false, const float maxOutputValue = 255.0, const float maxInputValue = 255.0, const float meanValue = 128.0);
inline void setPhotoreceptorsLocalAdaptationSensitivity(const float V0CompressionParameter)
{
_photoreceptorsPrefilter.setV0CompressionParameter(1 - V0CompressionParameter);
_setInitPeriodCount();
};
inline void setParvoGanglionCellsLocalAdaptationSensitivity(const float V0CompressionParameter)
{
_ParvoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);
_setInitPeriodCount();
};
inline void setGanglionCellsLocalAdaptationLPfilterParameters(const float spatialResponse, const float temporalResponse)
{
_ParvoRetinaFilter.setGanglionCellsLocalAdaptationLPfilterParameters(temporalResponse, spatialResponse);
_setInitPeriodCount();
};
inline void setMagnoGanglionCellsLocalAdaptationSensitivity(const float V0CompressionParameter)
{
_MagnoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);
_setInitPeriodCount();
};
void setOPLandParvoParameters(const float beta1, const float tau1, const float k1, const float beta2, const float tau2, const float k2, const float V0CompressionParameter)
{
_ParvoRetinaFilter.setOPLandParvoFiltersParameters(beta1, tau1, k1, beta2, tau2, k2);
_ParvoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);
_setInitPeriodCount();
};
void setMagnoCoefficientsTable(const float parasolCells_beta, const float parasolCells_tau, const float parasolCells_k, const float amacrinCellsTemporalCutFrequency, const float V0CompressionParameter, const float localAdaptintegration_tau, const float localAdaptintegration_k)
{
_MagnoRetinaFilter.setCoefficientsTable(parasolCells_beta, parasolCells_tau, parasolCells_k, amacrinCellsTemporalCutFrequency, localAdaptintegration_tau, localAdaptintegration_k);
_MagnoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);
_setInitPeriodCount();
};
inline void activateNormalizeParvoOutput_0_maxOutputValue(const bool normalizeParvoOutput_0_maxOutputValue)
{
_normalizeParvoOutput_0_maxOutputValue = normalizeParvoOutput_0_maxOutputValue;
};
inline void activateNormalizeMagnoOutput_0_maxOutputValue(const bool normalizeMagnoOutput_0_maxOutputValue)
{
_normalizeMagnoOutput_0_maxOutputValue = normalizeMagnoOutput_0_maxOutputValue;
};
inline void setMaxOutputValue(const float maxOutputValue)
{
_maxOutputValue = maxOutputValue;
};
void setColorMode(const bool desiredColorMode)
{
_useColorMode = desiredColorMode;
};
inline void setColorSaturation(const bool saturateColors = true, const float colorSaturationValue = 4.0)
{
_colorEngine.setColorSaturation(saturateColors, colorSaturationValue);
};
inline const cv::ocl::oclMat &getLocalAdaptation() const
{
return _photoreceptorsPrefilter.getOutput();
};
inline const cv::ocl::oclMat &getPhotoreceptors() const
{
return _ParvoRetinaFilter.getPhotoreceptorsLPfilteringOutput();
};
inline const cv::ocl::oclMat &getHorizontalCells() const
{
return _ParvoRetinaFilter.getHorizontalCellsOutput();
};
inline bool areContoursProcessed()
{
return _useParvoOutput;
};
bool getParvoFoveaResponse(cv::ocl::oclMat &parvoFovealResponse);
inline void activateContoursProcessing(const bool useParvoOutput)
{
_useParvoOutput = useParvoOutput;
};
const cv::ocl::oclMat &getContours();
inline const cv::ocl::oclMat &getContoursON() const
{
return _ParvoRetinaFilter.getParvoON();
};
inline const cv::ocl::oclMat &getContoursOFF() const
{
return _ParvoRetinaFilter.getParvoOFF();
};
inline bool areMovingContoursProcessed()
{
return _useMagnoOutput;
};
inline void activateMovingContoursProcessing(const bool useMagnoOutput)
{
_useMagnoOutput = useMagnoOutput;
};
inline const cv::ocl::oclMat &getMovingContours() const
{
return _MagnoRetinaFilter.getOutput();
};
inline const cv::ocl::oclMat &getMovingContoursSaturated() const
{
return _MagnoRetinaFilter.getMagnoYsaturated();
};
inline const cv::ocl::oclMat &getMovingContoursON() const
{
return _MagnoRetinaFilter.getMagnoON();
};
inline const cv::ocl::oclMat &getMovingContoursOFF() const
{
return _MagnoRetinaFilter.getMagnoOFF();
};
inline const cv::ocl::oclMat &getRetinaParvoMagnoMappedOutput() const
{
return _retinaParvoMagnoMappedFrame;
};
inline const cv::ocl::oclMat &getParvoContoursChannel() const
{
return _colorEngine.getLuminance();
};
inline const cv::ocl::oclMat &getParvoChrominance() const
{
return _colorEngine.getChrominance();
};
inline const cv::ocl::oclMat &getColorOutput() const
{
return _colorEngine.getDemultiplexedColorFrame();
};
inline bool isColorMode()
{
return _useColorMode;
};
bool getColorMode()
{
return _useColorMode;
};
inline bool isInitTransitionDone()
{
if (_ellapsedFramesSinceLastReset < _globalTemporalConstant)
{
return false;
}
return true;
};
inline float getRetinaSamplingBackProjection(const float projectedRadiusLength)
{
return projectedRadiusLength;
};
inline unsigned int getInputNBrows()
{
return _photoreceptorsPrefilter.getNBrows();
};
inline unsigned int getInputNBcolumns()
{
return _photoreceptorsPrefilter.getNBcolumns();
};
inline unsigned int getInputNBpixels()
{
return _photoreceptorsPrefilter.getNBpixels();
};
inline unsigned int getOutputNBrows()
{
return _photoreceptorsPrefilter.getNBrows();
};
inline unsigned int getOutputNBcolumns()
{
return _photoreceptorsPrefilter.getNBcolumns();
};
inline unsigned int getOutputNBpixels()
{
return _photoreceptorsPrefilter.getNBpixels();
};
private:
bool _useParvoOutput;
bool _useMagnoOutput;
unsigned int _ellapsedFramesSinceLastReset;
unsigned int _globalTemporalConstant;
cv::ocl::oclMat _retinaParvoMagnoMappedFrame;
BasicRetinaFilter _photoreceptorsPrefilter;
ParvoRetinaFilter _ParvoRetinaFilter;
MagnoRetinaFilter _MagnoRetinaFilter;
RetinaColor _colorEngine;
bool _useMinimalMemoryForToneMappingONLY;
bool _normalizeParvoOutput_0_maxOutputValue;
bool _normalizeMagnoOutput_0_maxOutputValue;
float _maxOutputValue;
bool _useColorMode;
void _setInitPeriodCount();
void _processRetinaParvoMagnoMapping();
void _runGrayToneMapping(const cv::ocl::oclMat &grayImageInput, cv::ocl::oclMat &grayImageOutput , const float PhotoreceptorsCompression = 0.6, const float ganglionCellsCompression = 0.6);
};
} /* namespace ocl */
} /* namespace bioinspired */
} /* namespace cv */
#endif /* HAVE_OPENCV_OCL */
#endif /* __OCL_RETINA_HPP__ */
-725
View File
@@ -1,725 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
#include "precomp.hpp"
#include "retinacolor.hpp"
// @author Alexandre BENOIT, benoit.alexandre.vision@gmail.com, LISTIC : www.listic.univ-savoie.fr, Gipsa-Lab, France: www.gipsa-lab.inpg.fr/
#include <iostream>
#include <ctime>
namespace cv
{
namespace bioinspired
{
// init static values
static float _LMStoACr1Cr2[]={1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -0.5, -0.5, 1.0};
//static double _ACr1Cr2toLMS[]={0.5, 0.5, 0.0, 0.5, -0.5, 0.0, 0.5, 0.0, 1.0};
static float _LMStoLab[]={0.5774f, 0.5774f, 0.5774f, 0.4082f, 0.4082f, -0.8165f, 0.7071f, -0.7071f, 0.f};
// constructor/desctructor
RetinaColor::RetinaColor(const unsigned int NBrows, const unsigned int NBcolumns, const int samplingMethod)
:BasicRetinaFilter(NBrows, NBcolumns, 3),
_colorSampling(NBrows*NBcolumns),
_RGBmosaic(NBrows*NBcolumns*3),
_tempMultiplexedFrame(NBrows*NBcolumns),
_demultiplexedTempBuffer(NBrows*NBcolumns*3),
_demultiplexedColorFrame(NBrows*NBcolumns*3),
_chrominance(NBrows*NBcolumns*3),
_colorLocalDensity(NBrows*NBcolumns*3),
_imageGradient(NBrows*NBcolumns*2)
{
// link to parent buffers (let's recycle !)
_luminance=&_filterOutput;
_multiplexedFrame=&_localBuffer;
_objectInit=false;
_samplingMethod=samplingMethod;
_saturateColors=false;
_colorSaturationValue=4.0;
// set default spatio-temporal filter parameters
setLPfilterParameters(0.0, 0.0, 1.5);
setLPfilterParameters(0.0, 0.0, 10.5, 1);// for the low pass filter dedicated to contours energy extraction (demultiplexing process)
setLPfilterParameters(0.f, 0.f, 0.9f, 2);
// init default value on image Gradient
_imageGradient=0.57f;
// init color sampling map
_initColorSampling();
// flush all buffers
clearAllBuffers();
}
RetinaColor::~RetinaColor()
{
}
/**
* function that clears all buffers of the object
*/
void RetinaColor::clearAllBuffers()
{
BasicRetinaFilter::clearAllBuffers();
_tempMultiplexedFrame=0.f;
_demultiplexedTempBuffer=0.f;
_demultiplexedColorFrame=0.f;
_chrominance=0.f;
_imageGradient=0.57f;
}
/**
* resize retina color filter object (resize all allocated buffers)
* @param NBrows: the new height size
* @param NBcolumns: the new width size
*/
void RetinaColor::resize(const unsigned int NBrows, const unsigned int NBcolumns)
{
BasicRetinaFilter::clearAllBuffers();
_colorSampling.resize(NBrows*NBcolumns);
_RGBmosaic.resize(NBrows*NBcolumns*3);
_tempMultiplexedFrame.resize(NBrows*NBcolumns);
_demultiplexedTempBuffer.resize(NBrows*NBcolumns*3);
_demultiplexedColorFrame.resize(NBrows*NBcolumns*3);
_chrominance.resize(NBrows*NBcolumns*3);
_colorLocalDensity.resize(NBrows*NBcolumns*3);
_imageGradient.resize(NBrows*NBcolumns*2);
// link to parent buffers (let's recycle !)
_luminance=&_filterOutput;
_multiplexedFrame=&_localBuffer;
// init color sampling map
_initColorSampling();
// clean buffers
clearAllBuffers();
}
void RetinaColor::_initColorSampling()
{
// filling the conversion table for multiplexed <=> demultiplexed frame
srand((unsigned)time(NULL));
// preInit cones probabilities
_pR=_pB=_pG=0;
switch (_samplingMethod)
{
case RETINA_COLOR_RANDOM:
for (unsigned int index=0 ; index<this->getNBpixels(); ++index)
{
// random RGB sampling
unsigned int colorIndex=rand()%24;
if (colorIndex<8){
colorIndex=0;
++_pR;
}else
{
if (colorIndex<21){
colorIndex=1;
++_pG;
}else{
colorIndex=2;
++_pB;
}
}
_colorSampling[index] = colorIndex*this->getNBpixels()+index;
}
_pR/=(float)this->getNBpixels();
_pG/=(float)this->getNBpixels();
_pB/=(float)this->getNBpixels();
std::cout<<"Color channels proportions: pR, pG, pB= "<<_pR<<", "<<_pG<<", "<<_pB<<", "<<std::endl;
break;
case RETINA_COLOR_DIAGONAL:
for (unsigned int index=0 ; index<this->getNBpixels(); ++index)
{
_colorSampling[index] = index+((index%3+(index%_filterOutput.getNBcolumns()))%3)*_filterOutput.getNBpixels();
}
_pR=_pB=_pG=1.f/3;
break;
case RETINA_COLOR_BAYER: // default sets bayer sampling
for (unsigned int index=0 ; index<_filterOutput.getNBpixels(); ++index)
{
//First line: R G R G
_colorSampling[index] = index+((index/_filterOutput.getNBcolumns())%2)*_filterOutput.getNBpixels()+((index%_filterOutput.getNBcolumns())%2)*_filterOutput.getNBpixels();
//First line: G R G R
//_colorSampling[index] = 3*index+((index/_filterOutput.getNBcolumns())%2)+((index%_filterOutput.getNBcolumns()+1)%2);
}
_pR=_pB=0.25;
_pG=0.5;
break;
default:
#ifdef RETINACOLORDEBUG
std::cerr<<"RetinaColor::No or wrong color sampling method, skeeping"<<std::endl;
#endif
return;
break;//.. not useful, yes
}
// feeling the mosaic buffer:
_RGBmosaic=0;
for (unsigned int index=0 ; index<_filterOutput.getNBpixels(); ++index)
// the RGB _RGBmosaic buffer contains 1 where the pixel corresponds to a sampled color
_RGBmosaic[_colorSampling[index]]=1.0;
// computing photoreceptors local density
_spatiotemporalLPfilter(&_RGBmosaic[0], &_colorLocalDensity[0]);
_spatiotemporalLPfilter(&_RGBmosaic[0]+_filterOutput.getNBpixels(), &_colorLocalDensity[0]+_filterOutput.getNBpixels());
_spatiotemporalLPfilter(&_RGBmosaic[0]+_filterOutput.getDoubleNBpixels(), &_colorLocalDensity[0]+_filterOutput.getDoubleNBpixels());
unsigned int maxNBpixels=3*_filterOutput.getNBpixels();
register float *colorLocalDensityPTR=&_colorLocalDensity[0];
for (unsigned int i=0;i<maxNBpixels;++i, ++colorLocalDensityPTR)
*colorLocalDensityPTR=1.f/ *colorLocalDensityPTR;
#ifdef RETINACOLORDEBUG
std::cout<<"INIT _colorLocalDensity max, min: "<<_colorLocalDensity.max()<<", "<<_colorLocalDensity.min()<<std::endl;
#endif
// end of the init step
_objectInit=true;
}
// public functions
void RetinaColor::runColorDemultiplexing(const std::valarray<float> &multiplexedColorFrame, const bool adaptiveFiltering, const float maxInputValue)
{
// demultiplex the grey frame to RGB frame
// -> first set demultiplexed frame to 0
_demultiplexedTempBuffer=0;
// -> demultiplex process
register unsigned int *colorSamplingPRT=&_colorSampling[0];
register const float *multiplexedColorFramePtr=get_data(multiplexedColorFrame);
for (unsigned int indexa=0; indexa<_filterOutput.getNBpixels() ; ++indexa)
_demultiplexedTempBuffer[*(colorSamplingPRT++)]=*(multiplexedColorFramePtr++);
// interpolate the demultiplexed frame depending on the color sampling method
if (!adaptiveFiltering)
_interpolateImageDemultiplexedImage(&_demultiplexedTempBuffer[0]);
// low pass filtering the demultiplexed frame
_spatiotemporalLPfilter(&_demultiplexedTempBuffer[0], &_chrominance[0]);
_spatiotemporalLPfilter(&_demultiplexedTempBuffer[0]+_filterOutput.getNBpixels(), &_chrominance[0]+_filterOutput.getNBpixels());
_spatiotemporalLPfilter(&_demultiplexedTempBuffer[0]+_filterOutput.getDoubleNBpixels(), &_chrominance[0]+_filterOutput.getDoubleNBpixels());
/*if (_samplingMethod=BAYER)
{
_applyRIFfilter(_chrominance, _chrominance);
_applyRIFfilter(_chrominance+_filterOutput.getNBpixels(), _chrominance+_filterOutput.getNBpixels());
_applyRIFfilter(_chrominance+_filterOutput.getDoubleNBpixels(), _chrominance+_filterOutput.getDoubleNBpixels());
}*/
// normalize by the photoreceptors local density and retrieve the local luminance
register float *chrominancePTR= &_chrominance[0];
register float *colorLocalDensityPTR= &_colorLocalDensity[0];
register float *luminance= &(*_luminance)[0];
if (!adaptiveFiltering)// compute the gradient on the luminance
{
if (_samplingMethod==RETINA_COLOR_RANDOM)
for (unsigned int indexc=0; indexc<_filterOutput.getNBpixels() ; ++indexc, ++chrominancePTR, ++colorLocalDensityPTR, ++luminance)
{
// normalize by photoreceptors density
float Cr=*(chrominancePTR)*_colorLocalDensity[indexc];
float Cg=*(chrominancePTR+_filterOutput.getNBpixels())*_colorLocalDensity[indexc+_filterOutput.getNBpixels()];
float Cb=*(chrominancePTR+_filterOutput.getDoubleNBpixels())*_colorLocalDensity[indexc+_filterOutput.getDoubleNBpixels()];
*luminance=(Cr+Cg+Cb)*_pG;
*(chrominancePTR)=Cr-*luminance;
*(chrominancePTR+_filterOutput.getNBpixels())=Cg-*luminance;
*(chrominancePTR+_filterOutput.getDoubleNBpixels())=Cb-*luminance;
}
else
for (unsigned int indexc=0; indexc<_filterOutput.getNBpixels() ; ++indexc, ++chrominancePTR, ++colorLocalDensityPTR, ++luminance)
{
float Cr=*(chrominancePTR);
float Cg=*(chrominancePTR+_filterOutput.getNBpixels());
float Cb=*(chrominancePTR+_filterOutput.getDoubleNBpixels());
*luminance=_pR*Cr+_pG*Cg+_pB*Cb;
*(chrominancePTR)=Cr-*luminance;
*(chrominancePTR+_filterOutput.getNBpixels())=Cg-*luminance;
*(chrominancePTR+_filterOutput.getDoubleNBpixels())=Cb-*luminance;
}
// in order to get the color image, each colored map needs to be added the luminance
// -> to do so, compute: multiplexedColorFrame - remultiplexed chrominances
runColorMultiplexing(_chrominance, _tempMultiplexedFrame);
//lum = 1/3((f*(ImR))/(f*mR) + (f*(ImG))/(f*mG) + (f*(ImB))/(f*mB));
float *luminancePTR= &(*_luminance)[0];
chrominancePTR= &_chrominance[0];
float *demultiplexedColorFramePTR= &_demultiplexedColorFrame[0];
for (unsigned int indexp=0; indexp<_filterOutput.getNBpixels() ; ++indexp, ++luminancePTR, ++chrominancePTR, ++demultiplexedColorFramePTR)
{
*luminancePTR=(multiplexedColorFrame[indexp]-_tempMultiplexedFrame[indexp]);
*(demultiplexedColorFramePTR)=*(chrominancePTR)+*luminancePTR;
*(demultiplexedColorFramePTR+_filterOutput.getNBpixels())=*(chrominancePTR+_filterOutput.getNBpixels())+*luminancePTR;
*(demultiplexedColorFramePTR+_filterOutput.getDoubleNBpixels())=*(chrominancePTR+_filterOutput.getDoubleNBpixels())+*luminancePTR;
}
}else
{
register const float *multiplexedColorFramePTR= get_data(multiplexedColorFrame);
for (unsigned int indexc=0; indexc<_filterOutput.getNBpixels() ; ++indexc, ++chrominancePTR, ++colorLocalDensityPTR, ++luminance, ++multiplexedColorFramePTR)
{
// normalize by photoreceptors density
float Cr=*(chrominancePTR)*_colorLocalDensity[indexc];
float Cg=*(chrominancePTR+_filterOutput.getNBpixels())*_colorLocalDensity[indexc+_filterOutput.getNBpixels()];
float Cb=*(chrominancePTR+_filterOutput.getDoubleNBpixels())*_colorLocalDensity[indexc+_filterOutput.getDoubleNBpixels()];
*luminance=(Cr+Cg+Cb)*_pG;
_demultiplexedTempBuffer[_colorSampling[indexc]] = *multiplexedColorFramePTR - *luminance;
}
// compute the gradient of the luminance
#ifdef MAKE_PARALLEL // call the TemplateBuffer TBB clipping method
cv::parallel_for_(cv::Range(2,_filterOutput.getNBrows()-2), Parallel_computeGradient(_filterOutput.getNBcolumns(), _filterOutput.getNBrows(), &(*_luminance)[0], &_imageGradient[0]));
#else
_computeGradient(&(*_luminance)[0]);
#endif
// adaptively filter the submosaics to get the adaptive densities, here the buffer _chrominance is used as a temp buffer
_adaptiveSpatialLPfilter(&_RGBmosaic[0], &_chrominance[0]);
_adaptiveSpatialLPfilter(&_RGBmosaic[0]+_filterOutput.getNBpixels(), &_chrominance[0]+_filterOutput.getNBpixels());
_adaptiveSpatialLPfilter(&_RGBmosaic[0]+_filterOutput.getDoubleNBpixels(), &_chrominance[0]+_filterOutput.getDoubleNBpixels());
_adaptiveSpatialLPfilter(&_demultiplexedTempBuffer[0], &_demultiplexedColorFrame[0]);
_adaptiveSpatialLPfilter(&_demultiplexedTempBuffer[0]+_filterOutput.getNBpixels(), &_demultiplexedColorFrame[0]+_filterOutput.getNBpixels());
_adaptiveSpatialLPfilter(&_demultiplexedTempBuffer[0]+_filterOutput.getDoubleNBpixels(), &_demultiplexedColorFrame[0]+_filterOutput.getDoubleNBpixels());
/* for (unsigned int index=0; index<_filterOutput.getNBpixels()*3 ; ++index) // cette boucle pourrait tre supprimee en passant la densit la fonction de filtrage
_demultiplexedColorFrame[index] /= _chrominance[index];*/
_demultiplexedColorFrame/=_chrominance; // more optimal ;o)
// compute and substract the residual luminance
for (unsigned int index=0; index<_filterOutput.getNBpixels() ; ++index)
{
float residu = _pR*_demultiplexedColorFrame[index] + _pG*_demultiplexedColorFrame[index+_filterOutput.getNBpixels()] + _pB*_demultiplexedColorFrame[index+_filterOutput.getDoubleNBpixels()];
_demultiplexedColorFrame[index] = _demultiplexedColorFrame[index] - residu;
_demultiplexedColorFrame[index+_filterOutput.getNBpixels()] = _demultiplexedColorFrame[index+_filterOutput.getNBpixels()] - residu;
_demultiplexedColorFrame[index+_filterOutput.getDoubleNBpixels()] = _demultiplexedColorFrame[index+_filterOutput.getDoubleNBpixels()] - residu;
}
// multiplex the obtained chrominance
runColorMultiplexing(_demultiplexedColorFrame, _tempMultiplexedFrame);
_demultiplexedTempBuffer=0;
// get the luminance, et and add it to each chrominance
for (unsigned int index=0; index<_filterOutput.getNBpixels() ; ++index)
{
(*_luminance)[index]=multiplexedColorFrame[index]-_tempMultiplexedFrame[index];
_demultiplexedTempBuffer[_colorSampling[index]] = _demultiplexedColorFrame[_colorSampling[index]];//multiplexedColorFrame[index] - (*_luminance)[index];
}
_spatiotemporalLPfilter(&_demultiplexedTempBuffer[0], &_demultiplexedTempBuffer[0]);
_spatiotemporalLPfilter(&_demultiplexedTempBuffer[0]+_filterOutput.getNBpixels(), &_demultiplexedTempBuffer[0]+_filterOutput.getNBpixels());
_spatiotemporalLPfilter(&_demultiplexedTempBuffer[0]+_filterOutput.getDoubleNBpixels(), &_demultiplexedTempBuffer[0]+_filterOutput.getDoubleNBpixels());
// get the luminance and add it to each chrominance
for (unsigned int index=0; index<_filterOutput.getNBpixels() ; ++index)
{
_demultiplexedColorFrame[index] = _demultiplexedTempBuffer[index]*_colorLocalDensity[index]+ (*_luminance)[index];
_demultiplexedColorFrame[index+_filterOutput.getNBpixels()] = _demultiplexedTempBuffer[index+_filterOutput.getNBpixels()]*_colorLocalDensity[index+_filterOutput.getNBpixels()]+ (*_luminance)[index];
_demultiplexedColorFrame[index+_filterOutput.getDoubleNBpixels()] = _demultiplexedTempBuffer[index+_filterOutput.getDoubleNBpixels()]*_colorLocalDensity[index+_filterOutput.getDoubleNBpixels()]+ (*_luminance)[index];
}
}
// eliminate saturated colors by simple clipping values to the input range
clipRGBOutput_0_maxInputValue(NULL, maxInputValue);
/* transfert image gradient in order to check validity
memcpy((*_luminance), _imageGradient, sizeof(float)*_filterOutput.getNBpixels());
memcpy(_demultiplexedColorFrame, _imageGradient+_filterOutput.getNBpixels(), sizeof(float)*_filterOutput.getNBpixels());
memcpy(_demultiplexedColorFrame+_filterOutput.getNBpixels(), _imageGradient+_filterOutput.getNBpixels(), sizeof(float)*_filterOutput.getNBpixels());
memcpy(_demultiplexedColorFrame+2*_filterOutput.getNBpixels(), _imageGradient+_filterOutput.getNBpixels(), sizeof(float)*_filterOutput.getNBpixels());
*/
if (_saturateColors)
{
TemplateBuffer<float>::normalizeGrayOutputCentredSigmoide(128, _colorSaturationValue, maxInputValue, &_demultiplexedColorFrame[0], &_demultiplexedColorFrame[0], _filterOutput.getNBpixels());
TemplateBuffer<float>::normalizeGrayOutputCentredSigmoide(128, _colorSaturationValue, maxInputValue, &_demultiplexedColorFrame[0]+_filterOutput.getNBpixels(), &_demultiplexedColorFrame[0]+_filterOutput.getNBpixels(), _filterOutput.getNBpixels());
TemplateBuffer<float>::normalizeGrayOutputCentredSigmoide(128, _colorSaturationValue, maxInputValue, &_demultiplexedColorFrame[0]+_filterOutput.getNBpixels()*2, &_demultiplexedColorFrame[0]+_filterOutput.getNBpixels()*2, _filterOutput.getNBpixels());
}
}
// color multiplexing: input frame size=_NBrows*_filterOutput.getNBcolumns()*3, multiplexedFrame output size=_NBrows*_filterOutput.getNBcolumns()
void RetinaColor::runColorMultiplexing(const std::valarray<float> &demultiplexedInputFrame, std::valarray<float> &multiplexedFrame)
{
// multiply each color layer by its bayer mask
register unsigned int *colorSamplingPTR= &_colorSampling[0];
register float *multiplexedFramePTR= &multiplexedFrame[0];
for (unsigned int indexp=0; indexp<_filterOutput.getNBpixels(); ++indexp)
*(multiplexedFramePTR++)=demultiplexedInputFrame[*(colorSamplingPTR++)];
}
void RetinaColor::normalizeRGBOutput_0_maxOutputValue(const float maxOutputValue)
{
//normalizeGrayOutputCentredSigmoide(0.0, 2, _chrominance);
TemplateBuffer<float>::normalizeGrayOutput_0_maxOutputValue(&_demultiplexedColorFrame[0], 3*_filterOutput.getNBpixels(), maxOutputValue);
//normalizeGrayOutputCentredSigmoide(0.0, 2, _chrominance+_filterOutput.getNBpixels());
//normalizeGrayOutput_0_maxOutputValue(_demultiplexedColorFrame+_filterOutput.getNBpixels(), _filterOutput.getNBpixels(), maxOutputValue);
//normalizeGrayOutputCentredSigmoide(0.0, 2, _chrominance+2*_filterOutput.getNBpixels());
//normalizeGrayOutput_0_maxOutputValue(_demultiplexedColorFrame+_filterOutput.getDoubleNBpixels(), _filterOutput.getNBpixels(), maxOutputValue);
TemplateBuffer<float>::normalizeGrayOutput_0_maxOutputValue(&(*_luminance)[0], _filterOutput.getNBpixels(), maxOutputValue);
}
/// normalize output between 0 and maxOutputValue;
void RetinaColor::clipRGBOutput_0_maxInputValue(float *inputOutputBuffer, const float maxInputValue)
{
//std::cout<<"RetinaColor::normalizing RGB frame..."<<std::endl;
// if outputBuffer unsassigned, the rewrite the buffer
if (inputOutputBuffer==NULL)
inputOutputBuffer= &_demultiplexedColorFrame[0];
#ifdef MAKE_PARALLEL // call the TemplateBuffer TBB clipping method
cv::parallel_for_(cv::Range(0,_filterOutput.getNBpixels()*3), Parallel_clipBufferValues<float>(inputOutputBuffer, 0, maxInputValue));
#else
register float *inputOutputBufferPTR=inputOutputBuffer;
for (register unsigned int jf = 0; jf < _filterOutput.getNBpixels()*3; ++jf, ++inputOutputBufferPTR)
{
if (*inputOutputBufferPTR>maxInputValue)
*inputOutputBufferPTR=maxInputValue;
else if (*inputOutputBufferPTR<0)
*inputOutputBufferPTR=0;
}
#endif
//std::cout<<"RetinaColor::...normalizing RGB frame OK"<<std::endl;
}
void RetinaColor::_interpolateImageDemultiplexedImage(float *inputOutputBuffer)
{
switch(_samplingMethod)
{
case RETINA_COLOR_RANDOM:
return; // no need to interpolate
break;
case RETINA_COLOR_DIAGONAL:
_interpolateSingleChannelImage111(inputOutputBuffer);
break;
case RETINA_COLOR_BAYER: // default sets bayer sampling
_interpolateBayerRGBchannels(inputOutputBuffer);
break;
default:
std::cerr<<"RetinaColor::No or wrong color sampling method, skeeping"<<std::endl;
return;
break;//.. not useful, yes
}
}
void RetinaColor::_interpolateSingleChannelImage111(float *inputOutputBuffer)
{
for (unsigned int indexr=0 ; indexr<_filterOutput.getNBrows(); ++indexr)
{
for (unsigned int indexc=1 ; indexc<_filterOutput.getNBcolumns()-1; ++indexc)
{
unsigned int index=indexc+indexr*_filterOutput.getNBcolumns();
inputOutputBuffer[index]=(inputOutputBuffer[index-1]+inputOutputBuffer[index]+inputOutputBuffer[index+1])/3.f;
}
}
for (unsigned int indexc=0 ; indexc<_filterOutput.getNBcolumns(); ++indexc)
{
for (unsigned int indexr=1 ; indexr<_filterOutput.getNBrows()-1; ++indexr)
{
unsigned int index=indexc+indexr*_filterOutput.getNBcolumns();
inputOutputBuffer[index]=(inputOutputBuffer[index-_filterOutput.getNBcolumns()]+inputOutputBuffer[index]+inputOutputBuffer[index+_filterOutput.getNBcolumns()])/3.f;
}
}
}
void RetinaColor::_interpolateBayerRGBchannels(float *inputOutputBuffer)
{
for (unsigned int indexr=0 ; indexr<_filterOutput.getNBrows()-1; indexr+=2)
{
for (unsigned int indexc=1 ; indexc<_filterOutput.getNBcolumns()-1; indexc+=2)
{
unsigned int indexR=indexc+indexr*_filterOutput.getNBcolumns();
unsigned int indexB=_filterOutput.getDoubleNBpixels()+indexc+1+(indexr+1)*_filterOutput.getNBcolumns();
inputOutputBuffer[indexR]=(inputOutputBuffer[indexR-1]+inputOutputBuffer[indexR+1])/2.f;
inputOutputBuffer[indexB]=(inputOutputBuffer[indexB-1]+inputOutputBuffer[indexB+1])/2.f;
}
}
for (unsigned int indexr=1 ; indexr<_filterOutput.getNBrows()-1; indexr+=2)
{
for (unsigned int indexc=0 ; indexc<_filterOutput.getNBcolumns(); ++indexc)
{
unsigned int indexR=indexc+indexr*_filterOutput.getNBcolumns();
unsigned int indexB=_filterOutput.getDoubleNBpixels()+indexc+1+(indexr+1)*_filterOutput.getNBcolumns();
inputOutputBuffer[indexR]=(inputOutputBuffer[indexR-_filterOutput.getNBcolumns()]+inputOutputBuffer[indexR+_filterOutput.getNBcolumns()])/2.f;
inputOutputBuffer[indexB]=(inputOutputBuffer[indexB-_filterOutput.getNBcolumns()]+inputOutputBuffer[indexB+_filterOutput.getNBcolumns()])/2.f;
}
}
for (unsigned int indexr=1 ; indexr<_filterOutput.getNBrows()-1; ++indexr)
for (unsigned int indexc=0 ; indexc<_filterOutput.getNBcolumns(); indexc+=2)
{
unsigned int indexG=_filterOutput.getNBpixels()+indexc+(indexr)*_filterOutput.getNBcolumns()+indexr%2;
inputOutputBuffer[indexG]=(inputOutputBuffer[indexG-1]+inputOutputBuffer[indexG+1]+inputOutputBuffer[indexG-_filterOutput.getNBcolumns()]+inputOutputBuffer[indexG+_filterOutput.getNBcolumns()])*0.25f;
}
}
void RetinaColor::_applyRIFfilter(const float *sourceBuffer, float *destinationBuffer)
{
for (unsigned int indexr=1 ; indexr<_filterOutput.getNBrows()-1; ++indexr)
{
for (unsigned int indexc=1 ; indexc<_filterOutput.getNBcolumns()-1; ++indexc)
{
unsigned int index=indexc+indexr*_filterOutput.getNBcolumns();
_tempMultiplexedFrame[index]=(4.f*sourceBuffer[index]+sourceBuffer[index-1-_filterOutput.getNBcolumns()]+sourceBuffer[index-1+_filterOutput.getNBcolumns()]+sourceBuffer[index+1-_filterOutput.getNBcolumns()]+sourceBuffer[index+1+_filterOutput.getNBcolumns()])*0.125f;
}
}
memcpy(destinationBuffer, &_tempMultiplexedFrame[0], sizeof(float)*_filterOutput.getNBpixels());
}
void RetinaColor::_getNormalizedContoursImage(const float *inputFrame, float *outputFrame)
{
float maxValue=0.f;
float normalisationFactor=1.f/3.f;
for (unsigned int indexr=1 ; indexr<_filterOutput.getNBrows()-1; ++indexr)
{
for (unsigned int indexc=1 ; indexc<_filterOutput.getNBcolumns()-1; ++indexc)
{
unsigned int index=indexc+indexr*_filterOutput.getNBcolumns();
outputFrame[index]=normalisationFactor*fabs(8.f*inputFrame[index]-inputFrame[index-1]-inputFrame[index+1]-inputFrame[index-_filterOutput.getNBcolumns()]-inputFrame[index+_filterOutput.getNBcolumns()]-inputFrame[index-1-_filterOutput.getNBcolumns()]-inputFrame[index-1+_filterOutput.getNBcolumns()]-inputFrame[index+1-_filterOutput.getNBcolumns()]-inputFrame[index+1+_filterOutput.getNBcolumns()]);
if (outputFrame[index]>maxValue)
maxValue=outputFrame[index];
}
}
normalisationFactor=1.f/maxValue;
// normalisation [0, 1]
for (unsigned int indexp=1 ; indexp<_filterOutput.getNBrows()-1; ++indexp)
outputFrame[indexp]=outputFrame[indexp]*normalisationFactor;
}
//////////////////////////////////////////////////////////
// ADAPTIVE BASIC RETINA FILTER
//////////////////////////////////////////////////////////
// run LP filter for a new frame input and save result at a specific output adress
void RetinaColor::_adaptiveSpatialLPfilter(const float *inputFrame, float *outputFrame)
{
/**********/
_gain = (1-0.57f)*(1-0.57f)*(1-0.06f)*(1-0.06f);
// launch the serie of 1D directional filters in order to compute the 2D low pass filter
// -> horizontal filters work with the first layer of imageGradient
_adaptiveHorizontalCausalFilter_addInput(inputFrame, outputFrame, 0, _filterOutput.getNBrows());
_horizontalAnticausalFilter_Irregular(outputFrame, 0, _filterOutput.getNBrows(), &_imageGradient[0]);
// -> horizontal filters work with the second layer of imageGradient
_verticalCausalFilter_Irregular(outputFrame, 0, _filterOutput.getNBcolumns(), &_imageGradient[0]+_filterOutput.getNBpixels());
_adaptiveVerticalAnticausalFilter_multGain(outputFrame, 0, _filterOutput.getNBcolumns());
}
// horizontal causal filter which adds the input inside... replaces the parent _horizontalCausalFilter_Irregular_addInput by avoiding a product for each pixel
void RetinaColor::_adaptiveHorizontalCausalFilter_addInput(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDrowStart,IDrowEnd), Parallel_adaptiveHorizontalCausalFilter_addInput(inputFrame, outputFrame, &_imageGradient[0], _filterOutput.getNBcolumns()));
#else
register float* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns();
register const float* inputPTR=inputFrame+IDrowStart*_filterOutput.getNBcolumns();
register const float *imageGradientPTR= &_imageGradient[0]+IDrowStart*_filterOutput.getNBcolumns();
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{
register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{
//std::cout<<(*imageGradientPTR)<<" ";
result = *(inputPTR++) + (*imageGradientPTR)* result;
*(outputPTR++) = result;
++imageGradientPTR;
}
// std::cout<<" "<<std::endl;
}
#endif
}
// vertical anticausal filter which multiplies the output by _gain... replaces the parent _verticalAnticausalFilter_multGain by avoiding a product for each pixel and taking into account the second layer of the _imageGradient buffer
void RetinaColor::_adaptiveVerticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDcolumnStart,IDcolumnEnd), Parallel_adaptiveVerticalAnticausalFilter_multGain(outputFrame, &_imageGradient[0]+_filterOutput.getNBpixels(), _filterOutput.getNBrows(), _filterOutput.getNBcolumns(), _gain));
#else
float* outputOffset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
float* gradOffset= &_imageGradient[0]+_filterOutput.getNBpixels()*2-_filterOutput.getNBcolumns();
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{
register float result=0;
register float *outputPTR=outputOffset+IDcolumn;
register float *imageGradientPTR=gradOffset+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{
result = *(outputPTR) + (*(imageGradientPTR)) * result;
*(outputPTR) = _gain*result;
outputPTR-=_filterOutput.getNBcolumns();
imageGradientPTR-=_filterOutput.getNBcolumns();
}
}
#endif
}
///////////////////////////
void RetinaColor::_computeGradient(const float *luminance)
{
for (unsigned int idLine=2;idLine<_filterOutput.getNBrows()-2;++idLine)
{
for (unsigned int idColumn=2;idColumn<_filterOutput.getNBcolumns()-2;++idColumn)
{
const unsigned int pixelIndex=idColumn+_filterOutput.getNBcolumns()*idLine;
// horizontal and vertical local gradients
const float verticalGrad=fabs(luminance[pixelIndex+_filterOutput.getNBcolumns()]-luminance[pixelIndex-_filterOutput.getNBcolumns()]);
const float horizontalGrad=fabs(luminance[pixelIndex+1]-luminance[pixelIndex-1]);
// neighborhood horizontal and vertical gradients
const float verticalGrad_p=fabs(luminance[pixelIndex]-luminance[pixelIndex-2*_filterOutput.getNBcolumns()]);
const float horizontalGrad_p=fabs(luminance[pixelIndex]-luminance[pixelIndex-2]);
const float verticalGrad_n=fabs(luminance[pixelIndex+2*_filterOutput.getNBcolumns()]-luminance[pixelIndex]);
const float horizontalGrad_n=fabs(luminance[pixelIndex+2]-luminance[pixelIndex]);
const float horizontalGradient=0.5f*horizontalGrad+0.25f*(horizontalGrad_p+horizontalGrad_n);
const float verticalGradient=0.5f*verticalGrad+0.25f*(verticalGrad_p+verticalGrad_n);
// compare local gradient means and fill the appropriate filtering coefficient value that will be used in adaptative filters
if (horizontalGradient<verticalGradient)
{
_imageGradient[pixelIndex+_filterOutput.getNBpixels()]=0.06f;
_imageGradient[pixelIndex]=0.57f;
}
else
{
_imageGradient[pixelIndex+_filterOutput.getNBpixels()]=0.57f;
_imageGradient[pixelIndex]=0.06f;
}
}
}
}
bool RetinaColor::applyKrauskopfLMS2Acr1cr2Transform(std::valarray<float> &result)
{
bool processSuccess=true;
// basic preliminary error check
if (result.size()!=_demultiplexedColorFrame.size())
{
std::cerr<<"RetinaColor::applyKrauskopfLMS2Acr1cr2Transform: input buffer does not match retina buffer size, conversion aborted"<<std::endl;
return false;
}
// apply transformation
_applyImageColorSpaceConversion(_demultiplexedColorFrame, result, _LMStoACr1Cr2);
return processSuccess;
}
bool RetinaColor::applyLMS2LabTransform(std::valarray<float> &result)
{
bool processSuccess=true;
// basic preliminary error check
if (result.size()!=_demultiplexedColorFrame.size())
{
std::cerr<<"RetinaColor::applyKrauskopfLMS2Acr1cr2Transform: input buffer does not match retina buffer size, conversion aborted"<<std::endl;
return false;
}
// apply transformation
_applyImageColorSpaceConversion(_demultiplexedColorFrame, result, _LMStoLab);
return processSuccess;
}
// template function able to perform a custom color space transformation
void RetinaColor::_applyImageColorSpaceConversion(const std::valarray<float> &inputFrameBuffer, std::valarray<float> &outputFrameBuffer, const float *transformTable)
{
// two step methods in order to allow inputFrame and outputFrame to be the same
unsigned int nbPixels=(unsigned int)(inputFrameBuffer.size()/3), dbpixels=(unsigned int)(2*inputFrameBuffer.size()/3);
const float *inputFrame=get_data(inputFrameBuffer);
float *outputFrame= &outputFrameBuffer[0];
for (unsigned int dataIndex=0; dataIndex<nbPixels;++dataIndex, ++outputFrame, ++inputFrame)
{
// first step, compute each new values
float layer1 = *(inputFrame)**(transformTable+0) +*(inputFrame+nbPixels)**(transformTable+1) +*(inputFrame+dbpixels)**(transformTable+2);
float layer2 = *(inputFrame)**(transformTable+3) +*(inputFrame+nbPixels)**(transformTable+4) +*(inputFrame+dbpixels)**(transformTable+5);
float layer3 = *(inputFrame)**(transformTable+6) +*(inputFrame+nbPixels)**(transformTable+7) +*(inputFrame+dbpixels)**(transformTable+8);
// second, affect the output
*(outputFrame) = layer1;
*(outputFrame+nbPixels) = layer2;
*(outputFrame+dbpixels) = layer3;
}
}
}// end of namespace bioinspired
}// end of namespace cv
-389
View File
@@ -1,389 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
/**
* @class RetinaColor a color multilexing/demultiplexing (demosaicing) based on a human vision inspiration. Different mosaicing strategies can be used, included random sampling !
* => please take a look at the nice and efficient demosaicing strategy introduced by B.Chaix de Lavarene, take a look at the cited paper for more mathematical details
* @brief Retina color sampling model which allows classical bayer sampling, random and potentially several other method ! Low color errors on corners !
* -> Based on the research of:
* .Brice Chaix Lavarene (chaix@lis.inpg.fr)
* .Jeanny Herault (herault@lis.inpg.fr)
* .David Alleyson (david.alleyson@upmf-grenoble.fr)
* .collaboration: alexandre benoit (benoit.alexandre.vision@gmail.com or benoit@lis.inpg.fr)
* Please cite: B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
* @author Alexandre BENOIT, benoit.alexandre.vision@gmail.com, LISTIC / Gipsa-Lab, France: www.gipsa-lab.inpg.fr/
* Creation date 2007
*/
#ifndef RETINACOLOR_HPP_
#define RETINACOLOR_HPP_
#include "basicretinafilter.hpp"
//#define __RETINACOLORDEBUG //define RETINACOLORDEBUG in order to display debug data
namespace cv
{
namespace bioinspired
{
class RetinaColor: public BasicRetinaFilter
{
public:
/**
* @typedef which allows to select the type of photoreceptors color sampling
*/
/**
* constructor of the retina color processing model
* @param NBrows: number of rows of the input image
* @param NBcolumns: number of columns of the input image
* @param samplingMethod: the chosen color sampling method
*/
RetinaColor(const unsigned int NBrows, const unsigned int NBcolumns, const int samplingMethod=RETINA_COLOR_BAYER);
/**
* standard destructor
*/
virtual ~RetinaColor();
/**
* function that clears all buffers of the object
*/
void clearAllBuffers();
/**
* resize retina color filter object (resize all allocated buffers)
* @param NBrows: the new height size
* @param NBcolumns: the new width size
*/
void resize(const unsigned int NBrows, const unsigned int NBcolumns);
/**
* color multiplexing function: a demultiplexed RGB frame of size M*N*3 is transformed into a multiplexed M*N*1 pixels frame where each pixel is either Red, or Green or Blue
* @param inputRGBFrame: the input RGB frame to be processed
* @return, nothing but the multiplexed frame is available by the use of the getMultiplexedFrame() function
*/
inline void runColorMultiplexing(const std::valarray<float> &inputRGBFrame){runColorMultiplexing(inputRGBFrame, *_multiplexedFrame);};
/**
* color multiplexing function: a demultipleed RGB frame of size M*N*3 is transformed into a multiplexed M*N*1 pixels frame where each pixel is either Red, or Green or Blue if using RGB images
* @param demultiplexedInputFrame: the demultiplexed input frame to be processed of size M*N*3
* @param multiplexedFrame: the resulting multiplexed frame
*/
void runColorMultiplexing(const std::valarray<float> &demultiplexedInputFrame, std::valarray<float> &multiplexedFrame);
/**
* color demultiplexing function: a multiplexed frame of size M*N*1 pixels is transformed into a RGB demultiplexed M*N*3 pixels frame
* @param multiplexedColorFrame: the input multiplexed frame to be processed
* @param adaptiveFiltering: specifies if an adaptive filtering has to be perform rather than standard filtering (adaptive filtering allows a better rendering)
* @param maxInputValue: the maximum input data value (should be 255 for 8 bits images but it can change in the case of High Dynamic Range Images (HDRI)
* @return, nothing but the output demultiplexed frame is available by the use of the getDemultiplexedColorFrame() function, also use getLuminance() and getChrominance() in order to retreive either luminance or chrominance
*/
void runColorDemultiplexing(const std::valarray<float> &multiplexedColorFrame, const bool adaptiveFiltering=false, const float maxInputValue=255.0);
/**
* activate color saturation as the final step of the color demultiplexing process
* -> this saturation is a sigmoide function applied to each channel of the demultiplexed image.
* @param saturateColors: boolean that activates color saturation (if true) or desactivate (if false)
* @param colorSaturationValue: the saturation factor
* */
void setColorSaturation(const bool saturateColors=true, const float colorSaturationValue=4.0){_saturateColors=saturateColors; _colorSaturationValue=colorSaturationValue;};
/**
* set parameters of the low pass spatio-temporal filter used to retreive the low chrominance
* @param beta: gain of the filter (generally set to zero)
* @param tau: time constant of the filter (unit is frame for video processing), typically 0 when considering static processing, 1 or more if a temporal smoothing effect is required
* @param k: spatial constant of the filter (unit is pixels), typical value is 2.5
*/
void setChrominanceLPfilterParameters(const float beta, const float tau, const float k){setLPfilterParameters(beta, tau, k);};
/**
* apply to the retina color output the Krauskopf transformation which leads to an opponent color system: output colorspace if Acr1cr2 if input of the retina was LMS color space
* @param result: the input buffer to fill with the transformed colorspace retina output
* @return true if process ended successfully
*/
bool applyKrauskopfLMS2Acr1cr2Transform(std::valarray<float> &result);
/**
* apply to the retina color output the CIE Lab color transformation
* @param result: the input buffer to fill with the transformed colorspace retina output
* @return true if process ended successfully
*/
bool applyLMS2LabTransform(std::valarray<float> &result);
/**
* @return the multiplexed frame result (use this after function runColorMultiplexing)
*/
inline const std::valarray<float> &getMultiplexedFrame() const {return *_multiplexedFrame;};
/**
* @return the demultiplexed frame result (use this after function runColorDemultiplexing)
*/
inline const std::valarray<float> &getDemultiplexedColorFrame() const {return _demultiplexedColorFrame;};
/**
* @return the luminance of the processed frame (use this after function runColorDemultiplexing)
*/
inline const std::valarray<float> &getLuminance() const {return *_luminance;};
/**
* @return the chrominance of the processed frame (use this after function runColorDemultiplexing)
*/
inline const std::valarray<float> &getChrominance() const {return _chrominance;};
/**
* standard 0 to 255 image clipping function appled to RGB images (of size M*N*3 pixels)
* @param inputOutputBuffer: the image to be normalized (rewrites the input), if no parameter, then, the built in buffer reachable by getOutput() function is normalized
* @param maxOutputValue: the maximum value allowed at the output (values superior to it would be clipped
*/
void clipRGBOutput_0_maxInputValue(float *inputOutputBuffer, const float maxOutputValue=255.0);
/**
* standard 0 to 255 image normalization function appled to RGB images (of size M*N*3 pixels)
* @param maxOutputValue: the maximum value allowed at the output (values superior to it would be clipped
*/
void normalizeRGBOutput_0_maxOutputValue(const float maxOutputValue=255.0);
/**
* return the color sampling map: a Nrows*Mcolumns image in which each pixel value is the ofsset adress which gives the adress of the sampled pixel on an Nrows*Mcolumns*3 color image ordered by layers: layer1, layer2, layer3
*/
inline const std::valarray<unsigned int> &getSamplingMap() const {return _colorSampling;};
/**
* function used (to bypass processing) to manually set the color output
* @param demultiplexedImage: the color image (luminance+chrominance) which has to be written in the object buffer
*/
inline void setDemultiplexedColorFrame(const std::valarray<float> &demultiplexedImage){_demultiplexedColorFrame=demultiplexedImage;};
protected:
// private functions
int _samplingMethod;
bool _saturateColors;
float _colorSaturationValue;
// links to parent buffers (more convienient names
TemplateBuffer<float> *_luminance;
std::valarray<float> *_multiplexedFrame;
// instance buffers
std::valarray<unsigned int> _colorSampling; // table (size (_nbRows*_nbColumns) which specifies the color of each pixel
std::valarray<float> _RGBmosaic;
std::valarray<float> _tempMultiplexedFrame;
std::valarray<float> _demultiplexedTempBuffer;
std::valarray<float> _demultiplexedColorFrame;
std::valarray<float> _chrominance;
std::valarray<float> _colorLocalDensity;// buffer which contains the local density of the R, G and B photoreceptors for a normalization use
std::valarray<float> _imageGradient;
// variables
float _pR, _pG, _pB; // probabilities of color R, G and B
bool _objectInit;
// protected functions
void _initColorSampling();
void _interpolateImageDemultiplexedImage(float *inputOutputBuffer);
void _interpolateSingleChannelImage111(float *inputOutputBuffer);
void _interpolateBayerRGBchannels(float *inputOutputBuffer);
void _applyRIFfilter(const float *sourceBuffer, float *destinationBuffer);
void _getNormalizedContoursImage(const float *inputFrame, float *outputFrame);
// -> special adaptive filters dedicated to low pass filtering on the chrominance (skeeps filtering on the edges)
void _adaptiveSpatialLPfilter(const float *inputFrame, float *outputFrame);
void _adaptiveHorizontalCausalFilter_addInput(const float *inputFrame, float *outputFrame, const unsigned int IDrowStart, const unsigned int IDrowEnd); // TBB parallelized
void _adaptiveVerticalAnticausalFilter_multGain(float *outputFrame, const unsigned int IDcolumnStart, const unsigned int IDcolumnEnd);
void _computeGradient(const float *luminance);
void _normalizeOutputs_0_maxOutputValue(void);
// color space transform
void _applyImageColorSpaceConversion(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame, const float *transformTable);
#ifdef MAKE_PARALLEL
/******************************************************
** IF some parallelizing thread methods are available, then, main loops are parallelized using these functors
** ==> main idea paralellise main filters loops, then, only the most used methods are parallelized... TODO : increase the number of parallelised methods as necessary
** ==> functors names = Parallel_$$$ where $$$= the name of the serial method that is parallelised
** ==> functors constructors can differ from the parameters used with their related serial functions
*/
/* Template :
class Parallel_ : public cv::ParallelLoopBody
{
private:
public:
Parallel_()
: {}
virtual void operator()( const cv::Range& r ) const {
}
}:
*/
class Parallel_adaptiveHorizontalCausalFilter_addInput: public cv::ParallelLoopBody
{
private:
float *outputFrame;
const float *inputFrame, *imageGradient;
unsigned int nbColumns;
public:
Parallel_adaptiveHorizontalCausalFilter_addInput(const float *inputImg, float *bufferToProcess, const float *imageGrad, const unsigned int nbCols)
:outputFrame(bufferToProcess), inputFrame(inputImg), imageGradient(imageGrad), nbColumns(nbCols) {};
virtual void operator()( const Range& r ) const {
register float* outputPTR=outputFrame+r.start*nbColumns;
register const float* inputPTR=inputFrame+r.start*nbColumns;
register const float *imageGradientPTR= imageGradient+r.start*nbColumns;
for (int IDrow=r.start; IDrow!=r.end; ++IDrow)
{
register float result=0;
for (unsigned int index=0; index<nbColumns; ++index)
{
result = *(inputPTR++) + (*imageGradientPTR++)* result;
*(outputPTR++) = result;
}
}
}
};
class Parallel_adaptiveVerticalAnticausalFilter_multGain: public cv::ParallelLoopBody
{
private:
float *outputFrame;
const float *imageGradient;
unsigned int nbRows, nbColumns;
float filterParam_gain;
public:
Parallel_adaptiveVerticalAnticausalFilter_multGain(float *bufferToProcess, const float *imageGrad, const unsigned int nbRws, const unsigned int nbCols, const float gain)
:outputFrame(bufferToProcess), imageGradient(imageGrad), nbRows(nbRws), nbColumns(nbCols), filterParam_gain(gain){}
virtual void operator()( const Range& r ) const {
float* offset=outputFrame+nbColumns*nbRows-nbColumns;
const float* gradOffset= imageGradient+nbColumns*nbRows-nbColumns;
for (int IDcolumn=r.start; IDcolumn!=r.end; ++IDcolumn)
{
register float result=0;
register float *outputPTR=offset+IDcolumn;
register const float *imageGradientPTR=gradOffset+IDcolumn;
for (unsigned int index=0; index<nbRows; ++index)
{
result = *(outputPTR) + *(imageGradientPTR) * result;
*(outputPTR) = filterParam_gain*result;
outputPTR-=nbColumns;
imageGradientPTR-=nbColumns;
}
}
}
};
class Parallel_computeGradient: public cv::ParallelLoopBody
{
private:
float *imageGradient;
const float *luminance;
unsigned int nbColumns, doubleNbColumns, nbRows, nbPixels;
public:
Parallel_computeGradient(const unsigned int nbCols, const unsigned int nbRws, const float *lum, float *imageGrad)
:imageGradient(imageGrad), luminance(lum), nbColumns(nbCols), doubleNbColumns(2*nbCols), nbRows(nbRws), nbPixels(nbRws*nbCols){};
virtual void operator()( const Range& r ) const {
for (int idLine=r.start;idLine!=r.end;++idLine)
{
for (unsigned int idColumn=2;idColumn<nbColumns-2;++idColumn)
{
const unsigned int pixelIndex=idColumn+nbColumns*idLine;
// horizontal and vertical local gradients
const float verticalGrad=fabs(luminance[pixelIndex+nbColumns]-luminance[pixelIndex-nbColumns]);
const float horizontalGrad=fabs(luminance[pixelIndex+1]-luminance[pixelIndex-1]);
// neighborhood horizontal and vertical gradients
const float verticalGrad_p=fabs(luminance[pixelIndex]-luminance[pixelIndex-doubleNbColumns]);
const float horizontalGrad_p=fabs(luminance[pixelIndex]-luminance[pixelIndex-2]);
const float verticalGrad_n=fabs(luminance[pixelIndex+doubleNbColumns]-luminance[pixelIndex]);
const float horizontalGrad_n=fabs(luminance[pixelIndex+2]-luminance[pixelIndex]);
const float horizontalGradient=0.5f*horizontalGrad+0.25f*(horizontalGrad_p+horizontalGrad_n);
const float verticalGradient=0.5f*verticalGrad+0.25f*(verticalGrad_p+verticalGrad_n);
// compare local gradient means and fill the appropriate filtering coefficient value that will be used in adaptative filters
if (horizontalGradient<verticalGradient)
{
imageGradient[pixelIndex+nbPixels]=0.06f;
imageGradient[pixelIndex]=0.57f;
}
else
{
imageGradient[pixelIndex+nbPixels]=0.57f;
imageGradient[pixelIndex]=0.06f;
}
}
}
}
};
#endif
};
}// end of namespace bioinspired
}// end of namespace cv
#endif /*RETINACOLOR_HPP_*/
@@ -1,316 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2013
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
**
** This class is based on image processing tools of the author and already used within the Retina class (this is the same code as method retina::applyFastToneMapping, but in an independent class, it is ligth from a memory requirement point of view). It implements an adaptation of the efficient tone mapping algorithm propose by David Alleyson, Sabine Susstruck and Laurence Meylan's work, please cite:
** -> Meylan L., Alleysson D., and Susstrunk S., A Model of Retinal Local Adaptation for the Tone Mapping of Color Filter Array Images, Journal of Optical Society of America, A, Vol. 24, N 9, September, 1st, 2007, pp. 2807-2816
**
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
/*
* retinafasttonemapping.cpp
*
* Created on: May 26, 2013
* Author: Alexandre Benoit
*/
#include "precomp.hpp"
#include "basicretinafilter.hpp"
#include "retinacolor.hpp"
#include <cstdio>
#include <sstream>
#include <valarray>
namespace cv
{
namespace bioinspired
{
/**
* @class RetinaFastToneMappingImpl a wrapper class which allows the tone mapping algorithm of Meylan&al(2007) to be used with OpenCV.
* This algorithm is already implemented in thre Retina class (retina::applyFastToneMapping) but used it does not require all the retina model to be allocated. This allows a light memory use for low memory devices (smartphones, etc.
* As a summary, these are the model properties:
* => 2 stages of local luminance adaptation with a different local neighborhood for each.
* => first stage models the retina photorecetors local luminance adaptation
* => second stage models th ganglion cells local information adaptation
* => compared to the initial publication, this class uses spatio-temporal low pass filters instead of spatial only filters.
* ====> this can help noise robustness and temporal stability for video sequence use cases.
* for more information, read to the following papers :
* Meylan L., Alleysson D., and Susstrunk S., A Model of Retinal Local Adaptation for the Tone Mapping of Color Filter Array Images, Journal of Optical Society of America, A, Vol. 24, N 9, September, 1st, 2007, pp. 2807-2816Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
* regarding spatio-temporal filter and the bigger retina model :
* Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
*/
class RetinaFastToneMappingImpl : public RetinaFastToneMapping
{
public:
/**
* constructor
* @param imageInput: the size of the images to process
*/
RetinaFastToneMappingImpl(Size imageInput)
{
unsigned int nbPixels=imageInput.height*imageInput.width;
// basic error check
if (nbPixels <= 0)
throw cv::Exception(-1, "Bad retina size setup : size height and with must be superior to zero", "RetinaImpl::setup", "retinafasttonemapping.cpp", 0);
// resize buffers
_inputBuffer.resize(nbPixels*3); // buffer supports gray images but also 3 channels color buffers... (larger is better...)
_imageOutput.resize(nbPixels*3);
_temp2.resize(nbPixels);
// allocate the main filter with 2 setup sets properties (one for each low pass filter
_multiuseFilter = makePtr<BasicRetinaFilter>(imageInput.height, imageInput.width, 2);
// allocate the color manager (multiplexer/demultiplexer
_colorEngine = makePtr<RetinaColor>(imageInput.height, imageInput.width);
// setup filter behaviors with default values
setup();
}
/**
* basic destructor
*/
virtual ~RetinaFastToneMappingImpl(){};
/**
* method that applies a luminance correction (initially High Dynamic Range (HDR) tone mapping) using only the 2 local adaptation stages of the retina parvocellular channel : photoreceptors level and ganlion cells level. Spatio temporal filtering is applied but limited to temporal smoothing and eventually high frequencies attenuation. This is a lighter method than the one available using the regular retina::run method. It is then faster but it does not include complete temporal filtering nor retina spectral whitening. Then, it can have a more limited effect on images with a very high dynamic range. This is an adptation of the original still image HDR tone mapping algorithm of David Alleyson, Sabine Susstruck and Laurence Meylan's work, please cite:
* -> Meylan L., Alleysson D., and Susstrunk S., A Model of Retinal Local Adaptation for the Tone Mapping of Color Filter Array Images, Journal of Optical Society of America, A, Vol. 24, N 9, September, 1st, 2007, pp. 2807-2816
@param inputImage the input image to process RGB or gray levels
@param outputToneMappedImage the output tone mapped image
*/
virtual void applyFastToneMapping(InputArray inputImage, OutputArray outputToneMappedImage)
{
// first convert input image to the compatible format :
const bool colorMode = _convertCvMat2ValarrayBuffer(inputImage.getMat(), _inputBuffer);
// process tone mapping
if (colorMode)
{
_runRGBToneMapping(_inputBuffer, _imageOutput, true);
_convertValarrayBuffer2cvMat(_imageOutput, _multiuseFilter->getNBrows(), _multiuseFilter->getNBcolumns(), true, outputToneMappedImage);
}else
{
_runGrayToneMapping(_inputBuffer, _imageOutput);
_convertValarrayBuffer2cvMat(_imageOutput, _multiuseFilter->getNBrows(), _multiuseFilter->getNBcolumns(), false, outputToneMappedImage);
}
}
/**
* setup method that updates tone mapping behaviors by adjusing the local luminance computation area
* @param photoreceptorsNeighborhoodRadius the first stage local adaptation area
* @param ganglioncellsNeighborhoodRadius the second stage local adaptation area
* @param meanLuminanceModulatorK the factor applied to modulate the meanLuminance information (default is 1, see reference paper)
*/
virtual void setup(const float photoreceptorsNeighborhoodRadius=3.f, const float ganglioncellsNeighborhoodRadius=1.f, const float meanLuminanceModulatorK=1.f)
{
// setup the spatio-temporal properties of each filter
_meanLuminanceModulatorK = meanLuminanceModulatorK;
_multiuseFilter->setV0CompressionParameter(1.f, 255.f, 128.f);
_multiuseFilter->setLPfilterParameters(0.f, 0.f, photoreceptorsNeighborhoodRadius, 1);
_multiuseFilter->setLPfilterParameters(0.f, 0.f, ganglioncellsNeighborhoodRadius, 2);
}
private:
// a filter able to perform local adaptation and low pass spatio-temporal filtering
cv::Ptr <BasicRetinaFilter> _multiuseFilter;
cv::Ptr <RetinaColor> _colorEngine;
//!< buffer used to convert input cv::Mat to internal retina buffers format (valarrays)
std::valarray<float> _inputBuffer;
std::valarray<float> _imageOutput;
std::valarray<float> _temp2;
float _meanLuminanceModulatorK;
void _convertValarrayBuffer2cvMat(const std::valarray<float> &grayMatrixToConvert, const unsigned int nbRows, const unsigned int nbColumns, const bool colorMode, OutputArray outBuffer)
{
// fill output buffer with the valarray buffer
const float *valarrayPTR=get_data(grayMatrixToConvert);
if (!colorMode)
{
outBuffer.create(cv::Size(nbColumns, nbRows), CV_8U);
Mat outMat = outBuffer.getMat();
for (unsigned int i=0;i<nbRows;++i)
{
for (unsigned int j=0;j<nbColumns;++j)
{
cv::Point2d pixel(j,i);
outMat.at<unsigned char>(pixel)=(unsigned char)*(valarrayPTR++);
}
}
}else
{
const unsigned int nbPixels=nbColumns*nbRows;
const unsigned int doubleNBpixels=nbColumns*nbRows*2;
outBuffer.create(cv::Size(nbColumns, nbRows), CV_8UC3);
Mat outMat = outBuffer.getMat();
for (unsigned int i=0;i<nbRows;++i)
{
for (unsigned int j=0;j<nbColumns;++j,++valarrayPTR)
{
cv::Point2d pixel(j,i);
cv::Vec3b pixelValues;
pixelValues[2]=(unsigned char)*(valarrayPTR);
pixelValues[1]=(unsigned char)*(valarrayPTR+nbPixels);
pixelValues[0]=(unsigned char)*(valarrayPTR+doubleNBpixels);
outMat.at<cv::Vec3b>(pixel)=pixelValues;
}
}
}
}
bool _convertCvMat2ValarrayBuffer(InputArray inputMat, std::valarray<float> &outputValarrayMatrix)
{
const Mat inputMatToConvert=inputMat.getMat();
// first check input consistency
if (inputMatToConvert.empty())
throw cv::Exception(-1, "RetinaImpl cannot be applied, input buffer is empty", "RetinaImpl::run", "RetinaImpl.h", 0);
// retreive color mode from image input
int imageNumberOfChannels = inputMatToConvert.channels();
// convert to float AND fill the valarray buffer
typedef float T; // define here the target pixel format, here, float
const int dsttype = DataType<T>::depth; // output buffer is float format
const unsigned int nbPixels=inputMat.getMat().rows*inputMat.getMat().cols;
const unsigned int doubleNBpixels=inputMat.getMat().rows*inputMat.getMat().cols*2;
if(imageNumberOfChannels==4)
{
// create a cv::Mat table (for RGBA planes)
cv::Mat planes[4] =
{
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[doubleNBpixels]),
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[nbPixels]),
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0])
};
planes[3] = cv::Mat(inputMatToConvert.size(), dsttype); // last channel (alpha) does not point on the valarray (not usefull in our case)
// split color cv::Mat in 4 planes... it fills valarray directely
cv::split(Mat_<Vec<T, 4> >(inputMatToConvert), planes);
}
else if (imageNumberOfChannels==3)
{
// create a cv::Mat table (for RGB planes)
cv::Mat planes[] =
{
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[doubleNBpixels]),
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[nbPixels]),
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0])
};
// split color cv::Mat in 3 planes... it fills valarray directely
cv::split(cv::Mat_<Vec<T, 3> >(inputMatToConvert), planes);
}
else if(imageNumberOfChannels==1)
{
// create a cv::Mat header for the valarray
cv::Mat dst(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0]);
inputMatToConvert.convertTo(dst, dsttype);
}
else
CV_Error(Error::StsUnsupportedFormat, "input image must be single channel (gray levels), bgr format (color) or bgra (color with transparency which won't be considered");
return imageNumberOfChannels>1; // return bool : false for gray level image processing, true for color mode
}
// run the initilized retina filter in order to perform gray image tone mapping, after this call all retina outputs are updated
void _runGrayToneMapping(const std::valarray<float> &grayImageInput, std::valarray<float> &grayImageOutput)
{
// apply tone mapping on the multiplexed image
// -> photoreceptors local adaptation (large area adaptation)
_multiuseFilter->runFilter_LPfilter(grayImageInput, grayImageOutput, 0); // compute low pass filtering modeling the horizontal cells filtering to acess local luminance
_multiuseFilter->setV0CompressionParameterToneMapping(1.f, grayImageOutput.max(), _meanLuminanceModulatorK*grayImageOutput.sum()/(float)_multiuseFilter->getNBpixels());
_multiuseFilter->runFilter_LocalAdapdation(grayImageInput, grayImageOutput, _temp2); // adapt contrast to local luminance
// -> ganglion cells local adaptation (short area adaptation)
_multiuseFilter->runFilter_LPfilter(_temp2, grayImageOutput, 1); // compute low pass filtering (high cut frequency (remove spatio-temporal noise)
_multiuseFilter->setV0CompressionParameterToneMapping(1.f, _temp2.max(), _meanLuminanceModulatorK*grayImageOutput.sum()/(float)_multiuseFilter->getNBpixels());
_multiuseFilter->runFilter_LocalAdapdation(_temp2, grayImageOutput, grayImageOutput); // adapt contrast to local luminance
}
// run the initilized retina filter in order to perform color tone mapping, after this call all retina outputs are updated
void _runRGBToneMapping(const std::valarray<float> &RGBimageInput, std::valarray<float> &RGBimageOutput, const bool useAdaptiveFiltering)
{
// multiplex the image with the color sampling method specified in the constructor
_colorEngine->runColorMultiplexing(RGBimageInput);
// apply tone mapping on the multiplexed image
_runGrayToneMapping(_colorEngine->getMultiplexedFrame(), RGBimageOutput);
// demultiplex tone maped image
_colorEngine->runColorDemultiplexing(RGBimageOutput, useAdaptiveFiltering, _multiuseFilter->getMaxInputValue());//_ColorEngine->getMultiplexedFrame());//_ParvoRetinaFilter->getPhotoreceptorsLPfilteringOutput());
// rescaling result between 0 and 255
_colorEngine->normalizeRGBOutput_0_maxOutputValue(255.0);
// return the result
RGBimageOutput=_colorEngine->getDemultiplexedColorFrame();
}
};
CV_EXPORTS Ptr<RetinaFastToneMapping> createRetinaFastToneMapping(Size inputSize)
{
return makePtr<RetinaFastToneMappingImpl>(inputSize);
}
}// end of namespace bioinspired
}// end of namespace cv
-526
View File
@@ -1,526 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
#include "precomp.hpp"
#include "retinafilter.hpp"
// @author Alexandre BENOIT, benoit.alexandre.vision@gmail.com, LISTIC : www.listic.univ-savoie.fr, Gipsa-Lab, France: www.gipsa-lab.inpg.fr/
#include <iostream>
#include <cmath>
namespace cv
{
namespace bioinspired
{
// standard constructor without any log sampling of the input frame
RetinaFilter::RetinaFilter(const unsigned int sizeRows, const unsigned int sizeColumns, const bool colorMode, const int samplingMethod, const bool useRetinaLogSampling, const double reductionFactor, const double samplingStrenght)
:
_retinaParvoMagnoMappedFrame(0),
_retinaParvoMagnoMapCoefTable(0),
_photoreceptorsPrefilter((1-(int)useRetinaLogSampling)*sizeRows+useRetinaLogSampling*ImageLogPolProjection::predictOutputSize(sizeRows, reductionFactor), (1-(int)useRetinaLogSampling)*sizeColumns+useRetinaLogSampling*ImageLogPolProjection::predictOutputSize(sizeColumns, reductionFactor), 4),
_ParvoRetinaFilter((1-(int)useRetinaLogSampling)*sizeRows+useRetinaLogSampling*ImageLogPolProjection::predictOutputSize(sizeRows, reductionFactor), (1-(int)useRetinaLogSampling)*sizeColumns+useRetinaLogSampling*ImageLogPolProjection::predictOutputSize(sizeColumns, reductionFactor)),
_MagnoRetinaFilter((1-(int)useRetinaLogSampling)*sizeRows+useRetinaLogSampling*ImageLogPolProjection::predictOutputSize(sizeRows, reductionFactor), (1-(int)useRetinaLogSampling)*sizeColumns+useRetinaLogSampling*ImageLogPolProjection::predictOutputSize(sizeColumns, reductionFactor)),
_colorEngine((1-(int)useRetinaLogSampling)*sizeRows+useRetinaLogSampling*ImageLogPolProjection::predictOutputSize(sizeRows, reductionFactor), (1-(int)useRetinaLogSampling)*sizeColumns+useRetinaLogSampling*ImageLogPolProjection::predictOutputSize(sizeColumns, reductionFactor), samplingMethod),
// configure retina photoreceptors log sampling... if necessary
_photoreceptorsLogSampling(NULL)
{
#ifdef RETINADEBUG
std::cout<<"RetinaFilter::size( "<<_photoreceptorsPrefilter.getNBrows()<<", "<<_photoreceptorsPrefilter.getNBcolumns()<<")"<<" =? "<<_photoreceptorsPrefilter.getNBpixels()<<std::endl;
#endif
if (useRetinaLogSampling)
{
_photoreceptorsLogSampling = new ImageLogPolProjection(sizeRows, sizeColumns, ImageLogPolProjection::RETINALOGPROJECTION, true);
if (!_photoreceptorsLogSampling->initProjection(reductionFactor, samplingStrenght))
{
std::cerr<<"RetinaFilter::Problem initializing photoreceptors log sampling, could not setup retina filter"<<std::endl;
delete _photoreceptorsLogSampling;
_photoreceptorsLogSampling=NULL;
}
else
{
#ifdef RETINADEBUG
std::cout<<"_photoreceptorsLogSampling::size( "<<_photoreceptorsLogSampling->getNBrows()<<", "<<_photoreceptorsLogSampling->getNBcolumns()<<")"<<" =? "<<_photoreceptorsLogSampling->getNBpixels()<<std::endl;
#endif
}
}
// set default processing activities
_useParvoOutput=true;
_useMagnoOutput=true;
_useColorMode=colorMode;
// create hybrid output and related coefficient table
_createHybridTable();
// set default parameters
setGlobalParameters();
// stability controls values init
_setInitPeriodCount();
_globalTemporalConstant=25;
// reset all buffers
clearAllBuffers();
// std::cout<<"RetinaFilter::size( "<<this->getNBrows()<<", "<<this->getNBcolumns()<<")"<<_filterOutput.size()<<" =? "<<_filterOutput.getNBpixels()<<std::endl;
}
// destructor
RetinaFilter::~RetinaFilter()
{
if (_photoreceptorsLogSampling!=NULL)
delete _photoreceptorsLogSampling;
}
// function that clears all buffers of the object
void RetinaFilter::clearAllBuffers()
{
_photoreceptorsPrefilter.clearAllBuffers();
_ParvoRetinaFilter.clearAllBuffers();
_MagnoRetinaFilter.clearAllBuffers();
_colorEngine.clearAllBuffers();
if (_photoreceptorsLogSampling!=NULL)
_photoreceptorsLogSampling->clearAllBuffers();
// stability controls value init
_setInitPeriodCount();
}
/**
* resize retina filter object (resize all allocated buffers
* @param NBrows: the new height size
* @param NBcolumns: the new width size
*/
void RetinaFilter::resize(const unsigned int NBrows, const unsigned int NBcolumns)
{
unsigned int rows=NBrows, cols=NBcolumns;
// resize optionnal member and adjust other modules size if required
if (_photoreceptorsLogSampling)
{
_photoreceptorsLogSampling->resize(NBrows, NBcolumns);
rows=_photoreceptorsLogSampling->getOutputNBrows();
cols=_photoreceptorsLogSampling->getOutputNBcolumns();
}
_photoreceptorsPrefilter.resize(rows, cols);
_ParvoRetinaFilter.resize(rows, cols);
_MagnoRetinaFilter.resize(rows, cols);
_colorEngine.resize(rows, cols);
// reset parvo magno mapping
_createHybridTable();
// clean buffers
clearAllBuffers();
}
// stability controls value init
void RetinaFilter::_setInitPeriodCount()
{
// find out the maximum temporal constant value and apply a security factor
// false value (obviously too long) but appropriate for simple use
_globalTemporalConstant=(unsigned int)(_ParvoRetinaFilter.getPhotoreceptorsTemporalConstant()+_ParvoRetinaFilter.getHcellsTemporalConstant()+_MagnoRetinaFilter.getTemporalConstant());
// reset frame counter
_ellapsedFramesSinceLastReset=0;
}
void RetinaFilter::_createHybridTable()
{
// create hybrid output and related coefficient table
_retinaParvoMagnoMappedFrame.resize(_photoreceptorsPrefilter.getNBpixels());
_retinaParvoMagnoMapCoefTable.resize(_photoreceptorsPrefilter.getNBpixels()*2);
// fill _hybridParvoMagnoCoefTable
int i, j, halfRows=_photoreceptorsPrefilter.getNBrows()/2, halfColumns=_photoreceptorsPrefilter.getNBcolumns()/2;
float *hybridParvoMagnoCoefTablePTR= &_retinaParvoMagnoMapCoefTable[0];
float minDistance=MIN(halfRows, halfColumns)*0.7f;
for (i=0;i<(int)_photoreceptorsPrefilter.getNBrows();++i)
{
for (j=0;j<(int)_photoreceptorsPrefilter.getNBcolumns();++j)
{
float distanceToCenter=std::sqrt(((float)(i-halfRows)*(i-halfRows)+(j-halfColumns)*(j-halfColumns)));
if (distanceToCenter<minDistance)
{
float a=*(hybridParvoMagnoCoefTablePTR++)=0.5f+0.5f*(float)cos(CV_PI*distanceToCenter/minDistance);
*(hybridParvoMagnoCoefTablePTR++)=1.f-a;
}else
{
*(hybridParvoMagnoCoefTablePTR++)=0.f;
*(hybridParvoMagnoCoefTablePTR++)=1.f;
}
}
}
}
// setup parameters function and global data filling
void RetinaFilter::setGlobalParameters(const float OPLspatialResponse1, const float OPLtemporalresponse1, const float OPLassymetryGain, const float OPLspatialResponse2, const float OPLtemporalresponse2, const float LPfilterSpatialResponse, const float LPfilterGain, const float LPfilterTemporalresponse, const float MovingContoursExtractorCoefficient, const bool normalizeParvoOutput_0_maxOutputValue, const bool normalizeMagnoOutput_0_maxOutputValue, const float maxOutputValue, const float maxInputValue, const float meanValue)
{
_normalizeParvoOutput_0_maxOutputValue=normalizeParvoOutput_0_maxOutputValue;
_normalizeMagnoOutput_0_maxOutputValue=normalizeMagnoOutput_0_maxOutputValue;
_maxOutputValue=maxOutputValue;
_photoreceptorsPrefilter.setV0CompressionParameter(0.9f, maxInputValue, meanValue);
_photoreceptorsPrefilter.setLPfilterParameters(10, 0, 1.5, 1); // keeps low pass filter with high cut frequency in memory (usefull for the tone mapping function)
_photoreceptorsPrefilter.setLPfilterParameters(10, 0, 3.0, 2); // keeps low pass filter with low cut frequency in memory (usefull for the tone mapping function)
_photoreceptorsPrefilter.setLPfilterParameters(0, 0, 10, 3); // keeps low pass filter with low cut frequency in memory (usefull for the tone mapping function)
//this->setV0CompressionParameter(0.6, maxInputValue, meanValue); // keeps log compression sensitivity parameter (usefull for the tone mapping function)
_ParvoRetinaFilter.setOPLandParvoFiltersParameters(0,OPLtemporalresponse1, OPLspatialResponse1, OPLassymetryGain, OPLtemporalresponse2, OPLspatialResponse2);
_ParvoRetinaFilter.setV0CompressionParameter(0.9f, maxInputValue, meanValue);
_MagnoRetinaFilter.setCoefficientsTable(LPfilterGain, LPfilterTemporalresponse, LPfilterSpatialResponse, MovingContoursExtractorCoefficient, 0, 2.0f*LPfilterSpatialResponse);
_MagnoRetinaFilter.setV0CompressionParameter(0.7f, maxInputValue, meanValue);
// stability controls value init
_setInitPeriodCount();
}
bool RetinaFilter::checkInput(const std::valarray<float> &input, const bool)
{
BasicRetinaFilter *inputTarget=&_photoreceptorsPrefilter;
if (_photoreceptorsLogSampling)
inputTarget=_photoreceptorsLogSampling;
bool test=input.size()==inputTarget->getNBpixels() || input.size()==(inputTarget->getNBpixels()*3) ;
if (!test)
{
std::cerr<<"RetinaFilter::checkInput: input buffer does not match retina buffer size, conversion aborted"<<std::endl;
std::cout<<"RetinaFilter::checkInput: input size="<<input.size()<<" / "<<"retina size="<<inputTarget->getNBpixels()<<std::endl;
return false;
}
return true;
}
// main function that runs the filter for a given input frame
bool RetinaFilter::runFilter(const std::valarray<float> &imageInput, const bool useAdaptiveFiltering, const bool processRetinaParvoMagnoMapping, const bool useColorMode, const bool inputIsColorMultiplexed)
{
// preliminary check
bool processSuccess=true;
if (!checkInput(imageInput, useColorMode))
return false;
// run the color multiplexing if needed and compute each suub filter of the retina:
// -> local adaptation
// -> contours OPL extraction
// -> moving contours extraction
// stability controls value update
++_ellapsedFramesSinceLastReset;
_useColorMode=useColorMode;
/* pointer to the appropriate input data after,
* by default, if graylevel mode, the input is processed,
* if color or something else must be considered, specific preprocessing are applied
*/
const std::valarray<float> *selectedPhotoreceptorsLocalAdaptationInput= &imageInput;
const std::valarray<float> *selectedPhotoreceptorsColorInput=&imageInput;
//********** Following is input data specific photoreceptors processing
if (_photoreceptorsLogSampling)
{
_photoreceptorsLogSampling->runProjection(imageInput, useColorMode);
selectedPhotoreceptorsColorInput=selectedPhotoreceptorsLocalAdaptationInput=&(_photoreceptorsLogSampling->getSampledFrame());
}
if (useColorMode&& (!inputIsColorMultiplexed)) // not multiplexed color input case
{
_colorEngine.runColorMultiplexing(*selectedPhotoreceptorsColorInput);
selectedPhotoreceptorsLocalAdaptationInput=&(_colorEngine.getMultiplexedFrame());
}
//********** Following is generic Retina processing
// photoreceptors local adaptation
_photoreceptorsPrefilter.runFilter_LocalAdapdation(*selectedPhotoreceptorsLocalAdaptationInput, _ParvoRetinaFilter.getHorizontalCellsOutput());
// safety pixel values checks
//_photoreceptorsPrefilter.normalizeGrayOutput_0_maxOutputValue(_maxOutputValue);
// run parvo filter
_ParvoRetinaFilter.runFilter(_photoreceptorsPrefilter.getOutput(), _useParvoOutput);
if (_useParvoOutput)
{
_ParvoRetinaFilter.normalizeGrayOutputCentredSigmoide(); // models the saturation of the cells, usefull for visualisation of the ON-OFF Parvo Output, Bipolar cells outputs do not change !!!
_ParvoRetinaFilter.centerReductImageLuminance(); // best for further spectrum analysis
if (_normalizeParvoOutput_0_maxOutputValue)
_ParvoRetinaFilter.normalizeGrayOutput_0_maxOutputValue(_maxOutputValue);
}
if (_useParvoOutput&&_useMagnoOutput)
{
_MagnoRetinaFilter.runFilter(_ParvoRetinaFilter.getBipolarCellsON(), _ParvoRetinaFilter.getBipolarCellsOFF());
if (_normalizeMagnoOutput_0_maxOutputValue)
{
_MagnoRetinaFilter.normalizeGrayOutput_0_maxOutputValue(_maxOutputValue);
}
_MagnoRetinaFilter.normalizeGrayOutputNearZeroCentreredSigmoide();
}
if (_useParvoOutput&&_useMagnoOutput&&processRetinaParvoMagnoMapping)
{
_processRetinaParvoMagnoMapping();
if (_useColorMode)
_colorEngine.runColorDemultiplexing(_retinaParvoMagnoMappedFrame, useAdaptiveFiltering, _maxOutputValue);//_ColorEngine->getMultiplexedFrame());//_ParvoRetinaFilter->getPhotoreceptorsLPfilteringOutput());
return processSuccess;
}
if (_useParvoOutput&&_useColorMode)
{
_colorEngine.runColorDemultiplexing(_ParvoRetinaFilter.getOutput(), useAdaptiveFiltering, _maxOutputValue);//_ColorEngine->getMultiplexedFrame());//_ParvoRetinaFilter->getPhotoreceptorsLPfilteringOutput());
// compute A Cr1 Cr2 to LMS color space conversion
//if (true)
// _applyImageColorSpaceConversion(_ColorEngine->getChrominance(), lmsTempBuffer.Buffer(), _LMStoACr1Cr2);
}
return processSuccess;
}
const std::valarray<float> &RetinaFilter::getContours()
{
if (_useColorMode)
return _colorEngine.getLuminance();
else
return _ParvoRetinaFilter.getOutput();
}
// run the initilized retina filter in order to perform gray image tone mapping, after this call all retina outputs are updated
void RetinaFilter::runGrayToneMapping(const std::valarray<float> &grayImageInput, std::valarray<float> &grayImageOutput, const float PhotoreceptorsCompression, const float ganglionCellsCompression)
{
// preliminary check
if (!checkInput(grayImageInput, false))
return;
this->_runGrayToneMapping(grayImageInput, grayImageOutput, PhotoreceptorsCompression, ganglionCellsCompression);
}
// run the initilized retina filter in order to perform gray image tone mapping, after this call all retina outputs are updated
void RetinaFilter::_runGrayToneMapping(const std::valarray<float> &grayImageInput, std::valarray<float> &grayImageOutput, const float PhotoreceptorsCompression, const float ganglionCellsCompression)
{
// stability controls value update
++_ellapsedFramesSinceLastReset;
std::valarray<float> temp2(grayImageInput.size());
// apply tone mapping on the multiplexed image
// -> photoreceptors local adaptation (large area adaptation)
_photoreceptorsPrefilter.runFilter_LPfilter(grayImageInput, grayImageOutput, 2); // compute low pass filtering modeling the horizontal cells filtering to acess local luminance
_photoreceptorsPrefilter.setV0CompressionParameterToneMapping(1.f-PhotoreceptorsCompression, grayImageOutput.max(), 1.f*grayImageOutput.sum()/(float)_photoreceptorsPrefilter.getNBpixels());
_photoreceptorsPrefilter.runFilter_LocalAdapdation(grayImageInput, grayImageOutput, temp2); // adapt contrast to local luminance
// -> ganglion cells local adaptation (short area adaptation)
_photoreceptorsPrefilter.runFilter_LPfilter(temp2, grayImageOutput, 1); // compute low pass filtering (high cut frequency (remove spatio-temporal noise)
_photoreceptorsPrefilter.setV0CompressionParameterToneMapping(1.f-ganglionCellsCompression, temp2.max(), 1.f*temp2.sum()/(float)_photoreceptorsPrefilter.getNBpixels());
_photoreceptorsPrefilter.runFilter_LocalAdapdation(temp2, grayImageOutput, grayImageOutput); // adapt contrast to local luminance
}
// run the initilized retina filter in order to perform color tone mapping, after this call all retina outputs are updated
void RetinaFilter::runRGBToneMapping(const std::valarray<float> &RGBimageInput, std::valarray<float> &RGBimageOutput, const bool useAdaptiveFiltering, const float PhotoreceptorsCompression, const float ganglionCellsCompression)
{
// preliminary check
if (!checkInput(RGBimageInput, true))
return;
// multiplex the image with the color sampling method specified in the constructor
_colorEngine.runColorMultiplexing(RGBimageInput);
// apply tone mapping on the multiplexed image
_runGrayToneMapping(_colorEngine.getMultiplexedFrame(), RGBimageOutput, PhotoreceptorsCompression, ganglionCellsCompression);
// demultiplex tone maped image
_colorEngine.runColorDemultiplexing(RGBimageOutput, useAdaptiveFiltering, _photoreceptorsPrefilter.getMaxInputValue());//_ColorEngine->getMultiplexedFrame());//_ParvoRetinaFilter->getPhotoreceptorsLPfilteringOutput());
// rescaling result between 0 and 255
_colorEngine.normalizeRGBOutput_0_maxOutputValue(255.0);
// return the result
RGBimageOutput=_colorEngine.getDemultiplexedColorFrame();
}
void RetinaFilter::runLMSToneMapping(const std::valarray<float> &, std::valarray<float> &, const bool, const float, const float)
{
std::cerr<<"not working, sorry"<<std::endl;
/* // preliminary check
const std::valarray<float> &bufferInput=checkInput(LMSimageInput, true);
if (!bufferInput)
return NULL;
if (!_useColorMode)
std::cerr<<"RetinaFilter::Can not call tone mapping oeration if the retina filter was created for gray scale images"<<std::endl;
// create a temporary buffer of size nrows, Mcolumns, 3 layers
std::valarray<float> lmsTempBuffer(LMSimageInput);
std::cout<<"RetinaFilter::--->min LMS value="<<lmsTempBuffer.min()<<std::endl;
// setup local adaptation parameter at the photoreceptors level
setV0CompressionParameter(PhotoreceptorsCompression, _maxInputValue);
// get the local energy of each color channel
// ->L
_spatiotemporalLPfilter(LMSimageInput, _filterOutput, 1);
setV0CompressionParameterToneMapping(PhotoreceptorsCompression, _maxInputValue, this->sum()/_NBpixels);
_localLuminanceAdaptation(LMSimageInput, _filterOutput, lmsTempBuffer.Buffer());
// ->M
_spatiotemporalLPfilter(LMSimageInput+_NBpixels, _filterOutput, 1);
setV0CompressionParameterToneMapping(PhotoreceptorsCompression, _maxInputValue, this->sum()/_NBpixels);
_localLuminanceAdaptation(LMSimageInput+_NBpixels, _filterOutput, lmsTempBuffer.Buffer()+_NBpixels);
// ->S
_spatiotemporalLPfilter(LMSimageInput+_NBpixels*2, _filterOutput, 1);
setV0CompressionParameterToneMapping(PhotoreceptorsCompression, _maxInputValue, this->sum()/_NBpixels);
_localLuminanceAdaptation(LMSimageInput+_NBpixels*2, _filterOutput, lmsTempBuffer.Buffer()+_NBpixels*2);
// eliminate negative values
for (unsigned int i=0;i<lmsTempBuffer.size();++i)
if (lmsTempBuffer.Buffer()[i]<0)
lmsTempBuffer.Buffer()[i]=0;
std::cout<<"RetinaFilter::->min LMS value="<<lmsTempBuffer.min()<<std::endl;
// compute LMS to A Cr1 Cr2 color space conversion
_applyImageColorSpaceConversion(lmsTempBuffer.Buffer(), lmsTempBuffer.Buffer(), _LMStoACr1Cr2);
TemplateBuffer <float> acr1cr2TempBuffer(_NBrows, _NBcolumns, 3);
memcpy(acr1cr2TempBuffer.Buffer(), lmsTempBuffer.Buffer(), sizeof(float)*_NBpixels*3);
// compute A Cr1 Cr2 to LMS color space conversion
_applyImageColorSpaceConversion(acr1cr2TempBuffer.Buffer(), lmsTempBuffer.Buffer(), _ACr1Cr2toLMS);
// eliminate negative values
for (unsigned int i=0;i<lmsTempBuffer.size();++i)
if (lmsTempBuffer.Buffer()[i]<0)
lmsTempBuffer.Buffer()[i]=0;
// rewrite output to the appropriate buffer
_colorEngine->setDemultiplexedColorFrame(lmsTempBuffer.Buffer());
*/
}
// return image with center Parvo and peripheral Magno channels
void RetinaFilter::_processRetinaParvoMagnoMapping()
{
register float *hybridParvoMagnoPTR= &_retinaParvoMagnoMappedFrame[0];
register const float *parvoOutputPTR= get_data(_ParvoRetinaFilter.getOutput());
register const float *magnoXOutputPTR= get_data(_MagnoRetinaFilter.getOutput());
register float *hybridParvoMagnoCoefTablePTR= &_retinaParvoMagnoMapCoefTable[0];
for (unsigned int i=0 ; i<_photoreceptorsPrefilter.getNBpixels() ; ++i, hybridParvoMagnoCoefTablePTR+=2)
{
float hybridValue=*(parvoOutputPTR++)**(hybridParvoMagnoCoefTablePTR)+*(magnoXOutputPTR++)**(hybridParvoMagnoCoefTablePTR+1);
*(hybridParvoMagnoPTR++)=hybridValue;
}
TemplateBuffer<float>::normalizeGrayOutput_0_maxOutputValue(&_retinaParvoMagnoMappedFrame[0], _photoreceptorsPrefilter.getNBpixels());
}
bool RetinaFilter::getParvoFoveaResponse(std::valarray<float> &parvoFovealResponse)
{
if (!_useParvoOutput)
return false;
if (parvoFovealResponse.size() != _ParvoRetinaFilter.getNBpixels())
return false;
register const float *parvoOutputPTR= get_data(_ParvoRetinaFilter.getOutput());
register float *fovealParvoResponsePTR= &parvoFovealResponse[0];
register float *hybridParvoMagnoCoefTablePTR= &_retinaParvoMagnoMapCoefTable[0];
for (unsigned int i=0 ; i<_photoreceptorsPrefilter.getNBpixels() ; ++i, hybridParvoMagnoCoefTablePTR+=2)
{
*(fovealParvoResponsePTR++)=*(parvoOutputPTR++)**(hybridParvoMagnoCoefTablePTR);
}
return true;
}
// method to retrieve the parafoveal magnocellular pathway response (no energy motion in fovea)
bool RetinaFilter::getMagnoParaFoveaResponse(std::valarray<float> &magnoParafovealResponse)
{
if (!_useMagnoOutput)
return false;
if (magnoParafovealResponse.size() != _MagnoRetinaFilter.getNBpixels())
return false;
register const float *magnoXOutputPTR= get_data(_MagnoRetinaFilter.getOutput());
register float *parafovealMagnoResponsePTR=&magnoParafovealResponse[0];
register float *hybridParvoMagnoCoefTablePTR=&_retinaParvoMagnoMapCoefTable[0]+1;
for (unsigned int i=0 ; i<_photoreceptorsPrefilter.getNBpixels() ; ++i, hybridParvoMagnoCoefTablePTR+=2)
{
*(parafovealMagnoResponsePTR++)=*(magnoXOutputPTR++)**(hybridParvoMagnoCoefTablePTR);
}
return true;
}
}// end of namespace bioinspired
}// end of namespace cv
-548
View File
@@ -1,548 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
/**
* @class RetinaFilter
* @brief class which describes the retina model developped at the LIS/GIPSA-LAB www.gipsa-lab.inpg.fr:
* -> performs a contours and moving contours extraction with powerfull local data enhancement as at the retina level
* Based on Alexandre BENOIT thesis: "Le systeme visuel humain au secours de la vision par ordinateur"
*
* => various optimisations and enhancements added after 2007 such as tone mapping capabilities, see reference paper cited in the licence and :
* Benoit A.,Alleysson D., Herault J., Le Callet P. (2009), "Spatio-Temporal Tone Mapping Operator based on a Retina model", Computational Color Imaging Workshop (CCIW09),pp 12-22, Saint Etienne, France
*
* TYPICAL USE:
*
* // create object at a specified picture size
* Retina *retina;
* retina =new Retina(frameSizeRows, frameSizeColumns, RGBmode);
*
* // init gain, spatial and temporal parameters:
* retina->setParameters(0.7, 1, 0, 7, 1, 5, 0, 0, 3 , true);
*
* // during program execution, call the filter for local luminance correction, contours extraction, moving contours extraction from an input picture called "FrameBuffer":
* retina->runfilter(FrameBuffer);
*
* // get the different output frames, check in the class description below for more outputs:
* const std::valarray<float> correctedLuminance=retina->getLocalAdaptation();
* const std::valarray<float> contours=retina->getContours();
* const std::valarray<float> movingContours=retina->getMovingContours();
*
* // at the end of the program, destroy object:
* delete retina;
*
* @author Alexandre BENOIT, benoit.alexandre.vision@gmail.com, LISTIC / Gipsa-Lab, France: www.gipsa-lab.inpg.fr/
* Creation date 2007
*/
#ifndef RETINACLASSES_H_
#define RETINACLASSES_H_
#include "basicretinafilter.hpp"
#include "parvoretinafilter.hpp"
#include "magnoretinafilter.hpp"
// optional includes (depending on the related publications)
#include "imagelogpolprojection.hpp"
#include "retinacolor.hpp"
//#define __RETINADEBUG // define RETINADEBUG to display debug data
namespace cv
{
namespace bioinspired
{
// retina class that process the 3 outputs of the retina filtering stages
class RetinaFilter//: public BasicRetinaFilter
{
public:
/**
* constructor of the retina filter model with log sampling of the input frame (models the photoreceptors log sampling (central high resolution fovea and lower precision borders))
* @param sizeRows: number of rows of the input image
* @param sizeColumns: number of columns of the input image
* @param colorMode: specifies if the retina works with color (true) of stays in grayscale processing (false), can be adjusted online by the use of setColorMode method
* @param samplingMethod: specifies which kind of color sampling will be used
* @param useRetinaLogSampling: activate retina log sampling, if true, the 2 following parameters can be used
* @param reductionFactor: only usefull if param useRetinaLogSampling=true, specifies the reduction factor of the output frame (as the center (fovea) is high resolution and corners can be underscaled, then a reduction of the output is allowed without precision leak
* @param samplingStrenght: only usefull if param useRetinaLogSampling=true, specifies the strenght of the log scale that is applied
*/
RetinaFilter(const unsigned int sizeRows, const unsigned int sizeColumns, const bool colorMode=false, const int samplingMethod=RETINA_COLOR_BAYER, const bool useRetinaLogSampling=false, const double reductionFactor=1.0, const double samplingStrenght=10.0);
/**
* standard destructor
*/
~RetinaFilter();
/**
* function that clears all buffers of the object
*/
void clearAllBuffers();
/**
* resize retina parvo filter object (resize all allocated buffers)
* @param NBrows: the new height size
* @param NBcolumns: the new width size
*/
void resize(const unsigned int NBrows, const unsigned int NBcolumns);
/**
* Input buffer checker: allows to check if the passed image buffer corresponds to retina filter expectations
* @param input: the input image buffer
* @param colorMode: specifiy if the input should be considered by the retina as colored of not
* @return false if not compatible or it returns true if OK
*/
bool checkInput(const std::valarray<float> &input, const bool colorMode);
/**
* run the initilized retina filter, after this call all retina outputs are updated
* @param imageInput: image input buffer, can be grayscale or RGB image respecting the size specified at the constructor level
* @param useAdaptiveFiltering: set true if you want to use adaptive color demultilexing (solve some color artefact problems), see RetinaColor for citation references
* @param processRetinaParvoMagnoMapping: tels if the main outputs takes into account the mapping of the Parvo and Magno channels on the retina (centred parvo (fovea) and magno outside (parafovea))
* @param useColorMode: color information is used if true, warning, if input is only gray level, a buffer overflow error will occur
-> note that if color mode is activated and processRetinaParvoMagnoMapping==true, then the demultiplexed color frame (accessible throw getColorOutput() will be a color contours frame in the fovea and gray level moving contours outside
@param inputIsColorMultiplexed: set trus if the input data is a multiplexed color image (using Bayer sampling for example), the color sampling method must correspond to the RETINA_COLORSAMPLINGMETHOD passed at constructor!
* @return true if process ran well, false in case of failure
*/
bool runFilter(const std::valarray<float> &imageInput, const bool useAdaptiveFiltering=true, const bool processRetinaParvoMagnoMapping=false, const bool useColorMode=false, const bool inputIsColorMultiplexed=false);
/**
* run the initilized retina filter in order to perform color tone mapping applied on an RGB image, after this call the color output of the retina is updated (use function getColorOutput() to grab it)
* the algorithm is based on David Alleyson, Sabine Susstruck and Laurence Meylan's work, please cite:
* -> Meylan L., Alleysson D., and Ssstrunk S., A Model of Retinal Local Adaptation for the Tone Mapping of Color Filter Array Images, Journal of Optical Society of America, A, Vol. 24, N 9, September, 1st, 2007, pp. 2807-2816
* get the resulting gray frame by calling function getParvoColor()
* @param grayImageInput: RGB image input buffer respecting the size specified at the constructor level
* @param PhotoreceptorsCompression: sets the log compression parameters applied at the photoreceptors level (enhance luminance in dark areas)
* @param ganglionCellsCompression: sets the log compression applied at the gnaglion cells output (enhance contrast)
*/
void runGrayToneMapping(const std::valarray<float> &grayImageInput, std::valarray<float> &grayImageOutput, const float PhotoreceptorsCompression=0.6, const float ganglionCellsCompression=0.6);
/**
* run the initilized retina filter in order to perform color tone mapping applied on an RGB image, after this call the color output of the retina is updated (use function getColorOutput() to grab it)
* the algorithm is based on David Alleyson, Sabine Susstruck and Laurence Meylan's work, please cite:
* -> Meylan L., Alleysson D., and Ssstrunk S., A Model of Retinal Local Adaptation for the Tone Mapping of Color Filter Array Images, Journal of Optical Society of America, A, Vol. 24, N 9, September, 1st, 2007, pp. 2807-2816
* get the resulting RGB frame by calling function getParvoColor()
* @param RGBimageInput: RGB image input buffer respecting the size specified at the constructor level
* @param useAdaptiveFiltering: set true if you want to use adaptive color demultilexing (solve some color artefact problems), see RetinaColor for citation references
* @param PhotoreceptorsCompression: sets the log compression parameters applied at the photoreceptors level (enhance luminance in dark areas)
* @param ganglionCellsCompression: sets the log compression applied at the ganglion cells output (enhance contrast)
*/
void runRGBToneMapping(const std::valarray<float> &RGBimageInput, std::valarray<float> &imageOutput, const bool useAdaptiveFiltering, const float PhotoreceptorsCompression=0.6, const float ganglionCellsCompression=0.6);
/**
* run the initilized retina filter in order to perform color tone mapping applied on an RGB image, after this call the color output of the retina is updated (use function getColorOutput() to grab it)
* get the resulting RGB frame by calling function getParvoColor()
* @param LMSimageInput: RGB image input buffer respecting the size specified at the constructor level
* @param useAdaptiveFiltering: set true if you want to use adaptive color demultilexing (solve some color artefact problems), see RetinaColor for citation references
* @param PhotoreceptorsCompression: sets the log compression parameters applied at the photoreceptors level (enhance luminance in dark areas)
* @param ganglionCellsCompression: sets the log compression applied at the gnaglion cells output (enhance contrast)
*/
void runLMSToneMapping(const std::valarray<float> &LMSimageInput, std::valarray<float> &imageOutput, const bool useAdaptiveFiltering, const float PhotoreceptorsCompression=0.6, const float ganglionCellsCompression=0.6);
/**
* set up function of the retina filter: all the retina is initialized at this step, some specific parameters are set by default, use setOPLandParvoCoefficientsTable() and setMagnoCoefficientsTable in order to setup the retina with more options
* @param OPLspatialResponse1: (equal to k1 in setOPLandParvoCoefficientsTable() function) the spatial constant of the first order low pass filter of the photoreceptors, use it to cut high spatial frequencies (noise or thick contours), unit is pixels, typical value is 1 pixel
* @param OPLtemporalresponse1: (equal to tau1 in setOPLandParvoCoefficientsTable() function) the time constant of the first order low pass filter of the photoreceptors, use it to cut high temporal frequencies (noise or fast motion), unit is frames, typical value is 1 frame
* @param OPLassymetryGain: (equal to beta2 in setOPLandParvoCoefficientsTable() function) gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, then, the luminance is not filtered and is still reachable at the output, typicall value is 0
* @param OPLspatialResponse2: (equal to k2 in setOPLandParvoCoefficientsTable() function) the spatial constant of the first order low pass filter of the horizontal cells, use it to cut low spatial frequencies (local luminance), unit is pixels, typical value is 5 pixel
* @param OPLtemporalresponse2: (equal to tau2 in setOPLandParvoCoefficientsTable() function) the time constant of the first order low pass filter of the horizontal cells, use it to cut low temporal frequencies (local luminance variations), unit is frames, typical value is 1 frame, as the photoreceptors
* @param LPfilterSpatialResponse: (equal to parasolCells_k in setMagnoCoefficientsTable() function) the low pass filter spatial constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is pixels, typical value is 5
* @param LPfilterGain: (equal to parasolCells_beta in setMagnoCoefficientsTable() function) the low pass filter gain used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), typical value is 0
* @param LPfilterTemporalresponse: (equal to parasolCells_tau in setMagnoCoefficientsTable() function) the low pass filter time constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is frame, typical value is 0 (immediate response)
* @param MovingContoursExtractorCoefficient: (equal to amacrinCellsTemporalCutFrequency in setMagnoCoefficientsTable() function)the time constant of the first order high pass fiter of the magnocellular way (motion information channel), unit is frames, tipicall value is 5
* @param normalizeParvoOutput_0_maxOutputValue: specifies if the Parvo cellular output should be normalized between 0 and maxOutputValue (true) or not (false) in order to remain at a null mean value, true value is recommended for visualisation
* @param normalizeMagnoOutput_0_maxOutputValue: specifies if the Magno cellular output should be normalized between 0 and maxOutputValue (true) or not (false), setting true may be hazardous because it can enhace the noise response when nothing is moving
* @param maxOutputValue: the maximum amplitude value of the normalized outputs (generally 255 for 8bit per channel pictures)
* @param maxInputValue: the maximum pixel value of the input picture (generally 255 for 8bit per channel pictures), specify it in other case (for example High Dynamic Range Images)
* @param meanValue: the global mean value of the input data usefull for local adaptation setup
*/
void setGlobalParameters(const float OPLspatialResponse1=0.7, const float OPLtemporalresponse1=1, const float OPLassymetryGain=0, const float OPLspatialResponse2=5, const float OPLtemporalresponse2=1, const float LPfilterSpatialResponse=5, const float LPfilterGain=0, const float LPfilterTemporalresponse=0, const float MovingContoursExtractorCoefficient=5, const bool normalizeParvoOutput_0_maxOutputValue=false, const bool normalizeMagnoOutput_0_maxOutputValue=false, const float maxOutputValue=255.0, const float maxInputValue=255.0, const float meanValue=128.0);
/**
* setup the local luminance adaptation capability
* @param V0CompressionParameter: the compression strengh of the photoreceptors local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 160
*/
inline void setPhotoreceptorsLocalAdaptationSensitivity(const float V0CompressionParameter){_photoreceptorsPrefilter.setV0CompressionParameter(1-V0CompressionParameter);_setInitPeriodCount();};
/**
* setup the local luminance adaptation capability
* @param V0CompressionParameter: the compression strengh of the parvocellular pathway (details) local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 160
*/
inline void setParvoGanglionCellsLocalAdaptationSensitivity(const float V0CompressionParameter){_ParvoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);_setInitPeriodCount();};
/**
* setup the local luminance adaptation area of integration
* @param spatialResponse: the spatial constant of the low pass filter applied on the bipolar cells output in order to compute local contrast mean values
* @param temporalResponse: the spatial constant of the low pass filter applied on the bipolar cells output in order to compute local contrast mean values (generally set to zero: immediate response)
*/
inline void setGanglionCellsLocalAdaptationLPfilterParameters(const float spatialResponse, const float temporalResponse){_ParvoRetinaFilter.setGanglionCellsLocalAdaptationLPfilterParameters(temporalResponse, spatialResponse);_setInitPeriodCount();};
/**
* setup the local luminance adaptation capability
* @param V0CompressionParameter: the compression strengh of the magnocellular pathway (motion) local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 160
*/
inline void setMagnoGanglionCellsLocalAdaptationSensitivity(const float V0CompressionParameter){_MagnoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);_setInitPeriodCount();};
/**
* setup the OPL and IPL parvo channels
* @param beta1: gain of the horizontal cells network, if 0, then the mean value of the output is zero (default value), if the parameter is near 1, the amplitude is boosted but it should only be used for values rescaling... if needed
* @param tau1: the time constant of the first order low pass filter of the photoreceptors, use it to cut high temporal frequencies (noise or fast motion), unit is frames, typical value is 1 frame
* @param k1: the spatial constant of the first order low pass filter of the photoreceptors, use it to cut high spatial frequencies (noise or thick contours), unit is pixels, typical value is 1 pixel
* @param beta2: gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, then, the luminance is not filtered and is still reachable at the output, typicall value is 0
* @param tau2: the time constant of the first order low pass filter of the horizontal cells, use it to cut low temporal frequencies (local luminance variations), unit is frames, typical value is 1 frame, as the photoreceptors
* @param k2: the spatial constant of the first order low pass filter of the horizontal cells, use it to cut low spatial frequencies (local luminance), unit is pixels, typical value is 5 pixel, this value is also used for local contrast computing when computing the local contrast adaptation at the ganglion cells level (Inner Plexiform Layer parvocellular channel model)
* @param V0CompressionParameter: the compression strengh of the ganglion cells local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 230
*/
void setOPLandParvoParameters(const float beta1, const float tau1, const float k1, const float beta2, const float tau2, const float k2, const float V0CompressionParameter){_ParvoRetinaFilter.setOPLandParvoFiltersParameters(beta1, tau1, k1, beta2, tau2, k2);_ParvoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);_setInitPeriodCount();};
/**
* set parameters values for the Inner Plexiform Layer (IPL) magnocellular channel
* @param parasolCells_beta: the low pass filter gain used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), typical value is 0
* @param parasolCells_tau: the low pass filter time constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is frame, typical value is 0 (immediate response)
* @param parasolCells_k: the low pass filter spatial constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is pixels, typical value is 5
* @param amacrinCellsTemporalCutFrequency: the time constant of the first order high pass fiter of the magnocellular way (motion information channel), unit is frames, tipicall value is 5
* @param V0CompressionParameter: the compression strengh of the ganglion cells local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 200
* @param localAdaptintegration_tau: specifies the temporal constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
* @param localAdaptintegration_k: specifies the spatial constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
*/
void setMagnoCoefficientsTable(const float parasolCells_beta, const float parasolCells_tau, const float parasolCells_k, const float amacrinCellsTemporalCutFrequency, const float V0CompressionParameter, const float localAdaptintegration_tau, const float localAdaptintegration_k){_MagnoRetinaFilter.setCoefficientsTable(parasolCells_beta, parasolCells_tau, parasolCells_k, amacrinCellsTemporalCutFrequency, localAdaptintegration_tau, localAdaptintegration_k);_MagnoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);_setInitPeriodCount();};
/**
* set if the parvo output should be or not normalized between 0 and 255 (for display purpose generally)
* @param normalizeParvoOutput_0_maxOutputValue: true if normalization should be done
*/
inline void activateNormalizeParvoOutput_0_maxOutputValue(const bool normalizeParvoOutput_0_maxOutputValue){_normalizeParvoOutput_0_maxOutputValue=normalizeParvoOutput_0_maxOutputValue;};
/**
* set if the magno output should be or not normalized between 0 and 255 (for display purpose generally), take care, if nothing is moving, then, the noise will be enanced !!!
* @param normalizeMagnoOutput_0_maxOutputValue: true if normalization should be done
*/
inline void activateNormalizeMagnoOutput_0_maxOutputValue(const bool normalizeMagnoOutput_0_maxOutputValue){_normalizeMagnoOutput_0_maxOutputValue=normalizeMagnoOutput_0_maxOutputValue;};
/**
* setup the maximum amplitude value of the normalized outputs (generally 255 for 8bit per channel pictures)
* @param maxOutputValue: maximum amplitude value of the normalized outputs (generally 255 for 8bit per channel pictures)
*/
inline void setMaxOutputValue(const float maxOutputValue){_maxOutputValue=maxOutputValue;};
/**
* sets the color mode of the frame grabber
* @param desiredColorMode: true if the user needs color information, false for graylevels
*/
void setColorMode(const bool desiredColorMode){_useColorMode=desiredColorMode;};
/**
* activate color saturation as the final step of the color demultiplexing process
* -> this saturation is a sigmoide function applied to each channel of the demultiplexed image.
* @param saturateColors: boolean that activates color saturation (if true) or desactivate (if false)
* @param colorSaturationValue: the saturation factor
* */
inline void setColorSaturation(const bool saturateColors=true, const float colorSaturationValue=4.0){_colorEngine.setColorSaturation(saturateColors, colorSaturationValue);};
/////////////////////////////////////////////////////////////////
// function that retrieve the main retina outputs, one by one, or all in a structure
/**
* @return the input image sampled by the photoreceptors spatial sampling
*/
inline const std::valarray<float> &getPhotoreceptorsSampledFrame() const
{
CV_Assert(_photoreceptorsLogSampling);
return _photoreceptorsLogSampling->getSampledFrame();
};
/**
* @return photoreceptors output, locally adapted luminance only, no high frequency spatio-temporal noise reduction at the next retina processing stages, use getPhotoreceptors method to get complete photoreceptors output
*/
inline const std::valarray<float> &getLocalAdaptation() const {return _photoreceptorsPrefilter.getOutput();};
/**
* @return photoreceptors output: locally adapted luminance and high frequency spatio-temporal noise reduction, high luminance is a little saturated at this stage, but this is corrected naturally at the next retina processing stages
*/
inline const std::valarray<float> &getPhotoreceptors() const {return _ParvoRetinaFilter.getPhotoreceptorsLPfilteringOutput();};
/**
* @return the local luminance of the processed frame (it is the horizontal cells output)
*/
inline const std::valarray<float> &getHorizontalCells() const {return _ParvoRetinaFilter.getHorizontalCellsOutput();};
///////// CONTOURS part, PARVOCELLULAR RETINA PATHWAY
/**
* @return true if Parvocellular output is activated, false if not
*/
inline bool areContoursProcessed(){return _useParvoOutput;};
/**
* method to retrieve the foveal parvocellular pathway response (no details energy in parafovea)
* @param parvoParafovealResponse: buffer that will be filled with the response of the magnocellular pathway in the parafoveal area
* @return true if process succeeded (if buffer exists, is its size matches retina size, if magno channel is activated and if mapping is initialized
*/
bool getParvoFoveaResponse(std::valarray<float> &parvoFovealResponse);
/**
* @param useParvoOutput: true if Parvocellular output should be activated, false if not
*/
inline void activateContoursProcessing(const bool useParvoOutput){_useParvoOutput=useParvoOutput;};
/**
* @return the parvocellular contours information (details), should be used at the fovea level
*/
const std::valarray<float> &getContours(); // Parvocellular output
/**
* @return the parvocellular contours ON information (details), should be used at the fovea level
*/
inline const std::valarray<float> &getContoursON() const {return _ParvoRetinaFilter.getParvoON();};// Parvocellular ON output
/**
* @return the parvocellular contours OFF information (details), should be used at the fovea level
*/
inline const std::valarray<float> &getContoursOFF() const {return _ParvoRetinaFilter.getParvoOFF();};// Parvocellular OFF output
///////// MOVING CONTOURS part, MAGNOCELLULAR RETINA PATHWAY
/**
* @return true if Magnocellular output is activated, false if not
*/
inline bool areMovingContoursProcessed(){return _useMagnoOutput;};
/**
* method to retrieve the parafoveal magnocellular pathway response (no motion energy in fovea)
* @param magnoParafovealResponse: buffer that will be filled with the response of the magnocellular pathway in the parafoveal area
* @return true if process succeeded (if buffer exists, is its size matches retina size, if magno channel is activated and if mapping is initialized
*/
bool getMagnoParaFoveaResponse(std::valarray<float> &magnoParafovealResponse);
/**
* @param useMagnoOutput: true if Magnoocellular output should be activated, false if not
*/
inline void activateMovingContoursProcessing(const bool useMagnoOutput){_useMagnoOutput=useMagnoOutput;};
/**
* @return the magnocellular moving contours information (motion), should be used at the parafovea level without post-processing
*/
inline const std::valarray<float> &getMovingContours() const {return _MagnoRetinaFilter.getOutput();};// Magnocellular output
/**
* @return the magnocellular moving contours information (motion), should be used at the parafovea level with assymetric sigmoide post-processing which saturates motion information
*/
inline const std::valarray<float> &getMovingContoursSaturated() const {return _MagnoRetinaFilter.getMagnoYsaturated();};// Saturated Magnocellular output
/**
* @return the magnocellular moving contours ON information (motion), should be used at the parafovea level without post-processing
*/
inline const std::valarray<float> &getMovingContoursON() const {return _MagnoRetinaFilter.getMagnoON();};// Magnocellular ON output
/**
* @return the magnocellular moving contours OFF information (motion), should be used at the parafovea level without post-processing
*/
inline const std::valarray<float> &getMovingContoursOFF() const {return _MagnoRetinaFilter.getMagnoOFF();};// Magnocellular OFF output
/**
* @return a gray level image with center Parvo and peripheral Magno X channels, WARNING, the result will be ok if you called previously fucntion runFilter(imageInput, processRetinaParvoMagnoMapping=true);
* -> will be accessible even if color mode is activated (but the image is color sampled so quality is poor), but get the same thing but in color by the use of function getParvoColor()
*/
inline const std::valarray<float> &getRetinaParvoMagnoMappedOutput() const {return _retinaParvoMagnoMappedFrame;};// return image with center Parvo and peripheral Magno channels
/**
* color processing dedicated functions
* @return the parvo channel (contours, details) of the processed frame, grayscale output
*/
inline const std::valarray<float> &getParvoContoursChannel() const {return _colorEngine.getLuminance();};
/**
* color processing dedicated functions
* @return the chrominance of the processed frame (same colorspace as the input output, usually RGB)
*/
inline const std::valarray<float> &getParvoChrominance() const {return _colorEngine.getChrominance();}; // only retreive chrominance
/**
* color processing dedicated functions
* @return the parvo + chrominance channels of the processed frame (same colorspace as the input output, usually RGB)
*/
inline const std::valarray<float> &getColorOutput() const {return _colorEngine.getDemultiplexedColorFrame();};// retrieve luminance+chrominance
/**
* apply to the retina color output the Krauskopf transformation which leads to an opponent color system: output colorspace if Acr1cr2 if input of the retina was LMS color space
* @param result: the input buffer to fill with the transformed colorspace retina output
* @return true if process ended successfully
*/
inline bool applyKrauskopfLMS2Acr1cr2Transform(std::valarray<float> &result){return _colorEngine.applyKrauskopfLMS2Acr1cr2Transform(result);};
/**
* apply to the retina color output the Krauskopf transformation which leads to an opponent color system: output colorspace if Acr1cr2 if input of the retina was LMS color space
* @param result: the input buffer to fill with the transformed colorspace retina output
* @return true if process ended successfully
*/
inline bool applyLMS2LabTransform(std::valarray<float> &result){return _colorEngine.applyLMS2LabTransform(result);};
/**
* color processing dedicated functions
* @return the retina initialized mode, true if color mode (RGB), false if grayscale
*/
inline bool isColorMode(){return _useColorMode;}; // return true if RGB mode, false if gray level mode
/**
* @return the irregular low pass filter ouput at the photoreceptors level
*/
inline const std::valarray<float> &getIrregularLPfilteredInputFrame() const {return _photoreceptorsLogSampling->getIrregularLPfilteredInputFrame();};
/**
* @return true if color mode is activated, false if gray levels processing
*/
bool getColorMode(){return _useColorMode;};
/**
*
* @return true if a sufficient number of processed frames has been done since the last parameters update in order to get the stable state (rgime permanent)
*/
inline bool isInitTransitionDone(){if (_ellapsedFramesSinceLastReset<_globalTemporalConstant)return false; return true;};
/**
* find a distance in the image input space when the distance is known in the retina log sampled space...read again if it is not clear enough....sorry, i should sleep
* @param projectedRadiusLength: the distance to image center in the retina log sampled space
* @return the distance to image center in the input image space
*/
inline float getRetinaSamplingBackProjection(const float projectedRadiusLength)
{
if (_photoreceptorsLogSampling)
return (float)_photoreceptorsLogSampling->getOriginalRadiusLength(projectedRadiusLength);
return projectedRadiusLength;
};
/////////////////:
// retina dimensions getters
/**
* @return number of rows of the filter
*/
inline unsigned int getInputNBrows(){if (_photoreceptorsLogSampling) return _photoreceptorsLogSampling->getNBrows();else return _photoreceptorsPrefilter.getNBrows();};
/**
* @return number of columns of the filter
*/
inline unsigned int getInputNBcolumns(){if (_photoreceptorsLogSampling) return _photoreceptorsLogSampling->getNBcolumns();else return _photoreceptorsPrefilter.getNBcolumns();};
/**
* @return number of pixels of the filter
*/
inline unsigned int getInputNBpixels(){if (_photoreceptorsLogSampling) return _photoreceptorsLogSampling->getNBpixels();else return _photoreceptorsPrefilter.getNBpixels();};
/**
* @return the height of the frame output
*/
inline unsigned int getOutputNBrows(){return _photoreceptorsPrefilter.getNBrows();};
/**
* @return the width of the frame output
*/
inline unsigned int getOutputNBcolumns(){return _photoreceptorsPrefilter.getNBcolumns();};
/**
* @return the numbers of output pixels (width*height) of the images used by the object
*/
inline unsigned int getOutputNBpixels(){return _photoreceptorsPrefilter.getNBpixels();};
private:
// processing activation flags
bool _useParvoOutput;
bool _useMagnoOutput;
// filter stability controls
unsigned int _ellapsedFramesSinceLastReset;
unsigned int _globalTemporalConstant;
// private template buffers and related access pointers
std::valarray<float> _retinaParvoMagnoMappedFrame;
std::valarray<float> _retinaParvoMagnoMapCoefTable;
// private objects of the class
BasicRetinaFilter _photoreceptorsPrefilter;
ParvoRetinaFilter _ParvoRetinaFilter;
MagnoRetinaFilter _MagnoRetinaFilter;
RetinaColor _colorEngine;
ImageLogPolProjection *_photoreceptorsLogSampling;
bool _useMinimalMemoryForToneMappingONLY;
bool _normalizeParvoOutput_0_maxOutputValue;
bool _normalizeMagnoOutput_0_maxOutputValue;
float _maxOutputValue;
bool _useColorMode;
// private functions
void _setInitPeriodCount();
void _createHybridTable();
void _processRetinaParvoMagnoMapping();
void _runGrayToneMapping(const std::valarray<float> &grayImageInput, std::valarray<float> &grayImageOutput ,const float PhotoreceptorsCompression=0.6, const float ganglionCellsCompression=0.6);
};
}// end of namespace bioinspired
}// end of namespace cv
#endif /*RETINACLASSES_H_*/
-555
View File
@@ -1,555 +0,0 @@
/*#******************************************************************************
** 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.
**
**
** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
**
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
**
** Creation - enhancement process 2007-2011
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
**
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
** Refer to the following research paper for more information:
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
**
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
** ====> more informations in the above cited Jeanny Heraults's book.
**
** License Agreement
** For Open Source Computer Vision Library
**
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
**
** For Human Visual System tools (bioinspired)
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, 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:
**
** * Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** * 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.
*******************************************************************************/
#ifndef __TEMPLATEBUFFER_HPP__
#define __TEMPLATEBUFFER_HPP__
#include <valarray>
#include <cstdlib>
#include <iostream>
#include <cmath>
//#define __TEMPLATEBUFFERDEBUG //define TEMPLATEBUFFERDEBUG in order to display debug information
namespace cv
{
namespace bioinspired
{
//// If a parallelization method is available then, you should define MAKE_PARALLEL, in the other case, the classical serial code will be used
#define MAKE_PARALLEL
// ==> then include required includes
#ifdef MAKE_PARALLEL
// ==> declare usefull generic tools
template <class type>
class Parallel_clipBufferValues: public cv::ParallelLoopBody
{
private:
type *bufferToClip;
type minValue, maxValue;
public:
Parallel_clipBufferValues(type* bufferToProcess, const type min, const type max)
: bufferToClip(bufferToProcess), minValue(min), maxValue(max){}
virtual void operator()( const cv::Range &r ) const {
register type *inputOutputBufferPTR=bufferToClip+r.start;
for (register int jf = r.start; jf != r.end; ++jf, ++inputOutputBufferPTR)
{
if (*inputOutputBufferPTR>maxValue)
*inputOutputBufferPTR=maxValue;
else if (*inputOutputBufferPTR<minValue)
*inputOutputBufferPTR=minValue;
}
}
};
#endif
/**
* @class TemplateBuffer
* @brief this class is a simple template memory buffer which contains basic functions to get information on or normalize the buffer content
* note that thanks to the parent STL template class "valarray", it is possible to perform easily operations on the full array such as addition, product etc.
* @author Alexandre BENOIT (benoit.alexandre.vision@gmail.com), helped by Gelu IONESCU (gelu.ionescu@lis.inpg.fr)
* creation date: september 2007
*/
template <class type> class TemplateBuffer : public std::valarray<type>
{
public:
/**
* constructor for monodimensional array
* @param dim: the size of the vector
*/
TemplateBuffer(const size_t dim=0)
: std::valarray<type>((type)0, dim)
{
_NBrows=1;
_NBcolumns=dim;
_NBdepths=1;
_NBpixels=dim;
_doubleNBpixels=2*dim;
}
/**
* constructor by copy for monodimensional array
* @param pVal: the pointer to a buffer to copy
* @param dim: the size of the vector
*/
TemplateBuffer(const type* pVal, const size_t dim)
: std::valarray<type>(pVal, dim)
{
_NBrows=1;
_NBcolumns=dim;
_NBdepths=1;
_NBpixels=dim;
_doubleNBpixels=2*dim;
}
/**
* constructor for bidimensional array
* @param dimRows: the size of the vector
* @param dimColumns: the size of the vector
* @param depth: the number of layers of the buffer in its third dimension (3 of color images, 1 for gray images.
*/
TemplateBuffer(const size_t dimRows, const size_t dimColumns, const size_t depth=1)
: std::valarray<type>((type)0, dimRows*dimColumns*depth)
{
#ifdef TEMPLATEBUFFERDEBUG
std::cout<<"TemplateBuffer::TemplateBuffer: new buffer, size="<<dimRows<<", "<<dimColumns<<", "<<depth<<"valarraySize="<<this->size()<<std::endl;
#endif
_NBrows=dimRows;
_NBcolumns=dimColumns;
_NBdepths=depth;
_NBpixels=dimRows*dimColumns;
_doubleNBpixels=2*dimRows*dimColumns;
//_createTableIndex();
#ifdef TEMPLATEBUFFERDEBUG
std::cout<<"TemplateBuffer::TemplateBuffer: construction successful"<<std::endl;
#endif
}
/**
* copy constructor
* @param toCopy
* @return thenconstructed instance
*emplateBuffer(const TemplateBuffer &toCopy)
:_NBrows(toCopy.getNBrows()),_NBcolumns(toCopy.getNBcolumns()),_NBdepths(toCopy.getNBdephs()), _NBpixels(toCopy.getNBpixels()), _doubleNBpixels(toCopy.getNBpixels()*2)
//std::valarray<type>(toCopy)
{
memcpy(Buffer(), toCopy.Buffer(), this->size());
}*/
/**
* destructor
*/
virtual ~TemplateBuffer()
{
#ifdef TEMPLATEBUFFERDEBUG
std::cout<<"~TemplateBuffer"<<std::endl;
#endif
}
/**
* delete the buffer content (set zeros)
*/
inline void setZero(){std::valarray<type>::operator=(0);};//memset(Buffer(), 0, sizeof(type)*_NBpixels);};
/**
* @return the numbers of rows (height) of the images used by the object
*/
inline unsigned int getNBrows(){return (unsigned int)_NBrows;};
/**
* @return the numbers of columns (width) of the images used by the object
*/
inline unsigned int getNBcolumns(){return (unsigned int)_NBcolumns;};
/**
* @return the numbers of pixels (width*height) of the images used by the object
*/
inline unsigned int getNBpixels(){return (unsigned int)_NBpixels;};
/**
* @return the numbers of pixels (width*height) of the images used by the object
*/
inline unsigned int getDoubleNBpixels(){return (unsigned int)_doubleNBpixels;};
/**
* @return the numbers of depths (3rd dimension: 1 for gray images, 3 for rgb images) of the images used by the object
*/
inline unsigned int getDepthSize(){return (unsigned int)_NBdepths;};
/**
* resize the buffer and recompute table index etc.
*/
void resizeBuffer(const size_t dimRows, const size_t dimColumns, const size_t depth=1)
{
this->resize(dimRows*dimColumns*depth);
_NBrows=dimRows;
_NBcolumns=dimColumns;
_NBdepths=depth;
_NBpixels=dimRows*dimColumns;
_doubleNBpixels=2*dimRows*dimColumns;
}
inline TemplateBuffer<type> & operator=(const std::valarray<type> &b)
{
//std::cout<<"TemplateBuffer<type> & operator= affect vector: "<<std::endl;
std::valarray<type>::operator=(b);
return *this;
}
inline TemplateBuffer<type> & operator=(const type &b)
{
//std::cout<<"TemplateBuffer<type> & operator= affect value: "<<b<<std::endl;
std::valarray<type>::operator=(b);
return *this;
}
/* inline const type &operator[](const unsigned int &b)
{
return (*this)[b];
}
*/
/**
* @return the buffer adress in non const mode
*/
inline type* Buffer() { return &(*this)[0]; }
///////////////////////////////////////////////////////
// Standard Image manipulation functions
/**
* standard 0 to 255 image normalization function
* @param inputOutputBuffer: the image to be normalized (rewrites the input), if no parameter, then, the built in buffer reachable by getOutput() function is normalized
* @param nbPixels: specifies the number of pixel on which the normalization should be performed, if 0, then all pixels specified in the constructor are processed
* @param maxOutputValue: the maximum output value
*/
static void normalizeGrayOutput_0_maxOutputValue(type *inputOutputBuffer, const size_t nbPixels, const type maxOutputValue=(type)255.0);
/**
* standard 0 to 255 image normalization function
* @param inputOutputBuffer: the image to be normalized (rewrites the input), if no parameter, then, the built in buffer reachable by getOutput() function is normalized
* @param nbPixels: specifies the number of pixel on which the normalization should be performed, if 0, then all pixels specified in the constructor are processed
* @param maxOutputValue: the maximum output value
*/
void normalizeGrayOutput_0_maxOutputValue(const type maxOutputValue=(type)255.0){normalizeGrayOutput_0_maxOutputValue(this->Buffer(), this->size(), maxOutputValue);};
/**
* sigmoide image normalization function (saturates min and max values)
* @param meanValue: specifies the mean value of th pixels to be processed
* @param sensitivity: strenght of the sigmoide
* @param inputPicture: the image to be normalized if no parameter, then, the built in buffer reachable by getOutput() function is normalized
* @param outputBuffer: the ouput buffer on which the result is writed, if no parameter, then, the built in buffer reachable by getOutput() function is normalized
* @param maxOutputValue: the maximum output value
*/
static void normalizeGrayOutputCentredSigmoide(const type meanValue, const type sensitivity, const type maxOutputValue, type *inputPicture, type *outputBuffer, const unsigned int nbPixels);
/**
* sigmoide image normalization function on the current buffer (saturates min and max values)
* @param meanValue: specifies the mean value of th pixels to be processed
* @param sensitivity: strenght of the sigmoide
* @param maxOutputValue: the maximum output value
*/
inline void normalizeGrayOutputCentredSigmoide(const type meanValue=(type)0.0, const type sensitivity=(type)2.0, const type maxOutputValue=(type)255.0){ (void)maxOutputValue; normalizeGrayOutputCentredSigmoide(meanValue, sensitivity, 255.0, this->Buffer(), this->Buffer(), this->getNBpixels());};
/**
* sigmoide image normalization function (saturates min and max values), in this function, the sigmoide is centered on low values (high saturation of the medium and high values
* @param inputPicture: the image to be normalized if no parameter, then, the built in buffer reachable by getOutput() function is normalized
* @param outputBuffer: the ouput buffer on which the result is writed, if no parameter, then, the built in buffer reachable by getOutput() function is normalized
* @param sensitivity: strenght of the sigmoide
* @param maxOutputValue: the maximum output value
*/
void normalizeGrayOutputNearZeroCentreredSigmoide(type *inputPicture=(type*)NULL, type *outputBuffer=(type*)NULL, const type sensitivity=(type)40, const type maxOutputValue=(type)255.0);
/**
* center and reduct the image (image-mean)/std
* @param inputOutputBuffer: the image to be normalized if no parameter, the result is rewrited on it
*/
void centerReductImageLuminance(type *inputOutputBuffer=(type*)NULL);
/**
* @return standard deviation of the buffer
*/
double getStandardDeviation()
{
double standardDeviation=0;
double meanValue=getMean();
type *bufferPTR=Buffer();
for (unsigned int i=0;i<this->size();++i)
{
double diff=(*(bufferPTR++)-meanValue);
standardDeviation+=diff*diff;
}
return std::sqrt(standardDeviation/this->size());
};
/**
* Clip buffer histogram
* @param minRatio: the minimum ratio of the lower pixel values, range=[0,1] and lower than maxRatio
* @param maxRatio: the aximum ratio of the higher pixel values, range=[0,1] and higher than minRatio
*/
void clipHistogram(double minRatio, double maxRatio, double maxOutputValue)
{
if (minRatio>=maxRatio)
{
std::cerr<<"TemplateBuffer::clipHistogram: minRatio must be inferior to maxRatio, buffer unchanged"<<std::endl;
return;
}
/* minRatio=min(max(minRatio, 1.0),0.0);
maxRatio=max(max(maxRatio, 0.0),1.0);
*/
// find the pixel value just above the threshold
const double maxThreshold=this->max()*maxRatio;
const double minThreshold=(this->max()-this->min())*minRatio+this->min();
type *bufferPTR=this->Buffer();
double deltaH=maxThreshold;
double deltaL=maxThreshold;
double updatedHighValue=maxThreshold;
double updatedLowValue=maxThreshold;
for (unsigned int i=0;i<this->size();++i)
{
double curentValue=(double)*(bufferPTR++);
// updating "closest to the high threshold" pixel value
double highValueTest=maxThreshold-curentValue;
if (highValueTest>0)
{
if (deltaH>highValueTest)
{
deltaH=highValueTest;
updatedHighValue=curentValue;
}
}
// updating "closest to the low threshold" pixel value
double lowValueTest=curentValue-minThreshold;
if (lowValueTest>0)
{
if (deltaL>lowValueTest)
{
deltaL=lowValueTest;
updatedLowValue=curentValue;
}
}
}
std::cout<<"Tdebug"<<std::endl;
std::cout<<"deltaL="<<deltaL<<", deltaH="<<deltaH<<std::endl;
std::cout<<"this->max()"<<this->max()<<"maxThreshold="<<maxThreshold<<"updatedHighValue="<<updatedHighValue<<std::endl;
std::cout<<"this->min()"<<this->min()<<"minThreshold="<<minThreshold<<"updatedLowValue="<<updatedLowValue<<std::endl;
// clipping values outside than the updated thresholds
bufferPTR=this->Buffer();
#ifdef MAKE_PARALLEL // call the TemplateBuffer multitreaded clipping method
parallel_for_(cv::Range(0,this->size()), Parallel_clipBufferValues<type>(bufferPTR, updatedLowValue, updatedHighValue));
#else
for (unsigned int i=0;i<this->size();++i, ++bufferPTR)
{
if (*bufferPTR<updatedLowValue)
*bufferPTR=updatedLowValue;
else if (*bufferPTR>updatedHighValue)
*bufferPTR=updatedHighValue;
}
#endif
normalizeGrayOutput_0_maxOutputValue(this->Buffer(), this->size(), maxOutputValue);
}
/**
* @return the mean value of the vector
*/
inline double getMean(){return this->sum()/this->size();};
protected:
size_t _NBrows;
size_t _NBcolumns;
size_t _NBdepths;
size_t _NBpixels;
size_t _doubleNBpixels;
// utilities
static type _abs(const type x);
};
///////////////////////////////////////////////////////////////////////
/// normalize output between 0 and 255, can be applied on images of different size that the declared size if nbPixels parameters is setted up;
template <class type>
void TemplateBuffer<type>::normalizeGrayOutput_0_maxOutputValue(type *inputOutputBuffer, const size_t processedPixels, const type maxOutputValue)
{
type maxValue=inputOutputBuffer[0], minValue=inputOutputBuffer[0];
// get the min and max value
register type *inputOutputBufferPTR=inputOutputBuffer;
for (register size_t j = 0; j<processedPixels; ++j)
{
type pixValue = *(inputOutputBufferPTR++);
if (maxValue < pixValue)
maxValue = pixValue;
else if (minValue > pixValue)
minValue = pixValue;
}
// change the range of the data to 0->255
type factor = maxOutputValue/(maxValue-minValue);
type offset = (type)(-minValue*factor);
inputOutputBufferPTR=inputOutputBuffer;
for (register size_t j = 0; j < processedPixels; ++j, ++inputOutputBufferPTR)
*inputOutputBufferPTR=*(inputOutputBufferPTR)*factor+offset;
}
// normalize data with a sigmoide close to 0 (saturates values for those superior to 0)
template <class type>
void TemplateBuffer<type>::normalizeGrayOutputNearZeroCentreredSigmoide(type *inputBuffer, type *outputBuffer, const type sensitivity, const type maxOutputValue)
{
if (inputBuffer==NULL)
inputBuffer=Buffer();
if (outputBuffer==NULL)
outputBuffer=Buffer();
type X0cube=sensitivity*sensitivity*sensitivity;
register type *inputBufferPTR=inputBuffer;
register type *outputBufferPTR=outputBuffer;
for (register size_t j = 0; j < _NBpixels; ++j, ++inputBufferPTR)
{
type currentCubeLuminance=*inputBufferPTR**inputBufferPTR**inputBufferPTR;
*(outputBufferPTR++)=maxOutputValue*currentCubeLuminance/(currentCubeLuminance+X0cube);
}
}
// normalize and adjust luminance with a centered to 128 sigmode
template <class type>
void TemplateBuffer<type>::normalizeGrayOutputCentredSigmoide(const type meanValue, const type sensitivity, const type maxOutputValue, type *inputBuffer, type *outputBuffer, const unsigned int nbPixels)
{
if (sensitivity==1.0)
{
std::cerr<<"TemplateBuffer::TemplateBuffer<type>::normalizeGrayOutputCentredSigmoide error: 2nd parameter (sensitivity) must not equal 0, copying original data..."<<std::endl;
memcpy(outputBuffer, inputBuffer, sizeof(type)*nbPixels);
return;
}
type X0=maxOutputValue/(sensitivity-(type)1.0);
register type *inputBufferPTR=inputBuffer;
register type *outputBufferPTR=outputBuffer;
for (register size_t j = 0; j < nbPixels; ++j, ++inputBufferPTR)
*(outputBufferPTR++)=(meanValue+(meanValue+X0)*(*(inputBufferPTR)-meanValue)/(_abs(*(inputBufferPTR)-meanValue)+X0));
}
// center and reduct the image (image-mean)/std
template <class type>
void TemplateBuffer<type>::centerReductImageLuminance(type *inputOutputBuffer)
{
// if outputBuffer unsassigned, the rewrite the buffer
if (inputOutputBuffer==NULL)
inputOutputBuffer=Buffer();
type meanValue=0, stdValue=0;
// compute mean value
for (register size_t j = 0; j < _NBpixels; ++j)
meanValue+=inputOutputBuffer[j];
meanValue/=((type)_NBpixels);
// compute std value
register type *inputOutputBufferPTR=inputOutputBuffer;
for (size_t index=0;index<_NBpixels;++index)
{
type inputMinusMean=*(inputOutputBufferPTR++)-meanValue;
stdValue+=inputMinusMean*inputMinusMean;
}
stdValue=std::sqrt(stdValue/((type)_NBpixels));
// adjust luminance in regard of mean and std value;
inputOutputBufferPTR=inputOutputBuffer;
for (size_t index=0;index<_NBpixels;++index, ++inputOutputBufferPTR)
*inputOutputBufferPTR=(*(inputOutputBufferPTR)-meanValue)/stdValue;
}
template <class type>
type TemplateBuffer<type>::_abs(const type x)
{
if (x>0)
return x;
else
return -x;
}
template < >
inline int TemplateBuffer<int>::_abs(const int x)
{
return std::abs(x);
}
template < >
inline double TemplateBuffer<double>::_abs(const double x)
{
return std::fabs(x);
}
template < >
inline float TemplateBuffer<float>::_abs(const float x)
{
return std::fabs(x);
}
}// end of namespace bioinspired
}// end of namespace cv
#endif
-3
View File
@@ -1,3 +0,0 @@
#include "test_precomp.hpp"
CV_TEST_MAIN("cv")
-16
View File
@@ -1,16 +0,0 @@
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wmissing-declarations"
# if defined __clang__ || defined __APPLE__
# pragma GCC diagnostic ignored "-Wmissing-prototypes"
# pragma GCC diagnostic ignored "-Wextra"
# endif
#endif
#ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__
#include "opencv2/ts.hpp"
#include "opencv2/bioinspired.hpp"
#include <iostream>
#endif
@@ -1,164 +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) 2010-2013, Multicoreware, Inc., all rights reserved.
// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
// Peng Xiao, pengxiao@multicorewareinc.com
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other oclMaterials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors as is and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
#include "opencv2/opencv_modules.hpp"
#include "opencv2/bioinspired.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core/ocl.hpp" // cv::ocl::haveOpenCL
#if defined(HAVE_OPENCV_OCL)
#include "opencv2/ocl.hpp"
#define RETINA_ITERATIONS 5
static double checkNear(const cv::Mat &m1, const cv::Mat &m2)
{
return cv::norm(m1, m2, cv::NORM_INF);
}
#define PARAM_TEST_CASE(name, ...) struct name : testing::TestWithParam< std::tr1::tuple< __VA_ARGS__ > >
#define GET_PARAM(k) std::tr1::get< k >(GetParam())
static int oclInit = false;
static int oclAvailable = false;
PARAM_TEST_CASE(Retina_OCL, bool, int, bool, double, double)
{
bool colorMode;
int colorSamplingMethod;
bool useLogSampling;
double reductionFactor;
double samplingStrength;
virtual void SetUp()
{
colorMode = GET_PARAM(0);
colorSamplingMethod = GET_PARAM(1);
useLogSampling = GET_PARAM(2);
reductionFactor = GET_PARAM(3);
samplingStrength = GET_PARAM(4);
if (!oclInit)
{
if (cv::ocl::haveOpenCL())
{
try
{
const cv::ocl::DeviceInfo& dev = cv::ocl::Context::getContext()->getDeviceInfo();
std::cout << "Device name:" << dev.deviceName << std::endl;
oclAvailable = true;
}
catch (...)
{
std::cout << "Device name: N/A" << std::endl;
}
}
oclInit = true;
}
}
};
TEST_P(Retina_OCL, Accuracy)
{
if (!oclAvailable)
{
std::cout << "SKIP test" << std::endl;
return;
}
using namespace cv;
Mat input = imread(cvtest::TS::ptr()->get_data_path() + "shared/lena.png", colorMode);
CV_Assert(!input.empty());
ocl::oclMat ocl_input(input);
Ptr<bioinspired::Retina> ocl_retina = bioinspired::createRetina_OCL(
input.size(),
colorMode,
colorSamplingMethod,
useLogSampling,
reductionFactor,
samplingStrength);
Ptr<bioinspired::Retina> gold_retina = bioinspired::createRetina(
input.size(),
colorMode,
colorSamplingMethod,
useLogSampling,
reductionFactor,
samplingStrength);
Mat gold_parvo;
Mat gold_magno;
ocl::oclMat ocl_parvo;
ocl::oclMat ocl_magno;
for(int i = 0; i < RETINA_ITERATIONS; i ++)
{
ocl_retina->run(ocl_input);
gold_retina->run(input);
gold_retina->getParvo(gold_parvo);
gold_retina->getMagno(gold_magno);
ocl_retina->getParvo(ocl_parvo);
ocl_retina->getMagno(ocl_magno);
int eps = colorMode ? 2 : 1;
EXPECT_LE(checkNear(gold_parvo, (Mat)ocl_parvo), eps);
EXPECT_LE(checkNear(gold_magno, (Mat)ocl_magno), eps);
}
}
INSTANTIATE_TEST_CASE_P(Contrib, Retina_OCL, testing::Combine(
testing::Bool(),
testing::Values((int)cv::bioinspired::RETINA_COLOR_BAYER),
testing::Values(false/*,true*/),
testing::Values(1.0, 0.5),
testing::Values(10.0, 5.0)));
#endif
@@ -756,6 +756,7 @@ They are
:math:`[R_1, -t]`,
:math:`[R_2, t]`,
:math:`[R_2, -t]`.
By decomposing ``E``, you can only get the direction of the translation, so the function returns unit ``t``.
recoverPose
+2 -2
View File
@@ -80,7 +80,7 @@ namespace cv
class LMSolverImpl : public LMSolver
{
public:
LMSolverImpl() : maxIters(100) { init(); };
LMSolverImpl() : maxIters(100) { init(); }
LMSolverImpl(const Ptr<LMSolver::Callback>& _cb, int _maxIters) : cb(_cb), maxIters(_maxIters) { init(); }
void init()
@@ -215,7 +215,7 @@ CV_INIT_ALGORITHM(LMSolverImpl, "LMSolver",
obj.info()->addParam(obj, "epsx", obj.epsx);
obj.info()->addParam(obj, "epsf", obj.epsf);
obj.info()->addParam(obj, "maxIters", obj.maxIters);
obj.info()->addParam(obj, "printInterval", obj.printInterval));
obj.info()->addParam(obj, "printInterval", obj.printInterval))
Ptr<LMSolver> createLMSolver(const Ptr<LMSolver::Callback>& cb, int maxIters)
{
+2 -2
View File
@@ -386,11 +386,11 @@ public:
CV_INIT_ALGORITHM(RANSACPointSetRegistrator, "PointSetRegistrator.RANSAC",
obj.info()->addParam(obj, "threshold", obj.threshold);
obj.info()->addParam(obj, "confidence", obj.confidence);
obj.info()->addParam(obj, "maxIters", obj.maxIters));
obj.info()->addParam(obj, "maxIters", obj.maxIters))
CV_INIT_ALGORITHM(LMeDSPointSetRegistrator, "PointSetRegistrator.LMeDS",
obj.info()->addParam(obj, "confidence", obj.confidence);
obj.info()->addParam(obj, "maxIters", obj.maxIters));
obj.info()->addParam(obj, "maxIters", obj.maxIters))
Ptr<PointSetRegistrator> createRANSACPointSetRegistrator(const Ptr<PointSetRegistrator::Callback>& _cb,
int _modelPoints, double _threshold,
+14 -14
View File
@@ -290,8 +290,8 @@ int CV_CameraCalibrationTest::compare(double* val, double* ref_val, int len,
void CV_CameraCalibrationTest::run( int start_from )
{
int code = cvtest::TS::OK;
char filepath[200];
char filename[200];
cv::String filepath;
cv::String filename;
CvSize imageSize;
CvSize etalonSize;
@@ -337,12 +337,12 @@ void CV_CameraCalibrationTest::run( int start_from )
int progress = 0;
int values_read = -1;
sprintf( filepath, "%scameracalibration/", ts->get_data_path().c_str() );
sprintf( filename, "%sdatafiles.txt", filepath );
datafile = fopen( filename, "r" );
filepath = cv::format("%scv/cameracalibration/", ts->get_data_path().c_str() );
filename = cv::format("%sdatafiles.txt", filepath.c_str() );
datafile = fopen( filename.c_str(), "r" );
if( datafile == 0 )
{
ts->printf( cvtest::TS::LOG, "Could not open file with list of test files: %s\n", filename );
ts->printf( cvtest::TS::LOG, "Could not open file with list of test files: %s\n", filename.c_str() );
code = cvtest::TS::FAIL_MISSING_TEST_DATA;
goto _exit_;
}
@@ -354,15 +354,15 @@ void CV_CameraCalibrationTest::run( int start_from )
{
values_read = fscanf(datafile,"%s",i_dat_file);
CV_Assert(values_read == 1);
sprintf(filename, "%s%s", filepath, i_dat_file);
file = fopen(filename,"r");
filename = cv::format("%s%s", filepath.c_str(), i_dat_file);
file = fopen(filename.c_str(),"r");
ts->update_context( this, currTest, true );
if( file == 0 )
{
ts->printf( cvtest::TS::LOG,
"Can't open current test file: %s\n",filename);
"Can't open current test file: %s\n",filename.c_str());
if( numTests == 1 )
{
code = cvtest::TS::FAIL_MISSING_TEST_DATA;
@@ -1382,16 +1382,16 @@ void CV_StereoCalibrationTest::run( int )
for(int testcase = 1; testcase <= ntests; testcase++)
{
char filepath[1000];
cv::String filepath;
char buf[1000];
sprintf( filepath, "%sstereo/case%d/stereo_calib.txt", ts->get_data_path().c_str(), testcase );
f = fopen(filepath, "rt");
filepath = cv::format("%scv/stereo/case%d/stereo_calib.txt", ts->get_data_path().c_str(), testcase );
f = fopen(filepath.c_str(), "rt");
Size patternSize;
vector<string> imglist;
if( !f || !fgets(buf, sizeof(buf)-3, f) || sscanf(buf, "%d%d", &patternSize.width, &patternSize.height) != 2 )
{
ts->printf( cvtest::TS::LOG, "The file %s can not be opened or has invalid content\n", filepath );
ts->printf( cvtest::TS::LOG, "The file %s can not be opened or has invalid content\n", filepath.c_str() );
ts->set_failed_test_info( f ? cvtest::TS::FAIL_INVALID_TEST_DATA : cvtest::TS::FAIL_MISSING_TEST_DATA );
return;
}
@@ -1405,7 +1405,7 @@ void CV_StereoCalibrationTest::run( int )
buf[--len] = '\0';
if( buf[0] == '#')
continue;
sprintf(filepath, "%sstereo/case%d/%s", ts->get_data_path().c_str(), testcase, buf );
filepath = cv::format("%scv/stereo/case%d/%s", ts->get_data_path().c_str(), testcase, buf );
imglist.push_back(string(filepath));
}
fclose(f);
@@ -55,7 +55,7 @@ public:
~CV_CameraCalibrationBadArgTest() {}
protected:
void run(int);
void run_func(void) {};
void run_func(void) {}
const static int M = 1;
@@ -334,7 +334,7 @@ public:
CV_Rodrigues2BadArgTest() {}
~CV_Rodrigues2BadArgTest() {}
protected:
void run_func(void) {};
void run_func(void) {}
struct C_Caller
{
@@ -459,10 +459,10 @@ public:
Size imsSize(800, 600);
camMat << 300.f, 0.f, imsSize.width/2.f, 0, 300.f, imsSize.height/2.f, 0.f, 0.f, 1.f;
distCoeffs << 1.2f, 0.2f, 0.f, 0.f, 0.f;
};
~CV_ProjectPoints2BadArgTest() {} ;
}
~CV_ProjectPoints2BadArgTest() {}
protected:
void run_func(void) {};
void run_func(void) {}
Mat_<float> camMat;
Mat_<float> distCoeffs;
@@ -34,7 +34,7 @@ private:
Mat rvec, tvec;
};
};
}
#endif
+3 -3
View File
@@ -185,13 +185,13 @@ void CV_ChessboardDetectorTest::run_batch( const string& filename )
switch( pattern )
{
case CHESSBOARD:
folder = string(ts->get_data_path()) + "cameracalibration/";
folder = string(ts->get_data_path()) + "cv/cameracalibration/";
break;
case CIRCLES_GRID:
folder = string(ts->get_data_path()) + "cameracalibration/circles/";
folder = string(ts->get_data_path()) + "cv/cameracalibration/circles/";
break;
case ASYMMETRIC_CIRCLES_GRID:
folder = string(ts->get_data_path()) + "cameracalibration/asymmetric_circles/";
folder = string(ts->get_data_path()) + "cv/cameracalibration/asymmetric_circles/";
break;
}
@@ -62,8 +62,8 @@ void CV_ChessboardDetectorTimingTest::run( int start_from )
int code = cvtest::TS::OK;
/* test parameters */
char filepath[1000];
char filename[1000];
std::string filepath;
std::string filename;
CvMat* _v = 0;
CvPoint2D32f* v;
@@ -75,9 +75,9 @@ void CV_ChessboardDetectorTimingTest::run( int start_from )
int idx, max_idx;
int progress = 0;
sprintf( filepath, "%scameracalibration/", ts->get_data_path().c_str() );
sprintf( filename, "%schessboard_timing_list.dat", filepath );
CvFileStorage* fs = cvOpenFileStorage( filename, 0, CV_STORAGE_READ );
filepath = cv::format("%scv/cameracalibration/", ts->get_data_path().c_str() );
filename = cv::format("%schessboard_timing_list.dat", filepath.c_str() );
CvFileStorage* fs = cvOpenFileStorage( filename.c_str(), 0, CV_STORAGE_READ );
CvFileNode* board_list = fs ? cvGetFileNodeByName( fs, 0, "boards" ) : 0;
if( !fs || !board_list || !CV_NODE_IS_SEQ(board_list->tag) ||
@@ -105,14 +105,14 @@ void CV_ChessboardDetectorTimingTest::run( int start_from )
ts->update_context( this, idx-1, true );
/* read the image */
sprintf( filename, "%s%s", filepath, imgname );
filename = cv::format("%s%s", filepath.c_str(), imgname );
cv::Mat img2 = cv::imread( filename );
img = img2;
if( img2.empty() )
{
ts->printf( cvtest::TS::LOG, "one of chessboard images can't be read: %s\n", filename );
ts->printf( cvtest::TS::LOG, "one of chessboard images can't be read: %s\n", filename.c_str() );
if( max_idx == 1 )
{
code = cvtest::TS::FAIL_MISSING_TEST_DATA;
+1 -1
View File
@@ -1,3 +1,3 @@
#include "test_precomp.hpp"
CV_TEST_MAIN("cv")
CV_TEST_MAIN("")
+1 -1
View File
@@ -398,7 +398,7 @@ protected:
void CV_StereoMatchingTest::run(int)
{
string dataPath = ts->get_data_path();
string dataPath = ts->get_data_path() + "cv/";
string algorithmName = name;
assert( !algorithmName.empty() );
if( dataPath.empty() )
+2 -2
View File
@@ -523,7 +523,7 @@ public:
// Initializes a LDA with num_components (default 0) and specifies how
// samples are aligned (default dataAsRow=true).
LDA(int num_components = 0) :
_num_components(num_components) {};
_num_components(num_components) { }
// Initializes and performs a Discriminant Analysis with Fisher's
// Optimization Criterion on given data in src and corresponding labels
@@ -561,7 +561,7 @@ public:
Mat reconstruct(InputArray src);
// Returns the eigenvectors of this LDA.
Mat eigenvectors() const { return _eigenvectors; };
Mat eigenvectors() const { return _eigenvectors; }
// Returns the eigenvalues of this LDA.
Mat eigenvalues() const { return _eigenvalues; }
+9 -9
View File
@@ -55,7 +55,7 @@ void CvAdaptiveSkinDetector::initData(IplImage *src, int widthDivider, int heigh
imgGrayFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
imgLastGrayFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
imgHSVFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 3);
};
}
CvAdaptiveSkinDetector::CvAdaptiveSkinDetector(int samplingDivider, int morphingMethod)
{
@@ -80,7 +80,7 @@ CvAdaptiveSkinDetector::CvAdaptiveSkinDetector(int samplingDivider, int morphing
imgLastGrayFrame = NULL;
imgSaturationFrame = NULL;
imgHSVFrame = NULL;
};
}
CvAdaptiveSkinDetector::~CvAdaptiveSkinDetector()
{
@@ -93,7 +93,7 @@ CvAdaptiveSkinDetector::~CvAdaptiveSkinDetector()
cvReleaseImage(&imgGrayFrame);
cvReleaseImage(&imgLastGrayFrame);
cvReleaseImage(&imgHSVFrame);
};
}
void CvAdaptiveSkinDetector::process(IplImage *inputBGRImage, IplImage *outputHueMask)
{
@@ -190,7 +190,7 @@ void CvAdaptiveSkinDetector::process(IplImage *inputBGRImage, IplImage *outputHu
if (outputHueMask != NULL)
cvCopy(imgFilteredFrame, outputHueMask);
};
}
//------------------------- Histogram for Adaptive Skin Detector -------------------------//
@@ -202,12 +202,12 @@ CvAdaptiveSkinDetector::Histogram::Histogram()
float *ranges[] = { range };
fHistogram = cvCreateHist(1, histogramSize, CV_HIST_ARRAY, ranges, 1);
cvClearHist(fHistogram);
};
}
CvAdaptiveSkinDetector::Histogram::~Histogram()
{
cvReleaseHist(&fHistogram);
};
}
int CvAdaptiveSkinDetector::Histogram::findCoverageIndex(double surfaceToCover, int defaultValue)
{
@@ -221,7 +221,7 @@ int CvAdaptiveSkinDetector::Histogram::findCoverageIndex(double surfaceToCover,
}
}
return defaultValue;
};
}
void CvAdaptiveSkinDetector::Histogram::findCurveThresholds(int &x1, int &x2, double percent)
{
@@ -244,7 +244,7 @@ void CvAdaptiveSkinDetector::Histogram::findCurveThresholds(int &x1, int &x2, do
x2 = GSD_HUE_UT;
else
x2 += GSD_HUE_LT;
};
}
void CvAdaptiveSkinDetector::Histogram::mergeWith(CvAdaptiveSkinDetector::Histogram *source, double weight)
{
@@ -285,4 +285,4 @@ void CvAdaptiveSkinDetector::Histogram::mergeWith(CvAdaptiveSkinDetector::Histog
}
}
}
};
}
+4 -4
View File
@@ -940,7 +940,7 @@ static void fjac(int /*i*/, int /*j*/, CvMat *point_params, CvMat* cam_params, C
#endif
};
}
static void func(int /*i*/, int /*j*/, CvMat *point_params, CvMat* cam_params, CvMat* estim, void* /*data*/) {
//just do projections
CvMat _Mi;
@@ -979,17 +979,17 @@ static void func(int /*i*/, int /*j*/, CvMat *point_params, CvMat* cam_params, C
cvTranspose( _mp2, estim );
cvReleaseMat( &_mp );
cvReleaseMat( &_mp2 );
};
}
static void fjac_new(int i, int j, Mat& point_params, Mat& cam_params, Mat& A, Mat& B, void* data) {
CvMat _point_params = point_params, _cam_params = cam_params, _Al = A, _Bl = B;
fjac(i,j, &_point_params, &_cam_params, &_Al, &_Bl, data);
};
}
static void func_new(int i, int j, Mat& point_params, Mat& cam_params, Mat& estim, void* data) {
CvMat _point_params = point_params, _cam_params = cam_params, _estim = estim;
func(i,j,&_point_params,&_cam_params,&_estim,data);
};
}
void LevMarqSparse::bundleAdjust( std::vector<Point3d>& points, //positions of points in global coordinate system (input and output)
const std::vector<std::vector<Point2d> >& imagePoints, //projections of 3d points for every camera
+4 -4
View File
@@ -833,7 +833,7 @@ void LBPH::predict(InputArray _src, int &minClass, double &minDist) const {
minDist = DBL_MAX;
minClass = -1;
for(size_t sampleIdx = 0; sampleIdx < _histograms.size(); sampleIdx++) {
double dist = compareHist(_histograms[sampleIdx], query, HISTCMP_CHISQR);
double dist = compareHist(_histograms[sampleIdx], query, HISTCMP_CHISQR_ALT);
if((dist < minDist) && (dist < _threshold)) {
minDist = dist;
minClass = _labels.at<int>((int) sampleIdx);
@@ -872,7 +872,7 @@ CV_INIT_ALGORITHM(Eigenfaces, "FaceRecognizer.Eigenfaces",
obj.info()->addParam(obj, "labels", obj._labels, true);
obj.info()->addParam(obj, "eigenvectors", obj._eigenvectors, true);
obj.info()->addParam(obj, "eigenvalues", obj._eigenvalues, true);
obj.info()->addParam(obj, "mean", obj._mean, true));
obj.info()->addParam(obj, "mean", obj._mean, true))
CV_INIT_ALGORITHM(Fisherfaces, "FaceRecognizer.Fisherfaces",
obj.info()->addParam(obj, "ncomponents", obj._num_components);
@@ -881,7 +881,7 @@ CV_INIT_ALGORITHM(Fisherfaces, "FaceRecognizer.Fisherfaces",
obj.info()->addParam(obj, "labels", obj._labels, true);
obj.info()->addParam(obj, "eigenvectors", obj._eigenvectors, true);
obj.info()->addParam(obj, "eigenvalues", obj._eigenvalues, true);
obj.info()->addParam(obj, "mean", obj._mean, true));
obj.info()->addParam(obj, "mean", obj._mean, true))
CV_INIT_ALGORITHM(LBPH, "FaceRecognizer.LBPH",
obj.info()->addParam(obj, "radius", obj._radius);
@@ -890,7 +890,7 @@ CV_INIT_ALGORITHM(LBPH, "FaceRecognizer.LBPH",
obj.info()->addParam(obj, "grid_y", obj._grid_y);
obj.info()->addParam(obj, "threshold", obj._threshold);
obj.info()->addParam(obj, "histograms", obj._histograms, true);
obj.info()->addParam(obj, "labels", obj._labels, true));
obj.info()->addParam(obj, "labels", obj._labels, true))
bool initModule_contrib()
{
+41 -41
View File
@@ -41,7 +41,7 @@ CvFuzzyPoint::CvFuzzyPoint(double _x, double _y)
{
x = _x;
y = _y;
};
}
bool CvFuzzyCurve::between(double x, double x1, double x2)
{
@@ -51,37 +51,37 @@ bool CvFuzzyCurve::between(double x, double x1, double x2)
return true;
return false;
};
}
CvFuzzyCurve::CvFuzzyCurve()
{
value = 0;
};
}
CvFuzzyCurve::~CvFuzzyCurve()
{
// nothing to do
};
}
void CvFuzzyCurve::setCentre(double _centre)
{
centre = _centre;
};
}
double CvFuzzyCurve::getCentre()
{
return centre;
};
}
void CvFuzzyCurve::clear()
{
points.clear();
};
}
void CvFuzzyCurve::addPoint(double x, double y)
{
points.push_back(CvFuzzyPoint(x, y));
};
}
double CvFuzzyCurve::calcValue(double param)
{
@@ -102,41 +102,41 @@ double CvFuzzyCurve::calcValue(double param)
}
}
return 0;
};
}
double CvFuzzyCurve::getValue()
{
return value;
};
}
void CvFuzzyCurve::setValue(double _value)
{
value = _value;
};
}
CvFuzzyFunction::CvFuzzyFunction()
{
// nothing to do
};
}
CvFuzzyFunction::~CvFuzzyFunction()
{
curves.clear();
};
}
void CvFuzzyFunction::addCurve(CvFuzzyCurve *curve, double value)
{
curves.push_back(*curve);
curve->setValue(value);
};
}
void CvFuzzyFunction::resetValues()
{
int numCurves = (int)curves.size();
for (int i = 0; i < numCurves; i++)
curves[i].setValue(0);
};
}
double CvFuzzyFunction::calcValue()
{
@@ -153,7 +153,7 @@ double CvFuzzyFunction::calcValue()
return s1/s2;
else
return 0;
};
}
CvFuzzyCurve *CvFuzzyFunction::newCurve()
{
@@ -161,14 +161,14 @@ CvFuzzyCurve *CvFuzzyFunction::newCurve()
c = new CvFuzzyCurve();
addCurve(c);
return c;
};
}
CvFuzzyRule::CvFuzzyRule()
{
fuzzyInput1 = NULL;
fuzzyInput2 = NULL;
fuzzyOutput = NULL;
};
}
CvFuzzyRule::~CvFuzzyRule()
{
@@ -180,14 +180,14 @@ CvFuzzyRule::~CvFuzzyRule()
if (fuzzyOutput != NULL)
delete fuzzyOutput;
};
}
void CvFuzzyRule::setRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1)
{
fuzzyInput1 = c1;
fuzzyInput2 = c2;
fuzzyOutput = o1;
};
}
double CvFuzzyRule::calcValue(double param1, double param2)
{
@@ -203,31 +203,31 @@ double CvFuzzyRule::calcValue(double param1, double param2)
}
else
return v1;
};
}
CvFuzzyCurve *CvFuzzyRule::getOutputCurve()
{
return fuzzyOutput;
};
}
CvFuzzyController::CvFuzzyController()
{
// nothing to do
};
}
CvFuzzyController::~CvFuzzyController()
{
int size = (int)rules.size();
for(int i = 0; i < size; i++)
delete rules[i];
};
}
void CvFuzzyController::addRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1)
{
CvFuzzyRule *f = new CvFuzzyRule();
rules.push_back(f);
f->setRule(c1, c2, o1);
};
}
double CvFuzzyController::calcOutput(double param1, double param2)
{
@@ -243,7 +243,7 @@ double CvFuzzyController::calcOutput(double param1, double param2)
}
v = list.calcValue();
return v;
};
}
CvFuzzyMeanShiftTracker::FuzzyResizer::FuzzyResizer()
{
@@ -299,12 +299,12 @@ CvFuzzyMeanShiftTracker::FuzzyResizer::FuzzyResizer()
fuzzyController.addRule(i1L, NULL, oS);
fuzzyController.addRule(i1M, NULL, oZE);
fuzzyController.addRule(i1H, NULL, oE);
};
}
int CvFuzzyMeanShiftTracker::FuzzyResizer::calcOutput(double edgeDensity, double density)
{
return (int)fuzzyController.calcOutput(edgeDensity, density);
};
}
CvFuzzyMeanShiftTracker::SearchWindow::SearchWindow()
{
@@ -329,7 +329,7 @@ CvFuzzyMeanShiftTracker::SearchWindow::SearchWindow()
depthLow = 0;
depthHigh = 0;
fuzzyResizer = NULL;
};
}
CvFuzzyMeanShiftTracker::SearchWindow::~SearchWindow()
{
@@ -355,7 +355,7 @@ void CvFuzzyMeanShiftTracker::SearchWindow::setSize(int _x, int _y, int _width,
if (y + height > maxHeight)
height = maxHeight - y;
};
}
void CvFuzzyMeanShiftTracker::SearchWindow::initDepthValues(IplImage *maskImage, IplImage *depthMap)
{
@@ -409,7 +409,7 @@ void CvFuzzyMeanShiftTracker::SearchWindow::initDepthValues(IplImage *maskImage,
depthHigh = 32000;
depthLow = 0;
}
};
}
bool CvFuzzyMeanShiftTracker::SearchWindow::shift()
{
@@ -422,7 +422,7 @@ bool CvFuzzyMeanShiftTracker::SearchWindow::shift()
{
return false;
}
};
}
void CvFuzzyMeanShiftTracker::SearchWindow::extractInfo(IplImage *maskImage, IplImage *depthMap, bool initDepth)
{
@@ -528,7 +528,7 @@ void CvFuzzyMeanShiftTracker::SearchWindow::extractInfo(IplImage *maskImage, Ipl
ellipseAngle = 0;
density = 0;
}
};
}
void CvFuzzyMeanShiftTracker::SearchWindow::getResizeAttribsEdgeDensityLinear(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh) {
int x1 = horizontalEdgeTop;
@@ -572,7 +572,7 @@ void CvFuzzyMeanShiftTracker::SearchWindow::getResizeAttribsEdgeDensityLinear(in
} else {
resizeDw = - resizeDx;
}
};
}
void CvFuzzyMeanShiftTracker::SearchWindow::getResizeAttribsInnerDensity(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh)
{
@@ -588,7 +588,7 @@ void CvFuzzyMeanShiftTracker::SearchWindow::getResizeAttribsInnerDensity(int &re
resizeDy = (int)(py*dy);
resizeDw = (int)((1-px)*dx);
resizeDh = (int)((1-py)*dy);
};
}
void CvFuzzyMeanShiftTracker::SearchWindow::getResizeAttribsEdgeDensityFuzzy(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh)
{
@@ -627,7 +627,7 @@ void CvFuzzyMeanShiftTracker::SearchWindow::getResizeAttribsEdgeDensityFuzzy(int
resizeDy = int(-dy1);
resizeDh = int(dy1+dy2);
}
};
}
bool CvFuzzyMeanShiftTracker::SearchWindow::meanShift(IplImage *maskImage, IplImage *depthMap, int maxIteration, bool initDepth)
{
@@ -640,7 +640,7 @@ bool CvFuzzyMeanShiftTracker::SearchWindow::meanShift(IplImage *maskImage, IplIm
} while (++numShifts < maxIteration);
return false;
};
}
void CvFuzzyMeanShiftTracker::findOptimumSearchWindow(SearchWindow &searchWindow, IplImage *maskImage, IplImage *depthMap, int maxIteration, int resizeMethod, bool initDepth)
{
@@ -680,17 +680,17 @@ void CvFuzzyMeanShiftTracker::findOptimumSearchWindow(SearchWindow &searchWindow
searchWindow.setSize(searchWindow.x + resizeDx, searchWindow.y + resizeDy, searchWindow.width + resizeDw, searchWindow.height + resizeDh);
}
};
}
CvFuzzyMeanShiftTracker::CvFuzzyMeanShiftTracker()
{
searchMode = tsSetWindow;
};
}
CvFuzzyMeanShiftTracker::~CvFuzzyMeanShiftTracker()
{
// nothing to do
};
}
void CvFuzzyMeanShiftTracker::track(IplImage *maskImage, IplImage *depthMap, int resizeMethod, bool resetSearch, int minKernelMass)
{
@@ -718,4 +718,4 @@ void CvFuzzyMeanShiftTracker::track(IplImage *maskImage, IplImage *depthMap, int
else
searchMode = tsTracking;
}
};
}
+1 -1
View File
@@ -709,7 +709,7 @@ void cv::SpinImageModel::defaultParams()
T_GeometriccConsistency = 0.25f;
T_GroupingCorespondances = 0.25f;
};
}
Mat cv::SpinImageModel::packRandomScaledSpins(bool separateScale, size_t xCount, size_t yCount) const
{
+51 -26
View File
@@ -55,9 +55,9 @@ namespace cv
{
public:
typedef T float_type;
typedef cv::Matx<float_type, 3, 3> Mat3;
typedef cv::Matx<float_type, 4, 4> Mat4;
typedef cv::Vec<float_type, 3> Vec3;
typedef Matx<float_type, 3, 3> Mat3;
typedef Matx<float_type, 4, 4> Mat4;
typedef Vec<float_type, 3> Vec3;
Affine3();
@@ -70,11 +70,11 @@ namespace cv
//Rodrigues vector
Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0));
//Combines all contructors above. Supports 4x4, 3x3, 1x3, 3x1 sizes of data matrix
explicit Affine3(const cv::Mat& data, const Vec3& t = Vec3::all(0));
//Combines all contructors above. Supports 4x4, 3x4, 3x3, 1x3, 3x1 sizes of data matrix
explicit Affine3(const Mat& data, const Vec3& t = Vec3::all(0));
//Euler angles
Affine3(float_type alpha, float_type beta, float_type gamma, const Vec3& t = Vec3::all(0));
//From 16th element array
explicit Affine3(const float_type* vals);
static Affine3 Identity();
@@ -87,9 +87,6 @@ namespace cv
//Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
void rotation(const Mat& data);
//Euler angles
void rotation(float_type alpha, float_type beta, float_type gamma);
void linear(const Mat3& L);
void translation(const Vec3& t);
@@ -105,6 +102,9 @@ namespace cv
// a.rotate(R) is equivalent to Affine(R, 0) * a;
Affine3 rotate(const Mat3& R) const;
// a.rotate(R) is equivalent to Affine(rvec, 0) * a;
Affine3 rotate(const Vec3& rvec) const;
// a.translate(t) is equivalent to Affine(E, t) * a;
Affine3 translate(const Vec3& t) const;
@@ -113,6 +113,8 @@ namespace cv
template <typename Y> operator Affine3<Y>() const;
template <typename Y> Affine3<Y> cast() const;
Mat4 matrix;
#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H
@@ -132,10 +134,26 @@ namespace cv
typedef Affine3<float> Affine3f;
typedef Affine3<double> Affine3d;
static cv::Vec3f operator*(const cv::Affine3f& affine, const cv::Vec3f& vector);
static cv::Vec3d operator*(const cv::Affine3d& affine, const cv::Vec3d& vector);
}
static Vec3f operator*(const Affine3f& affine, const Vec3f& vector);
static Vec3d operator*(const Affine3d& affine, const Vec3d& vector);
template<typename _Tp> class DataType< Affine3<_Tp> >
{
public:
typedef Affine3<_Tp> value_type;
typedef Affine3<typename DataType<_Tp>::work_type> work_type;
typedef _Tp channel_type;
enum { generic_type = 0,
depth = DataType<channel_type>::depth,
channels = 16,
fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
type = CV_MAKETYPE(depth, channels)
};
typedef Vec<channel_type, channels> vec_type;
};
}
///////////////////////////////////////////////////////////////////////////////////
@@ -179,6 +197,12 @@ cv::Affine3<T>::Affine3(const cv::Mat& data, const Vec3& t)
data.copyTo(matrix);
return;
}
else if (data.cols == 4 && data.rows == 3)
{
rotation(data(Rect(0, 0, 3, 3)));
translation(data(Rect(3, 0, 1, 3)));
return;
}
rotation(data);
translation(t);
@@ -187,13 +211,8 @@ cv::Affine3<T>::Affine3(const cv::Mat& data, const Vec3& t)
}
template<typename T> inline
cv::Affine3<T>::Affine3(float_type alpha, float_type beta, float_type gamma, const Vec3& t)
{
rotation(alpha, beta, gamma);
translation(t);
matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
matrix.val[15] = 1;
}
cv::Affine3<T>::Affine3(const float_type* vals) : matrix(vals)
{}
template<typename T> inline
cv::Affine3<T> cv::Affine3<T>::Identity()
@@ -261,12 +280,6 @@ void cv::Affine3<T>::rotation(const cv::Mat& data)
CV_Assert(!"Input marix can be 3x3, 1x3 or 3x1");
}
template<typename T> inline
void cv::Affine3<T>::rotation(float_type alpha, float_type beta, float_type gamma)
{
rotation(Vec3(alpha, beta, gamma));
}
template<typename T> inline
void cv::Affine3<T>::linear(const Mat3& L)
{
@@ -382,6 +395,12 @@ cv::Affine3<T> cv::Affine3<T>::rotate(const Mat3& R) const
return result;
}
template<typename T> inline
cv::Affine3<T> cv::Affine3<T>::rotate(const Vec3& _rvec) const
{
return rotate(Affine3f(_rvec).rotation());
}
template<typename T> inline
cv::Affine3<T> cv::Affine3<T>::translate(const Vec3& t) const
{
@@ -404,6 +423,12 @@ cv::Affine3<T>::operator Affine3<Y>() const
return Affine3<Y>(matrix);
}
template<typename T> template <typename Y> inline
cv::Affine3<Y> cv::Affine3<T>::cast() const
{
return Affine3<Y>(matrix);
}
template<typename T> inline
cv::Affine3<T> cv::operator*(const cv::Affine3<T>& affine1, const cv::Affine3<T>& affine2)
{
@@ -0,0 +1,26 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2014, Advanced Micro Devices, Inc., all rights reserved.
#ifndef __OPENCV_CORE_BUFFER_POOL_HPP__
#define __OPENCV_CORE_BUFFER_POOL_HPP__
namespace cv
{
class BufferPoolController
{
protected:
~BufferPoolController() { }
public:
virtual size_t getReservedSize() const = 0;
virtual size_t getMaxReservedSize() const = 0;
virtual void setMaxReservedSize(size_t size) = 0;
virtual void freeAllReservedBuffers() = 0;
};
}
#endif // __OPENCV_CORE_BUFFER_POOL_HPP__
@@ -459,6 +459,7 @@ CV_INLINE int cvIsInf( double value )
# endif
# endif
#elif defined _MSC_VER && !defined RC_INVOKED
# include <intrin.h>
# define CV_XADD(addr, delta) (int)_InterlockedExchangeAdd((long volatile*)addr, delta)
#else
CV_INLINE CV_XADD(int* addr, int delta) { int tmp = *addr; *addr += delta; return tmp; }
@@ -67,10 +67,10 @@ namespace ocl {
using namespace cv::ocl;
// TODO static functions in the Context class
CV_EXPORTS Context2& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device);
CV_EXPORTS Context2& initializeContextFromD3D10Device(ID3D10Device* pD3D10Device);
CV_EXPORTS Context2& initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex* pDirect3DDevice9Ex);
CV_EXPORTS Context2& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9);
CV_EXPORTS Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device);
CV_EXPORTS Context& initializeContextFromD3D10Device(ID3D10Device* pD3D10Device);
CV_EXPORTS Context& initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex* pDirect3DDevice9Ex);
CV_EXPORTS Context& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9);
} // namespace cv::directx::ocl

Some files were not shown because too many files have changed in this diff Show More