Comparar commits
537 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 45191dd6a5 | |||
| cc2110440a | |||
| eb326cdbc8 | |||
| 3759476b38 | |||
| 956a029ede | |||
| b1aa7aecf0 | |||
| 389ecbe96d | |||
| be22891f71 | |||
| 132b5d6435 | |||
| 04f3c19b9a | |||
| b78811112f | |||
| 2e2972cef3 | |||
| 16687a2655 | |||
| e21f106159 | |||
| dd8e648d78 | |||
| def1745132 | |||
| 6bc795308e | |||
| 1e5b533d01 | |||
| 02d1e68c64 | |||
| 1af55b4bcb | |||
| efecf3b8fd | |||
| 8cf6bcb20a | |||
| 99299b3605 | |||
| 7e52a8d1b6 | |||
| 064bf167ad | |||
| 9ca65ceef8 | |||
| 13b6a3a15e | |||
| f57d692cd7 | |||
| e1331b44f5 | |||
| 014a500f79 | |||
| 2128bd25e4 | |||
| 15e7712a26 | |||
| 3882bbbf35 | |||
| 5138b7d209 | |||
| 524bde2aeb | |||
| 20838b6f6e | |||
| 02c7e221a3 | |||
| 0c3bdbf23a | |||
| 4db68b50f2 | |||
| d6d1d20816 | |||
| c02179a765 | |||
| b870b246e1 | |||
| f87987ed72 | |||
| 9944282b09 | |||
| 62af76c646 | |||
| 962884cdec | |||
| ffdbddd6b1 | |||
| f22ee7f0df | |||
| e9e46d3086 | |||
| b6efec5f8b | |||
| c513d4ecd6 | |||
| 2f1ca1b6b3 | |||
| 11293d071f | |||
| 512f0091db | |||
| 9526907cba | |||
| aaf779a3a2 | |||
| 0d00109f05 | |||
| 7bee55b84e | |||
| ee144852f2 | |||
| 7c37f5d7de | |||
| 660d23aa04 | |||
| 1a76242d99 | |||
| 64f821908e | |||
| 875294aa92 | |||
| 71e7d444d8 | |||
| ca7abe1239 | |||
| f4433ff9c4 | |||
| 77df8730ef | |||
| c8b658fdb6 | |||
| 48f19fba76 | |||
| 1555922228 | |||
| 8763ad6c99 | |||
| 35ac95930f | |||
| b35fa6c4ff | |||
| d7c89fc649 | |||
| 4ba33fa1ed | |||
| a75e5ac277 | |||
| 2c56a09bee | |||
| 98d7d99244 | |||
| 3c09b075fc | |||
| 41c9377db0 | |||
| ab25fe9e37 | |||
| dfa4b2fefa | |||
| 3edf7c5386 | |||
| 0973e86d8a | |||
| bac94f85c1 | |||
| d3354c543e | |||
| dd8e442bda | |||
| a319bae6e2 | |||
| d246b41573 | |||
| c2f2e33a5e | |||
| 743dce6a4b | |||
| aa0dafcc1f | |||
| 680eeecc3b | |||
| cd501d947c | |||
| 1a1f454241 | |||
| 7d94236c14 | |||
| da017fbeb9 | |||
| 09be997ed8 | |||
| 5c88577138 | |||
| 2508d8e2b4 | |||
| d6add763c7 | |||
| 94c310fc14 | |||
| 80a1d569ca | |||
| 3de6846d12 | |||
| 0bbba847a4 | |||
| 7701fa7a63 | |||
| aabb40e34d | |||
| fe0b88d291 | |||
| 6059a6875a | |||
| 4ccb5a30d9 | |||
| 1284121d89 | |||
| f5cd20d80b | |||
| 16f9b6f5e4 | |||
| 9b09f09b9a | |||
| 3f417f1ec3 | |||
| caf91ac159 | |||
| 8c057af862 | |||
| da93a1dab9 | |||
| 889674ef43 | |||
| 5a407153bd | |||
| 817a4c0c30 | |||
| 932204d197 | |||
| e1afb1409f | |||
| 64cf113d23 | |||
| 770a466dd2 | |||
| b876308d77 | |||
| 464826c232 | |||
| eaeae4a1ba | |||
| 5cc0abffa5 | |||
| 5ddf4e4ed7 | |||
| 2d45af790e | |||
| 88c71d1b7d | |||
| 9785a8ae34 | |||
| c470e15d45 | |||
| 6e244c83cd | |||
| d23a4f50bd | |||
| 8ef19e7664 | |||
| 0e1005ca92 | |||
| ee291a15da | |||
| e5468008aa | |||
| d1ca934115 | |||
| 87e0eee92b | |||
| f29c727ada | |||
| 746bc168e6 | |||
| a6c3ed5b36 | |||
| 67ce03d7dd | |||
| 60ad505a63 | |||
| 49e038c724 | |||
| 2bf56961c0 | |||
| f7dc98f67b | |||
| 9c6eed0ba3 | |||
| 940cf978b1 | |||
| 7660fe03a6 | |||
| e21884f4c4 | |||
| cdbbfc98e1 | |||
| 50946b59c1 | |||
| 615e7b2747 | |||
| 53f1e73535 | |||
| 5fe9bb717d | |||
| 18e77d606c | |||
| 7c6191ec11 | |||
| 79c3a8e03b | |||
| d550f95347 | |||
| 4102aaaf15 | |||
| c6263eb253 | |||
| 709a1cc083 | |||
| 8ca86e2f52 | |||
| 1821d21f5b | |||
| 0d880479f0 | |||
| aad76090ce | |||
| a6dc6f72b3 | |||
| 257d8df1d4 | |||
| d2ed8e5f30 | |||
| afa5809473 | |||
| e17710c478 | |||
| 0930ac497f | |||
| d94f08f0e7 | |||
| b689eca8a0 | |||
| 4ebcf2b224 | |||
| 722dedb04d | |||
| aabc33c772 | |||
| b0d3830399 | |||
| 7852b68c20 | |||
| 0f64f847b2 | |||
| 9823b7cd08 | |||
| a0c504aabc | |||
| e311613fc8 | |||
| 7ab9c4ccee | |||
| 6e0db3f527 | |||
| 06776b612c | |||
| be80ad1607 | |||
| 05d842bcd8 | |||
| 07744ccf3d | |||
| ae5649d3f7 | |||
| 00fbf58902 | |||
| 476efd7d37 | |||
| e10ee89ec4 | |||
| 22484872fa | |||
| 08fbf667f9 | |||
| f6ca38a579 | |||
| f12d945712 | |||
| 49c35fafc0 | |||
| c09a325d3e | |||
| 60a98aa5f7 | |||
| 677443f3ef | |||
| ea83d384c1 | |||
| 98031a4147 | |||
| bbfccb61f3 | |||
| 2eebd8d939 | |||
| d36f8b9eb3 | |||
| f6ff2b87fa | |||
| 64bed2060a | |||
| 7e8fab0747 | |||
| c646bd4b7a | |||
| 362655b02a | |||
| b57e801c04 | |||
| bb3d14e1a0 | |||
| 5047b3fba2 | |||
| e1a4d22da6 | |||
| 4e21f42714 | |||
| 8877066846 | |||
| 157cdeb443 | |||
| 50bebd6f0b | |||
| 3923484341 | |||
| 2e0161c6c5 | |||
| d985861462 | |||
| 1d97a4549d | |||
| ae149adb29 | |||
| 0b2c1dc871 | |||
| cbe22fb5d1 | |||
| 86f7a357ae | |||
| 24c920a33a | |||
| 03f402892d | |||
| 930b580e0d | |||
| 383e04d9e4 | |||
| d2591704e8 | |||
| b8b13ccd5c | |||
| 0711e65972 | |||
| 2e5a7284d2 | |||
| ce5e9a71b5 | |||
| e95fc27490 | |||
| 0efc32fc21 | |||
| 8266eab8b4 | |||
| 4116cbe2c0 | |||
| 2eca75ccdd | |||
| 22b0ea1cf0 | |||
| 554a7cb33a | |||
| 61a40ddff8 | |||
| 214629b220 | |||
| dc3aa27be4 | |||
| 8286e1a5f7 | |||
| c36dcbcada | |||
| 70c409f0e8 | |||
| 3fa630639f | |||
| 209f16455d | |||
| 1712d0930c | |||
| 05cd88ae42 | |||
| db965353f4 | |||
| 39da17a02a | |||
| a22edb037f | |||
| bd3179bda8 | |||
| b19f672843 | |||
| 60c0e41ba5 | |||
| 5225672dc0 | |||
| f022b12c57 | |||
| d2e88e1d4d | |||
| 63a022dcd7 | |||
| 11c6eb6305 | |||
| f00efcfc59 | |||
| a71ef7d67b | |||
| 572d2d6a84 | |||
| 76e8794e81 | |||
| e6b1ccdcdf | |||
| e8f9762ef3 | |||
| fbf3de43a2 | |||
| 19c87d1c9d | |||
| 7f97fb481c | |||
| 1f1e24be3c | |||
| 1b571bde10 | |||
| 0e339dd137 | |||
| 0ddd16cf78 | |||
| 7e57648ea2 | |||
| 28716d7f30 | |||
| e299595667 | |||
| 05db02fbc8 | |||
| 7a1874b2cc | |||
| d47c112434 | |||
| 7df45c0dcc | |||
| 91913364d6 | |||
| 5460cee9e9 | |||
| 23011ffd81 | |||
| 6eed90e5e8 | |||
| 901c0d80c3 | |||
| 97e36b9375 | |||
| 68d04d28b6 | |||
| 8daebeac8a | |||
| 9db1d9ba13 | |||
| be0c20b758 | |||
| fceb62386d | |||
| 285d6320be | |||
| f45b5b13f1 | |||
| 081887ee16 | |||
| 5c2d59066f | |||
| 2c67731a7b | |||
| 6ccd7aca4c | |||
| 3282e08f55 | |||
| 845e52b676 | |||
| 8579666b03 | |||
| 24af691843 | |||
| 8ecd22ba48 | |||
| c31f106012 | |||
| aa4e6a8a83 | |||
| 7f542e391a | |||
| d559c18ee5 | |||
| cfd634ca3e | |||
| 4fce5a5e83 | |||
| 934b623fa9 | |||
| d3397a1d6d | |||
| 5b148083fe | |||
| f172947ed5 | |||
| 5527fc62f4 | |||
| 04481d9ef4 | |||
| ab9311947a | |||
| 66a1ea7604 | |||
| 4abf0b3193 | |||
| 1f1d43fc88 | |||
| 9ca1162be8 | |||
| 6cd70c83fb | |||
| f6f1861a2f | |||
| 590d1d8118 | |||
| 759863d95c | |||
| 1e0bff3268 | |||
| a9f10e5cad | |||
| 0865227049 | |||
| c3e4a52fbe | |||
| 2e2d927273 | |||
| ee4f003e72 | |||
| 781c04324e | |||
| a30bbda3bd | |||
| 52a136227d | |||
| 8acfbde68e | |||
| 72e2b8b370 | |||
| 08910e81af | |||
| e3c93ad9cf | |||
| be40bd5c74 | |||
| 9cfa51a483 | |||
| 1edab12068 | |||
| 9719ea93b6 | |||
| aba5bae400 | |||
| 0938358002 | |||
| 72a63922d2 | |||
| e4fb680566 | |||
| 5bc66ec8e4 | |||
| a218507586 | |||
| 8ba9289a2c | |||
| 4d6bdc1533 | |||
| c803cbb93b | |||
| 7e301c5c0e | |||
| b5e009eb87 | |||
| a9919e01d0 | |||
| 606c23b9aa | |||
| 96e4eed018 | |||
| 9f5fcff3ea | |||
| bd9ca48fab | |||
| 6fb959710d | |||
| e06c5b6fd5 | |||
| aa92be34d6 | |||
| dda2eb0f76 | |||
| 580d8173e5 | |||
| afff9cf716 | |||
| 810829f32e | |||
| 29f89e8930 | |||
| d3ac282487 | |||
| 916967cac5 | |||
| 0cbf9eb22a | |||
| 40600fa504 | |||
| e6eb1b99e1 | |||
| 27eb2e27db | |||
| 9b251f8130 | |||
| df392cc830 | |||
| ac5cd48279 | |||
| fba62c9251 | |||
| 2bd35c4358 | |||
| fa55d51b6a | |||
| ca81628a9a | |||
| 022a8b9698 | |||
| 2bcb8dbd83 | |||
| f196e9fda4 | |||
| 0898c3c651 | |||
| 916ba4c0ea | |||
| fa62e2b72f | |||
| 312a58fcec | |||
| ef431f70b6 | |||
| 0424e2c8d2 | |||
| 1b9bccb856 | |||
| 30bce16ad6 | |||
| fdef0adf95 | |||
| 838842cc96 | |||
| dd595376ba | |||
| eb91593c08 | |||
| 64d6e6a48d | |||
| 672cf1f445 | |||
| 56c7ef06e7 | |||
| 7db1323f81 | |||
| b52fea7fae | |||
| 612a258506 | |||
| 0314e0e5d7 | |||
| c0359ed5c5 | |||
| 72b499df00 | |||
| 8108bd30fe | |||
| b83d4add2e | |||
| 4d9c7c1012 | |||
| 1917366528 | |||
| 4881205bae | |||
| dca27b4622 | |||
| e606a0d651 | |||
| ba50d19341 | |||
| 1bf85996b3 | |||
| 08b4e780de | |||
| 1cf7a46f3a | |||
| 0691dc554f | |||
| 5d15e4ea58 | |||
| 1a52a322b5 | |||
| 14a0dd8c98 | |||
| a3af5ede80 | |||
| 4aac1444ad | |||
| 1ab7af6995 | |||
| 2b7ce8b160 | |||
| 267d140bfe | |||
| dd9c53497b | |||
| d65b3e0617 | |||
| baef62b4d2 | |||
| a126532cb7 | |||
| dad56e202f | |||
| b131dfeecd | |||
| 0a4ed2bc01 | |||
| 8c9c2b3a03 | |||
| e5ffbf9498 | |||
| 91a9923dcf | |||
| 665bf430d5 | |||
| 2e54e2a586 | |||
| bff818afbd | |||
| 7ef378b230 | |||
| 9163471987 | |||
| 8a3e897999 | |||
| e379771c03 | |||
| f93cffaa0d | |||
| 1022094dc0 | |||
| f1e36043e6 | |||
| 4656872161 | |||
| 5fb9f48360 | |||
| 31a073ca66 | |||
| 4207552e19 | |||
| 157ab66ab9 | |||
| 6a3a723938 | |||
| 65543c53f6 | |||
| 4a1c4a9862 | |||
| a0be7b57f5 | |||
| 95b7f5c46c | |||
| 95869a6081 | |||
| ff8417db00 | |||
| 3cb9afb4e7 | |||
| a84334cfc2 | |||
| 2e8ed77383 | |||
| 16dd09ccfc | |||
| 017d970b9a | |||
| a22ee13620 | |||
| 40c0c60e2b | |||
| 7b6da394f0 | |||
| 2d0fc80c95 | |||
| 3d41846c39 | |||
| 5651743784 | |||
| 8e092f8b5d | |||
| 754fd7311b | |||
| 2914f24521 | |||
| 2d2c46e717 | |||
| 9771c3c7ec | |||
| 0ff8a4633d | |||
| cc300a69b1 | |||
| 26af7d7389 | |||
| b6081438fa | |||
| 296aa8854c | |||
| efd2615844 | |||
| 765dea9ddf | |||
| ba27d89173 | |||
| 8d90b973b0 | |||
| 801368ee82 | |||
| 6f53be4102 | |||
| dc74ce20ab | |||
| c04725b681 | |||
| 695827050f | |||
| b0b85f36f6 | |||
| f01c5d9033 | |||
| a54d456ad0 | |||
| fe2c38be80 | |||
| 7290d8576d | |||
| fb113e5ce4 | |||
| cd301e530f | |||
| 9966d7feba | |||
| 108fd169f7 | |||
| beb377b38c | |||
| 4d059e9e5b | |||
| 02646427fb | |||
| 66b90d19a6 | |||
| 468eefe0ce | |||
| 0f65dacb8b | |||
| e55b2f7d60 | |||
| e0cfc0ccf5 | |||
| 729d76ad09 | |||
| 8db5b7d7d4 | |||
| 0ad849d2fd | |||
| 772586801b | |||
| 6211f156e6 | |||
| f14a711bda | |||
| 91f47d2779 | |||
| 8dbde3297e | |||
| 26f9534544 | |||
| d681717702 | |||
| 275ab53ebc | |||
| 1cb21d292b | |||
| 9f8ce906f4 | |||
| 57775988e7 | |||
| ef6a6cfb40 | |||
| 78dd1893bb | |||
| d9ffe5e7c4 | |||
| cb66dd8000 | |||
| e8dd73798c | |||
| 5bc104cef5 | |||
| 73bbabf207 | |||
| 0e7ca71dcc | |||
| 9337246867 | |||
| 81f826db2b | |||
| 0442bca235 | |||
| 075372a71c | |||
| e7b81688a4 | |||
| 18ab16dbd3 |
BIN
Arquivo binário não exibido.
BIN
Arquivo binário não exibido.
externo
+1
-1
@@ -16,7 +16,7 @@ How to update opencv_ffmpeg.dll and opencv_ffmpeg_64.dll when a new version of F
|
||||
2. Install 64-bit MinGW. http://mingw-w64.sourceforge.net/
|
||||
Let's assume, it's installed in C:\MSYS64
|
||||
3. Copy C:\MSYS32\msys to C:\MSYS64\msys. Edit C:\MSYS64\msys\etc\fstab, change C:\MSYS32 to C:\MSYS64.
|
||||
|
||||
|
||||
4. Now you have working MSYS32 and MSYS64 environments.
|
||||
Launch, one by one, C:\MSYS32\msys\msys.bat and C:\MSYS64\msys\msys.bat to create your home directories.
|
||||
|
||||
|
||||
BIN
Arquivo binário não exibido.
BIN
Arquivo binário não exibido.
BIN
Arquivo binário não exibido.
BIN
Arquivo binário não exibido.
BIN
Arquivo binário não exibido.
+1
@@ -24,6 +24,7 @@ if(WIN32 AND NOT MINGW)
|
||||
endif(WIN32 AND NOT MINGW)
|
||||
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wno-implicit-function-declaration -Wno-uninitialized -Wmissing-prototypes -Wmissing-declarations -Wunused -Wshadow -Wsign-compare)
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter) # clang
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS /wd4013 /wd4018 /wd4101 /wd4244 /wd4267 /wd4715) # vs2005
|
||||
|
||||
if(UNIX)
|
||||
|
||||
externo
+1
@@ -26,6 +26,7 @@ if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
endif()
|
||||
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wcast-align -Wshadow -Wunused)
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter) # clang
|
||||
|
||||
set_target_properties(${JPEG_LIBRARY}
|
||||
PROPERTIES OUTPUT_NAME ${JPEG_LIBRARY}
|
||||
|
||||
externo
+1
@@ -89,6 +89,7 @@ endif(WIN32)
|
||||
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wno-unused-but-set-variable -Wmissing-prototypes -Wmissing-declarations -Wundef -Wunused -Wsign-compare
|
||||
-Wcast-align -Wshadow -Wno-maybe-uninitialized -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast)
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter) # clang
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-declarations -Wunused-parameter)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4018 /wd4100 /wd4127 /wd4311 /wd4701 /wd4706) # vs2005
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4244) # vs2008
|
||||
|
||||
externo
+2
-2
@@ -45,13 +45,13 @@ jasper-1.900.1 - JasPer is a collection of software
|
||||
and manipulation of images. This software can handle image data in a
|
||||
variety of formats. One such format supported by JasPer is the JPEG-2000
|
||||
format defined in ISO/IEC 15444-1.
|
||||
|
||||
|
||||
Copyright (c) 1999-2000 Image Power, Inc.
|
||||
Copyright (c) 1999-2000 The University of British Columbia
|
||||
Copyright (c) 2001-2003 Michael David Adams
|
||||
|
||||
The JasPer license can be found in src/libjasper.
|
||||
|
||||
|
||||
OpenCV on Windows uses pre-built libjasper library
|
||||
(lib/libjasper*). To get the latest source code,
|
||||
please, visit the project homepage:
|
||||
|
||||
externo
+20
-9
@@ -5,40 +5,46 @@ endif()
|
||||
|
||||
project(tbb)
|
||||
|
||||
# 4.1 - works fine
|
||||
set(tbb_ver "tbb41_20120718oss")
|
||||
set(tbb_url "http://threadingbuildingblocks.org/uploads/77/188/4.1/tbb41_20120718oss_src.tgz")
|
||||
set(tbb_md5 "31b9ec300f3d09da2504d5d882788dd4")
|
||||
# 4.1 update 1 - works fine
|
||||
set(tbb_ver "tbb41_20121003oss")
|
||||
set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20121003oss_src.tgz")
|
||||
set(tbb_md5 "2a684fefb855d2d0318d1ef09afa75ff")
|
||||
set(tbb_version_file "version_string.ver")
|
||||
|
||||
# 4.1 - works fine
|
||||
#set(tbb_ver "tbb41_20120718oss")
|
||||
#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20120718oss_src.tgz")
|
||||
#set(tbb_md5 "31b9ec300f3d09da2504d5d882788dd4")
|
||||
#set(tbb_version_file "version_string.ver")
|
||||
|
||||
# 4.0 update 5 - works fine
|
||||
#set(tbb_ver "tbb40_20120613oss")
|
||||
#set(tbb_url "http://threadingbuildingblocks.org/uploads/77/187/4.0%20update%205/tbb40_20120613oss_src.tgz")
|
||||
#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20120613oss_src.tgz")
|
||||
#set(tbb_md5 "da01ed74944ec5950cfae3476901a172")
|
||||
#set(tbb_version_file "version_string.ver")
|
||||
|
||||
# 4.0 update 4 - works fine
|
||||
#set(tbb_ver "tbb40_20120408oss")
|
||||
#set(tbb_url "http://threadingbuildingblocks.org/uploads/77/185/4.0%20update%204/tbb40_20120408oss_src.tgz")
|
||||
#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20120408oss_src.tgz")
|
||||
#set(tbb_md5 "734b356da7fe0ed308741f3e6018251e")
|
||||
#set(tbb_version_file "version_string.ver")
|
||||
|
||||
# 4.0 update 3 - build broken
|
||||
#set(tbb_ver "tbb40_20120201oss")
|
||||
#set(tbb_url "http://threadingbuildingblocks.org/uploads/77/182/4.0%20update%203/tbb40_20120201oss_src.tgz")
|
||||
#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20120201oss_src.tgz")
|
||||
#set(tbb_md5 "4669e7d4adee018de7a7b8b972987218")
|
||||
#set(tbb_version_file "version_string.tmp")
|
||||
|
||||
# 4.0 update 2 - works fine
|
||||
#set(tbb_ver "tbb40_20111130oss")
|
||||
#set(tbb_url "http://threadingbuildingblocks.org/uploads/77/180/4.0%20update%202/tbb40_20111130oss_src.tgz")
|
||||
#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20111130oss_src.tgz")
|
||||
#set(tbb_md5 "1e6926b21e865e79772119cd44fc3ad8")
|
||||
#set(tbb_version_file "version_string.tmp")
|
||||
#set(tbb_need_GENERIC_DWORD_LOAD_STORE TRUE)
|
||||
|
||||
# 4.0 update 1 - works fine
|
||||
#set(tbb_ver "tbb40_20111003oss")
|
||||
#set(tbb_url "http://threadingbuildingblocks.org/uploads/77/177/4.0%20update%201/tbb40_20111003oss_src.tgz")
|
||||
#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20111003oss_src.tgz")
|
||||
#set(tbb_md5 "7b5d94eb35a563b29ef402e0fd8f15c9")
|
||||
#set(tbb_version_file "version_string.tmp")
|
||||
#set(tbb_need_GENERIC_DWORD_LOAD_STORE TRUE)
|
||||
@@ -123,6 +129,11 @@ add_definitions(-D__TBB_DYNAMIC_LOAD_ENABLED=0 #required
|
||||
-DDO_ITT_NOTIFY=0 #it seems that we don't need these notifications
|
||||
)
|
||||
|
||||
if(ANDROID_COMPILER_IS_CLANG)
|
||||
add_definitions(-D__TBB_GCC_BUILTIN_ATOMICS_PRESENT=1)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-prototypes)
|
||||
endif()
|
||||
|
||||
if(tbb_need_GENERIC_DWORD_LOAD_STORE)
|
||||
#needed by TBB 4.0 update 1,2; fixed in TBB 4.0 update 3 but it has 2 new problems
|
||||
add_definitions(-D__TBB_USE_GENERIC_DWORD_LOAD_STORE=1)
|
||||
|
||||
+18
-20
@@ -110,17 +110,17 @@ endif()
|
||||
|
||||
# Optional 3rd party components
|
||||
# ===================================================
|
||||
OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON IF (UNIX AND NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON IF (UNIX AND NOT ANDROID AND NOT IOS AND NOT CARMA) )
|
||||
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_CUBLAS "Include NVidia Cuda Basic Linear Algebra Subprograms (BLAS) library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_CUDA "Include NVidia Cuda Runtime support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_CUFFT "Include NVidia Cuda Fast Fourier Transform (FFT) library support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_CUBLAS "Include NVidia Cuda Basic Linear Algebra Subprograms (BLAS) library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_NVCUVID "Include NVidia Video Decoding library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS AND NOT APPLE) )
|
||||
OCV_OPTION(WITH_EIGEN "Include Eigen2/Eigen3 support" ON)
|
||||
OCV_OPTION(WITH_FFMPEG "Include FFMPEG support" ON IF (NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_FFMPEG "Include FFMPEG support" ON IF (NOT ANDROID AND NOT IOS))
|
||||
OCV_OPTION(WITH_GSTREAMER "Include Gstreamer support" ON IF (UNIX AND NOT APPLE AND NOT ANDROID) )
|
||||
OCV_OPTION(WITH_GTK "Include GTK support" ON IF (UNIX AND NOT APPLE AND NOT ANDROID) )
|
||||
OCV_OPTION(WITH_IMAGEIO "ImageIO support for OS X" OFF IF APPLE)
|
||||
OCV_OPTION(WITH_IPP "Include Intel IPP support" OFF IF (MSVC OR X86 OR X86_64) )
|
||||
OCV_OPTION(WITH_JASPER "Include JPEG2K support" ON IF (NOT IOS) )
|
||||
OCV_OPTION(WITH_JPEG "Include JPEG support" ON IF (NOT IOS) )
|
||||
@@ -129,7 +129,6 @@ OCV_OPTION(WITH_OPENGL "Include OpenGL support" OFF
|
||||
OCV_OPTION(WITH_OPENNI "Include OpenNI support" OFF IF (NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_PNG "Include PNG support" ON IF (NOT IOS) )
|
||||
OCV_OPTION(WITH_PVAPI "Include Prosilica GigE support" ON IF (NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_GIGEAPI "Include Smartek GigE support" ON IF (NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_QT "Build with Qt Backend support" OFF IF (NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_QUICKTIME "Use QuickTime for Video I/O insted of QTKit" OFF IF APPLE )
|
||||
OCV_OPTION(WITH_TBB "Include Intel TBB support" OFF IF (NOT IOS) )
|
||||
@@ -140,9 +139,10 @@ OCV_OPTION(WITH_V4L "Include Video 4 Linux support" ON
|
||||
OCV_OPTION(WITH_VIDEOINPUT "Build HighGUI with DirectShow support" ON IF WIN32 )
|
||||
OCV_OPTION(WITH_XIMEA "Include XIMEA cameras support" OFF IF (NOT ANDROID AND NOT APPLE) )
|
||||
OCV_OPTION(WITH_XINE "Include Xine support (GPL)" OFF IF (UNIX AND NOT APPLE AND NOT ANDROID) )
|
||||
OCV_OPTION(WITH_OPENCL "Include OpenCL Runtime support" OFF IF (NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_OPENCLAMDFFT "Include AMD OpenCL FFT library support" OFF IF (NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" OFF IF (NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_CLP "Include Clp support (EPL)" OFF)
|
||||
OCV_OPTION(WITH_OPENCL "Include OpenCL Runtime support" OFF IF (NOT ANDROID AND NOT IOS AND NOT CARMA) )
|
||||
OCV_OPTION(WITH_OPENCLAMDFFT "Include AMD OpenCL FFT library support" OFF IF (NOT ANDROID AND NOT IOS AND NOT CARMA) )
|
||||
OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" OFF IF (NOT ANDROID AND NOT IOS AND NOT CARMA) )
|
||||
|
||||
|
||||
# OpenCV build components
|
||||
@@ -161,12 +161,12 @@ OCV_OPTION(BUILD_ANDROID_SERVICE "Build OpenCV Manager for Google Play" OFF I
|
||||
OCV_OPTION(BUILD_ANDROID_PACKAGE "Build platform-specific package for Google Play" OFF IF ANDROID )
|
||||
|
||||
# 3rd party libs
|
||||
OCV_OPTION(BUILD_ZLIB "Build zlib from source" WIN32 OR APPLE )
|
||||
OCV_OPTION(BUILD_TIFF "Build libtiff from source" WIN32 OR ANDROID OR APPLE )
|
||||
OCV_OPTION(BUILD_JASPER "Build libjasper from source" WIN32 OR ANDROID OR APPLE )
|
||||
OCV_OPTION(BUILD_JPEG "Build libjpeg from source" WIN32 OR ANDROID OR APPLE )
|
||||
OCV_OPTION(BUILD_PNG "Build libpng from source" WIN32 OR ANDROID OR APPLE )
|
||||
OCV_OPTION(BUILD_OPENEXR "Build openexr from source" WIN32 OR ANDROID OR APPLE )
|
||||
OCV_OPTION(BUILD_ZLIB "Build zlib from source" WIN32 OR APPLE OR CARMA )
|
||||
OCV_OPTION(BUILD_TIFF "Build libtiff from source" WIN32 OR ANDROID OR APPLE OR CARMA )
|
||||
OCV_OPTION(BUILD_JASPER "Build libjasper from source" WIN32 OR ANDROID OR APPLE OR CARMA )
|
||||
OCV_OPTION(BUILD_JPEG "Build libjpeg from source" WIN32 OR ANDROID OR APPLE OR CARMA )
|
||||
OCV_OPTION(BUILD_PNG "Build libpng from source" WIN32 OR ANDROID OR APPLE OR CARMA )
|
||||
OCV_OPTION(BUILD_OPENEXR "Build openexr from source" WIN32 OR ANDROID OR APPLE OR CARMA )
|
||||
|
||||
|
||||
# OpenCV installation options
|
||||
@@ -459,7 +459,7 @@ if(BUILD_EXAMPLES OR BUILD_ANDROID_EXAMPLES OR INSTALL_PYTHON_EXAMPLES)
|
||||
add_subdirectory(samples)
|
||||
endif()
|
||||
|
||||
if(BUILD_ANDROID_SERVICE)
|
||||
if(ANDROID)
|
||||
add_subdirectory(android/service)
|
||||
endif()
|
||||
|
||||
@@ -467,7 +467,7 @@ if(BUILD_ANDROID_PACKAGE)
|
||||
add_subdirectory(android/package)
|
||||
endif()
|
||||
|
||||
if (ANDROID AND NOT BUILD_ANDROID_SERVICE AND NOT BUILD_ANDROID_PACKAGE AND NOT BUILD_CAMERA_WRAPER)
|
||||
if (ANDROID)
|
||||
add_subdirectory(android/libinfo)
|
||||
endif()
|
||||
|
||||
@@ -565,6 +565,7 @@ if(ANDROID)
|
||||
status("")
|
||||
status(" Android: ")
|
||||
status(" Android ABI:" ${ANDROID_ABI})
|
||||
status(" STL type:" ${ANDROID_STL})
|
||||
status(" Native API level:" android-${ANDROID_NATIVE_API_LEVEL})
|
||||
status(" SDK target:" "${ANDROID_SDK_TARGET}")
|
||||
if(BUILD_WITH_ANDROID_NDK)
|
||||
@@ -697,10 +698,6 @@ if(DEFINED WITH_PVAPI)
|
||||
status(" PvAPI:" HAVE_PVAPI THEN YES ELSE NO)
|
||||
endif(DEFINED WITH_PVAPI)
|
||||
|
||||
if(DEFINED WITH_GIGEAPI)
|
||||
status(" GigEVisionSDK:" HAVE_GIGE_API THEN YES ELSE NO)
|
||||
endif(DEFINED WITH_GIGEAPI)
|
||||
|
||||
if(DEFINED WITH_QUICKTIME)
|
||||
status(" QuickTime:" WITH_QUICKTIME THEN YES ELSE NO)
|
||||
status(" QTKit:" WITH_QUICKTIME THEN NO ELSE YES)
|
||||
@@ -766,6 +763,7 @@ endif(DEFINED WITH_CUDA)
|
||||
status(" Use OpenCL:" HAVE_OPENCL THEN YES ELSE NO)
|
||||
|
||||
status(" Use Eigen:" HAVE_EIGEN THEN "YES (ver ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})" ELSE NO)
|
||||
status(" Use Clp:" HAVE_CLP THEN YES ELSE NO)
|
||||
|
||||
if(HAVE_CUDA)
|
||||
status("")
|
||||
|
||||
+351
-186
@@ -1,7 +1,37 @@
|
||||
# Copyright (c) 2010-2011, Ethan Rublee
|
||||
# Copyright (c) 2011-2012, Andrey Kamaev
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. The name of the copyright holders may 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 COPYRIGHT HOLDER 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.
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Android CMake toolchain file, for use with the Android NDK r5-r8
|
||||
# Requires cmake 2.6.3 or newer (2.8.5 or newer is recommended).
|
||||
# See home page: http://code.google.com/p/android-cmake/
|
||||
# See home page: https://github.com/taka-no-me/android-cmake
|
||||
#
|
||||
# The file is mantained by the OpenCV project. The latest version can be get at
|
||||
# http://code.opencv.org/projects/opencv/repository/revisions/master/changes/android/android.toolchain.cmake
|
||||
@@ -64,6 +94,20 @@
|
||||
# ANDROID_NATIVE_API_LEVEL=android-8 - level of Android API compile for.
|
||||
# Option is read-only when standalone toolchain is used.
|
||||
#
|
||||
# ANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.6 - the name of compiler
|
||||
# toolchain to be used. The list of possible values depends on the NDK
|
||||
# version. For NDK r8c the possible values are:
|
||||
#
|
||||
# * arm-linux-androideabi-4.4.3
|
||||
# * arm-linux-androideabi-4.6
|
||||
# * arm-linux-androideabi-clang3.1
|
||||
# * mipsel-linux-android-4.4.3
|
||||
# * mipsel-linux-android-4.6
|
||||
# * mipsel-linux-android-clang3.1
|
||||
# * x86-4.4.3
|
||||
# * x86-4.6
|
||||
# * x86-clang3.1
|
||||
#
|
||||
# ANDROID_FORCE_ARM_BUILD=OFF - set ON to generate 32-bit ARM instructions
|
||||
# instead of Thumb. Is not available for "x86" (inapplicable) and
|
||||
# "armeabi-v6 with VFP" (is forced to be ON) ABIs.
|
||||
@@ -147,13 +191,9 @@
|
||||
# under the ${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}
|
||||
# (depending on the target ABI). This is convenient for Android packaging.
|
||||
#
|
||||
# Authors:
|
||||
# Ethan Rublee ethan.ruble@gmail.com
|
||||
# Andrey Kamaev andrey.kamaev@itseez.com
|
||||
#
|
||||
# Change Log:
|
||||
# - initial version December 2010
|
||||
# - modified April 2011
|
||||
# - April 2011
|
||||
# [+] added possibility to build with NDK (without standalone toolchain)
|
||||
# [+] support cross-compilation on Windows (native, no cygwin support)
|
||||
# [+] added compiler option to force "char" type to be signed
|
||||
@@ -164,13 +204,13 @@
|
||||
# [+] EXECUTABLE_OUTPUT_PATH is set by toolchain (required on Windows)
|
||||
# [~] Fixed bug with ANDROID_API_LEVEL variable
|
||||
# [~] turn off SWIG search if it is not found first time
|
||||
# - modified May 2011
|
||||
# - May 2011
|
||||
# [~] ANDROID_LEVEL is renamed to ANDROID_API_LEVEL
|
||||
# [+] ANDROID_API_LEVEL is detected by toolchain if not specified
|
||||
# [~] added guard to prevent changing of output directories on the first
|
||||
# cmake pass
|
||||
# [~] toolchain exits with error if ARM_TARGET is not recognized
|
||||
# - modified June 2011
|
||||
# - June 2011
|
||||
# [~] default NDK path is updated for version r5c
|
||||
# [+] variable CMAKE_SYSTEM_PROCESSOR is set based on ARM_TARGET
|
||||
# [~] toolchain install directory is added to linker paths
|
||||
@@ -178,13 +218,13 @@
|
||||
# [+] added macro find_host_package, find_host_program to search
|
||||
# packages/programs on the host system
|
||||
# [~] fixed path to STL library
|
||||
# - modified July 2011
|
||||
# - July 2011
|
||||
# [~] fixed options caching
|
||||
# [~] search for all supported NDK versions
|
||||
# [~] allowed spaces in NDK path
|
||||
# - modified September 2011
|
||||
# - September 2011
|
||||
# [~] updated for NDK r6b
|
||||
# - modified November 2011
|
||||
# - November 2011
|
||||
# [*] rewritten for NDK r7
|
||||
# [+] x86 toolchain support (experimental)
|
||||
# [+] added "armeabi-v6 with VFP" ABI for ARMv6 processors.
|
||||
@@ -197,37 +237,37 @@
|
||||
# [~] ARM_TARGET is renamed to ANDROID_ABI
|
||||
# [~] ARMEABI_NDK_NAME is renamed to ANDROID_NDK_ABI_NAME
|
||||
# [~] ANDROID_API_LEVEL is renamed to ANDROID_NATIVE_API_LEVEL
|
||||
# - modified January 2012
|
||||
# - January 2012
|
||||
# [+] added stlport_static support (experimental)
|
||||
# [+] added special check for cygwin
|
||||
# [+] filtered out hidden files (starting with .) while globbing inside NDK
|
||||
# [+] automatically applied GLESv2 linkage fix for NDK revisions 5-6
|
||||
# [+] added ANDROID_GET_ABI_RAWNAME to get NDK ABI names by CMake flags
|
||||
# - modified February 2012
|
||||
# - February 2012
|
||||
# [+] updated for NDK r7b
|
||||
# [~] fixed cmake try_compile() command
|
||||
# [~] Fix for missing install_name_tool on OS X
|
||||
# - modified March 2012
|
||||
# - March 2012
|
||||
# [~] fixed incorrect C compiler flags
|
||||
# [~] fixed CMAKE_SYSTEM_PROCESSOR change on ANDROID_ABI change
|
||||
# [+] improved toolchain loading speed
|
||||
# [+] added assembler language support (.S)
|
||||
# [+] allowed preset search paths and extra search suffixes
|
||||
# - modified April 2012
|
||||
# - April 2012
|
||||
# [+] updated for NDK r7c
|
||||
# [~] fixed most of problems with compiler/linker flags and caching
|
||||
# [+] added option ANDROID_FUNCTION_LEVEL_LINKING
|
||||
# - modified May 2012
|
||||
# - May 2012
|
||||
# [+] updated for NDK r8
|
||||
# [+] added mips architecture support
|
||||
# - modified August 2012
|
||||
# - August 2012
|
||||
# [+] updated for NDK r8b
|
||||
# [~] all intermediate files generated by toolchain are moved to CMakeFiles
|
||||
# [~] libstdc++ and libsupc are removed from explicit link libraries
|
||||
# [+] added CCache support (via NDK_CCACHE environment or cmake variable)
|
||||
# [+] added gold linker support for NDK r8b
|
||||
# [~] fixed mips linker flags for NDK r8b
|
||||
# - modified September 2012
|
||||
# - September 2012
|
||||
# [+] added NDK release name detection (see ANDROID_NDK_RELEASE)
|
||||
# [+] added support for all C++ runtimes from NDK
|
||||
# (system, gabi++, stlport, gnustl)
|
||||
@@ -235,8 +275,14 @@
|
||||
# [~] use gold linker as default if available (NDK r8b)
|
||||
# [~] globally turned off rpath
|
||||
# [~] compiler options are aligned with NDK r8b
|
||||
# - modified October 2012
|
||||
# - October 2012
|
||||
# [~] fixed C++ linking: explicitly link with math library (OpenCV #2426)
|
||||
# - November 2012
|
||||
# [+] updated for NDK r8c
|
||||
# [+] added support for clang compiler
|
||||
# - December 2012
|
||||
# [~] fixed ccache full path search
|
||||
# [+] updated for NDK r8d
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
cmake_minimum_required( VERSION 2.6.3 )
|
||||
@@ -259,7 +305,7 @@ set( CMAKE_SYSTEM_VERSION 1 )
|
||||
# rpath makes low sence for Android
|
||||
set( CMAKE_SKIP_RPATH TRUE CACHE BOOL "If set, runtime paths are not added when using shared libraries." )
|
||||
|
||||
set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" )
|
||||
set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r8d -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" )
|
||||
if(NOT DEFINED ANDROID_NDK_SEARCH_PATHS)
|
||||
if( CMAKE_HOST_WIN32 )
|
||||
file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS )
|
||||
@@ -367,8 +413,8 @@ endmacro()
|
||||
|
||||
macro( __DETECT_TOOLCHAIN_MACHINE_NAME _var _root )
|
||||
if( EXISTS "${_root}" )
|
||||
file( GLOB __gccExePath "${_root}/bin/*-gcc${TOOL_OS_SUFFIX}" )
|
||||
__LIST_FILTER( __gccExePath "bin/[.].*-gcc${TOOL_OS_SUFFIX}$" )
|
||||
file( GLOB __gccExePath RELATIVE "${_root}/bin/" "${_root}/bin/*-gcc${TOOL_OS_SUFFIX}" )
|
||||
__LIST_FILTER( __gccExePath "^[.].*" )
|
||||
list( LENGTH __gccExePath __gccExePathsCount )
|
||||
if( NOT __gccExePathsCount EQUAL 1 AND NOT _CMAKE_IN_TRY_COMPILE )
|
||||
message( WARNING "Could not determine machine name for compiler from ${_root}" )
|
||||
@@ -506,55 +552,76 @@ if( BUILD_WITH_STANDALONE_TOOLCHAIN )
|
||||
elseif( __availableToolchainMachines MATCHES mipsel )
|
||||
set( __availableToolchainArchs "mipsel" )
|
||||
endif()
|
||||
if( ANDROID_COMPILER_VERSION )
|
||||
# do not run gcc every time because it is relatevely expencive
|
||||
set( __availableToolchainCompilerVersions "${ANDROID_COMPILER_VERSION}" )
|
||||
else()
|
||||
execute_process( COMMAND "${ANDROID_STANDALONE_TOOLCHAIN}/bin/${__availableToolchainMachines}-gcc${TOOL_OS_SUFFIX}" --version
|
||||
OUTPUT_VARIABLE __availableToolchainCompilerVersions OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||
string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?" __availableToolchainCompilerVersions "${__availableToolchainCompilerVersions}" )
|
||||
execute_process( COMMAND "${ANDROID_STANDALONE_TOOLCHAIN}/bin/${__availableToolchainMachines}-gcc${TOOL_OS_SUFFIX}" -dumpversion
|
||||
OUTPUT_VARIABLE __availableToolchainCompilerVersions OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||
string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?" __availableToolchainCompilerVersions "${__availableToolchainCompilerVersions}" )
|
||||
if( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/bin/clang${TOOL_OS_SUFFIX}" )
|
||||
list( APPEND __availableToolchains "standalone-clang" )
|
||||
list( APPEND __availableToolchainMachines ${__availableToolchainMachines} )
|
||||
list( APPEND __availableToolchainArchs ${__availableToolchainArchs} )
|
||||
list( APPEND __availableToolchainCompilerVersions ${__availableToolchainCompilerVersions} )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar )
|
||||
foreach( __toolchain ${${__availableToolchainsVar}} )
|
||||
if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK}/toolchains/${__toolchain}/prebuilt/" )
|
||||
string( REGEX REPLACE "-clang3[.][0-9]$" "-4.6" __gcc_toolchain "${__toolchain}" )
|
||||
else()
|
||||
set( __gcc_toolchain "${__toolchain}" )
|
||||
endif()
|
||||
__DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK}/toolchains/${__gcc_toolchain}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
|
||||
if( __machine )
|
||||
string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?$" __version "${__gcc_toolchain}" )
|
||||
string( REGEX MATCH "^[^-]+" __arch "${__gcc_toolchain}" )
|
||||
list( APPEND __availableToolchainMachines "${__machine}" )
|
||||
list( APPEND __availableToolchainArchs "${__arch}" )
|
||||
list( APPEND __availableToolchainCompilerVersions "${__version}" )
|
||||
else()
|
||||
list( REMOVE_ITEM ${__availableToolchainsVar} "${__toolchain}" )
|
||||
endif()
|
||||
unset( __gcc_toolchain )
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
# get all the details about NDK
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
file( GLOB ANDROID_SUPPORTED_NATIVE_API_LEVELS RELATIVE "${ANDROID_NDK}/platforms" "${ANDROID_NDK}/platforms/android-*" )
|
||||
string( REPLACE "android-" "" ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_SUPPORTED_NATIVE_API_LEVELS}" )
|
||||
file( GLOB __availableToolchains RELATIVE "${ANDROID_NDK}/toolchains" "${ANDROID_NDK}/toolchains/*" )
|
||||
__LIST_FILTER( __availableToolchains "^[.]" )
|
||||
set( __availableToolchains "" )
|
||||
set( __availableToolchainMachines "" )
|
||||
set( __availableToolchainArchs "" )
|
||||
set( __availableToolchainCompilerVersions "" )
|
||||
foreach( __toolchain ${__availableToolchains} )
|
||||
__DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK}/toolchains/${__toolchain}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
|
||||
if( __machine )
|
||||
string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?$" __version "${__toolchain}" )
|
||||
string( REGEX MATCH "^[^-]+" __arch "${__toolchain}" )
|
||||
list( APPEND __availableToolchainMachines "${__machine}" )
|
||||
list( APPEND __availableToolchainArchs "${__arch}" )
|
||||
list( APPEND __availableToolchainCompilerVersions "${__version}" )
|
||||
else()
|
||||
list( REMOVE_ITEM __availableToolchains "${__toolchain}" )
|
||||
endif()
|
||||
endforeach()
|
||||
if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/" )
|
||||
# do not go through all toolchains if we know the name
|
||||
set( __availableToolchains "${ANDROID_TOOLCHAIN_NAME}" )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains )
|
||||
endif()
|
||||
if( NOT __availableToolchains )
|
||||
message( FATAL_ERROR "Could not any working toolchain in the NDK. Probably your Android NDK is broken." )
|
||||
file( GLOB __availableToolchains RELATIVE "${ANDROID_NDK}/toolchains" "${ANDROID_NDK}/toolchains/*" )
|
||||
if( __availableToolchains )
|
||||
list(SORT __availableToolchains) # we need clang to go after gcc
|
||||
endif()
|
||||
__LIST_FILTER( __availableToolchains "^[.]" )
|
||||
__LIST_FILTER( __availableToolchains "llvm" )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains )
|
||||
endif()
|
||||
if( NOT __availableToolchains )
|
||||
message( FATAL_ERROR "Could not find any working toolchain in the NDK. Probably your Android NDK is broken." )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# build list of available ABIs
|
||||
set( ANDROID_SUPPORTED_ABIS "" )
|
||||
set( __uniqToolchainArchNames ${__availableToolchainArchs} )
|
||||
list( REMOVE_DUPLICATES __uniqToolchainArchNames )
|
||||
list( SORT __uniqToolchainArchNames )
|
||||
foreach( __arch ${__uniqToolchainArchNames} )
|
||||
list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} )
|
||||
endforeach()
|
||||
unset( __uniqToolchainArchNames )
|
||||
if( NOT ANDROID_SUPPORTED_ABIS )
|
||||
set( ANDROID_SUPPORTED_ABIS "" )
|
||||
set( __uniqToolchainArchNames ${__availableToolchainArchs} )
|
||||
list( REMOVE_DUPLICATES __uniqToolchainArchNames )
|
||||
list( SORT __uniqToolchainArchNames )
|
||||
foreach( __arch ${__uniqToolchainArchNames} )
|
||||
list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} )
|
||||
endforeach()
|
||||
unset( __uniqToolchainArchNames )
|
||||
if( NOT ANDROID_SUPPORTED_ABIS )
|
||||
message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." )
|
||||
endif()
|
||||
message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." )
|
||||
endif()
|
||||
|
||||
# choose target ABI
|
||||
@@ -569,33 +636,34 @@ if( __androidAbiIdx EQUAL -1 )
|
||||
endif()
|
||||
unset( __androidAbiIdx )
|
||||
|
||||
# remember target ABI
|
||||
set( ANDROID_ABI "${ANDROID_ABI}" CACHE STRING "The target ABI for Android. If arm, then armeabi-v7a is recommended for hardware floating point." FORCE )
|
||||
|
||||
# set target ABI options
|
||||
if( ANDROID_ABI STREQUAL "x86" )
|
||||
set( X86 true )
|
||||
set( ANDROID_NDK_ABI_NAME "x86" )
|
||||
set( ANDROID_ARCH_NAME "x86" )
|
||||
set( ANDROID_ARCH_FULLNAME "x86" )
|
||||
set( ANDROID_LLVM_TRIPLE "i686-none-linux-android" )
|
||||
set( CMAKE_SYSTEM_PROCESSOR "i686" )
|
||||
elseif( ANDROID_ABI STREQUAL "mips" )
|
||||
set( MIPS true )
|
||||
set( ANDROID_NDK_ABI_NAME "mips" )
|
||||
set( ANDROID_ARCH_NAME "mips" )
|
||||
set( ANDROID_ARCH_FULLNAME "mipsel" )
|
||||
set( ANDROID_LLVM_TRIPLE "mipsel-none-linux-android" )
|
||||
set( CMAKE_SYSTEM_PROCESSOR "mips" )
|
||||
elseif( ANDROID_ABI STREQUAL "armeabi" )
|
||||
set( ARMEABI true )
|
||||
set( ANDROID_NDK_ABI_NAME "armeabi" )
|
||||
set( ANDROID_ARCH_NAME "arm" )
|
||||
set( ANDROID_ARCH_FULLNAME "arm" )
|
||||
set( ANDROID_LLVM_TRIPLE "armv5te-none-linux-androideabi" )
|
||||
set( CMAKE_SYSTEM_PROCESSOR "armv5te" )
|
||||
elseif( ANDROID_ABI STREQUAL "armeabi-v6 with VFP" )
|
||||
set( ARMEABI_V6 true )
|
||||
set( ANDROID_NDK_ABI_NAME "armeabi" )
|
||||
set( ANDROID_ARCH_NAME "arm" )
|
||||
set( ANDROID_ARCH_FULLNAME "arm" )
|
||||
set( ANDROID_LLVM_TRIPLE "armv5te-none-linux-androideabi" )
|
||||
set( CMAKE_SYSTEM_PROCESSOR "armv6" )
|
||||
# need always fallback to older platform
|
||||
set( ARMEABI true )
|
||||
@@ -604,12 +672,14 @@ elseif( ANDROID_ABI STREQUAL "armeabi-v7a")
|
||||
set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
|
||||
set( ANDROID_ARCH_NAME "arm" )
|
||||
set( ANDROID_ARCH_FULLNAME "arm" )
|
||||
set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" )
|
||||
set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
|
||||
elseif( ANDROID_ABI STREQUAL "armeabi-v7a with VFPV3" )
|
||||
set( ARMEABI_V7A true )
|
||||
set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
|
||||
set( ANDROID_ARCH_NAME "arm" )
|
||||
set( ANDROID_ARCH_FULLNAME "arm" )
|
||||
set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" )
|
||||
set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
|
||||
set( VFPV3 true )
|
||||
elseif( ANDROID_ABI STREQUAL "armeabi-v7a with NEON" )
|
||||
@@ -617,6 +687,7 @@ elseif( ANDROID_ABI STREQUAL "armeabi-v7a with NEON" )
|
||||
set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
|
||||
set( ANDROID_ARCH_NAME "arm" )
|
||||
set( ANDROID_ARCH_FULLNAME "arm" )
|
||||
set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" )
|
||||
set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
|
||||
set( VFPV3 true )
|
||||
set( NEON true )
|
||||
@@ -630,12 +701,6 @@ if( CMAKE_BINARY_DIR AND EXISTS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMa
|
||||
file( APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" "SET(CMAKE_SYSTEM_PROCESSOR \"${CMAKE_SYSTEM_PROCESSOR}\")\n" )
|
||||
endif()
|
||||
|
||||
set( ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME}} CACHE INTERNAL "ANDROID_ABI can be changed only to one of these ABIs. Changing to any other ABI requires to reset cmake cache." FORCE )
|
||||
if( CMAKE_VERSION VERSION_GREATER "2.8" )
|
||||
list( SORT ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME} )
|
||||
set_property( CACHE ANDROID_ABI PROPERTY STRINGS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME}} )
|
||||
endif()
|
||||
|
||||
if( ANDROID_ARCH_NAME STREQUAL "arm" AND NOT ARMEABI_V6 )
|
||||
__INIT_VARIABLE( ANDROID_FORCE_ARM_BUILD OBSOLETE_FORCE_ARM VALUES OFF )
|
||||
set( ANDROID_FORCE_ARM_BUILD ${ANDROID_FORCE_ARM_BUILD} CACHE BOOL "Use 32-bit ARM instructions instead of Thumb-1" FORCE )
|
||||
@@ -648,11 +713,15 @@ endif()
|
||||
if( ANDROID_TOOLCHAIN_NAME )
|
||||
list( FIND __availableToolchains "${ANDROID_TOOLCHAIN_NAME}" __toolchainIdx )
|
||||
if( __toolchainIdx EQUAL -1 )
|
||||
message( FATAL_ERROR "Previously selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is missing. You need to remove CMakeCache.txt and rerun cmake manually to change the toolchain" )
|
||||
list( SORT __availableToolchains )
|
||||
string( REPLACE ";" "\n * " toolchains_list "${__availableToolchains}" )
|
||||
set( toolchains_list " * ${toolchains_list}")
|
||||
message( FATAL_ERROR "Specified toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is missing in your NDK or broken. Please verify that your NDK is working or select another compiler toolchain.
|
||||
To configure the toolchain set CMake variable ANDROID_TOOLCHAIN_NAME to one of the following values:\n${toolchains_list}\n" )
|
||||
endif()
|
||||
list( GET __availableToolchainArchs ${__toolchainIdx} __toolchainArch )
|
||||
if( NOT __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME )
|
||||
message( SEND_ERROR "Previously selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is not able to compile binaries for the \"${ANDROID_ARCH_NAME}\" platform." )
|
||||
message( SEND_ERROR "Selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is not able to compile binaries for the \"${ANDROID_ARCH_NAME}\" platform." )
|
||||
endif()
|
||||
else()
|
||||
set( __toolchainIdx -1 )
|
||||
@@ -681,8 +750,7 @@ endif()
|
||||
list( GET __availableToolchains ${__toolchainIdx} ANDROID_TOOLCHAIN_NAME )
|
||||
list( GET __availableToolchainMachines ${__toolchainIdx} ANDROID_TOOLCHAIN_MACHINE_NAME )
|
||||
list( GET __availableToolchainCompilerVersions ${__toolchainIdx} ANDROID_COMPILER_VERSION )
|
||||
set( ANDROID_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" CACHE INTERNAL "Name of toolchain used" FORCE )
|
||||
set( ANDROID_COMPILER_VERSION "${ANDROID_COMPILER_VERSION}" CACHE INTERNAL "compiler version from selected toolchain" FORCE )
|
||||
|
||||
unset( __toolchainIdx )
|
||||
unset( __availableToolchains )
|
||||
unset( __availableToolchainMachines )
|
||||
@@ -692,37 +760,35 @@ unset( __availableToolchainCompilerVersions )
|
||||
# choose native API level
|
||||
__INIT_VARIABLE( ANDROID_NATIVE_API_LEVEL ENV_ANDROID_NATIVE_API_LEVEL ANDROID_API_LEVEL ENV_ANDROID_API_LEVEL ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME} ANDROID_DEFAULT_NDK_API_LEVEL )
|
||||
string( REGEX MATCH "[0-9]+" ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" )
|
||||
# TODO: filter out unsupported levels
|
||||
# validate
|
||||
list( FIND ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_NATIVE_API_LEVEL}" __levelIdx )
|
||||
if( __levelIdx EQUAL -1 )
|
||||
message( SEND_ERROR "Specified Android native API level (${ANDROID_NATIVE_API_LEVEL}) is not supported by your NDK/toolchain." )
|
||||
else()
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
__DETECT_NATIVE_API_LEVEL( __realApiLevel "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include/android/api-level.h" )
|
||||
if( NOT __realApiLevel EQUAL ANDROID_NATIVE_API_LEVEL )
|
||||
message( SEND_ERROR "Specified Android API level (${ANDROID_NATIVE_API_LEVEL}) does not match to the level found (${__realApiLevel}). Probably your copy of NDK is broken." )
|
||||
endif()
|
||||
unset( __realApiLevel )
|
||||
endif()
|
||||
set( ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android API level for native code" FORCE )
|
||||
if( CMAKE_VERSION VERSION_GREATER "2.8" )
|
||||
list( SORT ANDROID_SUPPORTED_NATIVE_API_LEVELS )
|
||||
set_property( CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
|
||||
endif()
|
||||
endif()
|
||||
unset( __levelIdx )
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
__DETECT_NATIVE_API_LEVEL( __realApiLevel "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include/android/api-level.h" )
|
||||
if( NOT __realApiLevel EQUAL ANDROID_NATIVE_API_LEVEL )
|
||||
message( SEND_ERROR "Specified Android API level (${ANDROID_NATIVE_API_LEVEL}) does not match to the level found (${__realApiLevel}). Probably your copy of NDK is broken." )
|
||||
endif()
|
||||
unset( __realApiLevel )
|
||||
endif()
|
||||
set( ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android API level for native code" FORCE )
|
||||
|
||||
|
||||
# remember target ABI
|
||||
set( ANDROID_ABI "${ANDROID_ABI}" CACHE STRING "The target ABI for Android. If arm, then armeabi-v7a is recommended for hardware floating point." FORCE )
|
||||
if( CMAKE_VERSION VERSION_GREATER "2.8" )
|
||||
list( SORT ANDROID_SUPPORTED_NATIVE_API_LEVELS )
|
||||
set_property( CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
|
||||
list( SORT ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME} )
|
||||
set_property( CACHE ANDROID_ABI PROPERTY STRINGS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME}} )
|
||||
endif()
|
||||
|
||||
# setup output directories
|
||||
set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" )
|
||||
set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" )
|
||||
|
||||
if(NOT _CMAKE_IN_TRY_COMPILE)
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" )
|
||||
set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" )
|
||||
else()
|
||||
set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" )
|
||||
endif()
|
||||
set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "path for android libs" )
|
||||
endif()
|
||||
|
||||
# runtime choice (STL, rtti, exceptions)
|
||||
if( NOT ANDROID_STL )
|
||||
@@ -800,83 +866,11 @@ See https://android.googlesource.com/platform/development.git f907f4f9d4e56ccc80
|
||||
" )
|
||||
endif()
|
||||
|
||||
# setup paths and STL for NDK
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
|
||||
set( ANDROID_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}" )
|
||||
|
||||
if( ANDROID_STL STREQUAL "none" )
|
||||
# do nothing
|
||||
elseif( ANDROID_STL STREQUAL "system" )
|
||||
set( ANDROID_RTTI OFF )
|
||||
set( ANDROID_EXCEPTIONS OFF )
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" )
|
||||
elseif( ANDROID_STL STREQUAL "system_re" )
|
||||
set( ANDROID_RTTI ON )
|
||||
set( ANDROID_EXCEPTIONS ON )
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" )
|
||||
elseif( ANDROID_STL MATCHES "gabi" )
|
||||
if( ANDROID_NDK_RELEASE STRLESS "r7" )
|
||||
message( FATAL_ERROR "gabi++ is not awailable in your NDK. You have to upgrade to NDK r7 or newer to use gabi++.")
|
||||
endif()
|
||||
set( ANDROID_RTTI ON )
|
||||
set( ANDROID_EXCEPTIONS OFF )
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/gabi++/include" )
|
||||
set( __libstl "${ANDROID_NDK}/sources/cxx-stl/gabi++/libs/${ANDROID_NDK_ABI_NAME}/libgabi++_static.a" )
|
||||
elseif( ANDROID_STL MATCHES "stlport" )
|
||||
set( ANDROID_EXCEPTIONS OFF )
|
||||
if( ANDROID_NDK_RELEASE STRLESS "r7" )
|
||||
set( ANDROID_RTTI OFF )
|
||||
else()
|
||||
set( ANDROID_RTTI ON )
|
||||
endif()
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/stlport/stlport" )
|
||||
set( __libstl "${ANDROID_NDK}/sources/cxx-stl/stlport/libs/${ANDROID_NDK_ABI_NAME}/libstlport_static.a" )
|
||||
elseif( ANDROID_STL MATCHES "gnustl" )
|
||||
set( ANDROID_EXCEPTIONS ON )
|
||||
set( ANDROID_RTTI ON )
|
||||
if( EXISTS "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" )
|
||||
set( __libstl "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" )
|
||||
else()
|
||||
set( __libstl "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++" )
|
||||
endif()
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${__libstl}/include" "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/include" )
|
||||
if( EXISTS "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" )
|
||||
set( __libstl "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" )
|
||||
else()
|
||||
set( __libstl "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
|
||||
endif()
|
||||
else()
|
||||
message( FATAL_ERROR "Unknown runtime: ${ANDROID_STL}" )
|
||||
endif()
|
||||
# find libsupc++.a - rtti & exceptions
|
||||
if( ANDROID_STL STREQUAL "system_re" OR ANDROID_STL MATCHES "gnustl" )
|
||||
if( ANDROID_NDK_RELEASE STRGREATER "r8" ) # r8b
|
||||
set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
|
||||
elseif( NOT ANDROID_NDK_RELEASE STRLESS "r7" AND ANDROID_NDK_RELEASE STRLESS "r8b")
|
||||
set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
|
||||
else( ANDROID_NDK_RELEASE STRLESS "r7" )
|
||||
if( ARMEABI_V7A )
|
||||
if( ANDROID_FORCE_ARM_BUILD )
|
||||
set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" )
|
||||
else()
|
||||
set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libsupc++.a" )
|
||||
endif()
|
||||
elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD )
|
||||
set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libsupc++.a" )
|
||||
else()
|
||||
set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" )
|
||||
endif()
|
||||
endif()
|
||||
if( NOT EXISTS "${__libsupcxx}")
|
||||
message( ERROR "Could not find libsupc++.a for a chosen platform. Either your NDK is not supported or is broken.")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# setup paths and STL for standalone toolchain
|
||||
if( BUILD_WITH_STANDALONE_TOOLCHAIN )
|
||||
set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" )
|
||||
set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" )
|
||||
set( ANDROID_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot" )
|
||||
|
||||
if( NOT ANDROID_STL STREQUAL "none" )
|
||||
@@ -923,6 +917,115 @@ if( BUILD_WITH_STANDALONE_TOOLCHAIN )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# clang
|
||||
if( "${ANDROID_TOOLCHAIN_NAME}" STREQUAL "standalone-clang" )
|
||||
set( ANDROID_COMPILER_IS_CLANG 1 )
|
||||
execute_process( COMMAND "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/clang${TOOL_OS_SUFFIX}" --version OUTPUT_VARIABLE ANDROID_CLANG_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||
string( REGEX MATCH "[0-9]+[.][0-9]+" ANDROID_CLANG_VERSION "${ANDROID_CLANG_VERSION}")
|
||||
elseif( "${ANDROID_TOOLCHAIN_NAME}" MATCHES "-clang3[.][0-9]?$" )
|
||||
string( REGEX MATCH "3[.][0-9]$" ANDROID_CLANG_VERSION "${ANDROID_TOOLCHAIN_NAME}")
|
||||
string( REGEX REPLACE "-clang${ANDROID_CLANG_VERSION}$" "-4.6" ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" )
|
||||
if( NOT EXISTS "${ANDROID_NDK}/toolchains/llvm-${ANDROID_CLANG_VERSION}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}/bin/clang${TOOL_OS_SUFFIX}" )
|
||||
message( FATAL_ERROR "Could not find the " )
|
||||
endif()
|
||||
set( ANDROID_COMPILER_IS_CLANG 1 )
|
||||
set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/llvm-${ANDROID_CLANG_VERSION}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
|
||||
else()
|
||||
set( ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" )
|
||||
unset( ANDROID_COMPILER_IS_CLANG CACHE )
|
||||
endif()
|
||||
|
||||
string( REPLACE "." "" _clang_name "clang${ANDROID_CLANG_VERSION}" )
|
||||
if( NOT EXISTS "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}" )
|
||||
set( _clang_name "clang" )
|
||||
endif()
|
||||
|
||||
|
||||
# setup paths and STL for NDK
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
|
||||
set( ANDROID_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}" )
|
||||
|
||||
if( ANDROID_STL STREQUAL "none" )
|
||||
# do nothing
|
||||
elseif( ANDROID_STL STREQUAL "system" )
|
||||
set( ANDROID_RTTI OFF )
|
||||
set( ANDROID_EXCEPTIONS OFF )
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" )
|
||||
elseif( ANDROID_STL STREQUAL "system_re" )
|
||||
set( ANDROID_RTTI ON )
|
||||
set( ANDROID_EXCEPTIONS ON )
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" )
|
||||
elseif( ANDROID_STL MATCHES "gabi" )
|
||||
if( ANDROID_NDK_RELEASE STRLESS "r7" )
|
||||
message( FATAL_ERROR "gabi++ is not awailable in your NDK. You have to upgrade to NDK r7 or newer to use gabi++.")
|
||||
endif()
|
||||
set( ANDROID_RTTI ON )
|
||||
set( ANDROID_EXCEPTIONS OFF )
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/gabi++/include" )
|
||||
set( __libstl "${ANDROID_NDK}/sources/cxx-stl/gabi++/libs/${ANDROID_NDK_ABI_NAME}/libgabi++_static.a" )
|
||||
elseif( ANDROID_STL MATCHES "stlport" )
|
||||
if( NOT ANDROID_NDK_RELEASE STRLESS "r8d" )
|
||||
set( ANDROID_EXCEPTIONS ON )
|
||||
else()
|
||||
set( ANDROID_EXCEPTIONS OFF )
|
||||
endif()
|
||||
if( ANDROID_NDK_RELEASE STRLESS "r7" )
|
||||
set( ANDROID_RTTI OFF )
|
||||
else()
|
||||
set( ANDROID_RTTI ON )
|
||||
endif()
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/stlport/stlport" )
|
||||
set( __libstl "${ANDROID_NDK}/sources/cxx-stl/stlport/libs/${ANDROID_NDK_ABI_NAME}/libstlport_static.a" )
|
||||
elseif( ANDROID_STL MATCHES "gnustl" )
|
||||
set( ANDROID_EXCEPTIONS ON )
|
||||
set( ANDROID_RTTI ON )
|
||||
if( EXISTS "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" )
|
||||
if( ARMEABI_V7A AND ANDROID_COMPILER_VERSION VERSION_EQUAL "4.7" AND ANDROID_NDK_RELEASE STREQUAL "r8d" )
|
||||
# gnustl binary for 4.7 compiler is buggy :(
|
||||
# TODO: look for right fix
|
||||
set( __libstl "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.6" )
|
||||
else()
|
||||
set( __libstl "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" )
|
||||
endif()
|
||||
else()
|
||||
set( __libstl "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++" )
|
||||
endif()
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${__libstl}/include" "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/include" )
|
||||
if( EXISTS "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" )
|
||||
set( __libstl "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" )
|
||||
else()
|
||||
set( __libstl "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
|
||||
endif()
|
||||
else()
|
||||
message( FATAL_ERROR "Unknown runtime: ${ANDROID_STL}" )
|
||||
endif()
|
||||
# find libsupc++.a - rtti & exceptions
|
||||
if( ANDROID_STL STREQUAL "system_re" OR ANDROID_STL MATCHES "gnustl" )
|
||||
if( ANDROID_NDK_RELEASE STRGREATER "r8" ) # r8b
|
||||
set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
|
||||
elseif( NOT ANDROID_NDK_RELEASE STRLESS "r7" AND ANDROID_NDK_RELEASE STRLESS "r8b")
|
||||
set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
|
||||
else( ANDROID_NDK_RELEASE STRLESS "r7" )
|
||||
if( ARMEABI_V7A )
|
||||
if( ANDROID_FORCE_ARM_BUILD )
|
||||
set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" )
|
||||
else()
|
||||
set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libsupc++.a" )
|
||||
endif()
|
||||
elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD )
|
||||
set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libsupc++.a" )
|
||||
else()
|
||||
set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" )
|
||||
endif()
|
||||
endif()
|
||||
if( NOT EXISTS "${__libsupcxx}")
|
||||
message( ERROR "Could not find libsupc++.a for a chosen platform. Either your NDK is not supported or is broken.")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# case of shared STL linkage
|
||||
if( ANDROID_STL MATCHES "shared" AND DEFINED __libstl )
|
||||
string( REPLACE "_static.a" "_shared.so" __libstl "${__libstl}" )
|
||||
@@ -937,25 +1040,40 @@ if( ANDROID_STL MATCHES "shared" AND DEFINED __libstl )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# ccache support
|
||||
__INIT_VARIABLE( _ndk_ccache NDK_CCACHE ENV_NDK_CCACHE )
|
||||
if( _ndk_ccache )
|
||||
if( DEFINED NDK_CCACHE AND NOT EXISTS NDK_CCACHE )
|
||||
unset( NDK_CCACHE CACHE )
|
||||
endif()
|
||||
find_program( NDK_CCACHE "${_ndk_ccache}" DOC "The path to ccache binary")
|
||||
else()
|
||||
unset( NDK_CCACHE CACHE )
|
||||
endif()
|
||||
unset( _ndk_ccache )
|
||||
|
||||
|
||||
# setup the cross-compiler
|
||||
if( NOT CMAKE_C_COMPILER )
|
||||
if( NDK_CCACHE )
|
||||
set( CMAKE_C_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C compiler" )
|
||||
set( CMAKE_CXX_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C++ compiler" )
|
||||
set( CMAKE_C_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "gcc")
|
||||
set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "g++")
|
||||
if( ANDROID_COMPILER_IS_CLANG )
|
||||
set( CMAKE_C_COMPILER_ARG1 "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}" CACHE PATH "C compiler")
|
||||
set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
|
||||
else()
|
||||
set( CMAKE_C_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "C compiler")
|
||||
set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
|
||||
endif()
|
||||
else()
|
||||
set( CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "gcc" )
|
||||
set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "g++" )
|
||||
if( ANDROID_COMPILER_IS_CLANG )
|
||||
set( CMAKE_C_COMPILER "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}" CACHE PATH "C compiler")
|
||||
set( CMAKE_CXX_COMPILER "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
|
||||
else()
|
||||
set( CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "C compiler" )
|
||||
set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler" )
|
||||
endif()
|
||||
endif()
|
||||
set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "assembler" )
|
||||
set( CMAKE_STRIP "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-strip${TOOL_OS_SUFFIX}" CACHE PATH "strip" )
|
||||
@@ -982,15 +1100,22 @@ endif()
|
||||
# Force set compilers because standard identification works badly for us
|
||||
include( CMakeForceCompiler )
|
||||
CMAKE_FORCE_C_COMPILER( "${CMAKE_C_COMPILER}" GNU )
|
||||
if( ANDROID_COMPILER_IS_CLANG )
|
||||
set( CMAKE_C_COMPILER_ID Clang)
|
||||
endif()
|
||||
set( CMAKE_C_PLATFORM_ID Linux )
|
||||
set( CMAKE_C_SIZEOF_DATA_PTR 4 )
|
||||
set( CMAKE_C_HAS_ISYSROOT 1 )
|
||||
set( CMAKE_C_COMPILER_ABI ELF )
|
||||
CMAKE_FORCE_CXX_COMPILER( "${CMAKE_CXX_COMPILER}" GNU )
|
||||
if( ANDROID_COMPILER_IS_CLANG )
|
||||
set( CMAKE_CXX_COMPILER_ID Clang)
|
||||
endif()
|
||||
set( CMAKE_CXX_PLATFORM_ID Linux )
|
||||
set( CMAKE_CXX_SIZEOF_DATA_PTR 4 )
|
||||
set( CMAKE_CXX_HAS_ISYSROOT 1 )
|
||||
set( CMAKE_CXX_COMPILER_ABI ELF )
|
||||
set( CMAKE_CXX_SOURCE_FILE_EXTENSIONS cc cp cxx cpp CPP c++ C )
|
||||
# force ASM compiler (required for CMake < 2.8.5)
|
||||
set( CMAKE_ASM_COMPILER_ID_RUN TRUE )
|
||||
set( CMAKE_ASM_COMPILER_ID GNU )
|
||||
@@ -1056,10 +1181,10 @@ if( ARMEABI_V7A )
|
||||
elseif( VFPV3 )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3" )
|
||||
else()
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfp" )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3-d16" )
|
||||
endif()
|
||||
elseif( ARMEABI_V6 )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv6 -mfloat-abi=softfp -mfpu=vfp" )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv6 -mfloat-abi=softfp -mfpu=vfp" ) # vfp == vfpv2
|
||||
elseif( ARMEABI )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv5te -mtune=xscale -msoft-float" )
|
||||
endif()
|
||||
@@ -1148,17 +1273,25 @@ if( ANDROID_FUNCTION_LEVEL_LINKING )
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--gc-sections" )
|
||||
endif()
|
||||
|
||||
if( ANDROID_GOLD_LINKER AND CMAKE_HOST_UNIX AND (ARMEABI OR ARMEABI_V7A OR X86) AND ANDROID_COMPILER_VERSION VERSION_EQUAL "4.6" )
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=gold" )
|
||||
elseif( ANDROID_NDK_RELEASE STREQUAL "r8b" AND ARMEABI AND ANDROID_COMPILER_VERSION VERSION_EQUAL "4.6" AND NOT _CMAKE_IN_TRY_COMPILE )
|
||||
message( WARNING "The default bfd linker from arm GCC 4.6 toolchain can fail with 'unresolvable R_ARM_THM_CALL relocation' error message. See https://code.google.com/p/android/issues/detail?id=35342
|
||||
if( ANDROID_COMPILER_VERSION VERSION_EQUAL "4.6" )
|
||||
if( ANDROID_GOLD_LINKER AND (CMAKE_HOST_UNIX OR ANDROID_NDK_RELEASE STRGREATER "r8b") AND (ARMEABI OR ARMEABI_V7A OR X86) )
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=gold" )
|
||||
elseif( ANDROID_NDK_RELEASE STRGREATER "r8b")
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=bfd" )
|
||||
elseif( ANDROID_NDK_RELEASE STREQUAL "r8b" AND ARMEABI AND NOT _CMAKE_IN_TRY_COMPILE )
|
||||
message( WARNING "The default bfd linker from arm GCC 4.6 toolchain can fail with 'unresolvable R_ARM_THM_CALL relocation' error message. See https://code.google.com/p/android/issues/detail?id=35342
|
||||
On Linux and OS X host platform you can workaround this problem using gold linker (default).
|
||||
Rerun cmake with -DANDROID_GOLD_LINKER=ON option.
|
||||
Rerun cmake with -DANDROID_GOLD_LINKER=ON option in case of problems.
|
||||
" )
|
||||
endif()
|
||||
endif()
|
||||
endif() # version 4.6
|
||||
|
||||
if( ANDROID_NOEXECSTACK )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -Wa,--noexecstack" )
|
||||
if( ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -Xclang -mnoexecstack" )
|
||||
else()
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -Wa,--noexecstack" )
|
||||
endif()
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-z,noexecstack" )
|
||||
endif()
|
||||
|
||||
@@ -1166,6 +1299,22 @@ if( ANDROID_RELRO )
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,now" )
|
||||
endif()
|
||||
|
||||
if( ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "-Qunused-arguments ${ANDROID_CXX_FLAGS}" )
|
||||
if( ARMEABI_V7A AND NOT ANDROID_FORCE_ARM_BUILD )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-target thumbv7-none-linux-androideabi ${ANDROID_CXX_FLAGS_RELEASE}" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-target ${ANDROID_LLVM_TRIPLE} ${ANDROID_CXX_FLAGS_DEBUG}" )
|
||||
else()
|
||||
set( ANDROID_CXX_FLAGS "-target ${ANDROID_LLVM_TRIPLE} ${ANDROID_CXX_FLAGS}" )
|
||||
endif()
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
if(ANDROID_ARCH_NAME STREQUAL "arm" )
|
||||
set( ANDROID_CXX_FLAGS "-isystem ${ANDROID_CLANG_TOOLCHAIN_ROOT}/lib/clang/${ANDROID_CLANG_VERSION}/include ${ANDROID_CXX_FLAGS}" )
|
||||
endif()
|
||||
set( ANDROID_CXX_FLAGS "-gcc-toolchain ${ANDROID_TOOLCHAIN_ROOT} ${ANDROID_CXX_FLAGS}" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# cache flags
|
||||
set( CMAKE_CXX_FLAGS "" CACHE STRING "c++ flags" )
|
||||
set( CMAKE_C_FLAGS "" CACHE STRING "c flags" )
|
||||
@@ -1189,9 +1338,9 @@ set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FL
|
||||
set( CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" )
|
||||
|
||||
if( MIPS AND BUILD_WITH_ANDROID_NDK AND ANDROID_NDK_RELEASE STREQUAL "r8" )
|
||||
set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" )
|
||||
set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" )
|
||||
set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" )
|
||||
set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" )
|
||||
set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" )
|
||||
set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" )
|
||||
endif()
|
||||
|
||||
# configure rtti
|
||||
@@ -1218,6 +1367,19 @@ endif()
|
||||
include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_STL_INCLUDE_DIRS} )
|
||||
link_directories( "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" )
|
||||
|
||||
# setup output directories
|
||||
set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" )
|
||||
set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" )
|
||||
|
||||
if(NOT _CMAKE_IN_TRY_COMPILE)
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" )
|
||||
set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" )
|
||||
else()
|
||||
set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" )
|
||||
endif()
|
||||
set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "path for android libs" )
|
||||
endif()
|
||||
|
||||
# set these global flags for cmake client scripts to change behavior
|
||||
set( ANDROID True )
|
||||
set( BUILD_ANDROID True )
|
||||
@@ -1335,7 +1497,7 @@ endif()
|
||||
# Variables controlling behavior or set by cmake toolchain:
|
||||
# ANDROID_ABI : "armeabi-v7a" (default), "armeabi", "armeabi-v7a with NEON", "armeabi-v7a with VFPV3", "armeabi-v6 with VFP", "x86", "mips"
|
||||
# ANDROID_NATIVE_API_LEVEL : 3,4,5,8,9,14 (depends on NDK version)
|
||||
# ANDROID_SET_OBSOLETE_VARIABLES : ON/OFF
|
||||
# ANDROID_STL : gnustl_static/gnustl_shared/stlport_static/stlport_shared/gabi++_static/gabi++_shared/system_re/system/none
|
||||
# ANDROID_FORBID_SYGWIN : ON/OFF
|
||||
# ANDROID_NO_UNDEFINED : ON/OFF
|
||||
# ANDROID_SO_UNDEFINED : OFF/ON (default depends on NDK version)
|
||||
@@ -1343,16 +1505,15 @@ endif()
|
||||
# ANDROID_GOLD_LINKER : ON/OFF
|
||||
# ANDROID_NOEXECSTACK : ON/OFF
|
||||
# ANDROID_RELRO : ON/OFF
|
||||
# Variables that takes effect only at first run:
|
||||
# ANDROID_FORCE_ARM_BUILD : ON/OFF
|
||||
# ANDROID_STL : gnustl_static/gnustl_shared/stlport_static/stlport_shared/gabi++_static/gabi++_shared/system_re/system/none
|
||||
# ANDROID_STL_FORCE_FEATURES : ON/OFF
|
||||
# LIBRARY_OUTPUT_PATH_ROOT : <any valid path>
|
||||
# NDK_CCACHE : <path to your ccache executable>
|
||||
# ANDROID_SET_OBSOLETE_VARIABLES : ON/OFF
|
||||
# Can be set only at the first run:
|
||||
# ANDROID_NDK
|
||||
# ANDROID_STANDALONE_TOOLCHAIN
|
||||
# ANDROID_TOOLCHAIN_NAME : "arm-linux-androideabi-4.4.3" or "arm-linux-androideabi-4.6" or "mipsel-linux-android-4.4.3" or "mipsel-linux-android-4.6" or "x86-4.4.3" or "x86-4.6"
|
||||
# ANDROID_TOOLCHAIN_NAME : the NDK name of compiler toolchain
|
||||
# LIBRARY_OUTPUT_PATH_ROOT : <any valid path>
|
||||
# NDK_CCACHE : <path to your ccache executable>
|
||||
# Obsolete:
|
||||
# ANDROID_API_LEVEL : superseded by ANDROID_NATIVE_API_LEVEL
|
||||
# ARM_TARGET : superseded by ANDROID_ABI
|
||||
@@ -1375,10 +1536,11 @@ endif()
|
||||
# BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used
|
||||
# ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform
|
||||
# ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a", "x86" or "mips" depending on ANDROID_ABI
|
||||
# ANDROID_NDK_RELEASE : one of r5, r5b, r5c, r6, r6b, r7, r7b, r7c, r8, r8b; set only for NDK
|
||||
# ANDROID_NDK_RELEASE : one of r5, r5b, r5c, r6, r6b, r7, r7b, r7c, r8, r8b, r8c, r8d; set only for NDK
|
||||
# ANDROID_ARCH_NAME : "arm" or "x86" or "mips" depending on ANDROID_ABI
|
||||
# ANDROID_SYSROOT : path to the compiler sysroot
|
||||
# TOOL_OS_SUFFIX : "" or ".exe" depending on host platform
|
||||
# ANDROID_COMPILER_IS_CLANG : TRUE if clang compiler is used
|
||||
# Obsolete:
|
||||
# ARMEABI_NDK_NAME : superseded by ANDROID_NDK_ABI_NAME
|
||||
#
|
||||
@@ -1388,10 +1550,13 @@ endif()
|
||||
# ANDROID_SUPPORTED_ABIS : list of currently allowed values for ANDROID_ABI
|
||||
# ANDROID_TOOLCHAIN_MACHINE_NAME : "arm-linux-androideabi", "arm-eabi" or "i686-android-linux"
|
||||
# ANDROID_TOOLCHAIN_ROOT : path to the top level of toolchain (standalone or placed inside NDK)
|
||||
# ANDROID_CLANG_TOOLCHAIN_ROOT : path to clang tools
|
||||
# ANDROID_SUPPORTED_NATIVE_API_LEVELS : list of native API levels found inside NDK
|
||||
# ANDROID_STL_INCLUDE_DIRS : stl include paths
|
||||
# ANDROID_RTTI : if rtti is enabled by the runtime
|
||||
# ANDROID_EXCEPTIONS : if exceptions are enabled by the runtime
|
||||
# ANDROID_GCC_TOOLCHAIN_NAME : read-only, differs from ANDROID_TOOLCHAIN_NAME only if clang is used
|
||||
# ANDROID_CLANG_VERSION : version of clang compiler if clang is used
|
||||
#
|
||||
# Defaults:
|
||||
# ANDROID_DEFAULT_NDK_API_LEVEL
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@ Java API
|
||||
********
|
||||
|
||||
|
||||
`Java API reference external link (JavaDoc) <http://docs.opencv.org/java/>`_
|
||||
Java API reference (JavaDoc): external `link <http://docs.opencv.org/java/>`_.
|
||||
|
||||
@@ -35,5 +35,5 @@ set_target_properties(${the_module} PROPERTIES
|
||||
INSTALL_NAME_DIR lib
|
||||
)
|
||||
|
||||
get_filename_component(lib_name "opencv_info" NAME)
|
||||
install(FILES "${LIBRARY_OUTPUT_PATH}/${lib_name}" DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT main)
|
||||
get_filename_component(lib_name "libopencv_info.so" NAME)
|
||||
install(FILES "${LIBRARY_OUTPUT_PATH}/${lib_name}" DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT main)
|
||||
|
||||
@@ -7,7 +7,7 @@ const char* GetLibraryList(void);
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_android_StaticHelper_getLibraryList(JNIEnv *, jclass);
|
||||
|
||||
#define PACKAGE_NAME "org.opencv.lib_v" CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) "_" ANDROID_PACKAGE_PLATFORM
|
||||
#define PACKAGE_REVISION CVAUX_STR(CV_SUBMINOR_VERSION) CVAUX_STR(ANDROID_PACKAGE_RELEASE)
|
||||
#define PACKAGE_REVISION CVAUX_STR(CV_SUBMINOR_VERSION) "." CVAUX_STR(ANDROID_PACKAGE_RELEASE)
|
||||
|
||||
const char* GetPackageName(void)
|
||||
{
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
# make target; arch; API level; Android Source Code Root
|
||||
native_camera_r2.2.0; armeabi; 8; /home/alexander/Projects/AndroidSource/2.2.2
|
||||
native_camera_r2.2.0; armeabi-v7a; 8; /home/alexander/Projects/AndroidSource/2.2.2
|
||||
native_camera_r2.3.3; armeabi; 9; /home/alexander/Projects/AndroidSource/2.3.3
|
||||
native_camera_r2.3.3; armeabi-v7a; 9; /home/alexander/Projects/AndroidSource/2.3.3
|
||||
native_camera_r2.3.3; x86; 9; /home/alexander/Projects/AndroidSource/2.3.3
|
||||
native_camera_r3.0.1; armeabi; 9; /home/alexander/Projects/AndroidSource/3.0.1
|
||||
native_camera_r3.0.1; armeabi-v7a; 9; /home/alexander/Projects/AndroidSource/3.0.1
|
||||
native_camera_r3.0.1; x86; 9; /home/alexander/Projects/AndroidSource/3.0.1
|
||||
native_camera_r4.0.3; armeabi; 14; /home/alexander/Projects/AndroidSource/4.0.3
|
||||
native_camera_r4.0.3; armeabi-v7a; 14; /home/alexander/Projects/AndroidSource/4.0.3
|
||||
native_camera_r4.0.3; x86; 14; /home/alexander/Projects/AndroidSource/4.0.3
|
||||
native_camera_r4.0.3; mips; 14; /home/alexander/Projects/AndroidSource/4.0.3_mips
|
||||
native_camera_r4.0.0; armeabi; 14; /home/alexander/Projects/AndroidSource/4.0.0
|
||||
native_camera_r4.0.0; armeabi-v7a; 14; /home/alexander/Projects/AndroidSource/4.0.0
|
||||
native_camera_r4.1.1; armeabi; 14; /home/alexander/Projects/AndroidSource/4.1.1
|
||||
native_camera_r4.1.1; armeabi-v7a; 14; /home/alexander/Projects/AndroidSource/4.1.1
|
||||
native_camera_r4.1.1; x86; 14; /home/alexander/Projects/AndroidSource/4.1.1
|
||||
native_camera_r2.2.0; armeabi; 8; $ANDROID_STUB_ROOT/2.2.2
|
||||
native_camera_r2.2.0; armeabi-v7a; 8; $ANDROID_STUB_ROOT/2.2.2
|
||||
native_camera_r2.3.3; armeabi; 9; $ANDROID_STUB_ROOT/2.3.3
|
||||
native_camera_r2.3.3; armeabi-v7a; 9; $ANDROID_STUB_ROOT/2.3.3
|
||||
native_camera_r2.3.3; x86; 9; $ANDROID_STUB_ROOT/2.3.3
|
||||
native_camera_r3.0.1; armeabi; 9; $ANDROID_STUB_ROOT/3.0.1
|
||||
native_camera_r3.0.1; armeabi-v7a; 9; $ANDROID_STUB_ROOT/3.0.1
|
||||
native_camera_r3.0.1; x86; 9; $ANDROID_STUB_ROOT/3.0.1
|
||||
native_camera_r4.0.3; armeabi; 14; $ANDROID_STUB_ROOT/4.0.3
|
||||
native_camera_r4.0.3; armeabi-v7a; 14; $ANDROID_STUB_ROOT/4.0.3
|
||||
native_camera_r4.0.3; x86; 14; $ANDROID_STUB_ROOT/4.0.3
|
||||
native_camera_r4.0.3; mips; 14; $ANDROID_STUB_ROOT/4.0.3_mips
|
||||
native_camera_r4.0.0; armeabi; 14; $ANDROID_STUB_ROOT/4.0.0
|
||||
native_camera_r4.0.0; armeabi-v7a; 14; $ANDROID_STUB_ROOT/4.0.0
|
||||
native_camera_r4.1.1; armeabi; 14; $ANDROID_STUB_ROOT/4.1.1
|
||||
native_camera_r4.1.1; armeabi-v7a; 14; $ANDROID_STUB_ROOT/4.1.1
|
||||
native_camera_r4.1.1; x86; 14; $ANDROID_STUB_ROOT/4.1.1
|
||||
native_camera_r4.1.1; mips; 14; $ANDROID_STUB_ROOT/4.1.1
|
||||
native_camera_r4.2.0; armeabi-v7a; 14; $ANDROID_STUB_ROOT/4.2.0
|
||||
native_camera_r4.2.0; armeabi; 14; $ANDROID_STUB_ROOT/4.2.0
|
||||
native_camera_r4.2.0; x86; 14; $ANDROID_STUB_ROOT/4.2.0
|
||||
native_camera_r4.2.0; mips; 14; $ANDROID_STUB_ROOT/4.2.0
|
||||
|
||||
@@ -7,6 +7,16 @@ import shutil
|
||||
ScriptHome = os.path.split(sys.argv[0])[0]
|
||||
ConfFile = open(os.path.join(ScriptHome, "camera_build.conf"), "rt")
|
||||
HomeDir = os.getcwd()
|
||||
|
||||
stub = ""
|
||||
try:
|
||||
stub = os.environ["ANDROID_STUB_ROOT"]
|
||||
except:
|
||||
None
|
||||
|
||||
if (stub == ""):
|
||||
print("Warning: ANDROID_STUB_ROOT environment variable is not set")
|
||||
|
||||
for s in ConfFile.readlines():
|
||||
s = s[0:s.find("#")]
|
||||
if (not s):
|
||||
@@ -20,6 +30,7 @@ for s in ConfFile.readlines():
|
||||
NativeApiLevel = str.strip(keys[2])
|
||||
AndroidTreeRoot = str.strip(keys[3])
|
||||
AndroidTreeRoot = str.strip(AndroidTreeRoot, "\n")
|
||||
AndroidTreeRoot = os.path.expandvars(AndroidTreeRoot)
|
||||
print("Building %s for %s" % (MakeTarget, Arch))
|
||||
BuildDir = os.path.join(HomeDir, MakeTarget + "_" + Arch)
|
||||
|
||||
@@ -33,20 +44,27 @@ for s in ConfFile.readlines():
|
||||
continue
|
||||
|
||||
shutil.rmtree(os.path.join(AndroidTreeRoot, "out", "target", "product", "generic", "system"), ignore_errors=True)
|
||||
|
||||
LinkerLibs = os.path.join(AndroidTreeRoot, "bin_arm", "system")
|
||||
if (Arch == "x86"):
|
||||
shutil.copytree(os.path.join(AndroidTreeRoot, "bin_x86", "system"), os.path.join(AndroidTreeRoot, "out", "target", "product", "generic", "system"))
|
||||
LinkerLibs = os.path.join(AndroidTreeRoot, "bin_x86", "system")
|
||||
elif (Arch == "mips"):
|
||||
shutil.copytree(os.path.join(AndroidTreeRoot, "bin_mips", "system"), os.path.join(AndroidTreeRoot, "out", "target", "product", "generic", "system"))
|
||||
else:
|
||||
shutil.copytree(os.path.join(AndroidTreeRoot, "bin_arm", "system"), os.path.join(AndroidTreeRoot, "out", "target", "product", "generic", "system"))
|
||||
LinkerLibs = os.path.join(AndroidTreeRoot, "bin_mips", "system")
|
||||
|
||||
if (not os.path.exists(LinkerLibs)):
|
||||
print("Error: Paltform libs for linker in path \"%s\" not found" % LinkerLibs)
|
||||
print("Building %s for %s\t[\033[91mFAILED\033[0m]" % (MakeTarget, Arch))
|
||||
continue
|
||||
|
||||
shutil.copytree(LinkerLibs, os.path.join(AndroidTreeRoot, "out", "target", "product", "generic", "system"))
|
||||
|
||||
os.chdir(BuildDir)
|
||||
BuildLog = os.path.join(BuildDir, "build.log")
|
||||
CmakeCmdLine = "cmake -DCMAKE_TOOLCHAIN_FILE=../android.toolchain.cmake -DANDROID_SOURCE_TREE=\"%s\" -DANDROID_NATIVE_API_LEVEL=\"%s\" -DANDROID_ABI=\"%s\" -DANDROID_STL=stlport_static ../../ > \"%s\" 2>&1" % (AndroidTreeRoot, NativeApiLevel, Arch, BuildLog)
|
||||
MakeCmdLine = "make %s >> \"%s\" 2>&1" % (MakeTarget, BuildLog);
|
||||
print(CmakeCmdLine)
|
||||
#print(CmakeCmdLine)
|
||||
os.system(CmakeCmdLine)
|
||||
print(MakeCmdLine)
|
||||
#print(MakeCmdLine)
|
||||
os.system(MakeCmdLine)
|
||||
os.chdir(HomeDir)
|
||||
CameraLib = os.path.join(BuildDir, "lib", Arch, "lib" + MakeTarget + ".so")
|
||||
|
||||
@@ -4,5 +4,5 @@ cd `dirname $0`/..
|
||||
mkdir -p build_service
|
||||
cd build_service
|
||||
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=../android.toolchain.cmake -DANDROID_STL=stlport_static -DANDROID_STL_FORCE_FEATURES=OFF -DBUILD_ANDROID_SERVICE=ON -DANDROID_SOURCE_TREE=~/Projects/AndroidSource/ServiceStub/ $@ ../..
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=../android.toolchain.cmake -DANDROID_TOOLCHAIN_NAME="arm-linux-androideabi-4.4.3" -DANDROID_STL=stlport_static -DANDROID_STL_FORCE_FEATURES=OFF -DBUILD_ANDROID_SERVICE=ON -DANDROID_SOURCE_TREE=~/Projects/AndroidSource/ServiceStub/ $@ ../..
|
||||
|
||||
|
||||
@@ -1,2 +1,6 @@
|
||||
add_subdirectory(engine)
|
||||
#add_subdirectory(engine_test)
|
||||
if(BUILD_ANDROID_SERVICE)
|
||||
add_subdirectory(engine)
|
||||
#add_subdirectory(engine_test)
|
||||
endif()
|
||||
|
||||
install(FILES "readme.txt" DESTINATION "apk/" COMPONENT main)
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
***************
|
||||
Package Content
|
||||
***************
|
||||
|
||||
The package provides new OpenCV SDK that uses OpenCV Manager for library initialization. OpenCV Manager provides the following benefits:
|
||||
|
||||
* Less memory usage. All apps use the same binaries from service and do not keep native libs inside them self;
|
||||
* Hardware specific optimizations for all supported platforms;
|
||||
* Trusted OpenCV library source. All packages with OpenCV are published on Google Play service;
|
||||
* Regular updates and bug fixes;
|
||||
|
||||
Package consists from Library Project for Java development with Eclipse, C++ headers and libraries for native application development, javadoc samples and prebuilt binaries for ARM and X86 platforms.
|
||||
To try new SDK on serial device with Google Play just install sample package and follow application messages (Google Play service access will be needed).
|
||||
TO start example on device without Google Play you need to install OpenCV manager package and OpenCV binary pack for your platform from apk folder before.
|
||||
See docs/doc/tutorials/introduction/android_binary_package/android_binary_package.html and docs/android/refmain.html for details about service.
|
||||
On-line documentation will be available at address: http://docs.opencv.org/trunk
|
||||
|
||||
********
|
||||
Contacts
|
||||
********
|
||||
|
||||
Please send all feedback to Alexander Smorkalov mailto: alexander.smorkalov@itseez.com
|
||||
@@ -1,18 +1,20 @@
|
||||
*********************************************
|
||||
Base Loader Callback Interface implementation
|
||||
Base Loader Callback Interface Implementation
|
||||
*********************************************
|
||||
|
||||
.. highlight:: java
|
||||
.. class:: BaseLoaderCallback
|
||||
|
||||
Basic implementation of LoaderCallbackInterface. Logic of this implementation is well-described by the following scheme:
|
||||
Basic implementation of ``LoaderCallbackInterface``. Logic of this implementation is
|
||||
well-described by the following scheme:
|
||||
|
||||
.. image:: img/AndroidAppUsageModel.png
|
||||
|
||||
Using in Java Activity
|
||||
----------------------
|
||||
|
||||
There is a very base code snippet implementing the async initialization with BaseLoaderCallback. See the "15-puzzle" OpenCV sample for details.
|
||||
There is a very base code snippet implementing the async initialization with ``BaseLoaderCallback``.
|
||||
See the "15-puzzle" OpenCV sample for details.
|
||||
|
||||
.. code-block:: java
|
||||
:linenos:
|
||||
@@ -42,7 +44,7 @@ There is a very base code snippet implementing the async initialization with Bas
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
Log.i(TAG, "called onResume");
|
||||
Log.i(TAG, "Called onResume");
|
||||
super.onResume();
|
||||
|
||||
Log.i(TAG, "Trying to load OpenCV library");
|
||||
@@ -55,6 +57,7 @@ There is a very base code snippet implementing the async initialization with Bas
|
||||
Using in Service
|
||||
----------------
|
||||
|
||||
Default BaseLoaderCallback implementation treat application context as Activity and calls Activity.finish() method to exit in case of initialization failure.
|
||||
To override this behavior you need to override finish() method of BaseLoaderCallback class and implement your own finalization method.
|
||||
|
||||
Default ``BaseLoaderCallback`` implementation treats application context as ``Activity`` and calls
|
||||
``Activity.finish()`` method to exit in case of initialization failure.
|
||||
To override this behavior you need to override ``finish()`` method of ``BaseLoaderCallback`` class
|
||||
and implement your own finalization method.
|
||||
|
||||
@@ -28,7 +28,7 @@ void cancel()
|
||||
|
||||
.. method:: void cancel()
|
||||
|
||||
Installation if package has been canceled.
|
||||
Installation of package has been cancelled.
|
||||
|
||||
void wait_install()
|
||||
-------------------
|
||||
|
||||
@@ -7,34 +7,38 @@ Introduction
|
||||
|
||||
.. highlight:: java
|
||||
|
||||
OpenCV Manager is an Android service targeted to manage OpenCV library binaries on end users devices. It allows sharing the OpenCV dynamic libraries of different versions between applications on the same device. The Manager provides the following benefits\:
|
||||
OpenCV Manager is an Android service targeted to manage OpenCV library binaries on end users devices.
|
||||
It allows sharing the OpenCV dynamic libraries between applications on the same device. The Manager
|
||||
provides the following benefits\:
|
||||
|
||||
#. Less memory usage. All apps use the same binaries from service and do not keep native libs inside themselves;
|
||||
#. Hardware specific optimizations for all supported platforms;
|
||||
#. Trusted OpenCV library source. All packages with OpenCV are published on Google Play service;
|
||||
#. Trusted OpenCV library source. All packages with OpenCV are published on Google Play market;
|
||||
#. Regular updates and bug fixes;
|
||||
|
||||
Usage model for target user
|
||||
---------------------------
|
||||
Usage model for end user
|
||||
------------------------
|
||||
|
||||
.. image:: img/AndroidAppUsageModel.png
|
||||
|
||||
First OpenCV app\:
|
||||
|
||||
#. Any OpenCV-dependent app is installed from Google Play marketplace or manually;
|
||||
#. At the first launch, it suggests installing OpenCV Manager;
|
||||
#. Then OpenCV Manager is downloaded and installed, using Google Play marketplace service.
|
||||
#. When Manager has ben started, the application suggests installing OpenCV library for the target device trough Google Play marketplace if it is necessary;
|
||||
#. After installation is finished, the app may be launched to perform common tasks.
|
||||
#. At the first launch, it suggests installation of OpenCV Manager;
|
||||
#. Then OpenCV Manager is downloaded and installed, using the Google Play application.
|
||||
#. When Manager has been started, the application suggests installation of OpenCV library for the
|
||||
target device architecture if it is necessary;
|
||||
#. After the installation is finished, the app may be launched.
|
||||
|
||||
Next OpenCV app\:
|
||||
Subsequent launches of OpenCV apps\:
|
||||
|
||||
#. Any OpenCV-dependent app is installed from Google Play marketplace or manually;
|
||||
#. Any OpenCV-dependent app is installed from Google Play market or manually;
|
||||
#. At the first launch, the app starts as usually;
|
||||
#. If the selected version is not installed, OpenCV Manager suggests installing OpenCV library for the target device trough Google Play marketplace;
|
||||
#. After installation is finished, the app may be launched to perform common tasks.
|
||||
#. If the selected OpenCV version is not installed, OpenCV Manager suggests installing OpenCV
|
||||
library for the target device through Google Play marketplace;
|
||||
#. After the installation is finished, the app may be launched.
|
||||
|
||||
OpenCV Manager structure
|
||||
------------------------
|
||||
Architecture of OpenCV Manager
|
||||
------------------------------
|
||||
|
||||
.. image:: img/Structure.png
|
||||
@@ -12,23 +12,27 @@ boolean initDebug()
|
||||
|
||||
.. method:: static boolean initDebug()
|
||||
|
||||
Loads and initializes OpenCV library from within current application package. Roughly it is analog of ``system.loadLibrary("opencv_java")``.
|
||||
Loads and initializes OpenCV library from within current application package. Roughly it is
|
||||
analog of ``system.loadLibrary("opencv_java")``.
|
||||
|
||||
:rtype: boolean;
|
||||
:return: returns true if initialization of OpenCV was successful.
|
||||
|
||||
.. note:: This method is deprecated for production code. It is designed for experimantal and local development purposes only. If you want to publish your app use approach with async initialization.
|
||||
.. note:: This method is deprecated for production code. It is designed for experimental and local
|
||||
development purposes only. If you want to publish your app use approach with async
|
||||
initialization.
|
||||
|
||||
boolean initAsync()
|
||||
-------------------
|
||||
|
||||
.. method:: static boolean initAsync(String Version, Context AppContext, LoaderCallbackInterface Callback)
|
||||
|
||||
Loads and initializes OpenCV library using OpenCV Manager service.
|
||||
Loads and initializes OpenCV library using OpenCV Manager.
|
||||
|
||||
:param Version: OpenCV Library version.
|
||||
:param AppContext: application context for connecting to the service.
|
||||
:param Callback: object, that implements LoaderCallbackInterface for handling connection status (see BaseLoaderCallback).
|
||||
:param Callback: object, that implements ``LoaderCallbackInterface`` for handling connection
|
||||
status (see ``BaseLoaderCallback``).
|
||||
|
||||
:rtype: boolean;
|
||||
:return: returns true if initialization of OpenCV starts successfully.
|
||||
@@ -43,10 +47,3 @@ OpenCV version constants
|
||||
.. data:: OPENCV_VERSION_2_4_3
|
||||
|
||||
OpenCV Library version 2.4.3
|
||||
|
||||
Other constatnts
|
||||
----------------
|
||||
|
||||
.. data:: OPEN_CV_SERVICE_URL
|
||||
|
||||
Url for OpenCV Manager on Google Play (Android Market)
|
||||
@@ -12,9 +12,9 @@ void onManagerConnected()
|
||||
|
||||
.. method:: void onManagerConnected(int status)
|
||||
|
||||
Callback method that is called after OpenCV Library initialization.
|
||||
Callback method that is called after OpenCV library initialization.
|
||||
|
||||
:param status: status of initialization (see Initialization Status Constants).
|
||||
:param status: status of initialization (see "Initialization Status Constants" section below).
|
||||
|
||||
void onPackageInstall()
|
||||
-----------------------
|
||||
@@ -23,7 +23,7 @@ void onPackageInstall()
|
||||
|
||||
Callback method that is called in case when package installation is needed.
|
||||
|
||||
:param callback: answer object with approve and cancel methods and package description.
|
||||
:param callback: answer object with ``install`` and ``cancel`` methods and package description.
|
||||
|
||||
Initialization status constants
|
||||
-------------------------------
|
||||
@@ -34,15 +34,15 @@ Initialization status constants
|
||||
|
||||
.. data:: MARKET_ERROR
|
||||
|
||||
Google Play (Android Market) cannot be invoked
|
||||
Google Play (Android Market) application cannot be invoked
|
||||
|
||||
.. data:: INSTALL_CANCELED
|
||||
|
||||
OpenCV library installation was canceled by user
|
||||
OpenCV library installation was cancelled by user
|
||||
|
||||
.. data:: INCOMPATIBLE_MANAGER_VERSION
|
||||
|
||||
Version of OpenCV Manager Service is incompatible with this app. Service update is needed
|
||||
Version of OpenCV Manager is incompatible with this app. Manager update is needed.
|
||||
|
||||
.. data:: INIT_FAILED
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
*******************************************
|
||||
Manager Workflow
|
||||
*******************************************
|
||||
****************
|
||||
|
||||
.. _manager_selection:
|
||||
|
||||
.. include:: ../readme.txt
|
||||
|
||||
First application start
|
||||
-----------------------
|
||||
@@ -9,15 +12,15 @@ There is no OpenCV Manager or OpenCV libraries:
|
||||
|
||||
.. image:: img/NoService.png
|
||||
|
||||
Aditional library package installation
|
||||
--------------------------------------
|
||||
Additional library package installation
|
||||
---------------------------------------
|
||||
|
||||
There is an OpenCV Manager service, but there is no apropriate OpenCV library.
|
||||
There is an OpenCV Manager service, but it does not contain appropriate OpenCV library.
|
||||
If OpenCV library installation has been approved\:
|
||||
|
||||
.. image:: img/LibInstallAproved.png
|
||||
|
||||
If OpenCV library installation has been canceled\:
|
||||
If OpenCV library installation has been cancelled\:
|
||||
|
||||
.. image:: img/LibInstallCanceled.png
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.opencv.engine"
|
||||
android:versionCode="20"
|
||||
android:versionName="2.0" >
|
||||
android:versionCode="24@ANDROID_PLATFORM_VERSION_CODE@"
|
||||
android:versionName="2.4" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="8" />
|
||||
<uses-sdk android:minSdkVersion="@ANDROID_NATIVE_API_LEVEL@" />
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
|
||||
|
||||
<application
|
||||
|
||||
@@ -2,7 +2,29 @@ set(engine OpenCVEngine)
|
||||
set(JNI_LIB_NAME ${engine} ${engine}_jni)
|
||||
|
||||
unset(__android_project_chain CACHE)
|
||||
add_android_project(opencv_engine "${CMAKE_CURRENT_SOURCE_DIR}" SDK_TARGET 8 ${ANDROID_SDK_TARGET} IGNORE_JAVA ON)
|
||||
add_android_project(opencv_engine "${CMAKE_CURRENT_SOURCE_DIR}" SDK_TARGET 9 ${ANDROID_SDK_TARGET} IGNORE_JAVA ON IGNORE_MANIFEST ON )
|
||||
|
||||
set(ANDROID_PLATFORM_VERSION_CODE "0")
|
||||
|
||||
if(ARMEABI_V7A)
|
||||
if (ANDROID_NATIVE_API_LEVEL LESS 9)
|
||||
set(ANDROID_PLATFORM_VERSION_CODE "2")
|
||||
else()
|
||||
set(ANDROID_PLATFORM_VERSION_CODE "3")
|
||||
endif()
|
||||
elseif(ARMEABI_V6)
|
||||
set(ANDROID_PLATFORM_VERSION_CODE "1")
|
||||
elseif(ARMEABI)
|
||||
set(ANDROID_PLATFORM_VERSION_CODE "1")
|
||||
elseif(X86)
|
||||
set(ANDROID_PLATFORM_VERSION_CODE "4")
|
||||
elseif(MIPS)
|
||||
set(ANDROID_PLATFORM_VERSION_CODE "5")
|
||||
else()
|
||||
message(WARNING "Can not automatically determine the value for ANDROID_PLATFORM_VERSION_CODE")
|
||||
endif()
|
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${ANDROID_MANIFEST_FILE}" "${OpenCV_BINARY_DIR}/android/service/engine/.build/${ANDROID_MANIFEST_FILE}" @ONLY)
|
||||
|
||||
link_directories("${ANDROID_SOURCE_TREE}/out/target/product/generic/system/lib" "${ANDROID_SOURCE_TREE}/out/target/product/${ANDROID_PRODUCT}/system/lib" "${ANDROID_SOURCE_TREE}/bin/${ANDROID_ARCH_NAME}")
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="ManagerActivity" default="help">
|
||||
<project name="OpenCV Manager" default="help">
|
||||
|
||||
<!-- The local.properties file is created and updated by the 'android' tool.
|
||||
It contains the path to the SDK. It should *NOT* be checked into
|
||||
|
||||
@@ -35,7 +35,7 @@ LOCAL_MODULE := libOpenCVEngine
|
||||
|
||||
LOCAL_LDLIBS += -lz -lbinder -llog -lutils
|
||||
|
||||
LOCAL_LDFLAGS += -Wl,-allow-shlib-undefine
|
||||
LOCAL_LDFLAGS += -Wl,-allow-shlib-undefined
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
@@ -52,7 +52,8 @@ LOCAL_SRC_FILES := \
|
||||
NativeService/CommonPackageManager.cpp \
|
||||
JNIWrapper/JavaBasedPackageManager.cpp \
|
||||
NativeService/PackageInfo.cpp \
|
||||
JNIWrapper/HardwareDetector_jni.cpp
|
||||
JNIWrapper/HardwareDetector_jni.cpp \
|
||||
JNIWrapper/OpenCVLibraryInfo.cpp
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(LOCAL_PATH)/include \
|
||||
@@ -74,7 +75,6 @@ LOCAL_CFLAGS += -D__SUPPORT_MIPS
|
||||
LOCAL_MODULE := libOpenCVEngine_jni
|
||||
|
||||
LOCAL_LDLIBS += -lz -lbinder -llog -lutils -landroid_runtime
|
||||
|
||||
LOCAL_SHARED_LIBRARIES = libOpenCVEngine
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -83,4 +83,4 @@ include $(BUILD_SHARED_LIBRARY)
|
||||
# Native test application
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
include $(LOCAL_PATH)/Tests/Tests.mk
|
||||
#include $(LOCAL_PATH)/Tests/Tests.mk
|
||||
@@ -2,4 +2,5 @@ APP_ABI := armeabi x86 mips
|
||||
APP_PLATFORM := android-8
|
||||
APP_STL := stlport_static
|
||||
APP_CPPFLAGS := -fno-rtti -fno-exceptions
|
||||
NDK_TOOLCHAIN_VERSION=4.4.3
|
||||
#APP_OPTIM := debug
|
||||
@@ -130,7 +130,7 @@ android::String16 OpenCVEngine::GetLibraryList(android::String16 version)
|
||||
LOGD("Trying to load info library \"%s\"", tmp.c_str());
|
||||
|
||||
void* handle;
|
||||
const char* (*info_func)();
|
||||
InfoFunctionType info_func;
|
||||
|
||||
handle = dlopen(tmp.c_str(), RTLD_LAZY);
|
||||
if (handle)
|
||||
@@ -138,7 +138,7 @@ android::String16 OpenCVEngine::GetLibraryList(android::String16 version)
|
||||
const char* error;
|
||||
|
||||
dlerror();
|
||||
*(void **) (&info_func) = dlsym(handle, "GetLibraryList");
|
||||
info_func = (InfoFunctionType)dlsym(handle, "GetLibraryList");
|
||||
if ((error = dlerror()) == NULL)
|
||||
{
|
||||
result = String16((*info_func)());
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#include "OpenCVLibraryInfo.h"
|
||||
#include "EngineCommon.h"
|
||||
#include <utils/Log.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_open
|
||||
(JNIEnv * env, jobject, jstring str)
|
||||
{
|
||||
const char* infoLibPath = env->GetStringUTFChars(str, NULL);
|
||||
if (infoLibPath == NULL)
|
||||
return 0;
|
||||
|
||||
LOGD("Trying to load info library \"%s\"", infoLibPath);
|
||||
|
||||
void* handle;
|
||||
|
||||
handle = dlopen(infoLibPath, RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
LOGI("Info library not found by path \"%s\"", infoLibPath);
|
||||
|
||||
return (jlong)handle;
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getPackageName
|
||||
(JNIEnv* env, jobject, jlong handle)
|
||||
{
|
||||
InfoFunctionType info_func;
|
||||
const char* result;
|
||||
const char* error;
|
||||
|
||||
dlerror();
|
||||
info_func = (InfoFunctionType)dlsym((void*)handle, "GetPackageName");
|
||||
if ((error = dlerror()) == NULL)
|
||||
result = (*info_func)();
|
||||
else
|
||||
{
|
||||
LOGE("dlsym error: \"%s\"", error);
|
||||
result = "unknown";
|
||||
}
|
||||
|
||||
return env->NewStringUTF(result);
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getLibraryList
|
||||
(JNIEnv* env, jobject, jlong handle)
|
||||
{
|
||||
InfoFunctionType info_func;
|
||||
const char* result;
|
||||
const char* error;
|
||||
|
||||
dlerror();
|
||||
info_func = (InfoFunctionType)dlsym((void*)handle, "GetLibraryList");
|
||||
if ((error = dlerror()) == NULL)
|
||||
result = (*info_func)();
|
||||
else
|
||||
{
|
||||
LOGE("dlsym error: \"%s\"", error);
|
||||
result = "unknown";
|
||||
}
|
||||
|
||||
return env->NewStringUTF(result);
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getVersionName
|
||||
(JNIEnv* env, jobject, jlong handle)
|
||||
{
|
||||
InfoFunctionType info_func;
|
||||
const char* result;
|
||||
const char* error;
|
||||
|
||||
dlerror();
|
||||
info_func = (InfoFunctionType)dlsym((void*)handle, "GetRevision");
|
||||
if ((error = dlerror()) == NULL)
|
||||
result = (*info_func)();
|
||||
else
|
||||
{
|
||||
LOGE("dlsym error: \"%s\"", error);
|
||||
result = "unknown";
|
||||
}
|
||||
|
||||
return env->NewStringUTF(result);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_close
|
||||
(JNIEnv*, jobject, jlong handle)
|
||||
{
|
||||
dlclose((void*)handle);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <jni.h>
|
||||
|
||||
#ifndef _Included_org_opencv_engine_OpenCVLibraryInfo
|
||||
#define _Included_org_opencv_engine_OpenCVLibraryInfo
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_open
|
||||
(JNIEnv *, jobject, jstring);
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getPackageName
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getLibraryList
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getVersionName
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_close
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -78,49 +78,45 @@ string CommonPackageManager::GetPackagePathByVersion(const std::string& version,
|
||||
|
||||
if (!packages.empty())
|
||||
{
|
||||
vector<PackageInfo>::iterator found = find(packages.begin(), packages.end(), target_package);
|
||||
if (packages.end() != found)
|
||||
int OptRating = -1;
|
||||
std::string OptVersion = "";
|
||||
std::vector<std::pair<int, int> >& group = CommonPackageManager::ArmRating;
|
||||
|
||||
if ((cpu_id & ARCH_X86) || (cpu_id & ARCH_X64))
|
||||
group = CommonPackageManager::IntelRating;
|
||||
|
||||
int HardwareRating = GetHardwareRating(platform, cpu_id, group);
|
||||
LOGD("Current hardware platform rating %d for (%d,%d)", HardwareRating, platform, cpu_id);
|
||||
|
||||
if (-1 == HardwareRating)
|
||||
{
|
||||
result = found->GetInstalationPath();
|
||||
LOGE("Cannot calculate rating for current hardware platform!");
|
||||
}
|
||||
else
|
||||
{
|
||||
int OptRating = -1;
|
||||
std::vector<std::pair<int, int> >& group = CommonPackageManager::ArmRating;
|
||||
|
||||
if ((cpu_id & ARCH_X86) || (cpu_id & ARCH_X64))
|
||||
group = CommonPackageManager::IntelRating;
|
||||
|
||||
int HardwareRating = GetHardwareRating(platform, cpu_id, group);
|
||||
LOGD("Current hardware platform %d, %d", platform, cpu_id);
|
||||
|
||||
if (-1 == HardwareRating)
|
||||
vector<PackageInfo>::iterator found = packages.end();
|
||||
for (vector<PackageInfo>::iterator it = packages.begin(); it != packages.end(); ++it)
|
||||
{
|
||||
LOGE("Cannot calculate rating for current hardware platform!");
|
||||
int PackageRating = GetHardwareRating(it->GetPlatform(), it->GetCpuID(), group);
|
||||
LOGD("Package \"%s\" rating %d for (%d,%d)", it->GetFullName().c_str(), PackageRating, it->GetPlatform(), it->GetCpuID());
|
||||
if ((PackageRating >= 0) && (PackageRating <= HardwareRating))
|
||||
{
|
||||
if (((it->GetVersion() >= OptVersion) && (PackageRating >= OptRating)) || (it->GetVersion() > OptVersion))
|
||||
{
|
||||
OptRating = PackageRating;
|
||||
OptVersion = it->GetVersion();
|
||||
found = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((-1 != OptRating) && (packages.end() != found))
|
||||
{
|
||||
result = found->GetInstalationPath();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (vector<PackageInfo>::iterator it = packages.begin(); it != packages.end(); ++it)
|
||||
{
|
||||
int PackageRating = GetHardwareRating(it->GetPlatform(), it->GetCpuID(), group);
|
||||
if (PackageRating >= 0)
|
||||
{
|
||||
if ((PackageRating <= HardwareRating) && (PackageRating > OptRating))
|
||||
{
|
||||
OptRating = PackageRating;
|
||||
found = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((-1 != OptRating) && (packages.end() != found))
|
||||
{
|
||||
result = found->GetInstalationPath();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGI("Found package is incompatible with current hardware platform");
|
||||
}
|
||||
LOGI("Found package is incompatible with current hardware platform");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,7 +134,7 @@ bool CommonPackageManager::IsVersionCompatible(const std::string& target_version
|
||||
// major version is the same and minor package version is above or the same as target.
|
||||
if ((package_version[0] == target_version[0]) && (package_version[1] == target_version[1]) && (package_version[2] >= target_version[2]))
|
||||
{
|
||||
result = true;
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -148,13 +144,21 @@ int CommonPackageManager::GetHardwareRating(int platform, int cpu_id, const std:
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
for (size_t i = 0; i < group.size(); i++)
|
||||
if ((cpu_id & ARCH_X86) || (cpu_id & ARCH_X64) || (cpu_id & ARCH_MIPS))
|
||||
// Note: No raiting for x86, x64 and MIPS
|
||||
// only one package is used
|
||||
result = 0;
|
||||
else
|
||||
{
|
||||
if (group[i] == std::pair<int, int>(platform, cpu_id))
|
||||
{
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
// Calculate rating for Arm
|
||||
for (size_t i = 0; i < group.size(); i++)
|
||||
{
|
||||
if (group[i] == std::pair<int, int>(platform, cpu_id))
|
||||
{
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -171,14 +175,14 @@ std::vector<std::pair<int, int> > CommonPackageManager::InitArmRating()
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv6 | FEATURES_HAS_VFPv3 | FEATURES_HAS_VFPv3d16));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3d16));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_TEGRA2, ARCH_ARMv7 | FEATURES_HAS_VFPv3d16));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3d16 | FEATURES_HAS_VFPv3));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3d16 | FEATURES_HAS_NEON));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_VFPv3d16 | FEATURES_HAS_NEON));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_TEGRA2, ARCH_ARMv7 | FEATURES_HAS_VFPv3d16));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -197,6 +197,7 @@ InstallPath("")
|
||||
#ifndef __SUPPORT_TEGRA3
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
#endif
|
||||
|
||||
FullName = BasePackageName + "_v" + Version.substr(0, Version.size()-1);
|
||||
if (PLATFORM_UNKNOWN != Platform)
|
||||
{
|
||||
@@ -341,8 +342,8 @@ InstallPath(install_path)
|
||||
LOGD("Trying to load info library \"%s\"", tmp.c_str());
|
||||
|
||||
void* handle;
|
||||
const char* (*name_func)();
|
||||
const char* (*revision_func)();
|
||||
InfoFunctionType name_func;
|
||||
InfoFunctionType revision_func;
|
||||
|
||||
handle = dlopen(tmp.c_str(), RTLD_LAZY);
|
||||
if (handle)
|
||||
@@ -350,8 +351,8 @@ InstallPath(install_path)
|
||||
const char* error;
|
||||
|
||||
dlerror();
|
||||
*(void **) (&name_func) = dlsym(handle, "GetPackageName");
|
||||
*(void **) (&revision_func) = dlsym(handle, "GetRevision");
|
||||
name_func = (InfoFunctionType)dlsym(handle, "GetPackageName");
|
||||
revision_func = (InfoFunctionType)dlsym(handle, "GetRevision");
|
||||
error = dlerror();
|
||||
|
||||
if (!error && revision_func && name_func)
|
||||
@@ -392,7 +393,17 @@ InstallPath(install_path)
|
||||
Platform = SplitPlatfrom(features);
|
||||
if (PLATFORM_UNKNOWN != Platform)
|
||||
{
|
||||
CpuID = 0;
|
||||
switch (Platform)
|
||||
{
|
||||
case PLATFORM_TEGRA2:
|
||||
{
|
||||
CpuID = ARCH_ARMv7 | FEATURES_HAS_VFPv3d16;
|
||||
} break;
|
||||
case PLATFORM_TEGRA3:
|
||||
{
|
||||
CpuID = ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ LOCAL_CFLAGS += -D__SUPPORT_TEGRA3
|
||||
LOCAL_CFLAGS += -D__SUPPORT_MIPS
|
||||
#LOCAL_CFLAGS += -D__SUPPORT_ARMEABI_FEATURES
|
||||
|
||||
LOCAL_LDFLAGS = -Wl,-allow-shlib-undefined
|
||||
#LOCAL_LDFLAGS = -Wl,-allow-shlib-undefined
|
||||
|
||||
LOCAL_MODULE := OpenCVEngineTestApp
|
||||
|
||||
|
||||
@@ -5,10 +5,18 @@
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "OpenCVEngine"
|
||||
|
||||
// OpenCV Engine API version
|
||||
#ifndef OPEN_CV_ENGINE_VERSION
|
||||
#define OPEN_CV_ENGINE_VERSION 2
|
||||
#endif
|
||||
|
||||
#define LIB_OPENCV_INFO_NAME "libopencv_info.so"
|
||||
|
||||
// OpenCV Manager package name
|
||||
#define OPENCV_ENGINE_PACKAGE "org.opencv.engine"
|
||||
// Class name of OpenCV engine binder object. Is needned for connection to service
|
||||
#define OPECV_ENGINE_CLASSNAME "org.opencv.engine.OpenCVEngineInterface"
|
||||
|
||||
typedef const char* (*InfoFunctionType)();
|
||||
|
||||
#endif
|
||||
@@ -4,11 +4,7 @@
|
||||
#include <binder/IInterface.h>
|
||||
#include <binder/Parcel.h>
|
||||
#include <utils/String16.h>
|
||||
|
||||
// OpenCV Manager package name
|
||||
#define OPENCV_ENGINE_PACKAGE "org.opencv.engine"
|
||||
// Class name of OpenCV engine binder object. Is needned for connection to service
|
||||
#define OPECV_ENGINE_CLASSNAME "org.opencv.engine.OpenCVEngineInterface"
|
||||
#include "EngineCommon.h"
|
||||
|
||||
enum EngineMethonID
|
||||
{
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-8
|
||||
target=android-9
|
||||
|
||||
@@ -20,8 +20,6 @@ public class MarketConnector
|
||||
private static final String TAG = "OpenCVEngine/MarketConnector";
|
||||
protected Context mContext;
|
||||
|
||||
public boolean mIncludeManager = true;
|
||||
|
||||
public MarketConnector(Context context)
|
||||
{
|
||||
mContext = context;
|
||||
@@ -100,15 +98,13 @@ public class MarketConnector
|
||||
{
|
||||
List<PackageInfo> AllPackages = mContext.getPackageManager().getInstalledPackages(PackageManager.GET_CONFIGURATIONS);
|
||||
List<PackageInfo> OpenCVPackages = new ArrayList<PackageInfo>();
|
||||
if (mIncludeManager)
|
||||
{
|
||||
try {
|
||||
OpenCVPackages.add(mContext.getPackageManager().getPackageInfo("org.opencv.engine", PackageManager.GET_CONFIGURATIONS));
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.e(TAG, "OpenCV Manager package info was not found!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
OpenCVPackages.add(mContext.getPackageManager().getPackageInfo("org.opencv.engine", PackageManager.GET_CONFIGURATIONS));
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.e(TAG, "OpenCV Manager package info was not found!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Iterator<PackageInfo> it = AllPackages.iterator();
|
||||
while(it.hasNext())
|
||||
{
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.opencv.engine;
|
||||
|
||||
public class OpenCVLibraryInfo {
|
||||
public OpenCVLibraryInfo(String packagePath) {
|
||||
mNativeObj = open(packagePath + "/libopencv_info.so");
|
||||
if (mNativeObj != 0) {
|
||||
mPackageName = getPackageName(mNativeObj);
|
||||
mLibraryList = getLibraryList(mNativeObj);
|
||||
mVersionName = getVersionName(mNativeObj);
|
||||
close(mNativeObj);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean status() {
|
||||
return (mNativeObj != 0);
|
||||
}
|
||||
|
||||
public String packageName() {
|
||||
return mPackageName;
|
||||
}
|
||||
|
||||
public String libraryList() {
|
||||
return mLibraryList;
|
||||
}
|
||||
|
||||
public String versionName() {
|
||||
return mVersionName;
|
||||
}
|
||||
|
||||
private long mNativeObj;
|
||||
private String mPackageName;
|
||||
private String mLibraryList;
|
||||
private String mVersionName;
|
||||
|
||||
private native long open(String packagePath);
|
||||
private native String getPackageName(long obj);
|
||||
private native String getLibraryList(long obj);
|
||||
private native String getVersionName(long obj);
|
||||
private native void close(long obj);
|
||||
}
|
||||
@@ -7,7 +7,9 @@ import java.util.StringTokenizer;
|
||||
import org.opencv.engine.HardwareDetector;
|
||||
import org.opencv.engine.MarketConnector;
|
||||
import org.opencv.engine.OpenCVEngineInterface;
|
||||
import org.opencv.engine.OpenCVLibraryInfo;
|
||||
import org.opencv.engine.R;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -77,7 +79,7 @@ public class ManagerActivity extends Activity
|
||||
{
|
||||
HardwarePlatformView.setText("Tegra");
|
||||
}
|
||||
else if (HardwareDetector.PLATFORM_TEGRA == Platfrom)
|
||||
else if (HardwareDetector.PLATFORM_TEGRA2 == Platfrom)
|
||||
{
|
||||
HardwarePlatformView.setText("Tegra 2");
|
||||
}
|
||||
@@ -170,9 +172,13 @@ public class ManagerActivity extends Activity
|
||||
|
||||
mInstalledPackageView.setOnItemClickListener(new OnItemClickListener() {
|
||||
|
||||
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long id) {
|
||||
mInstalledPackageView.setTag(Integer.valueOf((int)id));
|
||||
mActionDialog.show();
|
||||
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
|
||||
//if (!mListViewItems.get((int) id).get("Name").equals("Built-in OpenCV library"));
|
||||
if (!mInstalledPackageInfo[(int) id].packageName.equals("org.opencv.engine"))
|
||||
{
|
||||
mInstalledPackageView.setTag(Integer.valueOf((int)id));
|
||||
mActionDialog.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -232,8 +238,6 @@ public class ManagerActivity extends Activity
|
||||
protected class OpenCVEngineServiceConnection implements ServiceConnection
|
||||
{
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
@@ -266,23 +270,58 @@ public class ManagerActivity extends Activity
|
||||
}
|
||||
};
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
|
||||
synchronized protected void FillPackageList()
|
||||
{
|
||||
synchronized (mListViewItems) {
|
||||
mMarket.mIncludeManager = false;
|
||||
mInstalledPackageInfo = mMarket.GetInstalledOpenCVPackages();
|
||||
mListViewItems.clear();
|
||||
|
||||
for (int i = 0; i < mInstalledPackageInfo.length; i++)
|
||||
int RealPackageCount = mInstalledPackageInfo.length;
|
||||
for (int i = 0; i < RealPackageCount; i++)
|
||||
{
|
||||
if (mInstalledPackageInfo[i] == null)
|
||||
break;
|
||||
|
||||
// Convert to Items for package list view
|
||||
HashMap<String,String> temp = new HashMap<String,String>();
|
||||
|
||||
String HardwareName = "";
|
||||
String NativeLibDir = "";
|
||||
String OpenCVersion = "";
|
||||
|
||||
String PublicName = mMarket.GetApplicationName(mInstalledPackageInfo[i].applicationInfo);
|
||||
String PackageName = mInstalledPackageInfo[i].packageName;
|
||||
String VersionName = mInstalledPackageInfo[i].versionName;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD)
|
||||
NativeLibDir = mInstalledPackageInfo[i].applicationInfo.nativeLibraryDir;
|
||||
else
|
||||
NativeLibDir = "/data/data/" + mInstalledPackageInfo[i].packageName + "/lib";
|
||||
|
||||
OpenCVLibraryInfo NativeInfo = new OpenCVLibraryInfo(NativeLibDir);
|
||||
|
||||
if (PackageName.equals("org.opencv.engine"))
|
||||
{
|
||||
if (NativeInfo.status())
|
||||
{
|
||||
PublicName = "Built-in OpenCV library";
|
||||
PackageName = NativeInfo.packageName();
|
||||
VersionName = NativeInfo.versionName();
|
||||
}
|
||||
else
|
||||
{
|
||||
mInstalledPackageInfo[i] = mInstalledPackageInfo[RealPackageCount-1];
|
||||
mInstalledPackageInfo[RealPackageCount-1] = null;
|
||||
RealPackageCount--;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
String OpenCVersion = "unknown";
|
||||
String HardwareName = "";
|
||||
StringTokenizer tokenizer = new StringTokenizer(mInstalledPackageInfo[i].packageName, "_");
|
||||
Log.d(TAG, PackageName);
|
||||
StringTokenizer tokenizer = new StringTokenizer(PackageName, "_");
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
if (idx == 1)
|
||||
@@ -303,6 +342,7 @@ public class ManagerActivity extends Activity
|
||||
}
|
||||
|
||||
String ActivePackagePath;
|
||||
String Tags = null;
|
||||
ActivePackagePath = mActivePackageMap.get(OpenCVersion);
|
||||
Log.d(TAG, OpenCVersion + " -> " + ActivePackagePath);
|
||||
|
||||
@@ -313,11 +353,13 @@ public class ManagerActivity extends Activity
|
||||
if (start >= 0 && ActivePackagePath.charAt(stop) == '/')
|
||||
{
|
||||
temp.put("Activity", "y");
|
||||
PublicName += " (in use)";
|
||||
Tags = "active";
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.put("Activity", "n");
|
||||
if (!PublicName.equals("Built-in OpenCV library"))
|
||||
Tags = "safe to remove";
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -325,9 +367,32 @@ public class ManagerActivity extends Activity
|
||||
temp.put("Activity", "n");
|
||||
}
|
||||
|
||||
temp.put("Version", NormalizeVersion(OpenCVersion, VersionName));
|
||||
// HACK: OpenCV Manager for Armv7-a Neon already has Tegra3 optimizations
|
||||
// that is enabled on proper hardware
|
||||
if (HardwareDetector.DetectKnownPlatforms() == HardwareDetector.PLATFORM_TEGRA3 &&
|
||||
HardwareName.equals("armv7a neon ") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD)
|
||||
{
|
||||
temp.put("Hardware", "Tegra 3");
|
||||
if (Tags == null)
|
||||
{
|
||||
Tags = "optimized";
|
||||
}
|
||||
else
|
||||
{
|
||||
Tags = Tags + ", optimized";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.put("Hardware", HardwareName);
|
||||
}
|
||||
|
||||
if (Tags != null)
|
||||
PublicName = PublicName + " (" + Tags + ")";
|
||||
|
||||
temp.put("Name", PublicName);
|
||||
temp.put("Version", NormalizeVersion(OpenCVersion, mInstalledPackageInfo[i].versionName));
|
||||
temp.put("Hardware", HardwareName);
|
||||
|
||||
mListViewItems.add(temp);
|
||||
}
|
||||
|
||||
@@ -337,10 +402,16 @@ public class ManagerActivity extends Activity
|
||||
|
||||
protected String NormalizeVersion(String OpenCVersion, String PackageVersion)
|
||||
{
|
||||
if (OpenCVersion == null || PackageVersion == null)
|
||||
return "unknown";
|
||||
|
||||
int dot = PackageVersion.indexOf(".");
|
||||
return OpenCVersion.substring(0, OpenCVersion.length()-1) + "." +
|
||||
OpenCVersion.toCharArray()[OpenCVersion.length()-1] + "." +
|
||||
PackageVersion.substring(0, dot) + " rev " + PackageVersion.substring(dot+1);
|
||||
if (dot == -1 || OpenCVersion.length() == 0)
|
||||
return "unknown";
|
||||
else
|
||||
return OpenCVersion.substring(0, OpenCVersion.length()-1) + "." +
|
||||
OpenCVersion.toCharArray()[OpenCVersion.length()-1] + "." +
|
||||
PackageVersion.substring(0, dot) + " rev " + PackageVersion.substring(dot+1);
|
||||
}
|
||||
|
||||
protected String ConvertPackageName(String Name, String Version)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
How to select the proper version of OpenCV Manager
|
||||
--------------------------------------------------
|
||||
|
||||
Since version 1.7 several packages of OpenCV Manager are built. Every package is targeted for some
|
||||
specific hardware platform and includes corresponding OpenCV binaries. So, in most cases OpenCV
|
||||
Manager uses built-in version of OpenCV. Separate package with OpenCV binaries is currently used in
|
||||
a single rare case, when an ARMv7-A processor without NEON support is detected. In this case an
|
||||
additional binary package is used. The new package selection logic in most cases simplifies OpenCV
|
||||
installation on end user devices. In most cases OpenCV Manager may be installed automatically from
|
||||
Google Play.
|
||||
|
||||
If Google Play is not available (i.e. on emulator, developer board, etc), you can install it
|
||||
manually using adb tool:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
adb install OpenCV-2.4.3-android-sdk/apk/OpenCV_2.4.3.2_Manager_2.4_<platform>.apk
|
||||
|
||||
Use the table below to determine proper OpenCV Manager package for your device:
|
||||
|
||||
+------------------------------+--------------+-----------------------------------------------------+
|
||||
| Hardware Platform | Android ver. | Package name |
|
||||
+==============================+==============+=====================================================+
|
||||
| armeabi-v7a (ARMv7-A + NEON) | >= 2.3 | OpenCV_2.4.3.2_Manager_2.4_armv7a-neon.apk |
|
||||
+------------------------------+--------------+-----------------------------------------------------+
|
||||
| armeabi-v7a (ARMv7-A + NEON) | = 2.2 | OpenCV_2.4.3.2_Manager_2.4_armv7a-neon-android8.apk |
|
||||
+------------------------------+--------------+-----------------------------------------------------+
|
||||
| armeabi (ARMv5, ARMv6) | >= 2.3 | OpenCV_2.4.3.2_Manager_2.4_armeabi.apk |
|
||||
+------------------------------+--------------+-----------------------------------------------------+
|
||||
| Intel x86 | >= 2.3 | OpenCV_2.4.3.2_Manager_2.4_x86.apk |
|
||||
+------------------------------+--------------+-----------------------------------------------------+
|
||||
| MIPS | >= 2.3 | OpenCV_2.4.3.2_Manager_2.4_mips.apk |
|
||||
+------------------------------+--------------+-----------------------------------------------------+
|
||||
@@ -2,7 +2,7 @@ if(IOS OR ANDROID)
|
||||
return()
|
||||
endif()
|
||||
|
||||
SET(OPENCV_TRAINCASCADE_DEPS opencv_core opencv_ml opencv_imgproc opencv_objdetect opencv_highgui opencv_calib3d opencv_video opencv_features2d opencv_flann opencv_legacy)
|
||||
set(OPENCV_TRAINCASCADE_DEPS opencv_core opencv_ml opencv_imgproc opencv_objdetect opencv_highgui opencv_calib3d opencv_video opencv_features2d opencv_flann opencv_legacy)
|
||||
ocv_check_dependencies(${OPENCV_TRAINCASCADE_DEPS})
|
||||
|
||||
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||
|
||||
@@ -56,18 +56,12 @@ if(MINGW)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(OPENCV_CAN_BREAK_BINARY_COMPATIBILITY)
|
||||
add_definitions(-DOPENCV_CAN_BREAK_BINARY_COMPATIBILITY)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
# High level of warnings.
|
||||
add_extra_compiler_option(-W)
|
||||
add_extra_compiler_option(-Wall)
|
||||
add_extra_compiler_option(-Werror=return-type)
|
||||
if(OPENCV_CAN_BREAK_BINARY_COMPATIBILITY)
|
||||
add_extra_compiler_option(-Werror=non-virtual-dtor)
|
||||
endif()
|
||||
add_extra_compiler_option(-Werror=non-virtual-dtor)
|
||||
add_extra_compiler_option(-Werror=address)
|
||||
add_extra_compiler_option(-Werror=sequence-point)
|
||||
add_extra_compiler_option(-Wformat)
|
||||
|
||||
@@ -179,7 +179,7 @@ unset(__android_project_chain CACHE)
|
||||
#add_android_project(target_name ${path} NATIVE_DEPS opencv_core LIBRARY_DEPS ${OpenCV_BINARY_DIR} SDK_TARGET 11)
|
||||
macro(add_android_project target path)
|
||||
# parse arguments
|
||||
set(android_proj_arglist NATIVE_DEPS LIBRARY_DEPS SDK_TARGET IGNORE_JAVA)
|
||||
set(android_proj_arglist NATIVE_DEPS LIBRARY_DEPS SDK_TARGET IGNORE_JAVA IGNORE_MANIFEST)
|
||||
set(__varname "android_proj_")
|
||||
foreach(v ${android_proj_arglist})
|
||||
set(${__varname}${v} "")
|
||||
@@ -220,9 +220,13 @@ macro(add_android_project target path)
|
||||
# get project sources
|
||||
file(GLOB_RECURSE android_proj_files RELATIVE "${path}" "${path}/res/*" "${path}/src/*")
|
||||
|
||||
if(NOT android_proj_IGNORE_MANIFEST)
|
||||
list(APPEND android_proj_files ${ANDROID_MANIFEST_FILE})
|
||||
endif()
|
||||
|
||||
# copy sources out from the build tree
|
||||
set(android_proj_file_deps "")
|
||||
foreach(f ${android_proj_files} ${ANDROID_MANIFEST_FILE})
|
||||
foreach(f ${android_proj_files})
|
||||
add_custom_command(
|
||||
OUTPUT "${android_proj_bin_dir}/${f}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${path}/${f}" "${android_proj_bin_dir}/${f}"
|
||||
@@ -324,6 +328,7 @@ macro(add_android_project target path)
|
||||
install(FILES "${OpenCV_BINARY_DIR}/bin/${target}.apk" DESTINATION "samples" COMPONENT main)
|
||||
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)
|
||||
|
||||
@@ -3,12 +3,17 @@ if(${CMAKE_VERSION} VERSION_LESS "2.8.3")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT MSVC AND NOT CMAKE_COMPILER_IS_GNUCXX OR MINGW)
|
||||
message(STATUS "CUDA compilation was disabled (due to unsuppoted host compiler).")
|
||||
if(WIN32 AND NOT MSVC)
|
||||
message(STATUS "CUDA compilation is disabled (due to only Visual Studio compiler supported on your platform).")
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(CUDA 4.1)
|
||||
if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
message(STATUS "CUDA compilation is disabled (due to Clang unsupported on your platform).")
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(CUDA 4.2)
|
||||
|
||||
if(CUDA_FOUND)
|
||||
set(HAVE_CUDA 1)
|
||||
@@ -21,15 +26,20 @@ if(CUDA_FOUND)
|
||||
set(HAVE_CUBLAS 1)
|
||||
endif()
|
||||
|
||||
message(STATUS "CUDA detected: " ${CUDA_VERSION})
|
||||
|
||||
if(${CUDA_VERSION_STRING} VERSION_GREATER "4.1")
|
||||
set(CUDA_ARCH_BIN "1.1 1.2 1.3 2.0 2.1(2.0) 3.0" CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported")
|
||||
else()
|
||||
set(CUDA_ARCH_BIN "1.1 1.2 1.3 2.0 2.1(2.0)" CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported")
|
||||
if(WITH_NVCUVID)
|
||||
find_cuda_helper_libs(nvcuvid)
|
||||
set(HAVE_NVCUVID 1)
|
||||
endif()
|
||||
|
||||
set(CUDA_ARCH_PTX "2.0" CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for")
|
||||
message(STATUS "CUDA detected: " ${CUDA_VERSION})
|
||||
|
||||
if (CARMA)
|
||||
set(CUDA_ARCH_BIN "2.1(2.0) 3.0" CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported")
|
||||
set(CUDA_ARCH_PTX "3.0" CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for")
|
||||
else()
|
||||
set(CUDA_ARCH_BIN "1.1 1.2 1.3 2.0 2.1(2.0) 3.0" CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported")
|
||||
set(CUDA_ARCH_PTX "2.0 3.0" CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for")
|
||||
endif()
|
||||
|
||||
string(REGEX REPLACE "\\." "" ARCH_BIN_NO_POINTS "${CUDA_ARCH_BIN}")
|
||||
string(REGEX REPLACE "\\." "" ARCH_PTX_NO_POINTS "${CUDA_ARCH_PTX}")
|
||||
@@ -67,11 +77,20 @@ if(CUDA_FOUND)
|
||||
|
||||
# Tell NVCC to add PTX intermediate code for the specified architectures
|
||||
string(REGEX MATCHALL "[0-9]+" ARCH_LIST "${ARCH_PTX_NO_POINTS}")
|
||||
foreach(ARCH IN LISTS ARCH_LIST)
|
||||
set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=compute_${ARCH})
|
||||
set(OPENCV_CUDA_ARCH_PTX "${OPENCV_CUDA_ARCH_PTX} ${ARCH}")
|
||||
set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${ARCH}")
|
||||
endforeach()
|
||||
foreach(ARCH IN LISTS ARCH_LIST)
|
||||
set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=compute_${ARCH})
|
||||
set(OPENCV_CUDA_ARCH_PTX "${OPENCV_CUDA_ARCH_PTX} ${ARCH}")
|
||||
set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${ARCH}")
|
||||
endforeach()
|
||||
|
||||
if(CARMA)
|
||||
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --target-cpu-architecture=ARM" )
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS 2.8.10)
|
||||
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -ccbin=${CMAKE_CXX_COMPILER}" )
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
# These vars will be processed in other scripts
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ${NVCC_FLAGS_EXTRA})
|
||||
@@ -79,7 +98,7 @@ if(CUDA_FOUND)
|
||||
|
||||
message(STATUS "CUDA NVCC target flags: ${CUDA_NVCC_FLAGS}")
|
||||
|
||||
OCV_OPTION(CUDA_FAST_MATH "Enable --use_fast_math for CUDA compiler " OFF)
|
||||
OCV_OPTION(CUDA_FAST_MATH "Enable --use_fast_math for CUDA compiler " OFF)
|
||||
|
||||
if(CUDA_FAST_MATH)
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} --use_fast_math)
|
||||
@@ -87,7 +106,6 @@ if(CUDA_FOUND)
|
||||
|
||||
mark_as_advanced(CUDA_BUILD_CUBIN CUDA_BUILD_EMULATION CUDA_VERBOSE_BUILD CUDA_SDK_ROOT_DIR)
|
||||
|
||||
unset(CUDA_npp_LIBRARY CACHE)
|
||||
find_cuda_helper_libs(npp)
|
||||
|
||||
macro(ocv_cuda_compile VAR)
|
||||
@@ -101,15 +119,15 @@ if(CUDA_FOUND)
|
||||
string(REPLACE "-ggdb3" "" ${var} "${${var}}")
|
||||
endforeach()
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -DCVAPI_EXPORTS)
|
||||
endif()
|
||||
|
||||
if(UNIX OR APPLE)
|
||||
set (CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fPIC)
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fPIC)
|
||||
endif()
|
||||
if(APPLE)
|
||||
set (CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fno-finite-math-only)
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fno-finite-math-only)
|
||||
endif()
|
||||
|
||||
# disabled because of multiple warnings during building nvcc auto generated files
|
||||
|
||||
@@ -54,7 +54,7 @@ endif()
|
||||
# Detect GNU version:
|
||||
# ----------------------------------------------------------------------------
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} --version
|
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
|
||||
OUTPUT_VARIABLE CMAKE_OPENCV_GCC_VERSION_FULL
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ else()
|
||||
else()
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_AMDSTREAMSDKROOT}/lib/x86_64)
|
||||
endif()
|
||||
elseif(ENV_CUDAPATH AND WIN32)
|
||||
elseif(ENV_CUDA_PATH AND WIN32)
|
||||
set(OPENCL_INCLUDE_SEARCH_PATH ${ENV_CUDA_PATH}/include)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_CUDA_PATH}/lib/Win32)
|
||||
|
||||
@@ -32,7 +32,7 @@ endif(WITH_CUDA)
|
||||
# --- Eigen ---
|
||||
if(WITH_EIGEN)
|
||||
find_path(EIGEN_INCLUDE_PATH "Eigen/Core"
|
||||
PATHS /usr/local /opt /usr ENV ProgramFiles ENV ProgramW6432
|
||||
PATHS /usr/local /opt /usr $ENV{EIGEN_ROOT}/include ENV ProgramFiles ENV ProgramW6432
|
||||
PATH_SUFFIXES include/eigen3 include/eigen2 Eigen/include/eigen3 Eigen/include/eigen2
|
||||
DOC "The path to Eigen3/Eigen2 headers"
|
||||
CMAKE_FIND_ROOT_PATH_BOTH)
|
||||
@@ -43,3 +43,42 @@ if(WITH_EIGEN)
|
||||
set(HAVE_EIGEN 1)
|
||||
endif()
|
||||
endif(WITH_EIGEN)
|
||||
|
||||
# --- Clp ---
|
||||
# Ubuntu: sudo apt-get install coinor-libclp-dev coinor-libcoinutils-dev
|
||||
ocv_clear_vars(HAVE_CLP)
|
||||
if(WITH_CLP)
|
||||
if(UNIX)
|
||||
PKG_CHECK_MODULES(CLP clp)
|
||||
if(CLP_FOUND)
|
||||
set(HAVE_CLP TRUE)
|
||||
if(NOT ${CLP_INCLUDE_DIRS} STREQUAL "")
|
||||
ocv_include_directories(${CLP_INCLUDE_DIRS})
|
||||
endif()
|
||||
link_directories(${CLP_LIBRARY_DIRS})
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CLP_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CLP_FOUND)
|
||||
find_path(CLP_INCLUDE_PATH "coin"
|
||||
PATHS "/usr/local/include" "/usr/include" "/opt/include"
|
||||
DOC "The path to Clp headers")
|
||||
if(CLP_INCLUDE_PATH)
|
||||
ocv_include_directories(${CLP_INCLUDE_PATH} "${CLP_INCLUDE_PATH}/coin")
|
||||
get_filename_component(_CLP_LIBRARY_DIR "${CLP_INCLUDE_PATH}/../lib" ABSOLUTE)
|
||||
set(CLP_LIBRARY_DIR "${_CLP_LIBRARY_DIR}" CACHE PATH "Full path of Clp library directory")
|
||||
link_directories(${CLP_LIBRARY_DIR})
|
||||
if(UNIX)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} Clp CoinUtils m)
|
||||
else()
|
||||
if(MINGW)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} Clp CoinUtils)
|
||||
else()
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} libClp libCoinUtils)
|
||||
endif()
|
||||
endif()
|
||||
set(HAVE_CLP TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endif(WITH_CLP)
|
||||
@@ -56,19 +56,6 @@ if(WITH_PVAPI)
|
||||
endif(PVAPI_INCLUDE_PATH)
|
||||
endif(WITH_PVAPI)
|
||||
|
||||
# --- GigEVisionSDK ---
|
||||
ocv_clear_vars(HAVE_GIGE_API)
|
||||
if(WITH_GIGEAPI)
|
||||
find_path(GIGEAPI_INCLUDE_PATH "GigEVisionSDK.h"
|
||||
PATHS /usr/local /var /opt /usr ENV ProgramFiles ENV ProgramW6432
|
||||
PATH_SUFFIXES include "Smartek Vision Technologies/GigEVisionSDK/gige_cpp" "GigEVisionSDK/gige_cpp" "GigEVisionSDK/gige_c"
|
||||
DOC "The path to Smartek GigEVisionSDK header")
|
||||
FIND_LIBRARY(GIGEAPI_LIBRARIES NAMES GigEVisionSDK)
|
||||
if(GIGEAPI_LIBRARIES AND GIGEAPI_INCLUDE_PATH)
|
||||
set(HAVE_GIGE_API TRUE)
|
||||
endif()
|
||||
endif(WITH_GIGEAPI)
|
||||
|
||||
# --- Dc1394 ---
|
||||
ocv_clear_vars(HAVE_DC1394 HAVE_DC1394_2)
|
||||
if(WITH_1394)
|
||||
|
||||
@@ -71,6 +71,12 @@ if(ANDROID)
|
||||
endforeach()
|
||||
string(REPLACE "opencv_" "" OPENCV_MODULES_CONFIGMAKE "${OPENCV_MODULES_CONFIGMAKE}")
|
||||
|
||||
# prepare 3rd-party component list without TBB for armeabi and mips platforms. TBB is useless there.
|
||||
set(OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE})
|
||||
foreach(mod ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB})
|
||||
string(REPLACE "tbb" "" OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB "${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB}")
|
||||
endforeach()
|
||||
|
||||
if(BUILD_FAT_JAVA_LIB)
|
||||
set(OPENCV_LIBS_CONFIGMAKE java)
|
||||
else()
|
||||
|
||||
@@ -19,7 +19,7 @@ IF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
|
||||
OUTPUT_VARIABLE gcc_compiler_version)
|
||||
#MESSAGE("GCC Version: ${gcc_compiler_version}")
|
||||
IF(gcc_compiler_version MATCHES "4\\.[0,2-9]\\.[0-9x]")
|
||||
IF(gcc_compiler_version VERSION_GREATER "4.2.-1")
|
||||
SET(PCHSupport_FOUND TRUE)
|
||||
ENDIF()
|
||||
|
||||
|
||||
@@ -29,8 +29,22 @@ ifeq ($(OPENCV_LIB_TYPE),SHARED)
|
||||
OPENCV_3RDPARTY_COMPONENTS:=
|
||||
OPENCV_EXTRA_COMPONENTS:=
|
||||
else
|
||||
OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE@
|
||||
OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@
|
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||
OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE@
|
||||
OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@
|
||||
endif
|
||||
ifeq ($(TARGET_ARCH_ABI),x86)
|
||||
OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE@
|
||||
OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@
|
||||
endif
|
||||
ifeq ($(TARGET_ARCH_ABI),armeabi)
|
||||
OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB@
|
||||
OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@
|
||||
endif
|
||||
ifeq ($(TARGET_ARCH_ABI),mips)
|
||||
OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB@
|
||||
OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq (${OPENCV_CAMERA_MODULES},on)
|
||||
|
||||
@@ -58,9 +58,6 @@
|
||||
/* OpenEXR codec */
|
||||
#cmakedefine HAVE_ILMIMF
|
||||
|
||||
/* Apple ImageIO Framework */
|
||||
#cmakedefine HAVE_IMAGEIO
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#cmakedefine HAVE_INTTYPES_H 1
|
||||
|
||||
@@ -175,21 +172,15 @@
|
||||
/* NVidia Cuda Runtime API*/
|
||||
#cmakedefine HAVE_CUDA
|
||||
|
||||
/* OpenCL Support */
|
||||
#cmakedefine HAVE_OPENCL
|
||||
|
||||
/* AMD's OpenCL Fast Fourier Transform Library*/
|
||||
#cmakedefine HAVE_CLAMDFFT
|
||||
|
||||
/* AMD's Basic Linear Algebra Subprograms Library*/
|
||||
#cmakedefine HAVE_CLAMDBLAS
|
||||
|
||||
/* NVidia Cuda Fast Fourier Transform (FFT) API*/
|
||||
#cmakedefine HAVE_CUFFT
|
||||
|
||||
/* NVidia Cuda Basic Linear Algebra Subprograms (BLAS) API*/
|
||||
#cmakedefine HAVE_CUBLAS
|
||||
|
||||
/* NVidia Video Decoding API*/
|
||||
#cmakedefine HAVE_NVCUVID
|
||||
|
||||
/* Compile for 'real' NVIDIA GPU architectures */
|
||||
#define CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN}"
|
||||
|
||||
@@ -202,6 +193,15 @@
|
||||
/* Create PTX or BIN for 1.0 compute capability */
|
||||
#cmakedefine CUDA_ARCH_BIN_OR_PTX_10
|
||||
|
||||
/* OpenCL Support */
|
||||
#cmakedefine HAVE_OPENCL
|
||||
|
||||
/* AMD's OpenCL Fast Fourier Transform Library*/
|
||||
#cmakedefine HAVE_CLAMDFFT
|
||||
|
||||
/* AMD's Basic Linear Algebra Subprograms Library*/
|
||||
#cmakedefine HAVE_CLAMDBLAS
|
||||
|
||||
/* VideoInput library */
|
||||
#cmakedefine HAVE_VIDEOINPUT
|
||||
|
||||
|
||||
+20
-5
@@ -2,8 +2,6 @@
|
||||
# CMake file for OpenCV docs
|
||||
#
|
||||
|
||||
file(GLOB FILES_DOC *.htm *.txt *.jpg *.png *.pdf)
|
||||
file(GLOB FILES_DOC_VS vidsurv/*.doc)
|
||||
file(GLOB FILES_TEX *.tex *.sty *.bib)
|
||||
file(GLOB FILES_TEX_PICS pics/*.png pics/*.jpg)
|
||||
|
||||
@@ -11,6 +9,14 @@ if(BUILD_DOCS AND HAVE_SPHINX)
|
||||
|
||||
project(opencv_docs)
|
||||
|
||||
set(DOC_LIST "${OpenCV_SOURCE_DIR}/doc/opencv-logo.png" "${OpenCV_SOURCE_DIR}/doc/opencv-logo2.png"
|
||||
"${OpenCV_SOURCE_DIR}/doc/opencv-logo-white.png" "${OpenCV_SOURCE_DIR}/doc/opencv.ico"
|
||||
"${OpenCV_SOURCE_DIR}/doc/haartraining.htm" "${OpenCV_SOURCE_DIR}/doc/license.txt"
|
||||
"${OpenCV_SOURCE_DIR}/doc/pattern.png" "${OpenCV_SOURCE_DIR}/doc/acircles_pattern.png")
|
||||
|
||||
set(OPTIONAL_DOC_LIST "")
|
||||
|
||||
|
||||
set(OPENCV2_BASE_MODULES core imgproc highgui video calib3d features2d objdetect ml flann gpu photo stitching nonfree contrib legacy)
|
||||
|
||||
# build lists of modules to be documented
|
||||
@@ -81,6 +87,9 @@ if(BUILD_DOCS AND HAVE_SPHINX)
|
||||
COMMENT "Generating the PDF Manuals"
|
||||
)
|
||||
|
||||
LIST(APPEND OPTIONAL_DOC_LIST "${CMAKE_BINARY_DIR}/doc/opencv2refman.pdf" "${CMAKE_BINARY_DIR}/doc/opencv2manager.pdf"
|
||||
"${CMAKE_BINARY_DIR}/doc/opencv_user.pdf" "${CMAKE_BINARY_DIR}/doc/opencv_tutorials.pdf" "${CMAKE_BINARY_DIR}/doc/opencv_cheatsheet.pdf")
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(docs PROPERTIES FOLDER "documentation")
|
||||
endif()
|
||||
@@ -97,7 +106,13 @@ if(BUILD_DOCS AND HAVE_SPHINX)
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(html_docs PROPERTIES FOLDER "documentation")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install(FILES ${FILES_DOC} DESTINATION "${OPENCV_DOC_INSTALL_PATH}" COMPONENT main)
|
||||
install(FILES ${FILES_DOC_VS} DESTINATION "${OPENCV_DOC_INSTALL_PATH}/vidsurv" COMPONENT main)
|
||||
foreach(f ${DOC_LIST})
|
||||
install(FILES "${f}" DESTINATION "${OPENCV_DOC_INSTALL_PATH}" COMPONENT main)
|
||||
endforeach()
|
||||
|
||||
foreach(f ${OPTIONAL_DOC_LIST})
|
||||
install(FILES "${f}" DESTINATION "${OPENCV_DOC_INSTALL_PATH}" OPTIONAL)
|
||||
endforeach()
|
||||
|
||||
endif()
|
||||
+8
@@ -394,4 +394,12 @@ div.body ul.search li {
|
||||
div.linenodiv {
|
||||
min-width: 1em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox input[type="text"] {
|
||||
width:auto;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox input[type="submit"] {
|
||||
width:auto;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
#/usr/bin/env python
|
||||
|
||||
import sys, glob
|
||||
|
||||
sys.path.append("../modules/python/src2/")
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#/usr/bin/env python
|
||||
|
||||
import os, sys, fnmatch, re
|
||||
|
||||
sys.path.append("../modules/python/src2/")
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#/usr/bin/env python
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# opencvstd documentation build configuration file, created by
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
ocv domain, a modified copy of sphinx.domains.cpp + shpinx.domains.python.
|
||||
|
||||
Arquivo binário não exibido.
-84565
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Arquivo binário não exibido.
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Arquivo binário não exibido.
+7
-7
@@ -4,14 +4,14 @@ INSTRUCTIONS TO BUILD WIN32 PACKAGES WITH CMAKE+CPACK
|
||||
|
||||
- Install NSIS.
|
||||
- Generate OpenCV solutions for MSVC using CMake as usual.
|
||||
- In cmake-gui:
|
||||
- Mark BUILD_PACKAGE
|
||||
- Mark BUILD_EXAMPLES (If examples are desired to be shipped as binaries...)
|
||||
- Unmark ENABLE_OPENMP, since this feature seems to have some issues yet...
|
||||
- Mark INSTALL_*_EXAMPLES
|
||||
- In cmake-gui:
|
||||
- Mark BUILD_PACKAGE
|
||||
- Mark BUILD_EXAMPLES (If examples are desired to be shipped as binaries...)
|
||||
- Unmark ENABLE_OPENMP, since this feature seems to have some issues yet...
|
||||
- Mark INSTALL_*_EXAMPLES
|
||||
- Open the OpenCV solution and build ALL in Debug and Release.
|
||||
- Build PACKAGE, from the Release configuration. An NSIS installer package will be
|
||||
- Build PACKAGE, from the Release configuration. An NSIS installer package will be
|
||||
created with both release and debug LIBs and DLLs.
|
||||
|
||||
|
||||
|
||||
Jose Luis Blanco, 2009/JUL/29
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
f=open(sys.argv[1], "rt")
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#/usr/bin/env python
|
||||
|
||||
"""gen_pattern.py
|
||||
To run:
|
||||
-c 10 -r 12 -o out.svg
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#/usr/bin/env python
|
||||
|
||||
# svgfig.py copyright (C) 2008 Jim Pivarski <jpivarski@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#/usr/bin/env python
|
||||
|
||||
import os, sys, re
|
||||
|
||||
finput=open(sys.argv[1], "rt")
|
||||
|
||||
@@ -3,30 +3,30 @@
|
||||
Camera calibration With OpenCV
|
||||
******************************
|
||||
|
||||
Cameras have been around for a long-long time. However, with the introduction of the cheap *pinhole* cameras in the late 20th century, they became a common occurrence in our everyday life. Unfortunately, this cheapness comes with its price: significant distortion. Luckily, these are constants and with a calibration and some remapping we can correct this. Furthermore, with calibration you may also determinate the relation between the camera's natural units (pixels) and the real world units (for example millimeters).
|
||||
Cameras have been around for a long-long time. However, with the introduction of the cheap *pinhole* cameras in the late 20th century, they became a common occurrence in our everyday life. Unfortunately, this cheapness comes with its price: significant distortion. Luckily, these are constants and with a calibration and some remapping we can correct this. Furthermore, with calibration you may also determinate the relation between the camera's natural units (pixels) and the real world units (for example millimeters).
|
||||
|
||||
Theory
|
||||
======
|
||||
|
||||
For the distortion OpenCV takes into account the radial and tangential factors. For the radial one uses the following formula:
|
||||
For the distortion OpenCV takes into account the radial and tangential factors. For the radial one uses the following formula:
|
||||
|
||||
.. math::
|
||||
.. math::
|
||||
|
||||
x_{corrected} = x( 1 + k_1 r^2 + k_2 r^4 + k^3 r^6) \\
|
||||
y_{corrected} = y( 1 + k_1 r^2 + k_2 r^4 + k^3 r^6)
|
||||
|
||||
So for an old pixel point at :math:`(x,y)` coordinate in the input image, for a corrected output image its position will be :math:`(x_{corrected} y_{corrected})` . The presence of the radial distortion manifests in form of the "barrel" or "fish-eye" effect.
|
||||
So for an old pixel point at :math:`(x,y)` coordinate in the input image, for a corrected output image its position will be :math:`(x_{corrected} y_{corrected})` . The presence of the radial distortion manifests in form of the "barrel" or "fish-eye" effect.
|
||||
|
||||
Tangential distortion occurs because the image taking lenses are not perfectly parallel to the imaging plane. Correcting this is made via the formulas:
|
||||
Tangential distortion occurs because the image taking lenses are not perfectly parallel to the imaging plane. Correcting this is made via the formulas:
|
||||
|
||||
.. math::
|
||||
.. math::
|
||||
|
||||
x_{corrected} = x + [ 2p_1xy + p_2(r^2+2x^2)] \\
|
||||
y_{corrected} = y + [ p_1(r^2+ 2y^2)+ 2p_2xy]
|
||||
|
||||
So we have five distortion parameters, which in OpenCV are organized in a 5 column one row matrix:
|
||||
So we have five distortion parameters, which in OpenCV are organized in a 5 column one row matrix:
|
||||
|
||||
.. math::
|
||||
.. math::
|
||||
|
||||
Distortion_{coefficients}=(k_1 \hspace{10pt} k_2 \hspace{10pt} p_1 \hspace{10pt} p_2 \hspace{10pt} k_3)
|
||||
|
||||
@@ -38,7 +38,7 @@ Now for the unit conversion, we use the following formula:
|
||||
|
||||
Here the presence of the :math:`w` is cause we use a homography coordinate system (and :math:`w=Z`). The unknown parameters are :math:`f_x` and :math:`f_y` (camera focal lengths) and :math:`(c_x, c_y)` what are the optical centers expressed in pixels coordinates. If for both axes a common focal length is used with a given :math:`a` aspect ratio (usually 1), then :math:`f_y=f_x*a` and in the upper formula we will have a single :math:`f` focal length. The matrix containing these four parameters is referred to as the *camera matrix*. While the distortion coefficients are the same regardless of the camera resolutions used, these should be scaled along with the current resolution from the calibrated resolution.
|
||||
|
||||
The process of determining these two matrices is the calibration. Calculating these parameters is done by some basic geometrical equations. The equations used depend on the calibrating objects used. Currently OpenCV supports three types of object for calibration:
|
||||
The process of determining these two matrices is the calibration. Calculating these parameters is done by some basic geometrical equations. The equations used depend on the calibrating objects used. Currently OpenCV supports three types of object for calibration:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
@@ -46,12 +46,12 @@ The process of determining these two matrices is the calibration. Calculating th
|
||||
+ Symmetrical circle pattern
|
||||
+ Asymmetrical circle pattern
|
||||
|
||||
Basically, you need to take snapshots of these patterns with your camera and let OpenCV find them. Each found pattern equals in a new equation. To solve the equation you need at least a predetermined number of pattern snapshots to form a well-posed equation system. This number is higher for the chessboard pattern and less for the circle ones. For example, in theory the chessboard one requires at least two. However, in practice we have a good amount of noise present in our input images, so for good results you will probably want at least 10 good snapshots of the input pattern in different position.
|
||||
Basically, you need to take snapshots of these patterns with your camera and let OpenCV find them. Each found pattern equals in a new equation. To solve the equation you need at least a predetermined number of pattern snapshots to form a well-posed equation system. This number is higher for the chessboard pattern and less for the circle ones. For example, in theory the chessboard one requires at least two. However, in practice we have a good amount of noise present in our input images, so for good results you will probably want at least 10 good snapshots of the input pattern in different position.
|
||||
|
||||
Goal
|
||||
====
|
||||
|
||||
The sample application will:
|
||||
The sample application will:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
@@ -67,7 +67,7 @@ Source code
|
||||
|
||||
You may also find the source code in the :file:`samples/cpp/tutorial_code/calib3d/camera_calibration/` folder of the OpenCV source library or :download:`download it from here <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp>`. The program has a single argument. The name of its configuration file. If none given it will try to open the one named "default.xml". :download:`Here's a sample configuration file <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/in_VID5.xml>` in XML format. In the configuration file you may choose to use as input a camera, a video file or an image list. If you opt for the later one, you need to create a configuration file where you enumerate the images to use. Here's :download:`an example of this <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/VID5.xml>`. The important part to remember is that the images needs to be specified using the absolute path or the relative one from your applications working directory. You may find all this in the beforehand mentioned directory.
|
||||
|
||||
The application starts up with reading the settings from the configuration file. Although, this is an important part of it, it has nothing to do with the subject of this tutorial: *camera calibration*. Therefore, I've chosen to do not post here the code part for that. The technical background on how to do this you can find in the :ref:`fileInputOutputXMLYAML` tutorial.
|
||||
The application starts up with reading the settings from the configuration file. Although, this is an important part of it, it has nothing to do with the subject of this tutorial: *camera calibration*. Therefore, I've chosen to do not post here the code part for that. The technical background on how to do this you can find in the :ref:`fileInputOutputXMLYAML` tutorial.
|
||||
|
||||
Explanation
|
||||
===========
|
||||
@@ -76,15 +76,15 @@ Explanation
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
Settings s;
|
||||
Settings s;
|
||||
const string inputSettingsFile = argc > 1 ? argv[1] : "default.xml";
|
||||
FileStorage fs(inputSettingsFile, FileStorage::READ); // Read the settings
|
||||
if (!fs.isOpened())
|
||||
{
|
||||
cout << "Could not open the configuration file: \"" << inputSettingsFile << "\"" << endl;
|
||||
cout << "Could not open the configuration file: \"" << inputSettingsFile << "\"" << endl;
|
||||
return -1;
|
||||
}
|
||||
fs["Settings"] >> s;
|
||||
fs["Settings"] >> s;
|
||||
fs.release(); // close Settings file
|
||||
|
||||
if (!s.goodInput)
|
||||
@@ -95,7 +95,7 @@ Explanation
|
||||
|
||||
For this I've used simple OpenCV class input operation. After reading the file I've an additional post-process function that checks for the validity of the input. Only if all of them are good will be the *goodInput* variable true.
|
||||
|
||||
#. **Get next input, if it fails or we have enough of them calibrate**. After this we have a big loop where we do the following operations: get the next image from the image list, camera or video file. If this fails or we have enough images we run the calibration process. In case of image we step out of the loop and otherwise the remaining frames will be undistorted (if the option is set) via changing from *DETECTION* mode to *CALIBRATED* one.
|
||||
#. **Get next input, if it fails or we have enough of them calibrate**. After this we have a big loop where we do the following operations: get the next image from the image list, camera or video file. If this fails or we have enough images we run the calibration process. In case of image we step out of the loop and otherwise the remaining frames will be undistorted (if the option is set) via changing from *DETECTION* mode to *CALIBRATED* one.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -123,7 +123,7 @@ Explanation
|
||||
if( s.flipVertical ) flip( view, view, 0 );
|
||||
}
|
||||
|
||||
For some cameras we may need to flip the input image. Here we do this too.
|
||||
For some cameras we may need to flip the input image. Here we do this too.
|
||||
|
||||
#. **Find the pattern in the current input**. The formation of the equations I mentioned above consists of finding the major patterns in the input: in case of the chessboard this is their corners of the squares and for the circles, well, the circles itself. The position of these will form the result and is collected into the *pointBuf* vector.
|
||||
|
||||
@@ -146,19 +146,19 @@ Explanation
|
||||
break;
|
||||
}
|
||||
|
||||
Depending on the type of the input pattern you use either the :calib3d:`findChessboardCorners <findchessboardcorners>` or the :calib3d:`findCirclesGrid <findcirclesgrid>` function. For both of them you pass on the current image, the size of the board and you'll get back the positions of the patterns. Furthermore, they return a boolean variable that states if in the input we could find or not the pattern (we only need to take into account images where this is true!).
|
||||
Depending on the type of the input pattern you use either the :calib3d:`findChessboardCorners <findchessboardcorners>` or the :calib3d:`findCirclesGrid <findcirclesgrid>` function. For both of them you pass on the current image, the size of the board and you'll get back the positions of the patterns. Furthermore, they return a boolean variable that states if in the input we could find or not the pattern (we only need to take into account images where this is true!).
|
||||
|
||||
Then again in case of cameras we only take camera images after an input delay time passed. This is in order to allow for the user to move the chessboard around and as getting different images. Same images mean same equations, and same equations at the calibration will form an ill-posed problem, so the calibration will fail. For square images the position of the corners are only approximate. We may improve this by calling the :feature2d:`cornerSubPix <cornersubpix>` function. This way will get a better calibration result. After this we add a valid inputs result to the *imagePoints* vector to collect all of the equations into a single container. Finally, for visualization feedback purposes we will draw the found points on the input image with the :calib3d:`findChessboardCorners <drawchessboardcorners>` function.
|
||||
Then again in case of cameras we only take camera images after an input delay time passed. This is in order to allow for the user to move the chessboard around and as getting different images. Same images mean same equations, and same equations at the calibration will form an ill-posed problem, so the calibration will fail. For square images the position of the corners are only approximate. We may improve this by calling the :feature2d:`cornerSubPix <cornersubpix>` function. This way will get a better calibration result. After this we add a valid inputs result to the *imagePoints* vector to collect all of the equations into a single container. Finally, for visualization feedback purposes we will draw the found points on the input image with the :calib3d:`findChessboardCorners <drawchessboardcorners>` function.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
if ( found) // If done with success,
|
||||
if ( found) // If done with success,
|
||||
{
|
||||
// improve the found corners' coordinate accuracy for chessboard
|
||||
if( s.calibrationPattern == Settings::CHESSBOARD)
|
||||
if( s.calibrationPattern == Settings::CHESSBOARD)
|
||||
{
|
||||
Mat viewGray;
|
||||
cvtColor(view, viewGray, CV_BGR2GRAY);
|
||||
cvtColor(view, viewGray, CV_BGR2GRAY);
|
||||
cornerSubPix( viewGray, pointBuf, Size(11,11),
|
||||
Size(-1,-1), TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
|
||||
}
|
||||
@@ -171,11 +171,11 @@ Explanation
|
||||
blinkOutput = s.inputCapture.isOpened();
|
||||
}
|
||||
|
||||
// Draw the corners.
|
||||
// Draw the corners.
|
||||
drawChessboardCorners( view, s.boardSize, Mat(pointBuf), found );
|
||||
}
|
||||
|
||||
#. **Show state and result for the user, plus command line control of the application**. The showing part consists of a text output on the live feed, and for video or camera input to show the "capturing" frame we simply bitwise negate the input image.
|
||||
#. **Show state and result for the user, plus command line control of the application**. The showing part consists of a text output on the live feed, and for video or camera input to show the "capturing" frame we simply bitwise negate the input image.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -183,7 +183,7 @@ Explanation
|
||||
string msg = (mode == CAPTURING) ? "100/100" :
|
||||
mode == CALIBRATED ? "Calibrated" : "Press 'g' to start";
|
||||
int baseLine = 0;
|
||||
Size textSize = getTextSize(msg, 1, 1, 1, &baseLine);
|
||||
Size textSize = getTextSize(msg, 1, 1, 1, &baseLine);
|
||||
Point textOrigin(view.cols - 2*textSize.width - 10, view.rows - 2*baseLine - 10);
|
||||
|
||||
if( mode == CAPTURING )
|
||||
@@ -199,7 +199,7 @@ Explanation
|
||||
if( blinkOutput )
|
||||
bitwise_not(view, view);
|
||||
|
||||
If we only ran the calibration and got the camera matrix plus the distortion coefficients we may just as correct the image with the :imgproc_geometric:`undistort <undistort>` function:
|
||||
If we only ran the calibration and got the camera matrix plus the distortion coefficients we may just as correct the image with the :imgproc_geometric:`undistort <undistort>` function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -229,7 +229,7 @@ Explanation
|
||||
imagePoints.clear();
|
||||
}
|
||||
|
||||
#. **Show the distortion removal for the images too**. When you work with an image list it is not possible to remove the distortion inside the loop. Therefore, you must append this after the loop. Taking advantage of this now I'll expand the :imgproc_geometric:`undistort <undistort>` function, which is in fact first a call of the :imgproc_geometric:`initUndistortRectifyMap <initundistortrectifymap>` to find out the transformation matrices and then doing the transformation with the :imgproc_geometric:`remap <remap>` function. Because, after a successful calibration the map calculation needs to be done only once, by using this expanded form you may speed up your application:
|
||||
#. **Show the distortion removal for the images too**. When you work with an image list it is not possible to remove the distortion inside the loop. Therefore, you must append this after the loop. Taking advantage of this now I'll expand the :imgproc_geometric:`undistort <undistort>` function, which is in fact first a call of the :imgproc_geometric:`initUndistortRectifyMap <initundistortrectifymap>` to find out the transformation matrices and then doing the transformation with the :imgproc_geometric:`remap <remap>` function. Because, after a successful calibration the map calculation needs to be done only once, by using this expanded form you may speed up your application:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -256,9 +256,9 @@ Explanation
|
||||
The calibration and save
|
||||
========================
|
||||
|
||||
Because the calibration needs to be only once per camera it makes sense to save them after a successful calibration. This way later on you can just load these values into your program. Due to this we first make the calibration, and if it succeeds we save the result into an OpenCV style XML or YAML file, depending on the extension you give in the configuration file.
|
||||
Because the calibration needs to be only once per camera it makes sense to save them after a successful calibration. This way later on you can just load these values into your program. Due to this we first make the calibration, and if it succeeds we save the result into an OpenCV style XML or YAML file, depending on the extension you give in the configuration file.
|
||||
|
||||
Therefore in the first function we just split up these two processes. Because we want to save many of the calibration variables we'll create these variables here and pass on both of them to the calibration and saving function. Again, I'll not show the saving part as that has little in common with the calibration. Explore the source file in order to find out how and what:
|
||||
Therefore in the first function we just split up these two processes. Because we want to save many of the calibration variables we'll create these variables here and pass on both of them to the calibration and saving function. Again, I'll not show the saving part as that has little in common with the calibration. Explore the source file in order to find out how and what:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -269,10 +269,10 @@ Therefore in the first function we just split up these two processes. Because we
|
||||
vector<float> reprojErrs;
|
||||
double totalAvgErr = 0;
|
||||
|
||||
bool ok = runCalibration(s,imageSize, cameraMatrix, distCoeffs, imagePoints, rvecs, tvecs,
|
||||
bool ok = runCalibration(s,imageSize, cameraMatrix, distCoeffs, imagePoints, rvecs, tvecs,
|
||||
reprojErrs, totalAvgErr);
|
||||
cout << (ok ? "Calibration succeeded" : "Calibration failed")
|
||||
<< ". avg re projection error = " << totalAvgErr ;
|
||||
<< ". avg re projection error = " << totalAvgErr ;
|
||||
|
||||
if( ok ) // save only if the calibration was done with success
|
||||
saveCameraParams( s, imageSize, cameraMatrix, distCoeffs, rvecs ,tvecs, reprojErrs,
|
||||
@@ -280,15 +280,15 @@ Therefore in the first function we just split up these two processes. Because we
|
||||
return ok;
|
||||
}
|
||||
|
||||
We do the calibration with the help of the :calib3d:`calibrateCamera <calibratecamera>` function. This has the following parameters:
|
||||
We do the calibration with the help of the :calib3d:`calibrateCamera <calibratecamera>` function. This has the following parameters:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
+ The object points. This is a vector of *Point3f* vector that for each input image describes how should the pattern look. If we have a planar pattern (like a chessboard) then we can simply set all Z coordinates to zero. This is a collection of the points where these important points are present. Because, we use a single pattern for all the input images we can calculate this just once and multiply it for all the other input views. We calculate the corner points with the *calcBoardCornerPositions* function as:
|
||||
+ The object points. This is a vector of *Point3f* vector that for each input image describes how should the pattern look. If we have a planar pattern (like a chessboard) then we can simply set all Z coordinates to zero. This is a collection of the points where these important points are present. Because, we use a single pattern for all the input images we can calculate this just once and multiply it for all the other input views. We calculate the corner points with the *calcBoardCornerPositions* function as:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void calcBoardCornerPositions(Size boardSize, float squareSize, vector<Point3f>& corners,
|
||||
void calcBoardCornerPositions(Size boardSize, float squareSize, vector<Point3f>& corners,
|
||||
Settings::Pattern patternType /*= Settings::CHESSBOARD*/)
|
||||
{
|
||||
corners.clear();
|
||||
@@ -310,19 +310,19 @@ We do the calibration with the help of the :calib3d:`calibrateCamera <calibratec
|
||||
}
|
||||
}
|
||||
|
||||
And then multiply it as:
|
||||
And then multiply it as:
|
||||
|
||||
.. code-block:: cpp
|
||||
.. code-block:: cpp
|
||||
|
||||
vector<vector<Point3f> > objectPoints(1);
|
||||
calcBoardCornerPositions(s.boardSize, s.squareSize, objectPoints[0], s.calibrationPattern);
|
||||
objectPoints.resize(imagePoints.size(),objectPoints[0]);
|
||||
objectPoints.resize(imagePoints.size(),objectPoints[0]);
|
||||
|
||||
+ The image points. This is a vector of *Point2f* vector that for each input image contains where the important points (corners for chessboard, and center of circles for the circle patterns) were found. We already collected this from what the :calib3d:`findChessboardCorners <findchessboardcorners>` or the :calib3d:`findCirclesGrid <findcirclesgrid>` function returned. We just need to pass it on.
|
||||
+ The image points. This is a vector of *Point2f* vector that for each input image contains where the important points (corners for chessboard, and center of circles for the circle patterns) were found. We already collected this from what the :calib3d:`findChessboardCorners <findchessboardcorners>` or the :calib3d:`findCirclesGrid <findcirclesgrid>` function returned. We just need to pass it on.
|
||||
|
||||
+ The size of the image acquired from the camera, video file or the images.
|
||||
+ The size of the image acquired from the camera, video file or the images.
|
||||
|
||||
+ The camera matrix. If we used the fix aspect ratio option we need to set the :math:`f_x` to zero:
|
||||
+ The camera matrix. If we used the fix aspect ratio option we need to set the :math:`f_x` to zero:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -330,24 +330,24 @@ We do the calibration with the help of the :calib3d:`calibrateCamera <calibratec
|
||||
if( s.flag & CV_CALIB_FIX_ASPECT_RATIO )
|
||||
cameraMatrix.at<double>(0,0) = 1.0;
|
||||
|
||||
+ The distortion coefficient matrix. Initialize with zero.
|
||||
+ The distortion coefficient matrix. Initialize with zero.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
distCoeffs = Mat::zeros(8, 1, CV_64F);
|
||||
|
||||
+ The function will calculate for all the views the rotation and translation vector that transform the object points (given in the model coordinate space) to the image points (given in the world coordinate space). The 7th and 8th parameters are an output vector of matrices containing in the ith position the rotation and translation vector for the ith object point to the ith image point.
|
||||
+ The function will calculate for all the views the rotation and translation vector that transform the object points (given in the model coordinate space) to the image points (given in the world coordinate space). The 7th and 8th parameters are an output vector of matrices containing in the ith position the rotation and translation vector for the ith object point to the ith image point.
|
||||
|
||||
+ The final argument is a flag. You need to specify here options like fix the aspect ratio for the focal length, assume zero tangential distortion or to fix the principal point.
|
||||
+ The final argument is a flag. You need to specify here options like fix the aspect ratio for the focal length, assume zero tangential distortion or to fix the principal point.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
double rms = calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix,
|
||||
distCoeffs, rvecs, tvecs, s.flag|CV_CALIB_FIX_K4|CV_CALIB_FIX_K5);
|
||||
|
||||
+ The function returns the average re-projection error. This number gives a good estimation of just how exact is the found parameters. This should be as close to zero as possible. Given the intrinsic, distortion, rotation and translation matrices we may calculate the error for one view by using the :calib3d:`projectPoints <projectpoints>` to first transform the object point to image point. Then we calculate the absolute norm between what we got with our transformation and the corner/circle finding algorithm. To find the average error we calculate the arithmetical mean of the errors calculate for all the calibration images.
|
||||
+ The function returns the average re-projection error. This number gives a good estimation of just how exact is the found parameters. This should be as close to zero as possible. Given the intrinsic, distortion, rotation and translation matrices we may calculate the error for one view by using the :calib3d:`projectPoints <projectpoints>` to first transform the object point to image point. Then we calculate the absolute norm between what we got with our transformation and the corner/circle finding algorithm. To find the average error we calculate the arithmetical mean of the errors calculate for all the calibration images.
|
||||
|
||||
.. code-block:: cpp
|
||||
.. code-block:: cpp
|
||||
|
||||
double computeReprojectionErrors( const vector<vector<Point3f> >& objectPoints,
|
||||
const vector<vector<Point2f> >& imagePoints,
|
||||
@@ -378,7 +378,7 @@ We do the calibration with the help of the :calib3d:`calibrateCamera <calibratec
|
||||
Results
|
||||
=======
|
||||
|
||||
Let there be :download:`this input chessboard pattern <../../../pattern.png>` that has a size of 9 X 6. I've used an AXIS IP camera to create a couple of snapshots of the board and saved it into a VID5 directory. I've put this inside the :file:`images/CameraCalibraation` folder of my working directory and created the following :file:`VID5.XML` file that describes which images to use:
|
||||
Let there be :download:`this input chessboard pattern <../../../pattern.png>` that has a size of 9 X 6. I've used an AXIS IP camera to create a couple of snapshots of the board and saved it into a VID5 directory. I've put this inside the :file:`images/CameraCalibraation` folder of my working directory and created the following :file:`VID5.XML` file that describes which images to use:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
@@ -396,25 +396,25 @@ Let there be :download:`this input chessboard pattern <../../../pattern.png>` th
|
||||
</images>
|
||||
</opencv_storage>
|
||||
|
||||
Then specified the :file:`images/CameraCalibraation/VID5/VID5.XML` as input in the configuration file. Here's a chessboard pattern found during the runtime of the application:
|
||||
Then specified the :file:`images/CameraCalibraation/VID5/VID5.XML` as input in the configuration file. Here's a chessboard pattern found during the runtime of the application:
|
||||
|
||||
.. image:: images/fileListImage.jpg
|
||||
.. image:: images/fileListImage.jpg
|
||||
:alt: A found chessboard
|
||||
:align: center
|
||||
|
||||
After applying the distortion removal we get:
|
||||
After applying the distortion removal we get:
|
||||
|
||||
.. image:: images/fileListImageUnDist.jpg
|
||||
.. image:: images/fileListImageUnDist.jpg
|
||||
:alt: Distortion removal for File List
|
||||
:align: center
|
||||
|
||||
The same works for :download:`this asymmetrical circle pattern <../../../acircles_pattern.png>` by setting the input width to 4 and height to 11. This time I've used a live camera feed by specifying its ID ("1") for the input. Here's, how a detected pattern should look:
|
||||
The same works for :download:`this asymmetrical circle pattern <../../../acircles_pattern.png>` by setting the input width to 4 and height to 11. This time I've used a live camera feed by specifying its ID ("1") for the input. Here's, how a detected pattern should look:
|
||||
|
||||
.. image:: images/asymetricalPattern.jpg
|
||||
.. image:: images/asymetricalPattern.jpg
|
||||
:alt: Asymmetrical circle detection
|
||||
:align: center
|
||||
|
||||
In both cases in the specified output XML/YAML file you'll find the camera and distortion coefficients matrices:
|
||||
In both cases in the specified output XML/YAML file you'll find the camera and distortion coefficients matrices:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -433,9 +433,9 @@ In both cases in the specified output XML/YAML file you'll find the camera and d
|
||||
-4.1802327176423804e-001 5.0715244063187526e-001 0. 0.
|
||||
-5.7843597214487474e-001</data></Distortion_Coefficients>
|
||||
|
||||
Add these values as constants to your program, call the :imgproc_geometric:`initUndistortRectifyMap <initundistortrectifymap>` and the :imgproc_geometric:`remap <remap>` function to remove distortion and enjoy distortion free inputs with cheap and low quality cameras.
|
||||
Add these values as constants to your program, call the :imgproc_geometric:`initUndistortRectifyMap <initundistortrectifymap>` and the :imgproc_geometric:`remap <remap>` function to remove distortion and enjoy distortion free inputs with cheap and low quality cameras.
|
||||
|
||||
You may observe a runtime instance of this on the `YouTube here <https://www.youtube.com/watch?v=ViPN810E0SU>`_.
|
||||
You may observe a runtime instance of this on the `YouTube here <https://www.youtube.com/watch?v=ViPN810E0SU>`_.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
|
||||
+6
-6
@@ -7,16 +7,16 @@ Camera calibration with square chessboard
|
||||
|
||||
The goal of this tutorial is to learn how to calibrate a camera given a set of chessboard images.
|
||||
|
||||
*Test data*: use images in your data/chess folder.
|
||||
*Test data*: use images in your data/chess folder.
|
||||
|
||||
#.
|
||||
Compile opencv with samples by setting ``BUILD_EXAMPLES`` to ``ON`` in cmake configuration.
|
||||
Compile opencv with samples by setting ``BUILD_EXAMPLES`` to ``ON`` in cmake configuration.
|
||||
|
||||
#.
|
||||
Go to ``bin`` folder and use ``imagelist_creator`` to create an ``XML/YAML`` list of your images.
|
||||
|
||||
|
||||
#.
|
||||
Then, run ``calibration`` sample to get camera parameters. Use square size equal to 3cm.
|
||||
Then, run ``calibration`` sample to get camera parameters. Use square size equal to 3cm.
|
||||
|
||||
Pose estimation
|
||||
===============
|
||||
@@ -57,6 +57,6 @@ Now, let us write a code that detects a chessboard in a new image and finds its
|
||||
distCoeffs, rvec, tvec, false);
|
||||
|
||||
#.
|
||||
Calculate reprojection error like it is done in ``calibration`` sample (see ``opencv/samples/cpp/calibration.cpp``, function ``computeReprojectionErrors``).
|
||||
Calculate reprojection error like it is done in ``calibration`` sample (see ``opencv/samples/cpp/calibration.cpp``, function ``computeReprojectionErrors``).
|
||||
|
||||
Question: how to calculate the distance from the camera origin to any of the corners?
|
||||
Question: how to calculate the distance from the camera origin to any of the corners?
|
||||
@@ -3,11 +3,11 @@
|
||||
*calib3d* module. Camera calibration and 3D reconstruction
|
||||
-----------------------------------------------------------
|
||||
|
||||
Although we got most of our images in a 2D format they do come from a 3D world. Here you will learn how to find out from the 2D images information about the 3D world.
|
||||
Although we got most of our images in a 2D format they do come from a 3D world. Here you will learn how to find out from the 2D images information about the 3D world.
|
||||
|
||||
.. include:: ../../definitions/tocDefinitions.rst
|
||||
.. include:: ../../definitions/tocDefinitions.rst
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
@@ -26,7 +26,7 @@ Although we got most of our images in a 2D format they do come from a 3D world.
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ Theory
|
||||
|
||||
.. note::
|
||||
|
||||
The explanation below belongs to the book `Computer Vision: Algorithms and Applications <http://szeliski.org/Book/>`_ by Richard Szeliski
|
||||
The explanation below belongs to the book `Computer Vision: Algorithms and Applications <http://szeliski.org/Book/>`_ by Richard Szeliski
|
||||
|
||||
From our previous tutorial, we know already a bit of *Pixel operators*. An interesting dyadic (two-input) operator is the *linear blend operator*:
|
||||
|
||||
@@ -43,7 +43,7 @@ As usual, after the not-so-lengthy explanation, let's go to the code:
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
double alpha = 0.5; double beta; double input;
|
||||
double alpha = 0.5; double beta; double input;
|
||||
|
||||
Mat src1, src2, dst;
|
||||
|
||||
@@ -69,7 +69,7 @@ As usual, after the not-so-lengthy explanation, let's go to the code:
|
||||
|
||||
beta = ( 1.0 - alpha );
|
||||
addWeighted( src1, alpha, src2, beta, 0.0, dst);
|
||||
|
||||
|
||||
imshow( "Linear Blend", dst );
|
||||
|
||||
waitKey(0);
|
||||
@@ -99,10 +99,10 @@ Explanation
|
||||
#. Now we need to generate the :math:`g(x)` image. For this, the function :add_weighted:`addWeighted <>` comes quite handy:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
|
||||
beta = ( 1.0 - alpha );
|
||||
addWeighted( src1, alpha, src2, beta, 0.0, dst);
|
||||
|
||||
|
||||
since :add_weighted:`addWeighted <>` produces:
|
||||
|
||||
.. math::
|
||||
@@ -110,12 +110,12 @@ Explanation
|
||||
dst = \alpha \cdot src1 + \beta \cdot src2 + \gamma
|
||||
|
||||
In this case, :math:`\gamma` is the argument :math:`0.0` in the code above.
|
||||
|
||||
#. Create windows, show the images and wait for the user to end the program.
|
||||
|
||||
#. Create windows, show the images and wait for the user to end the program.
|
||||
|
||||
Result
|
||||
=======
|
||||
|
||||
.. image:: images/Adding_Images_Tutorial_Result_0.jpg
|
||||
:alt: Blending Images Tutorial - Final Result
|
||||
:align: center
|
||||
:align: center
|
||||
|
||||
@@ -31,15 +31,15 @@ Point
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
Point pt;
|
||||
pt.x = 10;
|
||||
pt.y = 8;
|
||||
Point pt;
|
||||
pt.x = 10;
|
||||
pt.y = 8;
|
||||
|
||||
or
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
Point pt = Point(10, 8);
|
||||
Point pt = Point(10, 8);
|
||||
|
||||
Scalar
|
||||
-------
|
||||
@@ -49,7 +49,7 @@ Scalar
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
Scalar( a, b, c )
|
||||
Scalar( a, b, c )
|
||||
|
||||
We would be defining a RGB color such as: *Red = c*, *Green = b* and *Blue = a*
|
||||
|
||||
@@ -65,51 +65,51 @@ Explanation
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
/// Windows names
|
||||
char atom_window[] = "Drawing 1: Atom";
|
||||
char rook_window[] = "Drawing 2: Rook";
|
||||
/// Windows names
|
||||
char atom_window[] = "Drawing 1: Atom";
|
||||
char rook_window[] = "Drawing 2: Rook";
|
||||
|
||||
/// Create black empty images
|
||||
Mat atom_image = Mat::zeros( w, w, CV_8UC3 );
|
||||
Mat rook_image = Mat::zeros( w, w, CV_8UC3 );
|
||||
/// Create black empty images
|
||||
Mat atom_image = Mat::zeros( w, w, CV_8UC3 );
|
||||
Mat rook_image = Mat::zeros( w, w, CV_8UC3 );
|
||||
|
||||
#. We created functions to draw different geometric shapes. For instance, to draw the atom we used *MyEllipse* and *MyFilledCircle*:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
/// 1. Draw a simple atom:
|
||||
/// 1. Draw a simple atom:
|
||||
|
||||
/// 1.a. Creating ellipses
|
||||
MyEllipse( atom_image, 90 );
|
||||
MyEllipse( atom_image, 0 );
|
||||
MyEllipse( atom_image, 45 );
|
||||
MyEllipse( atom_image, -45 );
|
||||
/// 1.a. Creating ellipses
|
||||
MyEllipse( atom_image, 90 );
|
||||
MyEllipse( atom_image, 0 );
|
||||
MyEllipse( atom_image, 45 );
|
||||
MyEllipse( atom_image, -45 );
|
||||
|
||||
/// 1.b. Creating circles
|
||||
MyFilledCircle( atom_image, Point( w/2.0, w/2.0) );
|
||||
/// 1.b. Creating circles
|
||||
MyFilledCircle( atom_image, Point( w/2.0, w/2.0) );
|
||||
|
||||
#. And to draw the rook we employed *MyLine*, *rectangle* and a *MyPolygon*:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
/// 2. Draw a rook
|
||||
/// 2. Draw a rook
|
||||
|
||||
/// 2.a. Create a convex polygon
|
||||
MyPolygon( rook_image );
|
||||
/// 2.a. Create a convex polygon
|
||||
MyPolygon( rook_image );
|
||||
|
||||
/// 2.b. Creating rectangles
|
||||
rectangle( rook_image,
|
||||
Point( 0, 7*w/8.0 ),
|
||||
Point( w, w),
|
||||
Scalar( 0, 255, 255 ),
|
||||
-1,
|
||||
8 );
|
||||
/// 2.b. Creating rectangles
|
||||
rectangle( rook_image,
|
||||
Point( 0, 7*w/8.0 ),
|
||||
Point( w, w),
|
||||
Scalar( 0, 255, 255 ),
|
||||
-1,
|
||||
8 );
|
||||
|
||||
/// 2.c. Create a few lines
|
||||
MyLine( rook_image, Point( 0, 15*w/16 ), Point( w, 15*w/16 ) );
|
||||
MyLine( rook_image, Point( w/4, 7*w/8 ), Point( w/4, w ) );
|
||||
MyLine( rook_image, Point( w/2, 7*w/8 ), Point( w/2, w ) );
|
||||
MyLine( rook_image, Point( 3*w/4, 7*w/8 ), Point( 3*w/4, w ) );
|
||||
/// 2.c. Create a few lines
|
||||
MyLine( rook_image, Point( 0, 15*w/16 ), Point( w, 15*w/16 ) );
|
||||
MyLine( rook_image, Point( w/4, 7*w/8 ), Point( w/4, w ) );
|
||||
MyLine( rook_image, Point( w/2, 7*w/8 ), Point( w/2, w ) );
|
||||
MyLine( rook_image, Point( 3*w/4, 7*w/8 ), Point( 3*w/4, w ) );
|
||||
|
||||
#. Let's check what is inside each of these functions:
|
||||
|
||||
@@ -117,17 +117,15 @@ Explanation
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void MyLine( Mat img, Point start, Point end )
|
||||
{
|
||||
int thickness = 2;
|
||||
int lineType = 8;
|
||||
line( img,
|
||||
start,
|
||||
end,
|
||||
Scalar( 0, 0, 0 ),
|
||||
thickness,
|
||||
lineType );
|
||||
}
|
||||
void MyLine( Mat img, Point start, Point end )
|
||||
{
|
||||
int thickness = 2;
|
||||
int lineType = 8;
|
||||
line( img, start, end,
|
||||
Scalar( 0, 0, 0 ),
|
||||
thickness,
|
||||
lineType );
|
||||
}
|
||||
|
||||
As we can see, *MyLine* just call the function :line:`line <>`, which does the following:
|
||||
|
||||
@@ -143,32 +141,32 @@ Explanation
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void MyEllipse( Mat img, double angle )
|
||||
{
|
||||
int thickness = 2;
|
||||
int lineType = 8;
|
||||
void MyEllipse( Mat img, double angle )
|
||||
{
|
||||
int thickness = 2;
|
||||
int lineType = 8;
|
||||
|
||||
ellipse( img,
|
||||
Point( w/2.0, w/2.0 ),
|
||||
Size( w/4.0, w/16.0 ),
|
||||
angle,
|
||||
0,
|
||||
360,
|
||||
Scalar( 255, 0, 0 ),
|
||||
thickness,
|
||||
lineType );
|
||||
}
|
||||
ellipse( img,
|
||||
Point( w/2.0, w/2.0 ),
|
||||
Size( w/4.0, w/16.0 ),
|
||||
angle,
|
||||
0,
|
||||
360,
|
||||
Scalar( 255, 0, 0 ),
|
||||
thickness,
|
||||
lineType );
|
||||
}
|
||||
|
||||
From the code above, we can observe that the function :ellipse:`ellipse <>` draws an ellipse such that:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
* The ellipse is displayed in the image **img**
|
||||
* The ellipse center is located in the point **(w/2.0, w/2.0)** and is enclosed in a box of size **(w/4.0, w/16.0)**
|
||||
* The ellipse is rotated **angle** degrees
|
||||
* The ellipse extends an arc between **0** and **360** degrees
|
||||
* The color of the figure will be **Scalar( 255, 255, 0)** which means blue in RGB value.
|
||||
* The ellipse's **thickness** is 2.
|
||||
* The ellipse is displayed in the image **img**
|
||||
* The ellipse center is located in the point **(w/2.0, w/2.0)** and is enclosed in a box of size **(w/4.0, w/16.0)**
|
||||
* The ellipse is rotated **angle** degrees
|
||||
* The ellipse extends an arc between **0** and **360** degrees
|
||||
* The color of the figure will be **Scalar( 255, 255, 0)** which means blue in RGB value.
|
||||
* The ellipse's **thickness** is 2.
|
||||
|
||||
|
||||
* *MyFilledCircle*
|
||||
@@ -176,17 +174,17 @@ Explanation
|
||||
.. code-block:: cpp
|
||||
|
||||
void MyFilledCircle( Mat img, Point center )
|
||||
{
|
||||
int thickness = -1;
|
||||
int lineType = 8;
|
||||
{
|
||||
int thickness = -1;
|
||||
int lineType = 8;
|
||||
|
||||
circle( img,
|
||||
center,
|
||||
w/32.0,
|
||||
Scalar( 0, 0, 255 ),
|
||||
thickness,
|
||||
lineType );
|
||||
}
|
||||
circle( img,
|
||||
center,
|
||||
w/32.0,
|
||||
Scalar( 0, 0, 255 ),
|
||||
thickness,
|
||||
lineType );
|
||||
}
|
||||
|
||||
Similar to the ellipse function, we can observe that *circle* receives as arguments:
|
||||
|
||||
@@ -202,43 +200,43 @@ Explanation
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void MyPolygon( Mat img )
|
||||
{
|
||||
int lineType = 8;
|
||||
void MyPolygon( Mat img )
|
||||
{
|
||||
int lineType = 8;
|
||||
|
||||
/** Create some points */
|
||||
Point rook_points[1][20];
|
||||
rook_points[0][0] = Point( w/4.0, 7*w/8.0 );
|
||||
rook_points[0][1] = Point( 3*w/4.0, 7*w/8.0 );
|
||||
rook_points[0][2] = Point( 3*w/4.0, 13*w/16.0 );
|
||||
rook_points[0][3] = Point( 11*w/16.0, 13*w/16.0 );
|
||||
rook_points[0][4] = Point( 19*w/32.0, 3*w/8.0 );
|
||||
rook_points[0][5] = Point( 3*w/4.0, 3*w/8.0 );
|
||||
rook_points[0][6] = Point( 3*w/4.0, w/8.0 );
|
||||
rook_points[0][7] = Point( 26*w/40.0, w/8.0 );
|
||||
rook_points[0][8] = Point( 26*w/40.0, w/4.0 );
|
||||
rook_points[0][9] = Point( 22*w/40.0, w/4.0 );
|
||||
rook_points[0][10] = Point( 22*w/40.0, w/8.0 );
|
||||
rook_points[0][11] = Point( 18*w/40.0, w/8.0 );
|
||||
rook_points[0][12] = Point( 18*w/40.0, w/4.0 );
|
||||
rook_points[0][13] = Point( 14*w/40.0, w/4.0 );
|
||||
rook_points[0][14] = Point( 14*w/40.0, w/8.0 );
|
||||
rook_points[0][15] = Point( w/4.0, w/8.0 );
|
||||
rook_points[0][16] = Point( w/4.0, 3*w/8.0 );
|
||||
rook_points[0][17] = Point( 13*w/32.0, 3*w/8.0 );
|
||||
rook_points[0][18] = Point( 5*w/16.0, 13*w/16.0 );
|
||||
rook_points[0][19] = Point( w/4.0, 13*w/16.0) ;
|
||||
/** Create some points */
|
||||
Point rook_points[1][20];
|
||||
rook_points[0][0] = Point( w/4.0, 7*w/8.0 );
|
||||
rook_points[0][1] = Point( 3*w/4.0, 7*w/8.0 );
|
||||
rook_points[0][2] = Point( 3*w/4.0, 13*w/16.0 );
|
||||
rook_points[0][3] = Point( 11*w/16.0, 13*w/16.0 );
|
||||
rook_points[0][4] = Point( 19*w/32.0, 3*w/8.0 );
|
||||
rook_points[0][5] = Point( 3*w/4.0, 3*w/8.0 );
|
||||
rook_points[0][6] = Point( 3*w/4.0, w/8.0 );
|
||||
rook_points[0][7] = Point( 26*w/40.0, w/8.0 );
|
||||
rook_points[0][8] = Point( 26*w/40.0, w/4.0 );
|
||||
rook_points[0][9] = Point( 22*w/40.0, w/4.0 );
|
||||
rook_points[0][10] = Point( 22*w/40.0, w/8.0 );
|
||||
rook_points[0][11] = Point( 18*w/40.0, w/8.0 );
|
||||
rook_points[0][12] = Point( 18*w/40.0, w/4.0 );
|
||||
rook_points[0][13] = Point( 14*w/40.0, w/4.0 );
|
||||
rook_points[0][14] = Point( 14*w/40.0, w/8.0 );
|
||||
rook_points[0][15] = Point( w/4.0, w/8.0 );
|
||||
rook_points[0][16] = Point( w/4.0, 3*w/8.0 );
|
||||
rook_points[0][17] = Point( 13*w/32.0, 3*w/8.0 );
|
||||
rook_points[0][18] = Point( 5*w/16.0, 13*w/16.0 );
|
||||
rook_points[0][19] = Point( w/4.0, 13*w/16.0) ;
|
||||
|
||||
const Point* ppt[1] = { rook_points[0] };
|
||||
int npt[] = { 20 };
|
||||
const Point* ppt[1] = { rook_points[0] };
|
||||
int npt[] = { 20 };
|
||||
|
||||
fillPoly( img,
|
||||
ppt,
|
||||
npt,
|
||||
1,
|
||||
Scalar( 255, 255, 255 ),
|
||||
lineType );
|
||||
}
|
||||
fillPoly( img,
|
||||
ppt,
|
||||
npt,
|
||||
1,
|
||||
Scalar( 255, 255, 255 ),
|
||||
lineType );
|
||||
}
|
||||
|
||||
To draw a filled polygon we use the function :fill_poly:`fillPoly <>`. We note that:
|
||||
|
||||
@@ -254,12 +252,11 @@ Explanation
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
rectangle( rook_image,
|
||||
Point( 0, 7*w/8.0 ),
|
||||
Point( w, w),
|
||||
Scalar( 0, 255, 255 ),
|
||||
-1,
|
||||
8 );
|
||||
rectangle( rook_image,
|
||||
Point( 0, 7*w/8.0 ),
|
||||
Point( w, w),
|
||||
Scalar( 0, 255, 255 ),
|
||||
-1, 8 );
|
||||
|
||||
Finally we have the :rectangle:`rectangle <>` function (we did not create a special function for this guy). We note that:
|
||||
|
||||
|
||||
@@ -10,26 +10,24 @@ In this tutorial you will learn how to:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
+ Access pixel values
|
||||
|
||||
+ Access pixel values
|
||||
+ Initialize a matrix with zeros
|
||||
|
||||
+ Learn what :saturate_cast:`saturate_cast <>` does and why it is useful
|
||||
|
||||
+ Get some cool info about pixel transformations
|
||||
|
||||
Theory
|
||||
=======
|
||||
|
||||
|
||||
.. note::
|
||||
The explanation below belongs to the book `Computer Vision: Algorithms and Applications <http://szeliski.org/Book/>`_ by Richard Szeliski
|
||||
|
||||
The explanation below belongs to the book `Computer Vision: Algorithms and Applications <http://szeliski.org/Book/>`_ by Richard Szeliski
|
||||
|
||||
Image Processing
|
||||
--------------------
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
* A general image processing operator is a function that takes one or more input images and produces an output image.
|
||||
* A general image processing operator is a function that takes one or more input images and produces an output image.
|
||||
|
||||
* Image transforms can be seen as:
|
||||
|
||||
@@ -38,7 +36,7 @@ Image Processing
|
||||
|
||||
|
||||
Pixel Transforms
|
||||
^^^^^^^^^^^^^^^^^
|
||||
-----------------
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
@@ -47,32 +45,30 @@ Pixel Transforms
|
||||
* Examples of such operators include *brightness and contrast adjustments* as well as color correction and transformations.
|
||||
|
||||
Brightness and contrast adjustments
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
------------------------------------
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
* Two commonly used point processes are *multiplication* and *addition* with a constant:
|
||||
|
||||
.. math::
|
||||
|
||||
|
||||
g(x) = \alpha f(x) + \beta
|
||||
|
||||
|
||||
* The parameters :math:`\alpha > 0` and :math:`\beta` are often called the *gain* and *bias* parameters; sometimes these parameters are said to control *contrast* and *brightness* respectively.
|
||||
|
||||
* You can think of :math:`f(x)` as the source image pixels and :math:`g(x)` as the output image pixels. Then, more conveniently we can write the expression as:
|
||||
|
||||
.. math::
|
||||
|
||||
|
||||
g(i,j) = \alpha \cdot f(i,j) + \beta
|
||||
|
||||
where :math:`i` and :math:`j` indicates that the pixel is located in the *i-th* row and *j-th* column.
|
||||
|
||||
where :math:`i` and :math:`j` indicates that the pixel is located in the *i-th* row and *j-th* column.
|
||||
|
||||
Code
|
||||
=====
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
* The following code performs the operation :math:`g(i,j) = \alpha \cdot f(i,j) + \beta` :
|
||||
* The following code performs the operation :math:`g(i,j) = \alpha \cdot f(i,j) + \beta` :
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -87,38 +83,37 @@ Code
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
/// Read image given by user
|
||||
Mat image = imread( argv[1] );
|
||||
Mat new_image = Mat::zeros( image.size(), image.type() );
|
||||
/// Read image given by user
|
||||
Mat image = imread( argv[1] );
|
||||
Mat new_image = Mat::zeros( image.size(), image.type() );
|
||||
|
||||
/// Initialize values
|
||||
std::cout<<" Basic Linear Transforms "<<std::endl;
|
||||
std::cout<<"-------------------------"<<std::endl;
|
||||
std::cout<<"* Enter the alpha value [1.0-3.0]: ";std::cin>>alpha;
|
||||
std::cout<<"* Enter the beta value [0-100]: "; std::cin>>beta;
|
||||
/// Initialize values
|
||||
std::cout<<" Basic Linear Transforms "<<std::endl;
|
||||
std::cout<<"-------------------------"<<std::endl;
|
||||
std::cout<<"* Enter the alpha value [1.0-3.0]: ";std::cin>>alpha;
|
||||
std::cout<<"* Enter the beta value [0-100]: "; std::cin>>beta;
|
||||
|
||||
/// Do the operation new_image(i,j) = alpha*image(i,j) + beta
|
||||
for( int y = 0; y < image.rows; y++ )
|
||||
{ for( int x = 0; x < image.cols; x++ )
|
||||
{ for( int c = 0; c < 3; c++ )
|
||||
{
|
||||
new_image.at<Vec3b>(y,x)[c] =
|
||||
saturate_cast<uchar>( alpha*( image.at<Vec3b>(y,x)[c] ) + beta );
|
||||
}
|
||||
}
|
||||
/// Do the operation new_image(i,j) = alpha*image(i,j) + beta
|
||||
for( int y = 0; y < image.rows; y++ ) {
|
||||
for( int x = 0; x < image.cols; x++ ) {
|
||||
for( int c = 0; c < 3; c++ ) {
|
||||
new_image.at<Vec3b>(y,x)[c] =
|
||||
saturate_cast<uchar>( alpha*( image.at<Vec3b>(y,x)[c] ) + beta );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create Windows
|
||||
namedWindow("Original Image", 1);
|
||||
namedWindow("New Image", 1);
|
||||
/// Create Windows
|
||||
namedWindow("Original Image", 1);
|
||||
namedWindow("New Image", 1);
|
||||
|
||||
/// Show stuff
|
||||
imshow("Original Image", image);
|
||||
imshow("New Image", new_image);
|
||||
/// Show stuff
|
||||
imshow("Original Image", image);
|
||||
imshow("New Image", new_image);
|
||||
|
||||
/// Wait until user press some key
|
||||
waitKey();
|
||||
return 0;
|
||||
/// Wait until user press some key
|
||||
waitKey();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Explanation
|
||||
@@ -133,41 +128,42 @@ Explanation
|
||||
|
||||
|
||||
#. We load an image using :imread:`imread <>` and save it in a Mat object:
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
Mat image = imread( argv[1] );
|
||||
|
||||
#. Now, since we will make some transformations to this image, we need a new Mat object to store it. Also, we want this to have the following features:
|
||||
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
* Initial pixel values equal to zero
|
||||
* Same size and type as the original image
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
Mat new_image = Mat::zeros( image.size(), image.type() );
|
||||
|
||||
We observe that :mat_zeros:`Mat::zeros <>` returns a Matlab-style zero initializer based on *image.size()* and *image.type()*
|
||||
Mat new_image = Mat::zeros( image.size(), image.type() );
|
||||
|
||||
We observe that :mat_zeros:`Mat::zeros <>` returns a Matlab-style zero initializer based on *image.size()* and *image.type()*
|
||||
|
||||
#. Now, to perform the operation :math:`g(i,j) = \alpha \cdot f(i,j) + \beta` we will access to each pixel in image. Since we are operating with RGB images, we will have three values per pixel (R, G and B), so we will also access them separately. Here is the piece of code:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
for( int y = 0; y < image.rows; y++ )
|
||||
{ for( int x = 0; x < image.cols; x++ )
|
||||
{ for( int c = 0; c < 3; c++ )
|
||||
{ new_image.at<Vec3b>(y,x)[c] =
|
||||
saturate_cast<uchar>( alpha*( image.at<Vec3b>(y,x)[c] ) + beta ); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for( int y = 0; y < image.rows; y++ ) {
|
||||
for( int x = 0; x < image.cols; x++ ) {
|
||||
for( int c = 0; c < 3; c++ ) {
|
||||
new_image.at<Vec3b>(y,x)[c] =
|
||||
saturate_cast<uchar>( alpha*( image.at<Vec3b>(y,x)[c] ) + beta );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Notice the following:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
* To access each pixel in the images we are using this syntax: *image.at<Vec3b>(y,x)[c]* where *y* is the row, *x* is the column and *c* is R, G or B (0, 1 or 2).
|
||||
* To access each pixel in the images we are using this syntax: *image.at<Vec3b>(y,x)[c]* where *y* is the row, *x* is the column and *c* is R, G or B (0, 1 or 2).
|
||||
|
||||
* Since the operation :math:`\alpha \cdot p(i,j) + \beta` can give values out of range or not integers (if :math:`\alpha` is float), we use :saturate_cast:`saturate_cast <>` to make sure the values are valid.
|
||||
|
||||
@@ -175,7 +171,7 @@ Explanation
|
||||
#. Finally, we create windows and show the images, the usual way.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
|
||||
namedWindow("Original Image", 1);
|
||||
namedWindow("New Image", 1);
|
||||
|
||||
@@ -185,9 +181,9 @@ Explanation
|
||||
waitKey(0);
|
||||
|
||||
.. note::
|
||||
|
||||
|
||||
Instead of using the **for** loops to access each pixel, we could have simply used this command:
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
image.convertTo(new_image, -1, alpha, beta);
|
||||
@@ -209,6 +205,6 @@ Result
|
||||
|
||||
* We get this:
|
||||
|
||||
.. image:: images/Basic_Linear_Transform_Tutorial_Result_0.jpg
|
||||
:alt: Basic Linear Transform - Final Result
|
||||
:align: center
|
||||
.. image:: images/Basic_Linear_Transform_Tutorial_Result_0.jpg
|
||||
:alt: Basic Linear Transform - Final Result
|
||||
:align: center
|
||||
|
||||
@@ -4,22 +4,22 @@ Discrete Fourier Transform
|
||||
**************************
|
||||
|
||||
Goal
|
||||
====
|
||||
====
|
||||
|
||||
We'll seek answers for the following questions:
|
||||
We'll seek answers for the following questions:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
+ What is a Fourier transform and why use it?
|
||||
+ How to do it in OpenCV?
|
||||
+ What is a Fourier transform and why use it?
|
||||
+ How to do it in OpenCV?
|
||||
+ Usage of functions such as: :imgprocfilter:`copyMakeBorder() <copymakeborder>`, :operationsonarrays:`merge() <merge>`, :operationsonarrays:`dft() <dft>`, :operationsonarrays:`getOptimalDFTSize() <getoptimaldftsize>`, :operationsonarrays:`log() <log>` and :operationsonarrays:`normalize() <normalize>` .
|
||||
|
||||
Source code
|
||||
===========
|
||||
|
||||
You can :download:`download this from here <../../../../samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.cpp>` or find it in the :file:`samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.cpp` of the OpenCV source code library.
|
||||
You can :download:`download this from here <../../../../samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.cpp>` or find it in the :file:`samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.cpp` of the OpenCV source code library.
|
||||
|
||||
Here's a sample usage of :operationsonarrays:`dft() <dft>` :
|
||||
Here's a sample usage of :operationsonarrays:`dft() <dft>` :
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.cpp
|
||||
:language: cpp
|
||||
@@ -30,11 +30,11 @@ Here's a sample usage of :operationsonarrays:`dft() <dft>` :
|
||||
Explanation
|
||||
===========
|
||||
|
||||
The Fourier Transform will decompose an image into its sinus and cosines components. In other words, it will transform an image from its spatial domain to its frequency domain. The idea is that any function may be approximated exactly with the sum of infinite sinus and cosines functions. The Fourier Transform is a way how to do this. Mathematically a two dimensional images Fourier transform is:
|
||||
The Fourier Transform will decompose an image into its sinus and cosines components. In other words, it will transform an image from its spatial domain to its frequency domain. The idea is that any function may be approximated exactly with the sum of infinite sinus and cosines functions. The Fourier Transform is a way how to do this. Mathematically a two dimensional images Fourier transform is:
|
||||
|
||||
.. math::
|
||||
|
||||
F(k,l) = \displaystyle\sum\limits_{i=0}^{N-1}\sum\limits_{j=0}^{N-1} f(i,j)e^{-i2\pi(\frac{ki}{N}+\frac{lj}{N})}
|
||||
F(k,l) = \displaystyle\sum\limits_{i=0}^{N-1}\sum\limits_{j=0}^{N-1} f(i,j)e^{-i2\pi(\frac{ki}{N}+\frac{lj}{N})}
|
||||
|
||||
e^{ix} = \cos{x} + i\sin {x}
|
||||
|
||||
@@ -44,65 +44,65 @@ In this sample I'll show how to calculate and show the *magnitude* image of a Fo
|
||||
|
||||
1. **Expand the image to an optimal size**. The performance of a DFT is dependent of the image size. It tends to be the fastest for image sizes that are multiple of the numbers two, three and five. Therefore, to achieve maximal performance it is generally a good idea to pad border values to the image to get a size with such traits. The :operationsonarrays:`getOptimalDFTSize() <getoptimaldftsize>` returns this optimal size and we can use the :imgprocfilter:`copyMakeBorder() <copymakeborder>` function to expand the borders of an image:
|
||||
|
||||
.. code-block:: cpp
|
||||
.. code-block:: cpp
|
||||
|
||||
Mat padded; //expand input image to optimal size
|
||||
int m = getOptimalDFTSize( I.rows );
|
||||
int n = getOptimalDFTSize( I.cols ); // on the border add zero pixels
|
||||
copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0));
|
||||
|
||||
The appended pixels are initialized with zero.
|
||||
The appended pixels are initialized with zero.
|
||||
|
||||
2. **Make place for both the complex and the real values**. The result of a Fourier Transform is complex. This implies that for each image value the result is two image values (one per component). Moreover, the frequency domains range is much larger than its spatial counterpart. Therefore, we store these usually at least in a *float* format. Therefore we'll convert our input image to this type and expand it with another channel to hold the complex values:
|
||||
|
||||
.. code-block:: cpp
|
||||
.. code-block:: cpp
|
||||
|
||||
Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
|
||||
Mat complexI;
|
||||
merge(planes, 2, complexI); // Add to the expanded another plane with zeros
|
||||
|
||||
3. **Make the Discrete Fourier Transform**. It's possible an in-place calculation (same input as output):
|
||||
3. **Make the Discrete Fourier Transform**. It's possible an in-place calculation (same input as output):
|
||||
|
||||
.. code-block:: cpp
|
||||
.. code-block:: cpp
|
||||
|
||||
dft(complexI, complexI); // this way the result may fit in the source matrix
|
||||
|
||||
4. **Transform the real and complex values to magnitude**. A complex number has a real (*Re*) and a complex (imaginary - *Im*) part. The results of a DFT are complex numbers. The magnitude of a DFT is:
|
||||
4. **Transform the real and complex values to magnitude**. A complex number has a real (*Re*) and a complex (imaginary - *Im*) part. The results of a DFT are complex numbers. The magnitude of a DFT is:
|
||||
|
||||
.. math::
|
||||
|
||||
M = \sqrt[2]{ {Re(DFT(I))}^2 + {Im(DFT(I))}^2}
|
||||
|
||||
Translated to OpenCV code:
|
||||
Translated to OpenCV code:
|
||||
|
||||
.. code-block:: cpp
|
||||
.. code-block:: cpp
|
||||
|
||||
split(complexI, planes); // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
|
||||
magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude
|
||||
magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude
|
||||
Mat magI = planes[0];
|
||||
|
||||
5. **Switch to a logarithmic scale**. It turns out that the dynamic range of the Fourier coefficients is too large to be displayed on the screen. We have some small and some high changing values that we can't observe like this. Therefore the high values will all turn out as white points, while the small ones as black. To use the gray scale values to for visualization we can transform our linear scale to a logarithmic one:
|
||||
5. **Switch to a logarithmic scale**. It turns out that the dynamic range of the Fourier coefficients is too large to be displayed on the screen. We have some small and some high changing values that we can't observe like this. Therefore the high values will all turn out as white points, while the small ones as black. To use the gray scale values to for visualization we can transform our linear scale to a logarithmic one:
|
||||
|
||||
.. math::
|
||||
|
||||
M_1 = \log{(1 + M)}
|
||||
|
||||
Translated to OpenCV code:
|
||||
Translated to OpenCV code:
|
||||
|
||||
.. code-block:: cpp
|
||||
.. code-block:: cpp
|
||||
|
||||
magI += Scalar::all(1); // switch to logarithmic scale
|
||||
log(magI, magI);
|
||||
|
||||
6. **Crop and rearrange**. Remember, that at the first step, we expanded the image? Well, it's time to throw away the newly introduced values. For visualization purposes we may also rearrange the quadrants of the result, so that the origin (zero, zero) corresponds with the image center.
|
||||
6. **Crop and rearrange**. Remember, that at the first step, we expanded the image? Well, it's time to throw away the newly introduced values. For visualization purposes we may also rearrange the quadrants of the result, so that the origin (zero, zero) corresponds with the image center.
|
||||
|
||||
.. code-block:: cpp
|
||||
.. code-block:: cpp
|
||||
|
||||
magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2));
|
||||
int cx = magI.cols/2;
|
||||
int cy = magI.rows/2;
|
||||
|
||||
Mat q0(magI, Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant
|
||||
Mat q0(magI, Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant
|
||||
Mat q1(magI, Rect(cx, 0, cx, cy)); // Top-Right
|
||||
Mat q2(magI, Rect(0, cy, cx, cy)); // Bottom-Left
|
||||
Mat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-Right
|
||||
@@ -116,25 +116,25 @@ In this sample I'll show how to calculate and show the *magnitude* image of a Fo
|
||||
q2.copyTo(q1);
|
||||
tmp.copyTo(q2);
|
||||
|
||||
7. **Normalize**. This is done again for visualization purposes. We now have the magnitudes, however this are still out of our image display range of zero to one. We normalize our values to this range using the :operationsonarrays:`normalize() <normalize>` function.
|
||||
7. **Normalize**. This is done again for visualization purposes. We now have the magnitudes, however this are still out of our image display range of zero to one. We normalize our values to this range using the :operationsonarrays:`normalize() <normalize>` function.
|
||||
|
||||
.. code-block:: cpp
|
||||
.. code-block:: cpp
|
||||
|
||||
normalize(magI, magI, 0, 1, CV_MINMAX); // Transform the matrix with float values into a
|
||||
normalize(magI, magI, 0, 1, CV_MINMAX); // Transform the matrix with float values into a
|
||||
// viewable image form (float between values 0 and 1).
|
||||
|
||||
Result
|
||||
======
|
||||
|
||||
An application idea would be to determine the geometrical orientation present in the image. For example, let us find out if a text is horizontal or not? Looking at some text you'll notice that the text lines sort of form also horizontal lines and the letters form sort of vertical lines. These two main components of a text snippet may be also seen in case of the Fourier transform. Let us use :download:`this horizontal <../../../../samples/cpp/tutorial_code/images/imageTextN.png>` and :download:`this rotated<../../../../samples/cpp/tutorial_code/images/imageTextR.png>` image about a text.
|
||||
An application idea would be to determine the geometrical orientation present in the image. For example, let us find out if a text is horizontal or not? Looking at some text you'll notice that the text lines sort of form also horizontal lines and the letters form sort of vertical lines. These two main components of a text snippet may be also seen in case of the Fourier transform. Let us use :download:`this horizontal <../../../../samples/cpp/tutorial_code/images/imageTextN.png>` and :download:`this rotated<../../../../samples/cpp/tutorial_code/images/imageTextR.png>` image about a text.
|
||||
|
||||
In case of the horizontal text:
|
||||
In case of the horizontal text:
|
||||
|
||||
.. image:: images/result_normal.jpg
|
||||
:alt: In case of normal text
|
||||
:align: center
|
||||
|
||||
In case of a rotated text:
|
||||
In case of a rotated text:
|
||||
|
||||
.. image:: images/result_rotated.jpg
|
||||
:alt: In case of rotated text
|
||||
|
||||
+22
-22
@@ -4,9 +4,9 @@ File Input and Output using XML and YAML files
|
||||
**********************************************
|
||||
|
||||
Goal
|
||||
====
|
||||
====
|
||||
|
||||
You'll find answers for the following questions:
|
||||
You'll find answers for the following questions:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
@@ -18,7 +18,7 @@ You'll find answers for the following questions:
|
||||
Source code
|
||||
===========
|
||||
|
||||
You can :download:`download this from here <../../../../samples/cpp/tutorial_code/core/file_input_output/file_input_output.cpp>` or find it in the :file:`samples/cpp/tutorial_code/core/file_input_output/file_input_output.cpp` of the OpenCV source code library.
|
||||
You can :download:`download this from here <../../../../samples/cpp/tutorial_code/core/file_input_output/file_input_output.cpp>` or find it in the :file:`samples/cpp/tutorial_code/core/file_input_output/file_input_output.cpp` of the OpenCV source code library.
|
||||
|
||||
Here's a sample code of how to achieve all the stuff enumerated at the goal list.
|
||||
|
||||
@@ -31,9 +31,9 @@ Here's a sample code of how to achieve all the stuff enumerated at the goal list
|
||||
Explanation
|
||||
===========
|
||||
|
||||
Here we talk only about XML and YAML file inputs. Your output (and its respective input) file may have only one of these extensions and the structure coming from this. They are two kinds of data structures you may serialize: *mappings* (like the STL map) and *element sequence* (like the STL vector>. The difference between these is that in a map every element has a unique name through what you may access it. For sequences you need to go through them to query a specific item.
|
||||
Here we talk only about XML and YAML file inputs. Your output (and its respective input) file may have only one of these extensions and the structure coming from this. They are two kinds of data structures you may serialize: *mappings* (like the STL map) and *element sequence* (like the STL vector>. The difference between these is that in a map every element has a unique name through what you may access it. For sequences you need to go through them to query a specific item.
|
||||
|
||||
1. **XML\\YAML File Open and Close.** Before you write any content to such file you need to open it and at the end to close it. The XML\YAML data structure in OpenCV is :xmlymlpers:`FileStorage <filestorage>`. To specify that this structure to which file binds on your hard drive you can use either its constructor or the *open()* function of this:
|
||||
1. **XML\\YAML File Open and Close.** Before you write any content to such file you need to open it and at the end to close it. The XML\YAML data structure in OpenCV is :xmlymlpers:`FileStorage <filestorage>`. To specify that this structure to which file binds on your hard drive you can use either its constructor or the *open()* function of this:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -42,29 +42,29 @@ Here we talk only about XML and YAML file inputs. Your output (and its respectiv
|
||||
\\...
|
||||
fs.open(filename, FileStorage::READ);
|
||||
|
||||
Either one of this you use the second argument is a constant specifying the type of operations you'll be able to on them: WRITE, READ or APPEND. The extension specified in the file name also determinates the output format that will be used. The output may be even compressed if you specify an extension such as *.xml.gz*.
|
||||
Either one of this you use the second argument is a constant specifying the type of operations you'll be able to on them: WRITE, READ or APPEND. The extension specified in the file name also determinates the output format that will be used. The output may be even compressed if you specify an extension such as *.xml.gz*.
|
||||
|
||||
The file automatically closes when the :xmlymlpers:`FileStorage <filestorage>` objects is destroyed. However, you may explicitly call for this by using the *release* function:
|
||||
|
||||
The file automatically closes when the :xmlymlpers:`FileStorage <filestorage>` objects is destroyed. However, you may explicitly call for this by using the *release* function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
fs.release(); // explicit close
|
||||
|
||||
#. **Input and Output of text and numbers.** The data structure uses the same << output operator that the STL library. For outputting any type of data structure we need first to specify its name. We do this by just simply printing out the name of this. For basic types you may follow this with the print of the value :
|
||||
#. **Input and Output of text and numbers.** The data structure uses the same << output operator that the STL library. For outputting any type of data structure we need first to specify its name. We do this by just simply printing out the name of this. For basic types you may follow this with the print of the value :
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
fs << "iterationNr" << 100;
|
||||
|
||||
Reading in is a simple addressing (via the [] operator) and casting operation or a read via the >> operator :
|
||||
Reading in is a simple addressing (via the [] operator) and casting operation or a read via the >> operator :
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
int itNr;
|
||||
int itNr;
|
||||
fs["iterationNr"] >> itNr;
|
||||
itNr = (int) fs["iterationNr"];
|
||||
|
||||
#. **Input\\Output of OpenCV Data structures.** Well these behave exactly just as the basic C++ types:
|
||||
#. **Input\\Output of OpenCV Data structures.** Well these behave exactly just as the basic C++ types:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -77,7 +77,7 @@ Here we talk only about XML and YAML file inputs. Your output (and its respectiv
|
||||
fs["R"] >> R; // Read cv::Mat
|
||||
fs["T"] >> T;
|
||||
|
||||
#. **Input\\Output of vectors (arrays) and associative maps.** As I mentioned beforehand we can output maps and sequences (array, vector) too. Again we first print the name of the variable and then we have to specify if our output is either a sequence or map.
|
||||
#. **Input\\Output of vectors (arrays) and associative maps.** As I mentioned beforehand we can output maps and sequences (array, vector) too. Again we first print the name of the variable and then we have to specify if our output is either a sequence or map.
|
||||
|
||||
For sequence before the first element print the "[" character and after the last one the "]" character:
|
||||
|
||||
@@ -95,7 +95,7 @@ Here we talk only about XML and YAML file inputs. Your output (and its respectiv
|
||||
fs << "{" << "One" << 1;
|
||||
fs << "Two" << 2 << "}";
|
||||
|
||||
To read from these we use the :xmlymlpers:`FileNode <filenode>` and the :xmlymlpers:`FileNodeIterator <filenodeiterator>` data structures. The [] operator of the :xmlymlpers:`FileStorage <filestorage>` class returns a :xmlymlpers:`FileNode <filenode>` data type. If the node is sequential we can use the :xmlymlpers:`FileNodeIterator <filenodeiterator>` to iterate through the items:
|
||||
To read from these we use the :xmlymlpers:`FileNode <filenode>` and the :xmlymlpers:`FileNodeIterator <filenodeiterator>` data structures. The [] operator of the :xmlymlpers:`FileStorage <filestorage>` class returns a :xmlymlpers:`FileNode <filenode>` data type. If the node is sequential we can use the :xmlymlpers:`FileNodeIterator <filenodeiterator>` to iterate through the items:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -115,8 +115,8 @@ Here we talk only about XML and YAML file inputs. Your output (and its respectiv
|
||||
.. code-block:: cpp
|
||||
|
||||
n = fs["Mapping"]; // Read mappings from a sequence
|
||||
cout << "Two " << (int)(n["Two"]) << "; ";
|
||||
cout << "One " << (int)(n["One"]) << endl << endl;
|
||||
cout << "Two " << (int)(n["Two"]) << "; ";
|
||||
cout << "One " << (int)(n["One"]) << endl << endl;
|
||||
|
||||
#. **Read and write your own data structures.** Suppose you have a data structure such as:
|
||||
|
||||
@@ -148,7 +148,7 @@ Here we talk only about XML and YAML file inputs. Your output (and its respectiv
|
||||
id = (string)node["id"];
|
||||
}
|
||||
|
||||
Then you need to add the following functions definitions outside the class:
|
||||
Then you need to add the following functions definitions outside the class:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -175,17 +175,17 @@ Here we talk only about XML and YAML file inputs. Your output (and its respectiv
|
||||
fs << "MyData" << m; // your own data structures
|
||||
fs["MyData"] >> m; // Read your own structure_
|
||||
|
||||
Or to try out reading a non-existing read:
|
||||
Or to try out reading a non-existing read:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
fs["NonExisting"] >> m; // Do not add a fs << "NonExisting" << m command for this to work
|
||||
fs["NonExisting"] >> m; // Do not add a fs << "NonExisting" << m command for this to work
|
||||
cout << endl << "NonExisting = " << endl << m << endl;
|
||||
|
||||
Result
|
||||
======
|
||||
|
||||
Well mostly we just print out the defined numbers. On the screen of your console you could see:
|
||||
Well mostly we just print out the defined numbers. On the screen of your console you could see:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -212,7 +212,7 @@ Well mostly we just print out the defined numbers. On the screen of your console
|
||||
|
||||
Tip: Open up output.xml with a text editor to see the serialized data.
|
||||
|
||||
Nevertheless, it's much more interesting what you may see in the output xml file:
|
||||
Nevertheless, it's much more interesting what you may see in the output xml file:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
@@ -242,7 +242,7 @@ Nevertheless, it's much more interesting what you may see in the output xml file
|
||||
<id>mydata1234</id></MyData>
|
||||
</opencv_storage>
|
||||
|
||||
Or the YAML file:
|
||||
Or the YAML file:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ How to scan images, lookup tables and time measurement with OpenCV
|
||||
*******************************************************************
|
||||
|
||||
Goal
|
||||
====
|
||||
====
|
||||
|
||||
We'll seek answers for the following questions:
|
||||
We'll seek answers for the following questions:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
@@ -18,11 +18,11 @@ We'll seek answers for the following questions:
|
||||
Our test case
|
||||
=============
|
||||
|
||||
Let us consider a simple color reduction method. Using the unsigned char C and C++ type for matrix item storing a channel of pixel may have up to 256 different values. For a three channel image this can allow the formation of way too many colors (16 million to be exact). Working with so many color shades may give a heavy blow to our algorithm performance. However, sometimes it is enough to work with a lot less of them to get the same final result.
|
||||
Let us consider a simple color reduction method. Using the unsigned char C and C++ type for matrix item storing a channel of pixel may have up to 256 different values. For a three channel image this can allow the formation of way too many colors (16 million to be exact). Working with so many color shades may give a heavy blow to our algorithm performance. However, sometimes it is enough to work with a lot less of them to get the same final result.
|
||||
|
||||
In this cases it's common that we make a *color space reduction*. This means that we divide the color space current value with a new input value to end up with fewer colors. For instance every value between zero and nine takes the new value zero, every value between ten and nineteen the value ten and so on.
|
||||
In this cases it's common that we make a *color space reduction*. This means that we divide the color space current value with a new input value to end up with fewer colors. For instance every value between zero and nine takes the new value zero, every value between ten and nineteen the value ten and so on.
|
||||
|
||||
When you divide an *uchar* (unsigned char - aka values between zero and 255) value with an *int* value the result will be also *char*. These values may only be char values. Therefore, any fraction will be rounded down. Taking advantage of this fact the upper operation in the *uchar* domain may be expressed as:
|
||||
When you divide an *uchar* (unsigned char - aka values between zero and 255) value with an *int* value the result will be also *char*. These values may only be char values. Therefore, any fraction will be rounded down. Taking advantage of this fact the upper operation in the *uchar* domain may be expressed as:
|
||||
|
||||
.. math::
|
||||
|
||||
@@ -30,11 +30,11 @@ When you divide an *uchar* (unsigned char - aka values between zero and 255) val
|
||||
|
||||
A simple color space reduction algorithm would consist of just passing through every pixel of an image matrix and applying this formula. It's worth noting that we do a divide and a multiplication operation. These operations are bloody expensive for a system. If possible it's worth avoiding them by using cheaper operations such as a few subtractions, addition or in best case a simple assignment. Furthermore, note that we only have a limited number of input values for the upper operation. In case of the *uchar* system this is 256 to be exact.
|
||||
|
||||
Therefore, for larger images it would be wise to calculate all possible values beforehand and during the assignment just make the assignment, by using a lookup table. Lookup tables are simple arrays (having one or more dimensions) that for a given input value variation holds the final output value. Its strength lies that we do not need to make the calculation, we just need to read the result.
|
||||
Therefore, for larger images it would be wise to calculate all possible values beforehand and during the assignment just make the assignment, by using a lookup table. Lookup tables are simple arrays (having one or more dimensions) that for a given input value variation holds the final output value. Its strength lies that we do not need to make the calculation, we just need to read the result.
|
||||
|
||||
Our test case program (and the sample presented here) will do the following: read in a console line argument image (that may be either color or gray scale - console line argument too) and apply the reduction with the given console line argument integer value. In OpenCV, at the moment they are three major ways of going through an image pixel by pixel. To make things a little more interesting will make the scanning for each image using all of these methods, and print out how long it took.
|
||||
Our test case program (and the sample presented here) will do the following: read in a console line argument image (that may be either color or gray scale - console line argument too) and apply the reduction with the given console line argument integer value. In OpenCV, at the moment they are three major ways of going through an image pixel by pixel. To make things a little more interesting will make the scanning for each image using all of these methods, and print out how long it took.
|
||||
|
||||
You can download the full source code :download:`here <../../../../samples/cpp/tutorial_code/core/how_to_scan_images/how_to_scan_images.cpp>` or look it up in the samples directory of OpenCV at the cpp tutorial code for the core section. Its basic usage is:
|
||||
You can download the full source code :download:`here <../../../../samples/cpp/tutorial_code/core/how_to_scan_images/how_to_scan_images.cpp>` or look it up in the samples directory of OpenCV at the cpp tutorial code for the core section. Its basic usage is:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -45,25 +45,25 @@ The final argument is optional. If given the image will be loaded in gray scale
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/how_to_scan_images/how_to_scan_images.cpp
|
||||
:language: cpp
|
||||
:tab-width: 4
|
||||
:lines: 48-60
|
||||
:lines: 48-60
|
||||
|
||||
Here we first use the C++ *stringstream* class to convert the third command line argument from text to an integer format. Then we use a simple look and the upper formula to calculate the lookup table. No OpenCV specific stuff here.
|
||||
|
||||
Another issue is how do we measure time? Well OpenCV offers two simple functions to achieve this :UtilitySystemFunctions:`getTickCount() <gettickcount>` and :UtilitySystemFunctions:`getTickFrequency() <gettickfrequency>`. The first returns the number of ticks of your systems CPU from a certain event (like since you booted your system). The second returns how many times your CPU emits a tick during a second. So to measure in seconds the number of time elapsed between two operations is easy as:
|
||||
Another issue is how do we measure time? Well OpenCV offers two simple functions to achieve this :UtilitySystemFunctions:`getTickCount() <gettickcount>` and :UtilitySystemFunctions:`getTickFrequency() <gettickfrequency>`. The first returns the number of ticks of your systems CPU from a certain event (like since you booted your system). The second returns how many times your CPU emits a tick during a second. So to measure in seconds the number of time elapsed between two operations is easy as:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
double t = (double)getTickCount();
|
||||
// do something ...
|
||||
t = ((double)getTickCount() - t)/getTickFrequency();
|
||||
t = ((double)getTickCount() - t)/getTickFrequency();
|
||||
cout << "Times passed in seconds: " << t << endl;
|
||||
|
||||
.. _How_Image_Stored_Memory:
|
||||
.. _How_Image_Stored_Memory:
|
||||
|
||||
How the image matrix is stored in the memory?
|
||||
=============================================
|
||||
|
||||
As you could already read in my :ref:`matTheBasicImageContainer` tutorial the size of the matrix depends of the color system used. More accurately, it depends from the number of channels used. In case of a gray scale image we have something like:
|
||||
As you could already read in my :ref:`matTheBasicImageContainer` tutorial the size of the matrix depends of the color system used. More accurately, it depends from the number of channels used. In case of a gray scale image we have something like:
|
||||
|
||||
.. math::
|
||||
|
||||
@@ -94,14 +94,14 @@ Note that the order of the channels is inverse: BGR instead of RGB. Because in m
|
||||
The efficient way
|
||||
=================
|
||||
|
||||
When it comes to performance you cannot beat the classic C style operator[] (pointer) access. Therefore, the most efficient method we can recommend for making the assignment is:
|
||||
When it comes to performance you cannot beat the classic C style operator[] (pointer) access. Therefore, the most efficient method we can recommend for making the assignment is:
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/how_to_scan_images/how_to_scan_images.cpp
|
||||
:language: cpp
|
||||
:tab-width: 4
|
||||
:lines: 125-152
|
||||
|
||||
Here we basically just acquire a pointer to the start of each row and go through it until it ends. In the special case that the matrix is stored in a continues manner we only need to request the pointer a single time and go all the way to the end. We need to look out for color images: we have three channels so we need to pass through three times more items in each row.
|
||||
Here we basically just acquire a pointer to the start of each row and go through it until it ends. In the special case that the matrix is stored in a continues manner we only need to request the pointer a single time and go all the way to the end. We need to look out for color images: we have three channels so we need to pass through three times more items in each row.
|
||||
|
||||
There's another way of this. The *data* data member of a *Mat* object returns the pointer to the first row, first column. If this pointer is null you have no valid input in that object. Checking this is the simplest method to check if your image loading was a success. In case the storage is continues we can use this to go through the whole data pointer. In case of a gray scale image this would look like:
|
||||
|
||||
@@ -114,17 +114,17 @@ There's another way of this. The *data* data member of a *Mat* object returns th
|
||||
|
||||
You would get the same result. However, this code is a lot harder to read later on. It gets even harder if you have some more advanced technique there. Moreover, in practice I've observed you'll get the same performance result (as most of the modern compilers will probably make this small optimization trick automatically for you).
|
||||
|
||||
The iterator (safe) method
|
||||
The iterator (safe) method
|
||||
==========================
|
||||
|
||||
In case of the efficient way making sure that you pass through the right amount of *uchar* fields and to skip the gaps that may occur between the rows was your responsibility. The iterator method is considered a safer way as it takes over these tasks from the user. All you need to do is ask the begin and the end of the image matrix and then just increase the begin iterator until you reach the end. To acquire the value *pointed* by the iterator use the * operator (add it before it).
|
||||
In case of the efficient way making sure that you pass through the right amount of *uchar* fields and to skip the gaps that may occur between the rows was your responsibility. The iterator method is considered a safer way as it takes over these tasks from the user. All you need to do is ask the begin and the end of the image matrix and then just increase the begin iterator until you reach the end. To acquire the value *pointed* by the iterator use the * operator (add it before it).
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/how_to_scan_images/how_to_scan_images.cpp
|
||||
:language: cpp
|
||||
:tab-width: 4
|
||||
:lines: 154-182
|
||||
|
||||
In case of color images we have three uchar items per column. This may be considered a short vector of uchar items, that has been baptized in OpenCV with the *Vec3b* name. To access the n-th sub column we use simple operator[] access. It's important to remember that OpenCV iterators go through the columns and automatically skip to the next row. Therefore in case of color images if you use a simple *uchar* iterator you'll be able to access only the blue channel values.
|
||||
In case of color images we have three uchar items per column. This may be considered a short vector of uchar items, that has been baptized in OpenCV with the *Vec3b* name. To access the n-th sub column we use simple operator[] access. It's important to remember that OpenCV iterators go through the columns and automatically skip to the next row. Therefore in case of color images if you use a simple *uchar* iterator you'll be able to access only the blue channel values.
|
||||
|
||||
On-the-fly address calculation with reference returning
|
||||
=======================================================
|
||||
@@ -136,7 +136,7 @@ The final method isn't recommended for scanning. It was made to acquire or modif
|
||||
:tab-width: 4
|
||||
:lines: 184-216
|
||||
|
||||
The functions takes your input type and coordinates and calculates on the fly the address of the queried item. Then returns a reference to that. This may be a constant when you *get* the value and non-constant when you *set* the value. As a safety step in **debug mode only*** there is performed a check that your input coordinates are valid and does exist. If this isn't the case you'll get a nice output message of this on the standard error output stream. Compared to the efficient way in release mode the only difference in using this is that for every element of the image you'll get a new row pointer for what we use the C operator[] to acquire the column element.
|
||||
The functions takes your input type and coordinates and calculates on the fly the address of the queried item. Then returns a reference to that. This may be a constant when you *get* the value and non-constant when you *set* the value. As a safety step in **debug mode only*** there is performed a check that your input coordinates are valid and does exist. If this isn't the case you'll get a nice output message of this on the standard error output stream. Compared to the efficient way in release mode the only difference in using this is that for every element of the image you'll get a new row pointer for what we use the C operator[] to acquire the column element.
|
||||
|
||||
If you need to multiple lookups using this method for an image it may be troublesome and time consuming to enter the type and the at keyword for each of the accesses. To solve this problem OpenCV has a :basicstructures:`Mat_ <id3>` data type. It's the same as Mat with the extra need that at definition you need to specify the data type through what to look at the data matrix, however in return you can use the operator() for fast access of items. To make things even better this is easily convertible from and to the usual :basicstructures:`Mat <id3>` data type. A sample usage of this you can see in case of the color images of the upper function. Nevertheless, it's important to note that the same operation (with the same runtime speed) could have been done with the :basicstructures:`at() <mat-at>` function. It's just a less to write for the lazy programmer trick.
|
||||
|
||||
|
||||
+17
-17
@@ -6,7 +6,7 @@ Interoperability with OpenCV 1
|
||||
Goal
|
||||
====
|
||||
|
||||
For the OpenCV developer team it's important to constantly improve the library. We are constantly thinking about methods that will ease your work process, while still maintain the libraries flexibility. The new C++ interface is a development of us that serves this goal. Nevertheless, backward compatibility remains important. We do not want to break your code written for earlier version of the OpenCV library. Therefore, we made sure that we add some functions that deal with this. In the following you'll learn:
|
||||
For the OpenCV developer team it's important to constantly improve the library. We are constantly thinking about methods that will ease your work process, while still maintain the libraries flexibility. The new C++ interface is a development of us that serves this goal. Nevertheless, backward compatibility remains important. We do not want to break your code written for earlier version of the OpenCV library. Therefore, we made sure that we add some functions that deal with this. In the following you'll learn:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
@@ -17,9 +17,9 @@ For the OpenCV developer team it's important to constantly improve the library.
|
||||
General
|
||||
=======
|
||||
|
||||
When making the switch you first need to learn some about the new data structure for images: :ref:`matTheBasicImageContainer`, this replaces the old *CvMat* and *IplImage* ones. Switching to the new functions is easier. You just need to remember a couple of new things.
|
||||
When making the switch you first need to learn some about the new data structure for images: :ref:`matTheBasicImageContainer`, this replaces the old *CvMat* and *IplImage* ones. Switching to the new functions is easier. You just need to remember a couple of new things.
|
||||
|
||||
OpenCV 2 received reorganization. No longer are all the functions crammed into a single library. We have many modules, each of them containing data structures and functions relevant to certain tasks. This way you do not need to ship a large library if you use just a subset of OpenCV. This means that you should also include only those headers you will use. For example:
|
||||
OpenCV 2 received reorganization. No longer are all the functions crammed into a single library. We have many modules, each of them containing data structures and functions relevant to certain tasks. This way you do not need to ship a large library if you use just a subset of OpenCV. This means that you should also include only those headers you will use. For example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -28,13 +28,13 @@ OpenCV 2 received reorganization. No longer are all the functions crammed into a
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
|
||||
|
||||
All the OpenCV related stuff is put into the *cv* namespace to avoid name conflicts with other libraries data structures and functions. Therefore, either you need to prepend the *cv::* keyword before everything that comes from OpenCV or after the includes, you just add a directive to use this:
|
||||
All the OpenCV related stuff is put into the *cv* namespace to avoid name conflicts with other libraries data structures and functions. Therefore, either you need to prepend the *cv::* keyword before everything that comes from OpenCV or after the includes, you just add a directive to use this:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
using namespace cv; // The new C++ interface API is inside this namespace. Import it.
|
||||
|
||||
Because the functions are already in a namespace there is no need for them to contain the *cv* prefix in their name. As such all the new C++ compatible functions don't have this and they follow the camel case naming rule. This means the first letter is small (unless it's a name, like Canny) and the subsequent words start with a capital letter (like *copyMakeBorder*).
|
||||
Because the functions are already in a namespace there is no need for them to contain the *cv* prefix in their name. As such all the new C++ compatible functions don't have this and they follow the camel case naming rule. This means the first letter is small (unless it's a name, like Canny) and the subsequent words start with a capital letter (like *copyMakeBorder*).
|
||||
|
||||
Now, remember that you need to link to your application all the modules you use, and in case you are on Windows using the *DLL* system you will need to add, again, to the path all the binaries. For more in-depth information if you're on Windows read :ref:`Windows_Visual_Studio_How_To` and for Linux an example usage is explained in :ref:`Linux_Eclipse_Usage`.
|
||||
|
||||
@@ -42,7 +42,7 @@ Now for converting the *Mat* object you can use either the *IplImage* or the *Cv
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
Mat I;
|
||||
Mat I;
|
||||
IplImage pI = I;
|
||||
CvMat mI = I;
|
||||
|
||||
@@ -50,9 +50,9 @@ Now if you want pointers the conversion gets just a little more complicated. The
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
Mat I;
|
||||
IplImage* pI = &I.operator IplImage();
|
||||
CvMat* mI = &I.operator CvMat();
|
||||
Mat I;
|
||||
IplImage* pI = &I.operator IplImage();
|
||||
CvMat* mI = &I.operator CvMat();
|
||||
|
||||
One of the biggest complaints of the C interface is that it leaves all the memory management to you. You need to figure out when it is safe to release your unused objects and make sure you do so before the program finishes or you could have troublesome memory leeks. To work around this issue in OpenCV there is introduced a sort of smart pointer. This will automatically release the object when it's no longer in use. To use this declare the pointers as a specialization of the *Ptr* :
|
||||
|
||||
@@ -60,11 +60,11 @@ One of the biggest complaints of the C interface is that it leaves all the memor
|
||||
|
||||
Ptr<IplImage> piI = &I.operator IplImage();
|
||||
|
||||
Converting from the C data structures to the *Mat* is done by passing these inside its constructor. For example:
|
||||
Converting from the C data structures to the *Mat* is done by passing these inside its constructor. For example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
Mat K(piL), L;
|
||||
Mat K(piL), L;
|
||||
L = Mat(pI);
|
||||
|
||||
A case study
|
||||
@@ -79,7 +79,7 @@ Now that you have the basics done :download:`here's <../../../../samples/cpp/tut
|
||||
:tab-width: 4
|
||||
:lines: 1-9, 22-25, 27-44
|
||||
|
||||
Here you can observe that with the new structure we have no pointer problems, although it is possible to use the old functions and in the end just transform the result to a *Mat* object.
|
||||
Here you can observe that with the new structure we have no pointer problems, although it is possible to use the old functions and in the end just transform the result to a *Mat* object.
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp
|
||||
:language: cpp
|
||||
@@ -87,7 +87,7 @@ Here you can observe that with the new structure we have no pointer problems, al
|
||||
:tab-width: 4
|
||||
:lines: 46-51
|
||||
|
||||
Because, we want to mess around with the images luma component we first convert from the default RGB to the YUV color space and then split the result up into separate planes. Here the program splits: in the first example it processes each plane using one of the three major image scanning algorithms in OpenCV (C [] operator, iterator, individual element access). In a second variant we add to the image some Gaussian noise and then mix together the channels according to some formula.
|
||||
Because, we want to mess around with the images luma component we first convert from the default RGB to the YUV color space and then split the result up into separate planes. Here the program splits: in the first example it processes each plane using one of the three major image scanning algorithms in OpenCV (C [] operator, iterator, individual element access). In a second variant we add to the image some Gaussian noise and then mix together the channels according to some formula.
|
||||
|
||||
The scanning version looks like:
|
||||
|
||||
@@ -97,7 +97,7 @@ The scanning version looks like:
|
||||
:tab-width: 4
|
||||
:lines: 55-75
|
||||
|
||||
Here you can observe that we may go through all the pixels of an image in three fashions: an iterator, a C pointer and an individual element access style. You can read a more in-depth description of these in the :ref:`howToScanImagesOpenCV` tutorial. Converting from the old function names is easy. Just remove the cv prefix and use the new *Mat* data structure. Here's an example of this by using the weighted addition function:
|
||||
Here you can observe that we may go through all the pixels of an image in three fashions: an iterator, a C pointer and an individual element access style. You can read a more in-depth description of these in the :ref:`howToScanImagesOpenCV` tutorial. Converting from the old function names is easy. Just remove the cv prefix and use the new *Mat* data structure. Here's an example of this by using the weighted addition function:
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp
|
||||
:language: cpp
|
||||
@@ -105,7 +105,7 @@ Here you can observe that we may go through all the pixels of an image in three
|
||||
:tab-width: 4
|
||||
:lines: 79-112
|
||||
|
||||
As you may observe the *planes* variable is of type *Mat*. However, converting from *Mat* to *IplImage* is easy and made automatically with a simple assignment operator.
|
||||
As you may observe the *planes* variable is of type *Mat*. However, converting from *Mat* to *IplImage* is easy and made automatically with a simple assignment operator.
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp
|
||||
:language: cpp
|
||||
@@ -113,14 +113,14 @@ As you may observe the *planes* variable is of type *Mat*. However, converting f
|
||||
:tab-width: 4
|
||||
:lines: 115-127
|
||||
|
||||
The new *imshow* highgui function accepts both the *Mat* and *IplImage* data structures. Compile and run the program and if the first image below is your input you may get either the first or second as output:
|
||||
The new *imshow* highgui function accepts both the *Mat* and *IplImage* data structures. Compile and run the program and if the first image below is your input you may get either the first or second as output:
|
||||
|
||||
.. image:: images/outputInteropOpenCV1.jpg
|
||||
:alt: The output of the sample
|
||||
:align: center
|
||||
|
||||
|
||||
You may observe a runtime instance of this on the `YouTube here <https://www.youtube.com/watch?v=qckm-zvo31w>`_ and you can :download:`download the source code from here <../../../../samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp>` or find it in the :file:`samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp` of the OpenCV source code library.
|
||||
You may observe a runtime instance of this on the `YouTube here <https://www.youtube.com/watch?v=qckm-zvo31w>`_ and you can :download:`download the source code from here <../../../../samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp>` or find it in the :file:`samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp` of the OpenCV source code library.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@ Mask operations on matrices are quite simple. The idea is that we recalculate ea
|
||||
Our test case
|
||||
=============
|
||||
|
||||
Let us consider the issue of an image contrast enhancement method. Basically we want to apply for every pixel of the image the following formula:
|
||||
Let us consider the issue of an image contrast enhancement method. Basically we want to apply for every pixel of the image the following formula:
|
||||
|
||||
.. math::
|
||||
|
||||
I(i,j) = 5*I(i,j) - [ I(i-1,j) + I(i+1,j) + I(i,j-1) + I(i,j+1)]
|
||||
I(i,j) = 5*I(i,j) - [ I(i-1,j) + I(i+1,j) + I(i,j-1) + I(i,j+1)]
|
||||
|
||||
\iff I(i,j)*M, \text{where }
|
||||
M = \bordermatrix{ _i\backslash ^j & -1 & 0 & +1 \cr
|
||||
@@ -23,12 +23,12 @@ Let us consider the issue of an image contrast enhancement method. Basically we
|
||||
|
||||
The first notation is by using a formula, while the second is a compacted version of the first by using a mask. You use the mask by putting the center of the mask matrix (in the upper case noted by the zero-zero index) on the pixel you want to calculate and sum up the pixel values multiplied with the overlapped matrix values. It's the same thing, however in case of large matrices the latter notation is a lot easier to look over.
|
||||
|
||||
Now let us see how we can make this happen by using the basic pixel access method or by using the :filtering:`filter2D <filter2d>` function.
|
||||
Now let us see how we can make this happen by using the basic pixel access method or by using the :filtering:`filter2D <filter2d>` function.
|
||||
|
||||
The Basic Method
|
||||
================
|
||||
|
||||
Here's a function that will do this:
|
||||
Here's a function that will do this:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -49,7 +49,7 @@ Here's a function that will do this:
|
||||
|
||||
for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i)
|
||||
{
|
||||
*output++ = saturate_cast<uchar>(5*current[i]
|
||||
*output++ = saturate_cast<uchar>(5*current[i]
|
||||
-current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]);
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ We'll use the plain C [] operator to access pixels. Because we need to access mu
|
||||
|
||||
for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i)
|
||||
{
|
||||
*output++ = saturate_cast<uchar>(5*current[i]
|
||||
*output++ = saturate_cast<uchar>(5*current[i]
|
||||
-current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]);
|
||||
}
|
||||
}
|
||||
@@ -96,7 +96,7 @@ On the borders of the image the upper notation results inexistent pixel location
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
Result.row(0).setTo(Scalar(0)); // The top row
|
||||
Result.row(0).setTo(Scalar(0)); // The top row
|
||||
Result.row(Result.rows-1).setTo(Scalar(0)); // The bottom row
|
||||
Result.col(0).setTo(Scalar(0)); // The left column
|
||||
Result.col(Result.cols-1).setTo(Scalar(0)); // The right column
|
||||
@@ -108,19 +108,19 @@ Applying such filters are so common in image processing that in OpenCV there exi
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
Mat kern = (Mat_<char>(3,3) << 0, -1, 0,
|
||||
Mat kern = (Mat_<char>(3,3) << 0, -1, 0,
|
||||
-1, 5, -1,
|
||||
0, -1, 0);
|
||||
|
||||
Then call the :filtering:`filter2D <filter2d>` function specifying the input, the output image and the kernell to use:
|
||||
Then call the :filtering:`filter2D <filter2d>` function specifying the input, the output image and the kernell to use:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
filter2D(I, K, I.depth(), kern );
|
||||
filter2D(I, K, I.depth(), kern );
|
||||
|
||||
The function even has a fifth optional argument to specify the center of the kernel, and a sixth one for determining what to do in the regions where the operation is undefined (borders). Using this function has the advantage that it's shorter, less verbose and because there are some optimization techniques implemented it is usually faster than the *hand-coded method*. For example in my test while the second one took only 13 milliseconds the first took around 31 milliseconds. Quite some difference.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
.. image:: images/resultMatMaskFilter2D.png
|
||||
:alt: A sample output of the program
|
||||
@@ -128,7 +128,7 @@ For example:
|
||||
|
||||
You can download this source code from :download:`here <../../../../samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp>` or look in the OpenCV source code libraries sample directory at :file:`samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp`.
|
||||
|
||||
Check out an instance of running the program on our `YouTube channel <http://www.youtube.com/watch?v=7PF1tAU9se4>`_ .
|
||||
Check out an instance of running the program on our `YouTube channel <http://www.youtube.com/watch?v=7PF1tAU9se4>`_ .
|
||||
|
||||
.. raw:: html
|
||||
|
||||
|
||||
+20
-20
@@ -19,13 +19,13 @@ For example in the above image you can see that the mirror of the care is nothin
|
||||
|
||||
OpenCV has been around ever since 2001. In those days the library was built around a *C* interface. In those days to store the image in the memory they used a C structure entitled *IplImage*. This is the one you'll see in most of the older tutorials and educational materials. The problem with this is that it brings to the table all the minuses of the C language. The biggest issue is the manual management. It builds on the assumption that the user is responsible for taking care of memory allocation and deallocation. While this is no issue in case of smaller programs once your code base start to grove larger and larger it will be more and more a struggle to handle all this rather than focusing on actually solving your development goal.
|
||||
|
||||
Luckily C++ came around and introduced the concept of classes making possible to build another road for the user: automatic memory management (more or less). The good news is that C++ if fully compatible with C so no compatibility issues can arise from making the change. Therefore, OpenCV with its 2.0 version introduced a new C++ interface that by taking advantage of these offers a new way of doing things. A way, in which you do not need to fiddle with memory management; making your code concise (less to write, to achieve more). The only main downside of the C++ interface is that many embedded development systems at the moment support only C. Therefore, unless you are targeting this platform, there's no point on using the *old* methods (unless you're a masochist programmer and you're asking for trouble).
|
||||
Luckily C++ came around and introduced the concept of classes making possible to build another road for the user: automatic memory management (more or less). The good news is that C++ if fully compatible with C so no compatibility issues can arise from making the change. Therefore, OpenCV with its 2.0 version introduced a new C++ interface that by taking advantage of these offers a new way of doing things. A way, in which you do not need to fiddle with memory management; making your code concise (less to write, to achieve more). The only main downside of the C++ interface is that many embedded development systems at the moment support only C. Therefore, unless you are targeting this platform, there's no point on using the *old* methods (unless you're a masochist programmer and you're asking for trouble).
|
||||
|
||||
The first thing you need to know about *Mat* is that you no longer need to manually allocate its size and release it as soon as you do not need it. While doing this is still a possibility, most of the OpenCV functions will allocate its output data manually. As a nice bonus if you pass on an already existing *Mat* object, what already has allocated the required space for the matrix, this will be reused. In other words we use at all times only as much memory as much we must to perform the task.
|
||||
|
||||
*Mat* is basically a class having two data parts: the matrix header (containing information such as the size of the matrix, the method used for storing, at which address is the matrix stored and so on) and a pointer to the matrix containing the pixel values (may take any dimensionality depending on the method chosen for storing) . The matrix header size is constant. However, the size of the matrix itself may vary from image to image and usually is larger by order of magnitudes. Therefore, when you're passing on images in your program and at some point you need to create a copy of the image the big price you will need to build is for the matrix itself rather than its header. OpenCV is an image processing library. It contains a large collection of image processing functions. To solve a computational challenge most of the time you will end up using multiple functions of the library. Due to this passing on images to functions is a common practice. We should not forget that we are talking about image processing algorithms, which tend to be quite computational heavy. The last thing we want to do is to further decrease the speed of your program by making unnecessary copies of potentially *large* images.
|
||||
|
||||
To tackle this issue OpenCV uses a reference counting system. The idea is that each *Mat* object has its own header, however the matrix may be shared between two instance of them by having their matrix pointer point to the same address. Moreover, the copy operators **will only copy the headers**, and as also copy the pointer to the large matrix too, however not the matrix itself.
|
||||
To tackle this issue OpenCV uses a reference counting system. The idea is that each *Mat* object has its own header, however the matrix may be shared between two instance of them by having their matrix pointer point to the same address. Moreover, the copy operators **will only copy the headers**, and as also copy the pointer to the large matrix too, however not the matrix itself.
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
@@ -37,21 +37,21 @@ To tackle this issue OpenCV uses a reference counting system. The idea is that e
|
||||
|
||||
C = A; // Assignment operator
|
||||
|
||||
All the above objects, in the end point to the same single data matrix. Their headers are different, however making any modification using either one of them will affect all the other ones too. In practice the different objects just provide different access method to the same underlying data. Nevertheless, their header parts are different. The real interesting part comes that you can create headers that refer only to a subsection of the full data. For example, to create a region of interest (*ROI*) in an image you just create a new header with the new boundaries:
|
||||
All the above objects, in the end point to the same single data matrix. Their headers are different, however making any modification using either one of them will affect all the other ones too. In practice the different objects just provide different access method to the same underlying data. Nevertheless, their header parts are different. The real interesting part comes that you can create headers that refer only to a subsection of the full data. For example, to create a region of interest (*ROI*) in an image you just create a new header with the new boundaries:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle
|
||||
Mat E = A(Range:all(), Range(1,3)); // using row and column boundaries
|
||||
Mat E = A(Range:all(), Range(1,3)); // using row and column boundaries
|
||||
|
||||
Now you may ask if the matrix itself may belong to multiple *Mat* objects who will take responsibility for its cleaning when it's no longer needed. The short answer is: the last object that used it. For this a reference counting mechanism is used. Whenever somebody copies a header of a *Mat* object a counter is increased for the matrix. Whenever a header is cleaned this counter is decreased. When the counter reaches zero the matrix too is freed. Because, sometimes you will still want to copy the matrix itself too, there exists the :basicstructures:`clone() <mat-clone>` or the :basicstructures:`copyTo() <mat-copyto>` function.
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
Mat F = A.clone();
|
||||
Mat G;
|
||||
Mat F = A.clone();
|
||||
Mat G;
|
||||
A.copyTo(G);
|
||||
|
||||
Now modifying *F* or *G* will not affect the matrix pointed by the *Mat* header. What you need to remember from all this is that:
|
||||
@@ -64,19 +64,19 @@ Now modifying *F* or *G* will not affect the matrix pointed by the *Mat* header.
|
||||
* Use the :basicstructures:`clone()<mat-clone>` or the :basicstructures:`copyTo() <mat-copyto>` function to copy the underlying matrix of an image.
|
||||
|
||||
*Storing* methods
|
||||
=================
|
||||
=================
|
||||
|
||||
This is about how you store the pixel values. You can select the color space and the data type used. The color space refers to how we combine color components in order to code a given color. The simplest one is the gray scale. Here the colors at our disposal are black and white. The combination of these allows us to create many shades of gray.
|
||||
This is about how you store the pixel values. You can select the color space and the data type used. The color space refers to how we combine color components in order to code a given color. The simplest one is the gray scale. Here the colors at our disposal are black and white. The combination of these allows us to create many shades of gray.
|
||||
|
||||
For *colorful* ways we have a lot more of methods to choose from. However, every one of them breaks it down to three or four basic components and the combination of this will give all others. The most popular one of this is RGB, mainly because this is also how our eye builds up colors in our eyes. Its base colors are red, green and blue. To code the transparency of a color sometimes a fourth element: alpha (A) is added.
|
||||
For *colorful* ways we have a lot more of methods to choose from. However, every one of them breaks it down to three or four basic components and the combination of this will give all others. The most popular one of this is RGB, mainly because this is also how our eye builds up colors in our eyes. Its base colors are red, green and blue. To code the transparency of a color sometimes a fourth element: alpha (A) is added.
|
||||
|
||||
However, they are many color systems each with their own advantages:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
* RGB is the most common as our eyes use something similar, our display systems also compose colors using these.
|
||||
* The HSV and HLS decompose colors into their hue, saturation and value/luminance components, which is a more natural way for us to describe colors. Using you may for example dismiss the last component, making your algorithm less sensible to light conditions of the input image.
|
||||
* YCrCb is used by the popular JPEG image format.
|
||||
* The HSV and HLS decompose colors into their hue, saturation and value/luminance components, which is a more natural way for us to describe colors. Using you may for example dismiss the last component, making your algorithm less sensible to light conditions of the input image.
|
||||
* YCrCb is used by the popular JPEG image format.
|
||||
* CIE L*a*b* is a perceptually uniform color space, which comes handy if you need to measure the *distance* of a given color to another color.
|
||||
|
||||
Now each of the building components has their own valid domains. This leads to the data type used. How we store a component defines just how fine control we have over its domain. The smallest data type possible is *char*, which means one byte or 8 bits. This may be unsigned (so can store values from 0 to 255) or signed (values from -127 to +127). Although in case of three components this already gives 16 million possible colors to represent (like in case of RGB) we may acquire an even finer control by using the float (4 byte = 32 bit) or double (8 byte = 64 bit) data types for each component. Nevertheless, remember that increasing the size of a component also increases the size of the whole picture in the memory.
|
||||
@@ -84,13 +84,13 @@ Now each of the building components has their own valid domains. This leads to t
|
||||
Creating explicitly a *Mat* object
|
||||
==================================
|
||||
|
||||
In the :ref:`Load_Save_Image` tutorial you could already see how to write a matrix to an image file by using the :readWriteImageVideo:` imwrite() <imwrite>` function. However, for debugging purposes it's much more convenient to see the actual values. You can achieve this via the << operator of *Mat*. However, be aware that this only works for two dimensional matrices.
|
||||
In the :ref:`Load_Save_Image` tutorial you could already see how to write a matrix to an image file by using the :readWriteImageVideo:` imwrite() <imwrite>` function. However, for debugging purposes it's much more convenient to see the actual values. You can achieve this via the << operator of *Mat*. However, be aware that this only works for two dimensional matrices.
|
||||
|
||||
Although *Mat* is a great class as image container it is also a general matrix class. Therefore, it is possible to create and manipulate multidimensional matrices. You can create a Mat object in multiple ways:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
+ :basicstructures:`Mat() <mat-mat>` Constructor
|
||||
+ :basicstructures:`Mat() <mat-mat>` Constructor
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/mat_the_basic_image_container/mat_the_basic_image_container.cpp
|
||||
:language: cpp
|
||||
@@ -103,7 +103,7 @@ Although *Mat* is a great class as image container it is also a general matrix c
|
||||
|
||||
For two dimensional and multichannel images we first define their size: row and column count wise.
|
||||
|
||||
Then we need to specify the data type to use for storing the elements and the number of channels per matrix point. To do this we have multiple definitions made according to the following convention:
|
||||
Then we need to specify the data type to use for storing the elements and the number of channels per matrix point. To do this we have multiple definitions made according to the following convention:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -118,7 +118,7 @@ Although *Mat* is a great class as image container it is also a general matrix c
|
||||
:tab-width: 4
|
||||
:lines: 35-36
|
||||
|
||||
The upper example shows how to create a matrix with more than two dimensions. Specify its dimension, then pass a pointer containing the size for each dimension and the rest remains the same.
|
||||
The upper example shows how to create a matrix with more than two dimensions. Specify its dimension, then pass a pointer containing the size for each dimension and the rest remains the same.
|
||||
|
||||
|
||||
+ Create a header for an already existing IplImage pointer:
|
||||
@@ -174,7 +174,7 @@ Although *Mat* is a great class as image container it is also a general matrix c
|
||||
:alt: Demo image of the matrix output
|
||||
:align: center
|
||||
|
||||
.. note::
|
||||
.. note::
|
||||
|
||||
You can fill out a matrix with random values using the :operationsOnArrays:`randu() <randu>` function. You need to give the lower and upper value between what you want the random values:
|
||||
|
||||
@@ -187,11 +187,11 @@ Although *Mat* is a great class as image container it is also a general matrix c
|
||||
Print out formatting
|
||||
====================
|
||||
|
||||
In the above examples you could see the default formatting option. Nevertheless, OpenCV allows you to format your matrix output format to fit the rules of:
|
||||
In the above examples you could see the default formatting option. Nevertheless, OpenCV allows you to format your matrix output format to fit the rules of:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
+ Default
|
||||
+ Default
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/mat_the_basic_image_container/mat_the_basic_image_container.cpp
|
||||
:language: cpp
|
||||
@@ -213,7 +213,7 @@ In the above examples you could see the default formatting option. Nevertheless,
|
||||
:alt: Default Output
|
||||
:align: center
|
||||
|
||||
+ Comma separated values (CSV)
|
||||
+ Comma separated values (CSV)
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/mat_the_basic_image_container/mat_the_basic_image_container.cpp
|
||||
:language: cpp
|
||||
@@ -253,7 +253,7 @@ OpenCV offers support for print of other common OpenCV data structures too via t
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
+ 2D Point
|
||||
+ 2D Point
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/mat_the_basic_image_container/mat_the_basic_image_container.cpp
|
||||
:language: cpp
|
||||
|
||||
@@ -44,7 +44,7 @@ Here you will learn the about the basic building blocks of the library. A must r
|
||||
.. |HowScanImag| image:: images/howToScanImages.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
|
||||
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
@@ -193,7 +193,7 @@ Here you will learn the about the basic building blocks of the library. A must r
|
||||
*Author:* |Author_BernatG|
|
||||
|
||||
Did you used OpenCV before its 2.0 version? Do you wanna know what happened with your library with 2.0? Don't you know how to convert your old OpenCV programs to the new C++ interface? Look here to shed light on all this questions.
|
||||
|
||||
|
||||
=============== ======================================================
|
||||
|
||||
.. |InterOOpenCV1| image:: images/interopOpenCV1.png
|
||||
@@ -208,7 +208,7 @@ Here you will learn the about the basic building blocks of the library. A must r
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
|
||||
../mat_the_basic_image_container/mat_the_basic_image_container
|
||||
../how_to_scan_images/how_to_scan_images
|
||||
../mat-mask-operations/mat-mask-operations
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
|
||||
.. note::
|
||||
Unfortunetly we have no tutorials into this section. Nevertheless, our tutorial writting team is working on it. If you have a tutorial suggestion or you have writen yourself a tutorial (or coded a sample code) that you would like to see here please contact us via our :opencv_group:`user group <>`.
|
||||
Unfortunetly we have no tutorials into this section. Nevertheless, our tutorial writting team is working on it. If you have a tutorial suggestion or you have writen yourself a tutorial (or coded a sample code) that you would like to see here please contact us via our :opencv_group:`user group <>`.
|
||||
@@ -3,7 +3,7 @@
|
||||
.. |Author_AndreyK| unicode:: Andrey U+0020 Kamaev
|
||||
.. |Author_LeonidBLB| unicode:: Leonid U+0020 Beynenson
|
||||
.. |Author_VsevolodG| unicode:: Vsevolod U+0020 Glumov
|
||||
.. |Author_VictorE| unicode:: Victor U+0020 Eruhimov
|
||||
.. |Author_VictorE| unicode:: Victor U+0020 Eruhimov
|
||||
.. |Author_ArtemM| unicode:: Artem U+0020 Myagkov
|
||||
.. |Author_FernandoI| unicode:: Fernando U+0020 Iglesias U+0020 Garc U+00ED a
|
||||
.. |Author_EduardF| unicode:: Eduard U+0020 Feicho
|
||||
|
||||
+5
-5
@@ -5,9 +5,9 @@ Detection of planar objects
|
||||
|
||||
.. highlight:: cpp
|
||||
|
||||
The goal of this tutorial is to learn how to use *features2d* and *calib3d* modules for detecting known planar objects in scenes.
|
||||
The goal of this tutorial is to learn how to use *features2d* and *calib3d* modules for detecting known planar objects in scenes.
|
||||
|
||||
*Test data*: use images in your data folder, for instance, ``box.png`` and ``box_in_scene.png``.
|
||||
*Test data*: use images in your data folder, for instance, ``box.png`` and ``box_in_scene.png``.
|
||||
|
||||
#.
|
||||
Create a new console project. Read two input images. ::
|
||||
@@ -22,7 +22,7 @@ The goal of this tutorial is to learn how to use *features2d* and *calib3d* modu
|
||||
FastFeatureDetector detector(15);
|
||||
vector<KeyPoint> keypoints1;
|
||||
detector.detect(img1, keypoints1);
|
||||
|
||||
|
||||
... // do the same for the second image
|
||||
|
||||
#.
|
||||
@@ -32,7 +32,7 @@ The goal of this tutorial is to learn how to use *features2d* and *calib3d* modu
|
||||
SurfDescriptorExtractor extractor;
|
||||
Mat descriptors1;
|
||||
extractor.compute(img1, keypoints1, descriptors1);
|
||||
|
||||
|
||||
... // process keypoints from the second image as well
|
||||
|
||||
#.
|
||||
@@ -69,4 +69,4 @@ The goal of this tutorial is to learn how to use *features2d* and *calib3d* modu
|
||||
perspectiveTransform(Mat(points1), points1Projected, H);
|
||||
|
||||
#.
|
||||
Use ``drawMatches`` for drawing inliers.
|
||||
Use ``drawMatches`` for drawing inliers.
|
||||
|
||||
+52
-52
@@ -5,166 +5,166 @@
|
||||
|
||||
Learn about how to use the feature points detectors, descriptors and matching framework found inside OpenCV.
|
||||
|
||||
.. include:: ../../definitions/tocDefinitions.rst
|
||||
.. include:: ../../definitions/tocDefinitions.rst
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
===================== ==============================================
|
||||
|Harris| **Title:** :ref:`harris_detector`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Why is it a good idea to track corners? We learn to use the Harris method to detect corners
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |Harris| image:: images/trackingmotion/Harris_Detector_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
===================== ==============================================
|
||||
|ShiTomasi| **Title:** :ref:`good_features_to_track`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Where we use an improved method to detect corners more accuratelyI
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |ShiTomasi| image:: images/trackingmotion/Shi_Tomasi_Detector_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
===================== ==============================================
|
||||
|GenericCorner| **Title:** :ref:`generic_corner_detector`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Here you will learn how to use OpenCV functions to make your personalized corner detector!
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |GenericCorner| image:: images/trackingmotion/Generic_Corner_Detector_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
===================== ==============================================
|
||||
|Subpixel| **Title:** :ref:`corner_subpixeles`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Is pixel resolution enough? Here we learn a simple method to improve our accuracy.
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |Subpixel| image:: images/trackingmotion/Corner_Subpixeles_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
===================== ==============================================
|
||||
|FeatureDetect| **Title:** :ref:`feature_detection`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
In this tutorial, you will use *features2d* to detect interest points.
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |FeatureDetect| image:: images/Feature_Detection_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
===================== ==============================================
|
||||
|FeatureDescript| **Title:** :ref:`feature_description`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
In this tutorial, you will use *features2d* to calculate feature vectors.
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |FeatureDescript| image:: images/Feature_Description_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
===================== ==============================================
|
||||
|FeatureFlann| **Title:** :ref:`feature_flann_matcher`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
In this tutorial, you will use the FLANN library to make a fast matching.
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |FeatureFlann| image:: images/Feature_Flann_Matcher_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
===================== ==============================================
|
||||
|FeatureHomo| **Title:** :ref:`feature_homography`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
In this tutorial, you will use *features2d* and *calib3d* to detect an object in a scene.
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |FeatureHomo| image:: images/Feature_Homography_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
@@ -175,7 +175,7 @@ Learn about how to use the feature points detectors, descriptors and matching f
|
||||
|
||||
*Author:* |Author_VictorE|
|
||||
|
||||
You will use *features2d* and *calib3d* modules for detecting known planar objects in scenes.
|
||||
You will use *features2d* and *calib3d* modules for detecting known planar objects in scenes.
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
@@ -87,14 +87,14 @@ This tutorial code's is shown lines below. You can also download it from `here <
|
||||
|
||||
/// Apply corner detection
|
||||
goodFeaturesToTrack( src_gray,
|
||||
corners,
|
||||
maxCorners,
|
||||
qualityLevel,
|
||||
minDistance,
|
||||
Mat(),
|
||||
blockSize,
|
||||
useHarrisDetector,
|
||||
k );
|
||||
corners,
|
||||
maxCorners,
|
||||
qualityLevel,
|
||||
minDistance,
|
||||
Mat(),
|
||||
blockSize,
|
||||
useHarrisDetector,
|
||||
k );
|
||||
|
||||
|
||||
/// Draw corners detected
|
||||
|
||||
@@ -98,16 +98,16 @@ How does it work?
|
||||
u & v
|
||||
\end{bmatrix}
|
||||
\left (
|
||||
\displaystyle \sum_{x,y}
|
||||
\displaystyle \sum_{x,y}
|
||||
w(x,y)
|
||||
\begin{bmatrix}
|
||||
I_x^{2} & I_{x}I_{y} \\
|
||||
I_xI_{y} & I_{y}^{2}
|
||||
\end{bmatrix}
|
||||
\right )
|
||||
\begin{bmatrix}
|
||||
\end{bmatrix}
|
||||
\right )
|
||||
\begin{bmatrix}
|
||||
u \\
|
||||
v
|
||||
v
|
||||
\end{bmatrix}
|
||||
|
||||
* Let's denote:
|
||||
@@ -115,11 +115,11 @@ How does it work?
|
||||
.. math::
|
||||
|
||||
M = \displaystyle \sum_{x,y}
|
||||
w(x,y)
|
||||
\begin{bmatrix}
|
||||
I_x^{2} & I_{x}I_{y} \\
|
||||
I_xI_{y} & I_{y}^{2}
|
||||
\end{bmatrix}
|
||||
w(x,y)
|
||||
\begin{bmatrix}
|
||||
I_x^{2} & I_{x}I_{y} \\
|
||||
I_xI_{y} & I_{y}^{2}
|
||||
\end{bmatrix}
|
||||
|
||||
* So, our equation now is:
|
||||
|
||||
@@ -128,10 +128,10 @@ How does it work?
|
||||
E(u,v) \approx \begin{bmatrix}
|
||||
u & v
|
||||
\end{bmatrix}
|
||||
M
|
||||
\begin{bmatrix}
|
||||
M
|
||||
\begin{bmatrix}
|
||||
u \\
|
||||
v
|
||||
v
|
||||
\end{bmatrix}
|
||||
|
||||
|
||||
|
||||
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário