Comparar commits
581 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| facab40745 | |||
| 08545b8f96 | |||
| f22ee8fc19 | |||
| e6cb44edc3 | |||
| 1094179155 | |||
| a706de2446 | |||
| 65bb4250a4 | |||
| 07b1ccdeb0 | |||
| 2128b82c6b | |||
| 978132edc1 | |||
| 22d33373fa | |||
| eaaba1336a | |||
| 85c7a36f93 | |||
| 6be6adbbed | |||
| da455efc26 | |||
| a910360689 | |||
| 8f3883a28d | |||
| 82b9854837 | |||
| 3cfd3d3ee0 | |||
| af2552d72c | |||
| c865b28243 | |||
| 79cf292d78 | |||
| 1018d110d6 | |||
| fba0e6fc5c | |||
| 4811988caf | |||
| 2a73a6c445 | |||
| d18b2c2502 | |||
| c24d7cc066 | |||
| f533f0dca9 | |||
| bd38a1945d | |||
| 29b763dc60 | |||
| 5321da92cb | |||
| f4b413e830 | |||
| 1f411b5a2b | |||
| bf4c8c6ff1 | |||
| d0e340bc80 | |||
| ddc2e334da | |||
| f12369a53c | |||
| 831580ef31 | |||
| 6ce51d88a4 | |||
| 0771fd82c0 | |||
| f791344810 | |||
| 61ef48eee6 | |||
| 504008dbe0 | |||
| df456245e7 | |||
| 7c1f1d8837 | |||
| ed3c3822fc | |||
| 69eebdd608 | |||
| 2be893a21e | |||
| a5d2253be8 | |||
| 5b7a4cd955 | |||
| 0a8711d76b | |||
| af13c8604d | |||
| cbff75db9e | |||
| bf427c01c1 | |||
| 024185b9ed | |||
| 9ccf27c7f5 | |||
| 5d43ce853e | |||
| 1a82ceac9c | |||
| b836e3c65b | |||
| f03c04c151 | |||
| c54c7c8b2c | |||
| dba2ec0539 | |||
| 6df23428af | |||
| 6409a4b112 | |||
| 9ec5333a9b | |||
| da47ccec9c | |||
| 8304f17d63 | |||
| e9307259d7 | |||
| 7a08bbbcc7 | |||
| 0e5255d4fb | |||
| 1c1c3c29c3 | |||
| 4d2c864bea | |||
| 2304d5367f | |||
| f6dd3651ea | |||
| dcf7a69430 | |||
| 04faaa9e35 | |||
| 8458f5c489 | |||
| 3ff5689fe5 | |||
| 10402c8a85 | |||
| c9868fc01f | |||
| 4f7cfbc26e | |||
| a138e12a26 | |||
| ea433cc496 | |||
| 62f8b0fc48 | |||
| 0ac7f0d374 | |||
| e3a715882e | |||
| 11885e86ee | |||
| ab221e94c0 | |||
| a9b1c5db78 | |||
| 3c7bc6a51e | |||
| 0d12f451be | |||
| 11b83d4000 | |||
| 416432a8e5 | |||
| 087537463d | |||
| 25bbcba0ea | |||
| 9f15daf0a0 | |||
| 41dc829341 | |||
| bb7af3f78e | |||
| 6082f351ab | |||
| b6cdc849db | |||
| 59ebf4ed9f | |||
| 60981565fa | |||
| 620c699456 | |||
| cfd019e2a2 | |||
| 7047c23489 | |||
| 3b1fc16f36 | |||
| 7249457771 | |||
| f1a5c1328c | |||
| b7ebedc23e | |||
| 9bbf170054 | |||
| 720eaf1e1a | |||
| d050159f07 | |||
| 07ea88b8c6 | |||
| e6dd4e840d | |||
| dfbd5f6a02 | |||
| 9bbb0ed060 | |||
| 051aa4cb98 | |||
| 58f546dd93 | |||
| 3406832aa2 | |||
| b1975fb13d | |||
| e68901bbce | |||
| 7cd4edd695 | |||
| 1a488c0542 | |||
| 4bbdfbc9e7 | |||
| 7810254198 | |||
| 3316d0bfb2 | |||
| dea6148a1a | |||
| 2e3f4fdada | |||
| f4ef0c1598 | |||
| c17e9ef7ba | |||
| 8cfba6456b | |||
| 995154d10d | |||
| 379dcf87d5 | |||
| bfb644ac04 | |||
| e7b214b6d2 | |||
| eda2a76ee9 | |||
| e3803f9985 | |||
| f0dce1fa35 | |||
| 73ffd71a22 | |||
| 8b1f88c40f | |||
| afa993316f | |||
| 9f39c8eaa1 | |||
| 16461247ce | |||
| ff0d23e55b | |||
| 21f95a3b11 | |||
| d4e7bec29a | |||
| decf04dfec | |||
| a938534a7e | |||
| 4091eab45e | |||
| f816e10ac9 | |||
| e21a1d3124 | |||
| c1a5d1c44a | |||
| ce2559b332 | |||
| f6e0d327b0 | |||
| a567c03fdf | |||
| 429ae44ae3 | |||
| 637b48eec8 | |||
| 6ebb0e2ad2 | |||
| 96b2898f38 | |||
| 5691fd3abe | |||
| 5cc2a6bdbf | |||
| afa8e4e645 | |||
| 60f7b1d98d | |||
| 2fe7482b73 | |||
| ff7b604a25 | |||
| e06c3ec7c5 | |||
| 2bbb777d95 | |||
| 535f1fb2e2 | |||
| 0570aa6494 | |||
| 7697d79d93 | |||
| 39baa2237e | |||
| c6f6f9ab35 | |||
| a1c7e0368c | |||
| 6503836b4d | |||
| 9613135e8d | |||
| 69fd2d8273 | |||
| 7e5eee5bf1 | |||
| 3ead4449ad | |||
| 2853bab471 | |||
| edb15dee3d | |||
| f58dffe31f | |||
| 50d3e565c5 | |||
| 49c664fad4 | |||
| a8c2fc6908 | |||
| 5f32e0e24d | |||
| 6deda2531c | |||
| da1ddc752b | |||
| 78c924baad | |||
| f3874abf68 | |||
| 37c6357b97 | |||
| f9cf70e93e | |||
| 6619941c90 | |||
| a3a09cf4d1 | |||
| 8547984d29 | |||
| 37e2664cf0 | |||
| 42a2cb0a38 | |||
| 2181a41a07 | |||
| aa73bf6079 | |||
| 50f28c9e25 | |||
| 36e42084f0 | |||
| fe2e89df1b | |||
| 86bd325131 | |||
| 61b54149b1 | |||
| 08914aa708 | |||
| a828b60765 | |||
| ce2fd7fec9 | |||
| 54a0e5085c | |||
| 1498d2f427 | |||
| c7df17e77b | |||
| 0b20faf3d2 | |||
| 9e4792af1f | |||
| 82313b3f6c | |||
| 247df9f3fc | |||
| ca5e6f9522 | |||
| ac389507a0 | |||
| 8b7a28a7e4 | |||
| 0cf9c16adc | |||
| 7c77b402db | |||
| 5512f91d08 | |||
| 1751a963f2 | |||
| fdb07a0ac1 | |||
| b6e7aeabe0 | |||
| 3990564a83 | |||
| 2495b23a7d | |||
| 059ea5bebe | |||
| 54bcaa4934 | |||
| 80d760c96e | |||
| a370404d9c | |||
| 92e7e7d8e8 | |||
| 74e5650350 | |||
| 5cae645ba1 | |||
| b337d84adf | |||
| 9f9c333a26 | |||
| 7071bd63ab | |||
| 9f01074f4c | |||
| 8c44e1ff81 | |||
| 81b9f9b16b | |||
| 1869f77c0f | |||
| ffb3b5ddbe | |||
| 2ed6bc8aaf | |||
| 9d7300f003 | |||
| c61d7088ae | |||
| 5335c2f920 | |||
| d92a56ee2d | |||
| cc79f40e2b | |||
| 2a98c1f89c | |||
| 81832d76a8 | |||
| d067dc5a05 | |||
| 283b26e2db | |||
| 2075236757 | |||
| 716e0192b3 | |||
| 3ed6c09485 | |||
| 504264ab7b | |||
| 4045e6e588 | |||
| 46ca5c32cd | |||
| bb25111d23 | |||
| 4f4fe553bc | |||
| 571665b559 | |||
| 43d61d961e | |||
| e0ead7b606 | |||
| c7e7b77093 | |||
| 6ffd5edfb5 | |||
| 9591fb8f63 | |||
| 9a2d6f854b | |||
| 507e2dc0ad | |||
| b558bb4894 | |||
| 902463b6e9 | |||
| 08cd51df1f | |||
| b943277559 | |||
| 33502c86ac | |||
| 192ee15520 | |||
| 076941bb07 | |||
| 0b365f6aa5 | |||
| 4d6827212d | |||
| 79d5724794 | |||
| 51e58aeb25 | |||
| f8720ec60e | |||
| 03f7d2f1ca | |||
| afe85e7e51 | |||
| 203849d5e4 | |||
| 93d4abecf8 | |||
| 50cd5d9ce7 | |||
| 6e4aeff4c9 | |||
| 37d695a62e | |||
| b81f0887f0 | |||
| 4e243e1759 | |||
| 6645f50dd0 | |||
| 1120289fdb | |||
| 3ed99b7700 | |||
| ffb9da14fb | |||
| 60f056061a | |||
| 7882aba7af | |||
| 2e2e1355ac | |||
| bb3b1441c5 | |||
| bf575ba7fb | |||
| 7cdede0c55 | |||
| e31e924cf7 | |||
| fe0516c877 | |||
| 53e77ed468 | |||
| 568b935246 | |||
| b85a098d9c | |||
| 6b5eac328f | |||
| 3ef588b877 | |||
| f608df9640 | |||
| c0e3d48ebc | |||
| 7244fc1f6a | |||
| 727b6a7259 | |||
| 3c39e146a3 | |||
| d235c3a678 | |||
| 0b1599d88a | |||
| 9711ef6dee | |||
| 15d0484485 | |||
| c768731e89 | |||
| 9c939a8dcf | |||
| e58f4e44c8 | |||
| 650609aaeb | |||
| 6dc3b662f6 | |||
| 58c4d5f4b4 | |||
| fc4a2244fa | |||
| 37460acb21 | |||
| e2536f1c35 | |||
| a639a1ae5c | |||
| 3c5cb4931e | |||
| ac8744af6a | |||
| c8cad0857e | |||
| b79e8053c1 | |||
| b497380a68 | |||
| 2a669555de | |||
| 7e06b4755b | |||
| e7ea90f87f | |||
| 3154cdf8ac | |||
| bc68dfb4e8 | |||
| 0cd8684ade | |||
| db9de43fa5 | |||
| 6f1961031c | |||
| 87b0126e0d | |||
| 25086ed257 | |||
| 9e32c6993a | |||
| 013d54c230 | |||
| 51eba617a8 | |||
| b179e2dd2d | |||
| 992d47e9dc | |||
| 5ef58a474a | |||
| 0b6677f6d3 | |||
| 638c0d1bf4 | |||
| 57aa089ad6 | |||
| b24e4bddb1 | |||
| 7745c8806c | |||
| 098ea6fcb7 | |||
| 1becbd9fcc | |||
| 50299c1d5e | |||
| 18039d7829 | |||
| 39b4bf1828 | |||
| a8c014de33 | |||
| 13d2412d24 | |||
| 34ef209940 | |||
| 54e0765d80 | |||
| 7ca38d63d9 | |||
| 6de422701a | |||
| 92460adebe | |||
| 55b90d7bae | |||
| fe5b9df45f | |||
| 79e278c008 | |||
| ed4c687d45 | |||
| 82b6419d12 | |||
| e3b45910aa | |||
| e63b4591ff | |||
| 4f1913ed26 | |||
| abd9675a99 | |||
| acb2cb5bf0 | |||
| 53b0df87f1 | |||
| bf53ebd590 | |||
| b5ed86c6a1 | |||
| fe30da6e2c | |||
| fda32d3d8d | |||
| 50c2f87add | |||
| f3ae185fd0 | |||
| 2d6253609c | |||
| e0426148ba | |||
| 8b3c717e8f | |||
| e72c7736e7 | |||
| 9b4f2d1b53 | |||
| 33c26a93c6 | |||
| 5b03d47fb8 | |||
| 4ceb8dd149 | |||
| bc53a054f2 | |||
| 31d3c508db | |||
| 1f261c2f9d | |||
| f65a14d1ef | |||
| 5bc6365ba5 | |||
| f489eb9a5d | |||
| 26c7e7f292 | |||
| eaa5012163 | |||
| 11871528ce | |||
| c9d8e9900f | |||
| 6a29b13c45 | |||
| b362affd13 | |||
| 3c8787980c | |||
| 56fbcc541f | |||
| 3a55fb9d1b | |||
| 52b32ba8f0 | |||
| b6de1fccc3 | |||
| d7874238f6 | |||
| 62b9180c50 | |||
| 81f5e72630 | |||
| 8d9af7de61 | |||
| ae7460440e | |||
| 86b4b30a6d | |||
| 68be50bbab | |||
| e79e81c6cd | |||
| 6feade3110 | |||
| eeb865ee8a | |||
| 627b441022 | |||
| 7e5f877ad9 | |||
| d0350402de | |||
| 9ce2197e9d | |||
| 9690ed8232 | |||
| 82e325cbfa | |||
| 9908ff33de | |||
| 7305f955a5 | |||
| f9de98ec64 | |||
| 568591670c | |||
| 62ce815197 | |||
| b4d0dff4c5 | |||
| daa02aaa98 | |||
| c69312ea0d | |||
| 3dbb98e454 | |||
| c78cb21999 | |||
| 0b1fe53a46 | |||
| daead680cd | |||
| ab8d92e1b8 | |||
| 5021a792b1 | |||
| fe86f31f44 | |||
| 98fdd70466 | |||
| 287fb2c611 | |||
| 63873a8393 | |||
| 519e23bf0b | |||
| da884b4e1d | |||
| e7cbf65280 | |||
| 8c45b9d03d | |||
| 04f01ed21d | |||
| 11dfceb2c9 | |||
| bdf189faac | |||
| 5bd56e7464 | |||
| 7a6475c3f9 | |||
| 2b4ffd1161 | |||
| d7ea27b279 | |||
| 3a9c978b5e | |||
| 6abb69bd25 | |||
| 17130477c9 | |||
| 4044fbcb33 | |||
| 2320ec76b4 | |||
| a519bbc617 | |||
| 09d93af975 | |||
| ca98710640 | |||
| e33f3e8345 | |||
| cd46a674d1 | |||
| 4c9c27b244 | |||
| cf407c2ec0 | |||
| f9bff103dd | |||
| 146ca61a27 | |||
| 1a84bcc565 | |||
| 681ffd9a21 | |||
| d90b8d615c | |||
| 255cd61a8c | |||
| 7374445398 | |||
| 7e92826efc | |||
| d83914d478 | |||
| 8521ac5d21 | |||
| e87355463f | |||
| 1df10553bb | |||
| d8f749da52 | |||
| 9509dfd1de | |||
| b445f4b01d | |||
| dc11acf041 | |||
| 6385b0f7ed | |||
| ed949bc211 | |||
| 20de2f35f9 | |||
| f9ed0037b3 | |||
| 14c31bfda0 | |||
| 5d65d000ab | |||
| 94e2b5c140 | |||
| 7ad81ed46f | |||
| d5b15d6523 | |||
| 33ca4ba5c7 | |||
| 195d501b43 | |||
| cc399e2ade | |||
| a441980d68 | |||
| 3c4cfccc88 | |||
| 9f417268b3 | |||
| 2aae501234 | |||
| d574e6dc09 | |||
| 4f778436b5 | |||
| 395f0201e3 | |||
| 9cb4292d5c | |||
| e446903aac | |||
| 281d036fcf | |||
| ae6266e101 | |||
| b7e6b5af1b | |||
| 0773ab4d07 | |||
| e287dea91b | |||
| 2c32536bf4 | |||
| caa2c06e50 | |||
| 5eabcf8e4f | |||
| 4668a133f0 | |||
| 3889b34ec3 | |||
| 81721d0dce | |||
| 311d799344 | |||
| e05112a364 | |||
| 9060365f5e | |||
| 56c1a7fab6 | |||
| b5bd2cde9e | |||
| 02c9e0a3e0 | |||
| f6d82773f9 | |||
| 78dc44a7fd | |||
| 4d64db8be7 | |||
| 608fab60fd | |||
| 46c4390a2e | |||
| c92743d124 | |||
| 594f969641 | |||
| c2c2403a79 | |||
| 93f8e7ba74 | |||
| a45eb275e3 | |||
| abb9e08671 | |||
| f14b7af5ac | |||
| 9c7a8dd584 | |||
| 1ed507c065 | |||
| 55c74ebea8 | |||
| e9301c3c4b | |||
| e3474878b6 | |||
| 4feae810fa | |||
| 101e9bd456 | |||
| 82a9f9a5a9 | |||
| a8c0f1d962 | |||
| 7341eaa654 | |||
| 28afa8d2d4 | |||
| 0fed75a880 | |||
| 069844cd4e | |||
| b362d47d95 | |||
| 6169b1dc90 | |||
| bf3c2b0bbb | |||
| 0587bef667 | |||
| 3cdfa654ae | |||
| 3cb84ed17c | |||
| 9f0d5f60b5 | |||
| 8cb0343f4c | |||
| 8e42ca1764 | |||
| c49b23d4dd | |||
| b0e1cb473a | |||
| 5e2726fb17 | |||
| 64d89d3546 | |||
| cf8deac2b2 | |||
| b1384a6da8 | |||
| dff59ec960 | |||
| 59c6e2cc44 | |||
| 6131a847a2 | |||
| b81d1b25c7 | |||
| 3271e395c8 | |||
| 0d7ce141aa | |||
| 0334cf11cc | |||
| e383d39598 | |||
| 399c20a928 | |||
| e34aba60d9 | |||
| 873aefae19 | |||
| 46cf2e96b5 | |||
| 4e1ba6f02f | |||
| da9089612a | |||
| 47df8f4c2a | |||
| dcde359181 | |||
| 7f4bcd3d72 | |||
| 0e2958e888 | |||
| 260bdc057c | |||
| c49b1bc6d5 | |||
| e331787645 | |||
| c0411caef4 | |||
| b401c6a0c3 | |||
| aabbe11e64 | |||
| 5f41971305 | |||
| 5023afffc7 | |||
| ad326cb0be |
+35
-27
@@ -1,27 +1,36 @@
|
||||
.git* export-ignore
|
||||
|
||||
* text=auto
|
||||
* whitespace=!indent,trail,space
|
||||
* text=auto whitespace=trailing-space,space-before-tab,-indent-with-non-tab,tab-in-indent,tabwidth=4
|
||||
|
||||
*.py text whitespace=tab-in-indent,trail,space,fix
|
||||
*.cpp text whitespace=tab-in-indent,trail,space,fix
|
||||
*.hpp text whitespace=tab-in-indent,trail,space,fix
|
||||
*.cxx text whitespace=tab-in-indent,trail,space,fix
|
||||
*.hxx text whitespace=tab-in-indent,trail,space,fix
|
||||
*.mm text whitespace=tab-in-indent,trail,space,fix
|
||||
*.c text whitespace=tab-in-indent,trail,space,fix
|
||||
*.h text whitespace=tab-in-indent,trail,space,fix
|
||||
*.i text whitespace=tab-in-indent,trail,space,fix
|
||||
*.java text whitespace=tab-in-indent,trail,space,fix
|
||||
*.cu text whitespace=tab-in-indent,trail,space,fix
|
||||
*.cl text whitespace=tab-in-indent,trail,space,fix
|
||||
*.py text
|
||||
*.cpp text
|
||||
*.hpp text
|
||||
*.cxx text
|
||||
*.hxx text
|
||||
*.mm text
|
||||
*.c text
|
||||
*.h text
|
||||
*.i text
|
||||
*.js text
|
||||
*.java text
|
||||
*.scala text
|
||||
*.cu text
|
||||
*.cl text
|
||||
*.css_t text
|
||||
*.qrc text
|
||||
*.qss text
|
||||
*.S text
|
||||
*.rst text
|
||||
*.tex text
|
||||
*.sty text
|
||||
|
||||
*.cmake text whitespace=tab-in-indent,trail,space,fix
|
||||
*.cmakein text whitespace=tab-in-indent,trail,space,fix
|
||||
*.in text whitespace=tab-in-indent,trail,space,fix
|
||||
CMakeLists.txt text whitespace=tab-in-indent,trail,space,fix
|
||||
*.aidl text
|
||||
*.mk text
|
||||
|
||||
*.rst text whitespace=tab-in-indent,trail,space,fix
|
||||
*.cmake text whitespace=tabwidth=2
|
||||
*.cmakein text whitespace=tabwidth=2
|
||||
*.in text whitespace=tabwidth=2
|
||||
CMakeLists.txt text whitespace=tabwidth=2
|
||||
|
||||
*.png binary
|
||||
*.jepg binary
|
||||
@@ -32,22 +41,21 @@ CMakeLists.txt text whitespace=tab-in-indent,trail,space,fix
|
||||
*.a binary
|
||||
*.so binary
|
||||
*.dll binary
|
||||
*.jar binary
|
||||
|
||||
*.pdf binary
|
||||
*.pbxproj binary
|
||||
*.vec binary
|
||||
*.doc binary
|
||||
|
||||
*.css_t text
|
||||
*.qrc text
|
||||
*.qss text
|
||||
*.S text
|
||||
|
||||
*.xml -text
|
||||
*.yml -text
|
||||
*.xml -text whitespace=cr-at-eol
|
||||
*.yml -text whitespace=cr-at-eol
|
||||
.project -text whitespace=cr-at-eol merge=union
|
||||
.classpath -text whitespace=cr-at-eol merge=union
|
||||
.cproject -text whitespace=cr-at-eol merge=union
|
||||
org.eclipse.jdt.core.prefs -text whitespace=cr-at-eol merge=union
|
||||
|
||||
*.vcproj text eol=crlf merge=union
|
||||
*.cproject text eol=crlf merge=union
|
||||
*.bat text eol=crlf
|
||||
*.cmd text eol=crlf
|
||||
*.cmd.tmpl text eol=crlf
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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
+28
-16
@@ -1,15 +1,18 @@
|
||||
#build TBB for Android from source
|
||||
if(NOT ANDROID)
|
||||
message(FATAL_ERROR "The script is designed for Android only!")
|
||||
endif()
|
||||
|
||||
#Cross compile TBB from source
|
||||
project(tbb)
|
||||
|
||||
# 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")
|
||||
# 4.1 update 2 - works fine
|
||||
set(tbb_ver "tbb41_20130116oss")
|
||||
set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20130116oss_src.tgz")
|
||||
set(tbb_md5 "3809790e1001a1b32d59c9fee590ee85")
|
||||
set(tbb_version_file "version_string.ver")
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow)
|
||||
|
||||
# 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")
|
||||
@@ -121,9 +124,9 @@ list(APPEND lib_srcs "${tbb_src_dir}/src/rml/client/rml_tbb.cpp")
|
||||
|
||||
add_definitions(-D__TBB_DYNAMIC_LOAD_ENABLED=0 #required
|
||||
-D__TBB_BUILD=1 #required
|
||||
-D__TBB_SURVIVE_THREAD_SWITCH=0 #no cilk on Android ?
|
||||
-DUSE_PTHREAD #required
|
||||
-DTBB_USE_GCC_BUILTINS=1 #required
|
||||
-D__TBB_SURVIVE_THREAD_SWITCH=0 #no cilk support
|
||||
-DUSE_PTHREAD #required for Unix
|
||||
-DTBB_USE_GCC_BUILTINS=1 #required for ARM GCC
|
||||
-DTBB_USE_DEBUG=0 #just to be sure
|
||||
-DTBB_NO_LEGACY=1 #don't need backward compatibility
|
||||
-DDO_ITT_NOTIFY=0 #it seems that we don't need these notifications
|
||||
@@ -140,14 +143,24 @@ if(tbb_need_GENERIC_DWORD_LOAD_STORE)
|
||||
set(tbb_need_GENERIC_DWORD_LOAD_STORE ON PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
add_library(tbb STATIC ${lib_srcs} ${lib_hdrs} "${CMAKE_CURRENT_SOURCE_DIR}/android_additional.h" "${CMAKE_CURRENT_SOURCE_DIR}/${tbb_version_file}")
|
||||
set(TBB_SOURCE_FILES ${lib_srcs} ${lib_hdrs})
|
||||
|
||||
if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
|
||||
if (NOT ANDROID)
|
||||
set(TBB_SOURCE_FILES ${TBB_SOURCE_FILES} "${CMAKE_CURRENT_SOURCE_DIR}/arm_linux_stub.cpp")
|
||||
endif()
|
||||
set(TBB_SOURCE_FILES ${TBB_SOURCE_FILES} "${CMAKE_CURRENT_SOURCE_DIR}/android_additional.h")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include \"${CMAKE_CURRENT_SOURCE_DIR}/android_additional.h\"")
|
||||
endif()
|
||||
|
||||
set(TBB_SOURCE_FILES ${TBB_SOURCE_FILES} "${CMAKE_CURRENT_SOURCE_DIR}/${tbb_version_file}")
|
||||
|
||||
add_library(tbb ${TBB_SOURCE_FILES})
|
||||
target_link_libraries(tbb c m dl)
|
||||
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wmissing-declarations)
|
||||
string(REPLACE "-Werror=non-virtual-dtor" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include \"${CMAKE_CURRENT_SOURCE_DIR}/android_additional.h\"")
|
||||
|
||||
set_target_properties(tbb
|
||||
PROPERTIES OUTPUT_NAME tbb
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
@@ -164,4 +177,3 @@ endif()
|
||||
|
||||
# get TBB version
|
||||
ocv_parse_header("${tbb_src_dir}/include/tbb/tbb_stddef.h" TBB_VERSION_LINES TBB_VERSION_MAJOR TBB_VERSION_MINOR TBB_INTERFACE_VERSION CACHE)
|
||||
|
||||
|
||||
externo
+10
@@ -0,0 +1,10 @@
|
||||
#include "tbb/tbb_misc.h"
|
||||
|
||||
namespace tbb {
|
||||
namespace internal {
|
||||
|
||||
void affinity_helper::protect_affinity_mask() {}
|
||||
affinity_helper::~affinity_helper() {}
|
||||
|
||||
}
|
||||
}
|
||||
+96
-64
@@ -110,7 +110,7 @@ endif()
|
||||
|
||||
# Optional 3rd party components
|
||||
# ===================================================
|
||||
OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON IF (UNIX AND NOT ANDROID AND NOT IOS AND NOT CARMA) )
|
||||
OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON IF (UNIX AND NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_AVFOUNDATION "Use AVFoundation for Video I/O" ON IF IOS)
|
||||
OCV_OPTION(WITH_CARBON "Use Carbon for UI instead of Cocoa" OFF IF APPLE )
|
||||
OCV_OPTION(WITH_CUDA "Include NVidia Cuda Runtime support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS) )
|
||||
@@ -121,6 +121,7 @@ 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_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,25 +130,26 @@ 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) )
|
||||
OCV_OPTION(WITH_CSTRIPES "Include C= support" OFF IF WIN32 )
|
||||
OCV_OPTION(WITH_TIFF "Include TIFF support" ON IF (NOT IOS) )
|
||||
OCV_OPTION(WITH_UNICAP "Include Unicap support (GPL)" OFF IF (UNIX AND NOT APPLE AND NOT ANDROID) )
|
||||
OCV_OPTION(WITH_V4L "Include Video 4 Linux support" ON IF (UNIX AND NOT APPLE AND NOT ANDROID) )
|
||||
OCV_OPTION(WITH_V4L "Include Video 4 Linux support" ON IF (UNIX AND NOT ANDROID) )
|
||||
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_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) )
|
||||
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) )
|
||||
|
||||
|
||||
# OpenCV build components
|
||||
# ===================================================
|
||||
OCV_OPTION(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" NOT (ANDROID OR IOS) )
|
||||
OCV_OPTION(BUILD_opencv_apps "Build utility applications (used for example to train classifiers)" (NOT ANDROID) IF (NOT IOS) )
|
||||
OCV_OPTION(BUILD_ANDROID_EXAMPLES "Build examples for Android platform" ON IF ANDROID )
|
||||
OCV_OPTION(BUILD_DOCS "Create build rules for OpenCV Documentation" ON )
|
||||
OCV_OPTION(BUILD_EXAMPLES "Build all examples" OFF )
|
||||
@@ -156,18 +158,18 @@ OCV_OPTION(BUILD_PERF_TESTS "Build performance tests"
|
||||
OCV_OPTION(BUILD_TESTS "Build accuracy & regression tests" ON IF (NOT IOS) )
|
||||
OCV_OPTION(BUILD_WITH_DEBUG_INFO "Include debug info into debug libs (not MSCV only)" ON )
|
||||
OCV_OPTION(BUILD_WITH_STATIC_CRT "Enables use of staticaly linked CRT for staticaly linked OpenCV" ON IF MSVC )
|
||||
OCV_OPTION(BUILD_FAT_JAVA_LIB "Create fat java wrapper containing the whole OpenCV library" ON IF ANDROID AND NOT BUILD_SHARED_LIBS AND CMAKE_COMPILER_IS_GNUCXX )
|
||||
OCV_OPTION(BUILD_FAT_JAVA_LIB "Create fat java wrapper containing the whole OpenCV library" ON IF NOT BUILD_SHARED_LIBS AND CMAKE_COMPILER_IS_GNUCXX )
|
||||
OCV_OPTION(BUILD_ANDROID_SERVICE "Build OpenCV Manager for Google Play" OFF IF ANDROID AND ANDROID_SOURCE_TREE )
|
||||
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 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 )
|
||||
|
||||
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_TBB "Download and build TBB from source" ANDROID IF CMAKE_COMPILER_IS_GNUCXX )
|
||||
|
||||
# OpenCV installation options
|
||||
# ===================================================
|
||||
@@ -182,7 +184,7 @@ OCV_OPTION(INSTALL_TO_MANGLED_PATHS "Enables mangled install paths, that help wi
|
||||
OCV_OPTION(ENABLE_PRECOMPILED_HEADERS "Use precompiled headers" ON IF (NOT IOS) )
|
||||
OCV_OPTION(ENABLE_SOLUTION_FOLDERS "Solution folder in Visual Studio or in other IDEs" (MSVC_IDE OR CMAKE_GENERATOR MATCHES Xcode) IF (CMAKE_VERSION VERSION_GREATER "2.8.0") )
|
||||
OCV_OPTION(ENABLE_PROFILING "Enable profiling in the GCC compiler (Add flags: -g -pg)" OFF IF CMAKE_COMPILER_IS_GNUCXX )
|
||||
OCV_OPTION(ENABLE_OMIT_FRAME_POINTER "Enable -fomit-frame-pointer for GCC" ON IF CMAKE_COMPILER_IS_GNUCXX )
|
||||
OCV_OPTION(ENABLE_OMIT_FRAME_POINTER "Enable -fomit-frame-pointer for GCC" ON IF CMAKE_COMPILER_IS_GNUCXX AND NOT (APPLE AND CMAKE_COMPILER_IS_CLANGCXX) )
|
||||
OCV_OPTION(ENABLE_POWERPC "Enable PowerPC for GCC" ON IF (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_SYSTEM_PROCESSOR MATCHES powerpc.*) )
|
||||
OCV_OPTION(ENABLE_FAST_MATH "Enable -ffast-math (not recommended for GCC 4.6.x)" OFF IF (CMAKE_COMPILER_IS_GNUCXX AND (X86 OR X86_64)) )
|
||||
OCV_OPTION(ENABLE_SSE "Enable SSE instructions" ON IF ((MSVC OR CMAKE_COMPILER_IS_GNUCXX) AND (X86 OR X86_64)) )
|
||||
@@ -299,21 +301,19 @@ find_host_program(GIT_EXECUTABLE NAMES ${git_names} PATH_SUFFIXES Git/cmd Git/bi
|
||||
mark_as_advanced(GIT_EXECUTABLE)
|
||||
|
||||
if(GIT_EXECUTABLE)
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty --match "2.[0-9].[0-9]*"
|
||||
WORKING_DIRECTORY "${OpenCV_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE OPENCV_GIT_HASH_SORT
|
||||
OUTPUT_VARIABLE OPENCV_VCSVERSION
|
||||
RESULT_VARIABLE GIT_RESULT
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(GIT_RESULT EQUAL 0)
|
||||
set(OPENCV_VCSVERSION "commit:${OPENCV_GIT_HASH_SORT}")
|
||||
else()
|
||||
set(OPENCV_VCSVERSION "exported")
|
||||
if(NOT GIT_RESULT EQUAL 0)
|
||||
set(OPENCV_VCSVERSION "unknown")
|
||||
endif()
|
||||
else()
|
||||
# We don't have git:
|
||||
set(OPENCV_VCSVERSION "")
|
||||
set(OPENCV_VCSVERSION "unknown")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -415,10 +415,10 @@ if(WITH_OPENCL)
|
||||
if(OPENCL_FOUND)
|
||||
set(HAVE_OPENCL 1)
|
||||
endif()
|
||||
if(WITH_OPENCLAMDFFT)
|
||||
if(WITH_OPENCLAMDFFT AND CLAMDFFT_INCLUDE_DIR)
|
||||
set(HAVE_CLAMDFFT 1)
|
||||
endif()
|
||||
if(WITH_OPENCLAMDBLAS)
|
||||
if(WITH_OPENCLAMDBLAS AND CLAMDBLAS_INCLUDE_DIR)
|
||||
set(HAVE_CLAMDBLAS 1)
|
||||
endif()
|
||||
endif()
|
||||
@@ -452,7 +452,9 @@ add_subdirectory(doc)
|
||||
add_subdirectory(data)
|
||||
|
||||
# extra applications
|
||||
add_subdirectory(apps)
|
||||
if(BUILD_opencv_apps)
|
||||
add_subdirectory(apps)
|
||||
endif()
|
||||
|
||||
# examples
|
||||
if(BUILD_EXAMPLES OR BUILD_ANDROID_EXAMPLES OR INSTALL_PYTHON_EXAMPLES)
|
||||
@@ -519,10 +521,21 @@ if(NOT CMAKE_GENERATOR MATCHES "Xcode|Visual Studio")
|
||||
endif()
|
||||
|
||||
# ========================== C/C++ options ==========================
|
||||
if(CMAKE_CXX_COMPILER_VERSION)
|
||||
set(OPENCV_COMPILER_STR "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} (ver ${CMAKE_CXX_COMPILER_VERSION})")
|
||||
elseif(CMAKE_COMPILER_IS_CLANGCXX)
|
||||
set(OPENCV_COMPILER_STR "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} (ver ${CMAKE_CLANG_REGEX_VERSION})")
|
||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(OPENCV_COMPILER_STR "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} (ver ${CMAKE_GCC_REGEX_VERSION})")
|
||||
else()
|
||||
set(OPENCV_COMPILER_STR "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}")
|
||||
endif()
|
||||
string(STRIP "${OPENCV_COMPILER_STR}" OPENCV_COMPILER_STR)
|
||||
|
||||
status("")
|
||||
status(" C/C++:")
|
||||
status(" Built as dynamic libs?:" BUILD_SHARED_LIBS THEN YES ELSE NO)
|
||||
status(" C++ Compiler:" CMAKE_COMPILER_IS_GNUCXX THEN "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} (ver ${CMAKE_GCC_REGEX_VERSION})" ELSE "${CMAKE_CXX_COMPILER}" )
|
||||
status(" C++ Compiler:" ${OPENCV_COMPILER_STR})
|
||||
status(" C++ flags (Release):" ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE})
|
||||
status(" C++ flags (Debug):" ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG})
|
||||
status(" C Compiler:" ${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1})
|
||||
@@ -551,7 +564,11 @@ foreach(m ${OPENCV_MODULES_DISABLED_AUTO})
|
||||
list(APPEND __mdeps ${d})
|
||||
endif()
|
||||
endforeach()
|
||||
list(APPEND OPENCV_MODULES_DISABLED_AUTO_ST "${m}(deps: ${__mdeps})")
|
||||
if(__mdeps)
|
||||
list(APPEND OPENCV_MODULES_DISABLED_AUTO_ST "${m}(deps: ${__mdeps})")
|
||||
else()
|
||||
list(APPEND OPENCV_MODULES_DISABLED_AUTO_ST "${m}")
|
||||
endif()
|
||||
endforeach()
|
||||
string(REPLACE "opencv_" "" OPENCV_MODULES_DISABLED_AUTO_ST "${OPENCV_MODULES_DISABLED_AUTO_ST}")
|
||||
|
||||
@@ -567,15 +584,16 @@ if(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}")
|
||||
android_get_compatible_target(android_sdk_target_status ${ANDROID_NATIVE_API_LEVEL} ${ANDROID_SDK_TARGET} 11)
|
||||
status(" SDK target:" "${android_sdk_target_status}")
|
||||
if(BUILD_WITH_ANDROID_NDK)
|
||||
status(" Android NDK:" "${ANDROID_NDK} (toolchain: ${ANDROID_TOOLCHAIN_NAME})")
|
||||
elseif(BUILD_WITH_STANDALONE_TOOLCHAIN)
|
||||
status(" Android toolchain:" "${ANDROID_STANDALONE_TOOLCHAIN}")
|
||||
endif()
|
||||
status(" android tool:" ANDROID_EXECUTABLE THEN "${ANDROID_EXECUTABLE} (${ANDROID_TOOLS_Pkg_Desc})" ELSE NO)
|
||||
status(" ant:" ANT_EXECUTABLE THEN "${ANT_EXECUTABLE} (ver ${ANT_VERSION})" ELSE NO)
|
||||
status(" Google Play package:" BUILD_ANDROID_PACKAGE THEN YES ELSE NO)
|
||||
status(" Google Play package:" BUILD_ANDROID_PACKAGE THEN YES ELSE NO)
|
||||
status(" Android examples:" BUILD_ANDROID_EXAMPLES AND CAN_BUILD_ANDROID_PROJECTS THEN YES ELSE NO)
|
||||
endif()
|
||||
|
||||
# ========================== GUI ==========================
|
||||
@@ -698,6 +716,10 @@ 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)
|
||||
@@ -716,11 +738,13 @@ if(DEFINED WITH_V4L)
|
||||
endif()
|
||||
if(HAVE_CAMV4L2)
|
||||
set(HAVE_CAMV4L2_STR "YES")
|
||||
elseif(HAVE_VIDEOIO)
|
||||
set(HAVE_CAMV4L2_STR "YES(videoio)")
|
||||
else()
|
||||
set(HAVE_CAMV4L2_STR "NO")
|
||||
endif()
|
||||
status(" V4L/V4L2:" HAVE_LIBV4L THEN "Using libv4l (ver ${ALIASOF_libv4l1_VERSION})"
|
||||
ELSE "${HAVE_CAMV4L_STR}/${HAVE_CAMV4L2_STR}")
|
||||
ELSE "${HAVE_CAMV4L_STR}/${HAVE_CAMV4L2_STR}")
|
||||
endif(DEFINED WITH_V4L)
|
||||
|
||||
if(DEFINED WITH_VIDEOINPUT)
|
||||
@@ -739,47 +763,51 @@ endif(DEFINED WITH_XINE)
|
||||
status("")
|
||||
status(" Other third-party libraries:")
|
||||
|
||||
if(DEFINED WITH_IPP)
|
||||
if(WITH_IPP AND IPP_FOUND)
|
||||
status(" Use IPP:" "${IPP_LATEST_VERSION_STR} [${IPP_LATEST_VERSION_MAJOR}.${IPP_LATEST_VERSION_MINOR}.${IPP_LATEST_VERSION_BUILD}]")
|
||||
status(" at:" "${IPP_ROOT_DIR}")
|
||||
else()
|
||||
status(" Use IPP:" WITH_IPP AND NOT IPP_FOUND THEN "IPP not found" ELSE NO)
|
||||
endif()
|
||||
endif(DEFINED WITH_IPP)
|
||||
if(WITH_IPP AND IPP_FOUND)
|
||||
status(" Use IPP:" "${IPP_LATEST_VERSION_STR} [${IPP_LATEST_VERSION_MAJOR}.${IPP_LATEST_VERSION_MINOR}.${IPP_LATEST_VERSION_BUILD}]")
|
||||
status(" at:" "${IPP_ROOT_DIR}")
|
||||
else()
|
||||
status(" Use IPP:" WITH_IPP AND NOT IPP_FOUND THEN "IPP not found" ELSE NO)
|
||||
endif()
|
||||
|
||||
if(DEFINED WITH_TBB)
|
||||
status(" Use TBB:" HAVE_TBB THEN "YES (ver ${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR} interface ${TBB_INTERFACE_VERSION})" ELSE NO)
|
||||
endif(DEFINED WITH_TBB)
|
||||
|
||||
if(DEFINED WITH_CSTRIPES)
|
||||
status(" Use C=:" HAVE_CSTRIPES THEN YES ELSE NO)
|
||||
endif(DEFINED WITH_CSTRIPES)
|
||||
|
||||
if(DEFINED WITH_CUDA)
|
||||
status(" Use Cuda:" HAVE_CUDA THEN "YES (ver ${CUDA_VERSION_STRING})" ELSE NO)
|
||||
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)
|
||||
status(" Use Eigen:" HAVE_EIGEN THEN "YES (ver ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})" ELSE NO)
|
||||
status(" Use TBB:" HAVE_TBB THEN "YES (ver ${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR} interface ${TBB_INTERFACE_VERSION})" ELSE NO)
|
||||
status(" Use OpenMP:" HAVE_OPENMP THEN YES ELSE NO)
|
||||
status(" Use GCD" HAVE_GCD THEN YES ELSE NO)
|
||||
status(" Use Concurrency" HAVE_CONCURRENCY THEN YES ELSE NO)
|
||||
status(" Use C=:" HAVE_CSTRIPES THEN YES ELSE NO)
|
||||
status(" Use Cuda:" HAVE_CUDA THEN "YES (ver ${CUDA_VERSION_STRING})" ELSE NO)
|
||||
status(" Use OpenCL:" HAVE_OPENCL THEN YES ELSE NO)
|
||||
|
||||
if(HAVE_CUDA)
|
||||
status("")
|
||||
status(" NVIDIA CUDA")
|
||||
|
||||
status(" Use CUFFT:" HAVE_CUFFT THEN YES ELSE NO)
|
||||
status(" Use CUBLAS:" HAVE_CUBLAS THEN YES ELSE NO)
|
||||
status(" Use CUFFT:" HAVE_CUFFT THEN YES ELSE NO)
|
||||
status(" Use CUBLAS:" HAVE_CUBLAS THEN YES ELSE NO)
|
||||
status(" USE NVCUVID:" HAVE_NVCUVID THEN YES ELSE NO)
|
||||
status(" NVIDIA GPU arch:" ${OPENCV_CUDA_ARCH_BIN})
|
||||
status(" NVIDIA PTX archs:" ${OPENCV_CUDA_ARCH_PTX})
|
||||
status(" Use fast math:" CUDA_FAST_MATH THEN YES ELSE NO)
|
||||
endif()
|
||||
|
||||
if(HAVE_OPENCL AND BUILD_opencv_ocl)
|
||||
status("")
|
||||
status(" OpenCL")
|
||||
if(OPENCL_INCLUDE_DIR)
|
||||
status(" Include:" ${OPENCL_INCLUDE_DIR})
|
||||
endif()
|
||||
if(OPENCL_LIBRARIES)
|
||||
status(" libraries:" ${OPENCL_LIBRARIES})
|
||||
endif()
|
||||
status(" Use AMDFFT:" HAVE_CLAMDFFT THEN YES ELSE NO)
|
||||
status(" Use AMDBLAS:" HAVE_CLAMDBLAS THEN YES ELSE NO)
|
||||
endif()
|
||||
|
||||
# ========================== python ==========================
|
||||
status("")
|
||||
status(" Python:")
|
||||
status(" Interpreter:" PYTHON_EXECUTABLE THEN "${PYTHON_EXECUTABLE} (ver ${PYTHON_VERSION_FULL})" ELSE NO)
|
||||
status(" Interpreter:" PYTHON_EXECUTABLE THEN "${PYTHON_EXECUTABLE} (ver ${PYTHON_VERSION_FULL})" ELSE NO)
|
||||
if(BUILD_opencv_python)
|
||||
if(PYTHONLIBS_VERSION_STRING)
|
||||
status(" Libraries:" HAVE_opencv_python THEN "${PYTHON_LIBRARIES} (ver ${PYTHONLIBS_VERSION_STRING})" ELSE NO)
|
||||
@@ -790,6 +818,15 @@ if(BUILD_opencv_python)
|
||||
status(" packages path:" PYTHON_EXECUTABLE THEN "${PYTHON_PACKAGES_PATH}" ELSE "-")
|
||||
endif()
|
||||
|
||||
# ========================== java ==========================
|
||||
status("")
|
||||
status(" Java:")
|
||||
status(" ant:" ANT_EXECUTABLE THEN "${ANT_EXECUTABLE} (ver ${ANT_VERSION})" ELSE NO)
|
||||
if(NOT ANDROID)
|
||||
status(" JNI:" JNI_INCLUDE_DIRS THEN "${JNI_INCLUDE_DIRS}" ELSE NO)
|
||||
endif()
|
||||
status(" Java tests:" BUILD_TESTS AND (NOT ANDROID OR CAN_BUILD_ANDROID_PROJECTS) THEN YES ELSE NO)
|
||||
|
||||
# ========================== documentation ==========================
|
||||
if(BUILD_DOCS)
|
||||
status("")
|
||||
@@ -808,12 +845,7 @@ status("")
|
||||
status(" Tests and samples:")
|
||||
status(" Tests:" BUILD_TESTS AND HAVE_opencv_ts THEN YES ELSE NO)
|
||||
status(" Performance tests:" BUILD_PERF_TESTS AND HAVE_opencv_ts THEN YES ELSE NO)
|
||||
status(" Examples:" BUILD_EXAMPLES THEN YES ELSE NO)
|
||||
|
||||
if(ANDROID)
|
||||
status(" Android tests:" BUILD_TESTS AND CAN_BUILD_ANDROID_PROJECTS THEN YES ELSE NO)
|
||||
status(" Android examples:" BUILD_ANDROID_EXAMPLES AND CAN_BUILD_ANDROID_PROJECTS THEN YES ELSE NO)
|
||||
endif()
|
||||
status(" C/C++ Examples:" BUILD_EXAMPLES THEN YES ELSE NO)
|
||||
|
||||
# ========================== auxiliary ==========================
|
||||
status("")
|
||||
|
||||
@@ -6,8 +6,8 @@ const char* GetRevision(void);
|
||||
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_NAME "org.opencv.lib_v" CVAUX_STR(CV_VERSION_EPOCH) CVAUX_STR(CV_VERSION_MAJOR) "_" ANDROID_PACKAGE_PLATFORM
|
||||
#define PACKAGE_REVISION CVAUX_STR(CV_VERSION_MINOR) "." CVAUX_STR(CV_VERSION_REVISION) "." CVAUX_STR(ANDROID_PACKAGE_RELEASE)
|
||||
|
||||
const char* GetPackageName(void)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.opencv.lib_v@OPENCV_VERSION_MAJOR@@OPENCV_VERSION_MINOR@_@ANDROID_PACKAGE_PLATFORM@"
|
||||
android:versionCode="@OPENCV_VERSION_PATCH@@ANDROID_PACKAGE_RELEASE@"
|
||||
android:versionName="@OPENCV_VERSION_PATCH@.@ANDROID_PACKAGE_RELEASE@" >
|
||||
android:versionCode="@OPENCV_VERSION_PATCH@@OPENCV_VERSION_TWEAK@@ANDROID_PACKAGE_RELEASE@"
|
||||
android:versionName="@OPENCV_VERSION_PATCH@.@OPENCV_VERSION_TWEAK@.@ANDROID_PACKAGE_RELEASE@" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="@ANDROID_SDK_VERSION@" />
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
|
||||
|
||||
@@ -56,7 +56,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${ANDROID_MANIFEST_FILE}" "${PACKAGE
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/res/values/strings.xml" "${PACKAGE_DIR}/res/values/strings.xml" @ONLY)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/res/drawable/icon.png" "${PACKAGE_DIR}/res/drawable/icon.png" COPYONLY)
|
||||
|
||||
set(target_name "OpenCV_${OPENCV_VERSION_MAJOR}.${OPENCV_VERSION_MINOR}.${OPENCV_VERSION_PATCH}_binary_pack_${ANDROID_PACKAGE_PLATFORM}")
|
||||
set(target_name "OpenCV_${OPENCV_VERSION}_binary_pack_${ANDROID_PACKAGE_PLATFORM}")
|
||||
get_target_property(opencv_java_location opencv_java LOCATION)
|
||||
|
||||
set(android_proj_target_files ${ANDROID_PROJECT_FILES})
|
||||
@@ -86,7 +86,7 @@ add_custom_command(
|
||||
COMMAND ${CMAKE_COMMAND} -E touch "${APK_NAME}"
|
||||
WORKING_DIRECTORY "${PACKAGE_DIR}"
|
||||
MAIN_DEPENDENCY "${PACKAGE_DIR}/${ANDROID_MANIFEST_FILE}"
|
||||
DEPENDS "${OpenCV_BINARY_DIR}/bin/.classes.jar.dephelper" "${PACKAGE_DIR}/res/values/strings.xml" "${PACKAGE_DIR}/res/drawable/icon.png" ${camera_wrappers} opencv_java
|
||||
DEPENDS "${OpenCV_BINARY_DIR}/bin/classes.jar.dephelper" "${PACKAGE_DIR}/res/values/strings.xml" "${PACKAGE_DIR}/res/drawable/icon.png" ${camera_wrappers} opencv_java
|
||||
)
|
||||
|
||||
install(FILES "${APK_NAME}" DESTINATION "apk/" COMPONENT main)
|
||||
|
||||
@@ -1,130 +1,228 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from optparse import OptionParser
|
||||
from shutil import rmtree
|
||||
import os
|
||||
import sys
|
||||
|
||||
ANDROID_SDK_PATH = "/opt/android-sdk-linux"
|
||||
ANDROID_NDK_PATH = None
|
||||
INSTALL_DIRECTORY = None
|
||||
CLASS_PATH = None
|
||||
TMP_HEADER_PATH="tmp_include"
|
||||
HEADER_EXTS = set(['h', 'hpp'])
|
||||
SYS_INCLUDES = ["platforms/android-8/arch-arm/usr/include", "sources/cxx-stl/gnu-libstdc++/include", "sources/cxx-stl/gnu-libstdc++/libs/armeabi/include"]
|
||||
|
||||
PROJECT_NAME = "OpenCV-branch"
|
||||
TARGET_LIBS = ["libopencv_java.so"]
|
||||
ARCH = "armeabi"
|
||||
GCC_OPTIONS = "-fpermissive"
|
||||
EXCLUDE_HEADERS = set(["hdf5.h", "eigen.hpp", "cxeigen.hpp"]);
|
||||
architecture = 'armeabi'
|
||||
excludedHeaders = set(['hdf5.h', 'cap_ios.h',
|
||||
'eigen.hpp', 'cxeigen.hpp' #TOREMOVE
|
||||
])
|
||||
systemIncludes = ['sources/cxx-stl/gnu-libstdc++/4.6/include', \
|
||||
'/opt/android-ndk-r8c/platforms/android-8/arch-arm', # TODO: check if this one could be passed as command line arg
|
||||
'sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include']
|
||||
targetLibs = ['libopencv_java.so']
|
||||
preamble = ['Eigen/Core']
|
||||
# TODO: get gcc_options automatically
|
||||
gcc_options = ['-fexceptions', '-frtti', '-Wno-psabi', '--sysroot=/opt/android-ndk-r8c/platforms/android-8/arch-arm', '-fpic', '-D__ARM_ARCH_5__', '-D__ARM_ARCH_5T__', '-D__ARM_ARCH_5E__', '-D__ARM_ARCH_5TE__', '-fsigned-char', '-march=armv5te', '-mtune=xscale', '-msoft-float', '-fdata-sections', '-ffunction-sections', '-Wa,--noexecstack ', '-W', '-Wall', '-Werror=return-type', '-Werror=address', '-Werror=sequence-point', '-Wformat', '-Werror=format-security', '-Wmissing-declarations', '-Wundef', '-Winit-self', '-Wpointer-arith', '-Wshadow', '-Wsign-promo', '-Wno-narrowing', '-fdiagnostics-show-option', '-fomit-frame-pointer', '-mthumb', '-fomit-frame-pointer', '-O3', '-DNDEBUG ', '-DNDEBUG']
|
||||
excludedOptionsPrefix = '-W'
|
||||
|
||||
def FindClasses(root, prefix):
|
||||
classes = []
|
||||
if ("" != prefix):
|
||||
prefix = prefix + "."
|
||||
for path in os.listdir(root):
|
||||
currentPath = os.path.join(root, path)
|
||||
if (os.path.isdir(currentPath)):
|
||||
classes += FindClasses(currentPath, prefix + path)
|
||||
else:
|
||||
name = str.split(path, ".")[0]
|
||||
ext = str.split(path, ".")[1]
|
||||
if (ext == "class"):
|
||||
#print("class: %s" % (prefix + name))
|
||||
classes.append(prefix+name)
|
||||
return classes
|
||||
|
||||
def FindHeaders(root):
|
||||
|
||||
def GetHeaderFiles(root):
|
||||
headers = []
|
||||
for path in os.listdir(root):
|
||||
currentPath = os.path.join(root, path)
|
||||
if (os.path.isdir(currentPath)):
|
||||
headers += FindHeaders(currentPath)
|
||||
else:
|
||||
ext = str.split(path, ".")[-1]
|
||||
#print("%s: \"%s\"" % (currentPath, ext))
|
||||
if (ext in HEADER_EXTS):
|
||||
#print("Added as header file")
|
||||
if (path not in EXCLUDE_HEADERS):
|
||||
headers.append(currentPath)
|
||||
if not os.path.isdir(os.path.join(root, path)) \
|
||||
and os.path.splitext(path)[1] in ['.h', '.hpp'] \
|
||||
and not path in excludedHeaders:
|
||||
headers.append(os.path.join(root, path))
|
||||
return sorted(headers)
|
||||
|
||||
|
||||
|
||||
def GetClasses(root, prefix):
|
||||
classes = []
|
||||
if ('' != prefix):
|
||||
prefix = prefix + '.'
|
||||
for path in os.listdir(root):
|
||||
currentPath = os.path.join(root, path)
|
||||
if (os.path.isdir(currentPath)):
|
||||
classes += GetClasses(currentPath, prefix + path)
|
||||
else:
|
||||
name = str.split(path, '.')[0]
|
||||
ext = str.split(path, '.')[1]
|
||||
if (ext == 'class'):
|
||||
classes.append(prefix + name)
|
||||
return classes
|
||||
|
||||
|
||||
|
||||
def GetJavaHHeaders():
|
||||
print('\nGenerating JNI headers for Java API ...')
|
||||
|
||||
javahHeaders = os.path.join(managerDir, 'javah_generated_headers')
|
||||
if os.path.exists(javahHeaders):
|
||||
rmtree(javahHeaders)
|
||||
os.makedirs(os.path.join(os.getcwd(), javahHeaders))
|
||||
|
||||
AndroidJavaDeps = os.path.join(SDK_path, 'platforms/android-11/android.jar')
|
||||
|
||||
classPath = os.path.join(managerDir, 'sdk/java/bin/classes')
|
||||
if not os.path.exists(classPath):
|
||||
print('Error: no Java classes found in \'%s\'' % classPath)
|
||||
quit()
|
||||
|
||||
allJavaClasses = GetClasses(classPath, '')
|
||||
if not allJavaClasses:
|
||||
print('Error: no Java classes found')
|
||||
quit()
|
||||
|
||||
for currentClass in allJavaClasses:
|
||||
os.system('javah -d %s -classpath %s:%s %s' % (javahHeaders, classPath, \
|
||||
AndroidJavaDeps, currentClass))
|
||||
|
||||
print('\nBuilding JNI headers list ...')
|
||||
jniHeaders = GetHeaderFiles(javahHeaders)
|
||||
|
||||
return jniHeaders
|
||||
|
||||
|
||||
|
||||
def GetImmediateSubdirs(dir):
|
||||
return [name for name in os.listdir(dir)
|
||||
if os.path.isdir(os.path.join(dir, name))]
|
||||
|
||||
|
||||
|
||||
def GetOpenCVModules():
|
||||
makefile = open(os.path.join(managerDir, 'sdk/native/jni/OpenCV.mk'), 'r')
|
||||
makefileStr = makefile.read()
|
||||
left = makefileStr.find('OPENCV_MODULES:=') + len('OPENCV_MODULES:=')
|
||||
right = makefileStr[left:].find('\n')
|
||||
modules = makefileStr[left:left+right].split()
|
||||
modules = filter(lambda x: x != 'ts' and x != 'androidcamera', modules)
|
||||
return modules
|
||||
|
||||
|
||||
|
||||
def FindHeaders():
|
||||
headers = []
|
||||
|
||||
print('\nBuilding Native OpenCV header list ...')
|
||||
|
||||
cppHeadersFolder = os.path.join(managerDir, 'sdk/native/jni/include/opencv2')
|
||||
|
||||
modulesFolders = GetImmediateSubdirs(cppHeadersFolder)
|
||||
modules = GetOpenCVModules()
|
||||
|
||||
cppHeaders = []
|
||||
for m in modules:
|
||||
for f in modulesFolders:
|
||||
moduleHeaders = []
|
||||
if f == m:
|
||||
moduleHeaders += GetHeaderFiles(os.path.join(cppHeadersFolder, f))
|
||||
if m == 'flann':
|
||||
flann = os.path.join(cppHeadersFolder, f, 'flann.hpp')
|
||||
moduleHeaders.remove(flann)
|
||||
moduleHeaders.insert(0, flann)
|
||||
cppHeaders += moduleHeaders
|
||||
|
||||
|
||||
cppHeaders += GetHeaderFiles(cppHeadersFolder)
|
||||
headers += cppHeaders
|
||||
|
||||
cHeaders = GetHeaderFiles(os.path.join(managerDir, \
|
||||
'sdk/native/jni/include/opencv'))
|
||||
headers += cHeaders
|
||||
|
||||
headers += GetJavaHHeaders()
|
||||
|
||||
return headers
|
||||
|
||||
if (len(sys.argv) < 3):
|
||||
print("Error: Invalid command line arguments")
|
||||
exit(-1)
|
||||
|
||||
INSTALL_DIRECTORY = sys.argv[1]
|
||||
PROJECT_NAME = sys.argv[2]
|
||||
|
||||
CLASS_PATH = os.path.join(INSTALL_DIRECTORY, "sdk/java/bin/classes")
|
||||
if (not os.path.exists(CLASS_PATH)):
|
||||
print("Error: no java classes found in \"%s\"" % CLASS_PATH)
|
||||
exit(-2)
|
||||
def FindLibraries():
|
||||
libraries = []
|
||||
for lib in targetLibs:
|
||||
libraries.append(os.path.join(managerDir, 'sdk/native/libs', architecture, lib))
|
||||
return libraries
|
||||
|
||||
if (os.environ.has_key("NDK_ROOT")):
|
||||
ANDROID_NDK_PATH = os.environ["NDK_ROOT"];
|
||||
print("Using Android NDK from NDK_ROOT (\"%s\")" % ANDROID_NDK_PATH)
|
||||
|
||||
if (not ANDROID_NDK_PATH):
|
||||
pipe = os.popen("which ndk-build")
|
||||
tmp = str.strip(pipe.readline(), "\n")
|
||||
while(not tmp):
|
||||
tmp = str.strip(pipe.readline(), "\n")
|
||||
pipe.close()
|
||||
ANDROID_NDK_PATH = os.path.split(tmp)[0]
|
||||
print("Using Android NDK from PATH (\"%s\")" % ANDROID_NDK_PATH)
|
||||
|
||||
print("Using Android SDK from \"%s\"" % ANDROID_SDK_PATH)
|
||||
def FindIncludes():
|
||||
includes = [os.path.join(managerDir, 'sdk', 'native', 'jni', 'include'),
|
||||
os.path.join(managerDir, 'sdk', 'native', 'jni', 'include', 'opencv'),
|
||||
os.path.join(managerDir, 'sdk', 'native', 'jni', 'include', 'opencv2')]
|
||||
|
||||
outputFileName = PROJECT_NAME + ".xml"
|
||||
try:
|
||||
outputFile = open(outputFileName, "w")
|
||||
except:
|
||||
print("Error: Cannot open output file \"%s\" for writing" % outputFileName)
|
||||
for inc in systemIncludes:
|
||||
includes.append(os.path.join(NDK_path, inc))
|
||||
|
||||
allJavaClasses = FindClasses(CLASS_PATH, "")
|
||||
if (not allJavaClasses):
|
||||
print("Error: No Java classes found :(")
|
||||
exit(-1)
|
||||
return includes
|
||||
|
||||
if (not os.path.exists(TMP_HEADER_PATH)):
|
||||
os.makedirs(os.path.join(os.getcwd(), TMP_HEADER_PATH))
|
||||
|
||||
print("Generating JNI headers for Java API ...")
|
||||
AndroidJavaDeps = os.path.join(ANDROID_SDK_PATH, "platforms/android-11/android.jar")
|
||||
for currentClass in allJavaClasses:
|
||||
os.system("javah -d %s -classpath %s:%s %s" % (TMP_HEADER_PATH, CLASS_PATH, AndroidJavaDeps, currentClass))
|
||||
|
||||
print("Building JNI headers list ...")
|
||||
jniHeaders = FindHeaders(TMP_HEADER_PATH)
|
||||
#print(jniHeaders)
|
||||
def FilterGCCOptions():
|
||||
gcc = filter(lambda x: not x.startswith(excludedOptionsPrefix), gcc_options)
|
||||
return sorted(gcc)
|
||||
|
||||
print("Building Native OpenCV header list ...")
|
||||
cHeaders = FindHeaders(os.path.join(INSTALL_DIRECTORY, "sdk/native/jni/include/opencv"))
|
||||
cppHeaders = FindHeaders(os.path.join(INSTALL_DIRECTORY, "sdk/native/jni/include/opencv2"))
|
||||
#print(cHeaders)
|
||||
#print(cppHeaders)
|
||||
|
||||
print("Writing config file ...")
|
||||
outputFile.write("<descriptor>\n\n<version>\n\t%s\n</version>\n\n<headers>\n" % PROJECT_NAME)
|
||||
outputFile.write("\t" + "\n\t".join(cHeaders))
|
||||
outputFile.write("\n\t" + "\n\t".join(cppHeaders))
|
||||
outputFile.write("\n\t" + "\n\t".join(jniHeaders))
|
||||
outputFile.write("\n</headers>\n\n")
|
||||
|
||||
includes = [os.path.join(INSTALL_DIRECTORY, "sdk", "native", "jni", "include"),
|
||||
os.path.join(INSTALL_DIRECTORY, "sdk", "native", "jni", "include", "opencv"),
|
||||
os.path.join(INSTALL_DIRECTORY, "sdk", "native", "jni", "include", "opencv2")]
|
||||
def WriteXml(version, headers, includes, libraries):
|
||||
xmlName = version + '.xml'
|
||||
|
||||
for inc in SYS_INCLUDES:
|
||||
includes.append(os.path.join(ANDROID_NDK_PATH, inc))
|
||||
print '\noutput file: ' + xmlName
|
||||
try:
|
||||
xml = open(xmlName, 'w')
|
||||
except:
|
||||
print 'Error: Cannot open output file "%s" for writing' % xmlName
|
||||
quit()
|
||||
|
||||
outputFile.write("<include_paths>\n\t%s\n</include_paths>\n\n" % "\n\t".join(includes))
|
||||
xml.write('<descriptor>')
|
||||
|
||||
libraries = []
|
||||
for lib in TARGET_LIBS:
|
||||
libraries.append(os.path.join(INSTALL_DIRECTORY, "sdk/native/libs", ARCH, lib))
|
||||
xml.write('\n\n<version>')
|
||||
xml.write('\n\t%s' % version)
|
||||
xml.write('\n</version>')
|
||||
|
||||
outputFile.write("<libs>\n\t%s\n</libs>\n\n" % "\n\t".join(libraries))
|
||||
outputFile.write("<gcc_options>\n\t%s\n</gcc_options>\n\n</descriptor>" % GCC_OPTIONS)
|
||||
xml.write('\n\n<headers>')
|
||||
xml.write('\n\t%s' % '\n\t'.join(headers))
|
||||
xml.write('\n</headers>')
|
||||
|
||||
print("done!")
|
||||
xml.write('\n\n<include_paths>')
|
||||
xml.write('\n\t%s' % '\n\t'.join(includes))
|
||||
xml.write('\n</include_paths>')
|
||||
|
||||
# TODO: uncomment when Eigen problem is solved
|
||||
# xml.write('\n\n<include_preamble>')
|
||||
# xml.write('\n\t%s' % '\n\t'.join(preamble))
|
||||
# xml.write('\n</include_preamble>')
|
||||
|
||||
xml.write('\n\n<libs>')
|
||||
xml.write('\n\t%s' % '\n\t'.join(libraries))
|
||||
xml.write('\n</libs>')
|
||||
|
||||
xml.write('\n\n<gcc_options>')
|
||||
xml.write('\n\t%s' % '\n\t'.join(gcc_options))
|
||||
xml.write('\n</gcc_options>')
|
||||
|
||||
xml.write('\n\n</descriptor>')
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
usage = '%prog <OpenCV_Manager install directory> <OpenCV_Manager version>'
|
||||
parser = OptionParser(usage = usage)
|
||||
|
||||
args = parser.parse_args()
|
||||
if 2 != len(args):
|
||||
parser.print_help()
|
||||
quit()
|
||||
|
||||
managerDir = args[1][0]
|
||||
version = args[1][1]
|
||||
|
||||
NDK_path = '/opt/android-ndk-r8c'
|
||||
print '\nUsing Android NDK from "%s"' % NDK_path
|
||||
|
||||
SDK_path = '~/NVPACK/android-sdk-linux'
|
||||
print '\nUsing Android SDK from "%s"' % SDK_path
|
||||
|
||||
headers = FindHeaders()
|
||||
|
||||
includes = FindIncludes()
|
||||
|
||||
libraries = FindLibraries()
|
||||
|
||||
gcc_options = FilterGCCOptions()
|
||||
|
||||
WriteXml(version, headers, includes, libraries)
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
# make target; arch; API level; Android Source Code Root
|
||||
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
|
||||
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_r4.1.1; mips; 14; /home/alexander/Projects/AndroidSource/4.1.1_mips
|
||||
native_camera_r4.2.0; armeabi-v7a; 14; /home/alexander/Projects/AndroidSource/4.2
|
||||
native_camera_r4.2.0; armeabi; 14; /home/alexander/Projects/AndroidSource/4.2
|
||||
native_camera_r4.2.0; x86; 14; /home/alexander/Projects/AndroidSource/4.2
|
||||
native_camera_r4.2.0; mips; 14; /home/alexander/Projects/AndroidSource/4.2
|
||||
|
||||
@@ -7,16 +7,6 @@ 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):
|
||||
@@ -30,7 +20,6 @@ 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)
|
||||
|
||||
|
||||
@@ -5,4 +5,3 @@ mkdir -p build_service
|
||||
cd build_service
|
||||
|
||||
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/ $@ ../..
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ See the "15-puzzle" OpenCV sample for details.
|
||||
super.onResume();
|
||||
|
||||
Log.i(TAG, "Trying to load OpenCV library");
|
||||
if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mOpenCVCallBack))
|
||||
if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_4, this, mOpenCVCallBack))
|
||||
{
|
||||
Log.e(TAG, "Cannot connect to OpenCV Manager");
|
||||
}
|
||||
|
||||
@@ -47,3 +47,7 @@ OpenCV version constants
|
||||
.. data:: OPENCV_VERSION_2_4_3
|
||||
|
||||
OpenCV Library version 2.4.3
|
||||
|
||||
.. data:: OPENCV_VERSION_2_4_4
|
||||
|
||||
OpenCV Library version 2.4.4
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.opencv.engine"
|
||||
android:versionCode="24@ANDROID_PLATFORM_VERSION_CODE@"
|
||||
android:versionName="2.4" >
|
||||
android:versionCode="26@ANDROID_PLATFORM_VERSION_CODE@"
|
||||
android:versionName="2.6" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="@ANDROID_NATIVE_API_LEVEL@" />
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
|
||||
|
||||
@@ -62,3 +62,14 @@ set_target_properties(${engine}_jni PROPERTIES
|
||||
|
||||
get_target_property(engine_lib_location ${engine}_jni LOCATION)
|
||||
add_custom_command(TARGET ${engine}_jni POST_BUILD COMMAND ${CMAKE_STRIP} --strip-unneeded "${engine_lib_location}")
|
||||
|
||||
# native tests
|
||||
add_definitions(-DGTEST_HAS_CLONE=0 -DANDROID -DGTEST_HAS_TR1_TUPLE=0)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-allow-shlib-undefined")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/jni/Tests)
|
||||
file(GLOB engine_test_files "jni/Tests/*.cpp")
|
||||
|
||||
add_executable(opencv_test_engine ${engine_test_files} jni/Tests/gtest/gtest-all.cpp)
|
||||
target_link_libraries(opencv_test_engine z binder log utils android_runtime ${engine} ${engine}_jni)
|
||||
|
||||
|
||||
@@ -15,60 +15,44 @@ using namespace android;
|
||||
|
||||
const int OpenCVEngine::Platform = DetectKnownPlatforms();
|
||||
const int OpenCVEngine::CpuID = GetCpuID();
|
||||
const int OpenCVEngine::KnownVersions[] = {2040000, 2040100, 2040200, 2040300, 2040301, 2040302, 2040400};
|
||||
|
||||
std::set<std::string> OpenCVEngine::InitKnownOpenCVersions()
|
||||
bool OpenCVEngine::ValidateVersion(int version)
|
||||
{
|
||||
std::set<std::string> result;
|
||||
for (size_t i = 0; i < sizeof(KnownVersions)/sizeof(int); i++)
|
||||
if (KnownVersions[i] == version)
|
||||
return true;
|
||||
|
||||
result.insert("240");
|
||||
result.insert("241");
|
||||
result.insert("242");
|
||||
result.insert("243");
|
||||
|
||||
return result;
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::set<std::string> OpenCVEngine::KnownVersions = InitKnownOpenCVersions();
|
||||
|
||||
bool OpenCVEngine::ValidateVersionString(const std::string& version)
|
||||
int OpenCVEngine::NormalizeVersionString(std::string version)
|
||||
{
|
||||
return (KnownVersions.find(version) != KnownVersions.end());
|
||||
}
|
||||
|
||||
std::string OpenCVEngine::NormalizeVersionString(std::string version)
|
||||
{
|
||||
std::string result = "";
|
||||
std::string suffix = "";
|
||||
int result = 0;
|
||||
|
||||
if (version.empty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (('a' == version[version.size()-1]) || ('b' == version[version.size()-1]))
|
||||
{
|
||||
suffix = version[version.size()-1];
|
||||
version.erase(version.size()-1);
|
||||
}
|
||||
|
||||
std::vector<std::string> parts = SplitStringVector(version, '.');
|
||||
|
||||
if (parts.size() >= 2)
|
||||
// Use only 4 digits of the version, i.e. 1.2.3.4.
|
||||
// Other digits will be ignored.
|
||||
if (parts.size() > 4)
|
||||
parts.erase(parts.begin()+4, parts.end());
|
||||
|
||||
int multiplyer = 1000000;
|
||||
for (std::vector<std::string>::const_iterator it = parts.begin(); it != parts.end(); ++it)
|
||||
{
|
||||
if (parts.size() >= 3)
|
||||
{
|
||||
result = parts[0] + parts[1] + parts[2] + suffix;
|
||||
if (!ValidateVersionString(result))
|
||||
result = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = parts[0] + parts[1] + "0" + suffix;
|
||||
if (!ValidateVersionString(result))
|
||||
result = "";
|
||||
}
|
||||
int digit = atoi(it->c_str());
|
||||
result += multiplyer*digit;
|
||||
multiplyer /= 100;
|
||||
}
|
||||
|
||||
if (!ValidateVersion(result))
|
||||
result = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -86,19 +70,19 @@ int32_t OpenCVEngine::GetVersion()
|
||||
String16 OpenCVEngine::GetLibPathByVersion(android::String16 version)
|
||||
{
|
||||
std::string std_version(String8(version).string());
|
||||
std::string norm_version;
|
||||
int norm_version;
|
||||
std::string path;
|
||||
|
||||
LOGD("OpenCVEngine::GetLibPathByVersion(%s) impl", String8(version).string());
|
||||
|
||||
norm_version = NormalizeVersionString(std_version);
|
||||
|
||||
if (!norm_version.empty())
|
||||
if (0 != norm_version)
|
||||
{
|
||||
path = PackageManager->GetPackagePathByVersion(norm_version, Platform, CpuID);
|
||||
if (path.empty())
|
||||
{
|
||||
LOGI("Package OpenCV of version %s is not installed. Try to install it :)", norm_version.c_str());
|
||||
LOGI("Package OpenCV of version \"%s\" (%d) is not installed. Try to install it :)", String8(version).string(), norm_version);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -107,7 +91,7 @@ String16 OpenCVEngine::GetLibPathByVersion(android::String16 version)
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("OpenCV version \"%s\" (%s) is not supported", String8(version).string(), norm_version.c_str());
|
||||
LOGE("OpenCV version \"%s\" (%d) is not supported", String8(version).string(), norm_version);
|
||||
}
|
||||
|
||||
return String16(path.c_str());
|
||||
@@ -116,11 +100,11 @@ String16 OpenCVEngine::GetLibPathByVersion(android::String16 version)
|
||||
android::String16 OpenCVEngine::GetLibraryList(android::String16 version)
|
||||
{
|
||||
std::string std_version = String8(version).string();
|
||||
std::string norm_version;
|
||||
int norm_version;
|
||||
String16 result;
|
||||
norm_version = NormalizeVersionString(std_version);
|
||||
|
||||
if (!norm_version.empty())
|
||||
if (0 != norm_version)
|
||||
{
|
||||
std::string tmp = PackageManager->GetPackagePathByVersion(norm_version, Platform, CpuID);
|
||||
if (!tmp.empty())
|
||||
@@ -156,12 +140,12 @@ android::String16 OpenCVEngine::GetLibraryList(android::String16 version)
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGI("Package OpenCV of version %s is not installed. Try to install it :)", norm_version.c_str());
|
||||
LOGI("Package OpenCV of version \"%s\" (%d) is not installed. Try to install it :)", std_version.c_str(), norm_version);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("OpenCV version \"%s\" is not supported", norm_version.c_str());
|
||||
LOGE("OpenCV version \"%s\" is not supported", std_version.c_str());
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -170,21 +154,21 @@ android::String16 OpenCVEngine::GetLibraryList(android::String16 version)
|
||||
bool OpenCVEngine::InstallVersion(android::String16 version)
|
||||
{
|
||||
std::string std_version = String8(version).string();
|
||||
std::string norm_version;
|
||||
int norm_version;
|
||||
bool result = false;
|
||||
|
||||
LOGD("OpenCVEngine::InstallVersion() begin");
|
||||
|
||||
norm_version = NormalizeVersionString(std_version);
|
||||
|
||||
if (!norm_version.empty())
|
||||
if (0 != norm_version)
|
||||
{
|
||||
LOGD("PackageManager->InstallVersion call");
|
||||
result = PackageManager->InstallVersion(norm_version, Platform, CpuID);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("OpenCV version \"%s\" is not supported", norm_version.c_str());
|
||||
LOGE("OpenCV version \"%s\" (%d) is not supported", std_version.c_str(), norm_version);
|
||||
}
|
||||
|
||||
LOGD("OpenCVEngine::InstallVersion() end");
|
||||
|
||||
@@ -23,16 +23,15 @@ public:
|
||||
|
||||
protected:
|
||||
IPackageManager* PackageManager;
|
||||
static const std::set<std::string> KnownVersions;
|
||||
static const int KnownVersions[];
|
||||
|
||||
OpenCVEngine();
|
||||
static std::set<std::string> InitKnownOpenCVersions();
|
||||
bool ValidateVersionString(const std::string& version);
|
||||
std::string NormalizeVersionString(std::string version);
|
||||
bool ValidateVersion(int version);
|
||||
int NormalizeVersionString(std::string version);
|
||||
bool FixPermissions(const std::string& path);
|
||||
|
||||
static const int Platform;
|
||||
static const int CpuID;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -40,13 +40,16 @@ bool JavaBasedPackageManager::InstallPackage(const PackageInfo& package)
|
||||
if (!jmethod)
|
||||
{
|
||||
LOGE("MarketConnector::GetAppFormMarket method was not found!");
|
||||
jenv->DeleteLocalRef(jclazz);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGD("Calling java package manager with package name %s\n", package.GetFullName().c_str());
|
||||
jobject jpkgname = jenv->NewStringUTF(package.GetFullName().c_str());
|
||||
bool result = jenv->CallNonvirtualBooleanMethod(JavaPackageManager, jclazz, jmethod, jpkgname);
|
||||
|
||||
jenv->DeleteLocalRef(jpkgname);
|
||||
jenv->DeleteLocalRef(jclazz);
|
||||
|
||||
if (self_attached)
|
||||
{
|
||||
@@ -72,7 +75,6 @@ vector<PackageInfo> JavaBasedPackageManager::GetInstalledPackages()
|
||||
JavaContext->AttachCurrentThread(&jenv, NULL);
|
||||
}
|
||||
|
||||
LOGD("GetObjectClass call");
|
||||
jclass jclazz = jenv->GetObjectClass(JavaPackageManager);
|
||||
if (!jclazz)
|
||||
{
|
||||
@@ -80,15 +82,14 @@ vector<PackageInfo> JavaBasedPackageManager::GetInstalledPackages()
|
||||
return result;
|
||||
}
|
||||
|
||||
LOGD("GetMethodID call");
|
||||
jmethodID jmethod = jenv->GetMethodID(jclazz, "GetInstalledOpenCVPackages", "()[Landroid/content/pm/PackageInfo;");
|
||||
if (!jmethod)
|
||||
{
|
||||
LOGE("MarketConnector::GetInstalledOpenCVPackages method was not found!");
|
||||
jenv->DeleteLocalRef(jclazz);
|
||||
return result;
|
||||
}
|
||||
|
||||
LOGD("Java package manager call");
|
||||
jobjectArray jpkgs = static_cast<jobjectArray>(jenv->CallNonvirtualObjectMethod(JavaPackageManager, jclazz, jmethod));
|
||||
jsize size = jenv->GetArrayLength(jpkgs);
|
||||
|
||||
@@ -100,13 +101,15 @@ vector<PackageInfo> JavaBasedPackageManager::GetInstalledPackages()
|
||||
{
|
||||
jobject jtmp = jenv->GetObjectArrayElement(jpkgs, i);
|
||||
PackageInfo tmp = ConvertPackageFromJava(jtmp, jenv);
|
||||
jenv->DeleteLocalRef(jtmp);
|
||||
|
||||
if (tmp.IsValid())
|
||||
result.push_back(tmp);
|
||||
|
||||
jenv->DeleteLocalRef(jtmp);
|
||||
}
|
||||
|
||||
jenv->DeleteLocalRef(jpkgs);
|
||||
jenv->DeleteLocalRef(jclazz);
|
||||
|
||||
if (self_attached)
|
||||
{
|
||||
@@ -118,10 +121,21 @@ vector<PackageInfo> JavaBasedPackageManager::GetInstalledPackages()
|
||||
return result;
|
||||
}
|
||||
|
||||
static jint GetAndroidVersion(JNIEnv* jenv)
|
||||
{
|
||||
jclass jclazz = jenv->FindClass("android/os/Build$VERSION");
|
||||
jfieldID jfield = jenv->GetStaticFieldID(jclazz, "SDK_INT", "I");
|
||||
jint api_level = jenv->GetStaticIntField(jclazz, jfield);
|
||||
jenv->DeleteLocalRef(jclazz);
|
||||
|
||||
return api_level;
|
||||
}
|
||||
|
||||
// IMPORTANT: This method can be called only if thread is attached to Dalvik
|
||||
PackageInfo JavaBasedPackageManager::ConvertPackageFromJava(jobject package, JNIEnv* jenv)
|
||||
{
|
||||
jclass jclazz = jenv->GetObjectClass(package);
|
||||
|
||||
jfieldID jfield = jenv->GetFieldID(jclazz, "packageName", "Ljava/lang/String;");
|
||||
jstring jnameobj = static_cast<jstring>(jenv->GetObjectField(package, jfield));
|
||||
const char* jnamestr = jenv->GetStringUTFChars(jnameobj, NULL);
|
||||
@@ -134,22 +148,27 @@ PackageInfo JavaBasedPackageManager::ConvertPackageFromJava(jobject package, JNI
|
||||
string verison(jversionstr);
|
||||
jenv->DeleteLocalRef(jversionobj);
|
||||
|
||||
jenv->DeleteLocalRef(jclazz);
|
||||
|
||||
static const jint api_level = GetAndroidVersion(jenv);
|
||||
string path;
|
||||
jclazz = jenv->FindClass("android/os/Build$VERSION");
|
||||
jfield = jenv->GetStaticFieldID(jclazz, "SDK_INT", "I");
|
||||
jint api_level = jenv->GetStaticIntField(jclazz, jfield);
|
||||
if (api_level > 8)
|
||||
{
|
||||
jclazz = jenv->GetObjectClass(package);
|
||||
jfield = jenv->GetFieldID(jclazz, "applicationInfo", "Landroid/content/pm/ApplicationInfo;");
|
||||
jobject japp_info = jenv->GetObjectField(package, jfield);
|
||||
jenv->DeleteLocalRef(jclazz);
|
||||
|
||||
jclazz = jenv->GetObjectClass(japp_info);
|
||||
jfield = jenv->GetFieldID(jclazz, "nativeLibraryDir", "Ljava/lang/String;");
|
||||
jstring jpathobj = static_cast<jstring>(jenv->GetObjectField(japp_info, jfield));
|
||||
const char* jpathstr = jenv->GetStringUTFChars(jpathobj, NULL);
|
||||
path = string(jpathstr);
|
||||
jenv->ReleaseStringUTFChars(jpathobj, jpathstr);
|
||||
|
||||
jenv->DeleteLocalRef(japp_info);
|
||||
jenv->DeleteLocalRef(jpathobj);
|
||||
jenv->DeleteLocalRef(jclazz);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -19,4 +19,4 @@ private:
|
||||
|
||||
JavaBasedPackageManager();
|
||||
PackageInfo ConvertPackageFromJava(jobject package, JNIEnv* jenv);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -11,22 +11,24 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
set<string> CommonPackageManager::GetInstalledVersions()
|
||||
vector<int> CommonPackageManager::GetInstalledVersions()
|
||||
{
|
||||
set<string> result;
|
||||
vector<int> result;
|
||||
vector<PackageInfo> installed_packages = GetInstalledPackages();
|
||||
|
||||
for (vector<PackageInfo>::const_iterator it = installed_packages.begin(); it != installed_packages.end(); ++it)
|
||||
result.resize(installed_packages.size());
|
||||
|
||||
for (size_t i = 0; i < installed_packages.size(); i++)
|
||||
{
|
||||
string version = it->GetVersion();
|
||||
assert(!version.empty());
|
||||
result.insert(version);
|
||||
int version = installed_packages[i].GetVersion();
|
||||
assert(version);
|
||||
result[i] = version;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CommonPackageManager::CheckVersionInstalled(const std::string& version, int platform, int cpu_id)
|
||||
bool CommonPackageManager::CheckVersionInstalled(int version, int platform, int cpu_id)
|
||||
{
|
||||
bool result = false;
|
||||
LOGD("CommonPackageManager::CheckVersionInstalled() begin");
|
||||
@@ -48,14 +50,14 @@ bool CommonPackageManager::CheckVersionInstalled(const std::string& version, int
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CommonPackageManager::InstallVersion(const std::string& version, int platform, int cpu_id)
|
||||
bool CommonPackageManager::InstallVersion(int version, int platform, int cpu_id)
|
||||
{
|
||||
LOGD("CommonPackageManager::InstallVersion() begin");
|
||||
PackageInfo package(version, platform, cpu_id);
|
||||
return InstallPackage(package);
|
||||
}
|
||||
|
||||
string CommonPackageManager::GetPackagePathByVersion(const std::string& version, int platform, int cpu_id)
|
||||
string CommonPackageManager::GetPackagePathByVersion(int version, int platform, int cpu_id)
|
||||
{
|
||||
string result;
|
||||
PackageInfo target_package(version, platform, cpu_id);
|
||||
@@ -64,7 +66,7 @@ string CommonPackageManager::GetPackagePathByVersion(const std::string& version,
|
||||
|
||||
for (vector<PackageInfo>::iterator it = all_packages.begin(); it != all_packages.end(); ++it)
|
||||
{
|
||||
LOGD("Check version \"%s\" compatibility with \"%s\"\n", version.c_str(), it->GetVersion().c_str());
|
||||
LOGD("Check version \"%d\" compatibility with \"%d\"\n", version, it->GetVersion());
|
||||
if (IsVersionCompatible(version, it->GetVersion()))
|
||||
{
|
||||
LOGD("Compatible");
|
||||
@@ -78,17 +80,21 @@ string CommonPackageManager::GetPackagePathByVersion(const std::string& version,
|
||||
|
||||
if (!packages.empty())
|
||||
{
|
||||
int OptRating = -1;
|
||||
std::string OptVersion = "";
|
||||
std::vector<std::pair<int, int> >& group = CommonPackageManager::ArmRating;
|
||||
int platform_group = 0;
|
||||
|
||||
if ((cpu_id & ARCH_X86) || (cpu_id & ARCH_X64))
|
||||
group = CommonPackageManager::IntelRating;
|
||||
platform_group = 1;
|
||||
|
||||
int HardwareRating = GetHardwareRating(platform, cpu_id, group);
|
||||
LOGD("Current hardware platform rating %d for (%d,%d)", HardwareRating, platform, cpu_id);
|
||||
if (cpu_id & ARCH_MIPS)
|
||||
platform_group = 2;
|
||||
|
||||
if (-1 == HardwareRating)
|
||||
int opt_rating = -1;
|
||||
int opt_version = 0;
|
||||
|
||||
const int hardware_rating = GetHardwareRating(platform, cpu_id, ArchRatings[platform_group]);
|
||||
LOGD("Current hardware platform rating %d for (%d,%d)", hardware_rating, platform, cpu_id);
|
||||
|
||||
if (-1 == hardware_rating)
|
||||
{
|
||||
LOGE("Cannot calculate rating for current hardware platform!");
|
||||
}
|
||||
@@ -97,26 +103,38 @@ string CommonPackageManager::GetPackagePathByVersion(const std::string& version,
|
||||
vector<PackageInfo>::iterator found = packages.end();
|
||||
for (vector<PackageInfo>::iterator it = packages.begin(); it != packages.end(); ++it)
|
||||
{
|
||||
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))
|
||||
int package_group = 0;
|
||||
|
||||
if ((it->GetCpuID() & ARCH_X86) || (it->GetCpuID() & ARCH_X64))
|
||||
package_group = 1;
|
||||
|
||||
if (it->GetCpuID() & ARCH_MIPS)
|
||||
package_group = 2;
|
||||
|
||||
if (package_group != platform_group)
|
||||
continue;
|
||||
|
||||
const int package_rating = GetHardwareRating(it->GetPlatform(), it->GetCpuID(), ArchRatings[package_group]);
|
||||
|
||||
LOGD("Package \"%s\" rating %d for (%d,%d)", it->GetFullName().c_str(), package_rating, it->GetPlatform(), it->GetCpuID());
|
||||
if ((package_rating >= 0) && (package_rating <= hardware_rating))
|
||||
{
|
||||
if (((it->GetVersion() >= OptVersion) && (PackageRating >= OptRating)) || (it->GetVersion() > OptVersion))
|
||||
if (((it->GetVersion() >= opt_version) && (package_rating >= opt_rating)) || (it->GetVersion() > opt_version))
|
||||
{
|
||||
OptRating = PackageRating;
|
||||
OptVersion = it->GetVersion();
|
||||
opt_rating = package_rating;
|
||||
opt_version = it->GetVersion();
|
||||
found = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((-1 != OptRating) && (packages.end() != found))
|
||||
if ((-1 != opt_rating) && (packages.end() != found))
|
||||
{
|
||||
result = found->GetInstalationPath();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGI("Found package is incompatible with current hardware platform");
|
||||
LOGI("No compatible packages found!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,20 +142,13 @@ string CommonPackageManager::GetPackagePathByVersion(const std::string& version,
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CommonPackageManager::IsVersionCompatible(const std::string& target_version, const std::string& package_version)
|
||||
bool CommonPackageManager::IsVersionCompatible(int target_version, int package_version)
|
||||
{
|
||||
assert (target_version.size() == 3);
|
||||
assert (package_version.size() == 3);
|
||||
|
||||
bool result = false;
|
||||
assert(target_version);
|
||||
assert(package_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;
|
||||
}
|
||||
|
||||
return result;
|
||||
return ( (package_version/10000 == target_version/10000) && (package_version%10000 >= target_version%10000) );
|
||||
}
|
||||
|
||||
int CommonPackageManager::GetHardwareRating(int platform, int cpu_id, const std::vector<std::pair<int, int> >& group)
|
||||
@@ -151,10 +162,13 @@ int CommonPackageManager::GetHardwareRating(int platform, int cpu_id, const std:
|
||||
else
|
||||
{
|
||||
// Calculate rating for Arm
|
||||
LOGD("!!! Calculating rating for ARM\n");
|
||||
for (size_t i = 0; i < group.size(); i++)
|
||||
{
|
||||
LOGD("Checking (%d, %d) against (%d,%d)\n", group[i].first, group[i].second, platform, cpu_id);
|
||||
if (group[i] == std::pair<int, int>(platform, cpu_id))
|
||||
{
|
||||
LOGD("Rating found: %d\n", i);
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
@@ -187,21 +201,27 @@ std::vector<std::pair<int, int> > CommonPackageManager::InitArmRating()
|
||||
return result;
|
||||
}
|
||||
|
||||
// Stub for Intel platforms rating initialization. Common package for all Intel based devices is used now
|
||||
std::vector<std::pair<int, int> > CommonPackageManager::InitIntelRating()
|
||||
{
|
||||
std::vector<std::pair<int, int> > result;
|
||||
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_X64));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSSE3));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSE2));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSE));
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_X86));
|
||||
return result;
|
||||
}
|
||||
|
||||
// Stub for MIPS platforms rating initialization. Common package for all MIPS based devices is used now
|
||||
std::vector<std::pair<int, int> > CommonPackageManager::InitMipsRating()
|
||||
{
|
||||
std::vector<std::pair<int, int> > result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::pair<int, int> > CommonPackageManager::IntelRating = CommonPackageManager::InitIntelRating();
|
||||
std::vector<std::pair<int, int> > CommonPackageManager::ArmRating = InitArmRating();
|
||||
const std::vector<std::pair<int, int> > CommonPackageManager::ArchRatings[] = {
|
||||
CommonPackageManager::InitArmRating(),
|
||||
CommonPackageManager::InitIntelRating(),
|
||||
CommonPackageManager::InitMipsRating()
|
||||
};
|
||||
|
||||
CommonPackageManager::~CommonPackageManager()
|
||||
{
|
||||
|
||||
@@ -3,27 +3,26 @@
|
||||
|
||||
#include "IPackageManager.h"
|
||||
#include "PackageInfo.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class CommonPackageManager: public IPackageManager
|
||||
{
|
||||
public:
|
||||
std::set<std::string> GetInstalledVersions();
|
||||
bool CheckVersionInstalled(const std::string& version, int platform, int cpu_id);
|
||||
bool InstallVersion(const std::string& version, int platform, int cpu_id);
|
||||
std::string GetPackagePathByVersion(const std::string& version, int platform, int cpu_id);
|
||||
std::vector<int> GetInstalledVersions();
|
||||
bool CheckVersionInstalled(int version, int platform, int cpu_id);
|
||||
bool InstallVersion(int version, int platform, int cpu_id);
|
||||
std::string GetPackagePathByVersion(int version, int platform, int cpu_id);
|
||||
virtual ~CommonPackageManager();
|
||||
|
||||
protected:
|
||||
static std::vector<std::pair<int, int> > ArmRating;
|
||||
static std::vector<std::pair<int, int> > IntelRating;
|
||||
static const std::vector<std::pair<int, int> > ArchRatings[];
|
||||
|
||||
static std::vector<std::pair<int, int> > InitArmRating();
|
||||
static std::vector<std::pair<int, int> > InitIntelRating();
|
||||
static std::vector<std::pair<int, int> > InitMipsRating();
|
||||
|
||||
bool IsVersionCompatible(const std::string& target_version, const std::string& package_version);
|
||||
bool IsVersionCompatible(int target_version, int package_version);
|
||||
int GetHardwareRating(int platform, int cpu_id, const std::vector<std::pair<int, int> >& group);
|
||||
|
||||
virtual bool InstallPackage(const PackageInfo& package) = 0;
|
||||
@@ -31,4 +30,4 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -124,14 +124,29 @@ inline int SplitIntelFeatures(const vector<string>& features)
|
||||
return result;
|
||||
}
|
||||
|
||||
inline string SplitVersion(const vector<string>& features, const string& package_version)
|
||||
inline int SplitVersion(const vector<string>& features, const string& package_version)
|
||||
{
|
||||
string result;
|
||||
int result = 0;
|
||||
|
||||
if ((features.size() > 1) && ('v' == features[1][0]))
|
||||
{
|
||||
result = features[1].substr(1);
|
||||
result += SplitStringVector(package_version, '.')[0];
|
||||
// Taking major and minor mart of library version from package name
|
||||
string tmp1 = features[1].substr(1);
|
||||
result += atoi(tmp1.substr(0,1).c_str())*1000000 + atoi(tmp1.substr(1,1).c_str())*10000;
|
||||
|
||||
// Taking release and build number from package revision
|
||||
vector<string> tmp2 = SplitStringVector(package_version, '.');
|
||||
if (tmp2.size() == 2)
|
||||
{
|
||||
// the 2nd digit is revision
|
||||
result += atoi(tmp2[0].c_str())*100 + 00;
|
||||
}
|
||||
else
|
||||
{
|
||||
// the 2nd digit is part of library version
|
||||
// the 3rd digit is revision
|
||||
result += atoi(tmp2[0].c_str())*100 + atoi(tmp2[1].c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -186,19 +201,26 @@ inline int SplitPlatfrom(const vector<string>& features)
|
||||
* Second part is version. Version starts from "v" symbol. After "v" symbol version nomber without dot symbol added.
|
||||
* If platform is known third part is platform name
|
||||
* If platform is unknown it is defined by hardware capabilities using pattern: <arch>_<floating point and vectorization features>_<other features>
|
||||
* Example: armv7_neon, armv5_vfpv3
|
||||
* Example: armv7_neon
|
||||
*/
|
||||
PackageInfo::PackageInfo(const string& version, int platform, int cpu_id, std::string install_path):
|
||||
Version(version),
|
||||
Platform(platform),
|
||||
CpuID(cpu_id),
|
||||
InstallPath("")
|
||||
PackageInfo::PackageInfo(int version, int platform, int cpu_id, std::string install_path):
|
||||
Version(version),
|
||||
Platform(platform),
|
||||
CpuID(cpu_id),
|
||||
InstallPath("")
|
||||
{
|
||||
#ifndef __SUPPORT_TEGRA3
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
#endif
|
||||
|
||||
FullName = BasePackageName + "_v" + Version.substr(0, Version.size()-1);
|
||||
int major_version = version/1000000;
|
||||
int minor_version = version/10000 - major_version*100;
|
||||
|
||||
char tmp[32];
|
||||
|
||||
sprintf(tmp, "%d%d", major_version, minor_version);
|
||||
|
||||
FullName = BasePackageName + std::string("_v") + std::string(tmp);
|
||||
if (PLATFORM_UNKNOWN != Platform)
|
||||
{
|
||||
FullName += string("_") + JoinPlatform(platform);
|
||||
@@ -296,7 +318,7 @@ InstallPath("")
|
||||
else
|
||||
{
|
||||
LOGD("PackageInfo::PackageInfo: package arch unknown");
|
||||
Version.clear();
|
||||
Version = 0;
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
}
|
||||
@@ -304,7 +326,7 @@ InstallPath("")
|
||||
else
|
||||
{
|
||||
LOGD("PackageInfo::PackageInfo: package arch unknown");
|
||||
Version.clear();
|
||||
Version = 0;
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
}
|
||||
@@ -371,7 +393,7 @@ InstallPath(install_path)
|
||||
{
|
||||
LOGI("Info library not found in package");
|
||||
LOGI("OpenCV Manager package does not contain any verison of OpenCV library");
|
||||
Version.clear();
|
||||
Version = 0;
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
return;
|
||||
@@ -383,7 +405,7 @@ InstallPath(install_path)
|
||||
if (!features.empty() && (BasePackageName == features[0]))
|
||||
{
|
||||
Version = SplitVersion(features, package_version);
|
||||
if (Version.empty())
|
||||
if (0 == Version)
|
||||
{
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
@@ -410,7 +432,7 @@ InstallPath(install_path)
|
||||
if (features.size() < 3)
|
||||
{
|
||||
LOGD("It is not OpenCV library package for this platform");
|
||||
Version.clear();
|
||||
Version = 0;
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
return;
|
||||
@@ -444,7 +466,7 @@ InstallPath(install_path)
|
||||
else
|
||||
{
|
||||
LOGD("It is not OpenCV library package for this platform");
|
||||
Version.clear();
|
||||
Version = 0;
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
return;
|
||||
@@ -454,7 +476,7 @@ InstallPath(install_path)
|
||||
else
|
||||
{
|
||||
LOGD("It is not OpenCV library package for this platform");
|
||||
Version.clear();
|
||||
Version = 0;
|
||||
CpuID = ARCH_UNKNOWN;
|
||||
Platform = PLATFORM_UNKNOWN;
|
||||
return;
|
||||
@@ -463,7 +485,7 @@ InstallPath(install_path)
|
||||
|
||||
bool PackageInfo::IsValid() const
|
||||
{
|
||||
return !(Version.empty() && (PLATFORM_UNKNOWN == Platform) && (ARCH_UNKNOWN == CpuID));
|
||||
return !((0 == Version) && (PLATFORM_UNKNOWN == Platform) && (ARCH_UNKNOWN == CpuID));
|
||||
}
|
||||
|
||||
int PackageInfo::GetPlatform() const
|
||||
@@ -481,7 +503,7 @@ string PackageInfo::GetFullName() const
|
||||
return FullName;
|
||||
}
|
||||
|
||||
string PackageInfo::GetVersion() const
|
||||
int PackageInfo::GetVersion() const
|
||||
{
|
||||
return Version;
|
||||
}
|
||||
@@ -494,4 +516,4 @@ string PackageInfo::GetInstalationPath() const
|
||||
bool PackageInfo::operator==(const PackageInfo& package) const
|
||||
{
|
||||
return (package.FullName == FullName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
class PackageInfo
|
||||
{
|
||||
public:
|
||||
PackageInfo(const std::string& version, int platform, int cpu_id, std::string install_path = "/data/data/");
|
||||
PackageInfo(int version, int platform, int cpu_id, std::string install_path = "/data/data/");
|
||||
PackageInfo(const std::string& fullname, const std::string& install_path, std::string package_version = "0.0");
|
||||
std::string GetFullName() const;
|
||||
std::string GetVersion() const;
|
||||
int GetVersion() const;
|
||||
int GetPlatform() const;
|
||||
int GetCpuID() const;
|
||||
std::string GetInstalationPath() const;
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
|
||||
protected:
|
||||
static std::map<int, std::string> InitPlatformNameMap();
|
||||
std::string Version;
|
||||
int Version;
|
||||
int Platform;
|
||||
int CpuID;
|
||||
std::string FullName;
|
||||
@@ -51,4 +51,4 @@ protected:
|
||||
static const std::string BasePackageName;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -111,7 +111,6 @@ TEST(Split, SplitMultiElementString)
|
||||
TEST(CpuCount, CheckNonZero)
|
||||
{
|
||||
EXPECT_TRUE(GetProcessorCount() != 0);
|
||||
EXPECT_TRUE(a.find("") == a.end());
|
||||
}
|
||||
|
||||
TEST(GetCpuInfo, GetCpuInfo)
|
||||
@@ -127,7 +126,7 @@ TEST(CpuID, CheckNotEmpy)
|
||||
EXPECT_NE(0, cpu_id);
|
||||
}
|
||||
|
||||
#ifdef __i386__
|
||||
#if defined(__i386__)
|
||||
TEST(CpuID, CheckX86)
|
||||
{
|
||||
int cpu_id = GetCpuID();
|
||||
@@ -139,14 +138,14 @@ TEST(CpuID, CheckSSE2)
|
||||
int cpu_id = GetCpuID();
|
||||
EXPECT_TRUE(cpu_id & FEATURES_HAS_SSE2);
|
||||
}
|
||||
#elseif __mips
|
||||
#ifdef __SUPPORT_MIPS
|
||||
TEST(CpuID, CheckMips)
|
||||
{
|
||||
#elif defined(__mips)
|
||||
#ifdef __SUPPORT_MIPS
|
||||
TEST(CpuID, CheckMips)
|
||||
{
|
||||
int cpu_id = GetCpuID();
|
||||
EXPECT_TRUE(cpu_id & ARCH_MIPS);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
TEST(TegraDetector, Detect)
|
||||
{
|
||||
@@ -175,4 +174,4 @@ TEST(PlatfromDetector, CheckTegra)
|
||||
{
|
||||
EXPECT_NE(PLATFORM_UNKNOWN, DetectKnownPlatforms());
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -69,7 +69,7 @@ TEST(OpenCVEngineTest, GetPathForExecHWExistVersion)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion("240", PLATFORM_UNKNOWN, ARCH_X86);
|
||||
Starter.PackageManager->InstallVersion(2040000, PLATFORM_UNKNOWN, ARCH_X86);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4"));
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v24_x86/lib", String8(result).string());
|
||||
@@ -79,7 +79,7 @@ TEST(OpenCVEngineTest, GetPathForExecHWOldVersion)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion("242", PLATFORM_UNKNOWN, ARCH_X86);
|
||||
Starter.PackageManager->InstallVersion(2040200, PLATFORM_UNKNOWN, ARCH_X86);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4.1"));
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v24_x86/lib", String8(result).string());
|
||||
@@ -89,7 +89,7 @@ TEST(OpenCVEngineTest, GetPathForExecHWNewVersion)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion("241", PLATFORM_UNKNOWN, ARCH_X86);
|
||||
Starter.PackageManager->InstallVersion(2040100, PLATFORM_UNKNOWN, ARCH_X86);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4.2"));
|
||||
EXPECT_EQ(0, result.size());
|
||||
@@ -100,7 +100,7 @@ TEST(OpenCVEngineTest, GetPathForExecHWExistVersion)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion("240", PLATFORM_UNKNOWN, ARCH_MIPS);
|
||||
Starter.PackageManager->InstallVersion(2040000, PLATFORM_UNKNOWN, ARCH_MIPS);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4"));
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v24_mips/lib", String8(result).string());
|
||||
@@ -110,7 +110,7 @@ TEST(OpenCVEngineTest, GetPathForExecHWOldVersion)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion("242", PLATFORM_UNKNOWN, ARCH_MIPS);
|
||||
Starter.PackageManager->InstallVersion(2040200, PLATFORM_UNKNOWN, ARCH_MIPS);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4.1"));
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v24_mips/lib", String8(result).string());
|
||||
@@ -120,7 +120,7 @@ TEST(OpenCVEngineTest, GetPathForExecHWNewVersion)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion("241", PLATFORM_UNKNOWN, ARCH_MIPS);
|
||||
Starter.PackageManager->InstallVersion(2040100, PLATFORM_UNKNOWN, ARCH_MIPS);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4.2"));
|
||||
EXPECT_EQ(0, result.size());
|
||||
@@ -131,7 +131,7 @@ TEST(OpenCVEngineTest, GetPathForExecHWExistVersion)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion("240", PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_NEON);
|
||||
Starter.PackageManager->InstallVersion(2040000, PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4"));
|
||||
#ifdef __SUPPORT_TEGRA3
|
||||
@@ -149,7 +149,7 @@ TEST(OpenCVEngineTest, GetPathForExecHWOldVersion)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion("242", PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_NEON);
|
||||
Starter.PackageManager->InstallVersion(2040200, PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4.1"));
|
||||
#ifdef __SUPPORT_TEGRA3
|
||||
@@ -167,7 +167,7 @@ TEST(OpenCVEngineTest, GetPathForExecHWNewVersion)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion("241", PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_NEON);
|
||||
Starter.PackageManager->InstallVersion(2040100, PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_NEON);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4.2"));
|
||||
EXPECT_EQ(0, result.size());
|
||||
@@ -177,7 +177,7 @@ TEST(OpenCVEngineTest, GetPathForCompatiblePackage1)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion("242", PLATFORM_UNKNOWN, ARCH_ARMv5);
|
||||
Starter.PackageManager->InstallVersion(2040200, PLATFORM_UNKNOWN, ARCH_ARMv5);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4"));
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v24_armv5/lib", String8(result).string());
|
||||
@@ -187,7 +187,7 @@ TEST(OpenCVEngineTest, GetPathForCompatiblePackage2)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion("242", PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_NEON);
|
||||
Starter.PackageManager->InstallVersion(2040200, PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4"));
|
||||
#ifdef __SUPPORT_TEGRA3
|
||||
@@ -218,6 +218,66 @@ TEST(OpenCVEngineTest, InstallAndGetVersion)
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(OpenCVEngineTest, GetPathFor2_4_2)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion(2040200, PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4.2"));
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v24_armv7a/lib", String8(result).string());
|
||||
}
|
||||
|
||||
TEST(OpenCVEngineTest, GetPathFor2_4_3)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion(2040300, PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4.3"));
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v24_armv7a/lib", String8(result).string());
|
||||
}
|
||||
|
||||
TEST(OpenCVEngineTest, GetPathFor2_4_3_1)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion(2040301, PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4.3.1"));
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v24_armv7a/lib", String8(result).string());
|
||||
}
|
||||
|
||||
TEST(OpenCVEngineTest, GetPathFor2_4_3_2)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion(2040302, PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4.3.2"));
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v24_armv7a/lib", String8(result).string());
|
||||
}
|
||||
|
||||
TEST(OpenCVEngineTest, GetPathFor2_4_4)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion(2040400, PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4.4"));
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v24_armv7a/lib", String8(result).string());
|
||||
}
|
||||
|
||||
TEST(OpenCVEngineTest, GetPathFor2_4_5)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion(2040500, PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4.5"));
|
||||
EXPECT_EQ(0, result.size()); // 2.4.5 is not published yet
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __i386__
|
||||
@@ -225,7 +285,7 @@ TEST(OpenCVEngineTest, GetPathForInCompatiblePackage1)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion("242", PLATFORM_UNKNOWN, ARCH_X64);
|
||||
Starter.PackageManager->InstallVersion(2040200, PLATFORM_UNKNOWN, ARCH_X64);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4"));
|
||||
EXPECT_EQ(0, result.size());
|
||||
@@ -235,7 +295,7 @@ TEST(OpenCVEngineTest, GetPathForInCompatiblePackage1)
|
||||
{
|
||||
sp<IOpenCVEngine> Engine = InitConnect();
|
||||
Starter.PackageManager->InstalledPackages.clear();
|
||||
Starter.PackageManager->InstallVersion("242", PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
Starter.PackageManager->InstallVersion(2040200, PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.4"));
|
||||
EXPECT_EQ(0, result.size());
|
||||
@@ -248,4 +308,4 @@ TEST(OpenCVEngineTest, GetPathForUnExistVersion)
|
||||
EXPECT_FALSE(NULL == Engine.get());
|
||||
String16 result = Engine->GetLibPathByVersion(String16("2.5"));
|
||||
EXPECT_EQ(0, result.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@ using namespace std;
|
||||
|
||||
TEST(PackageInfo, FullNameArmv7)
|
||||
{
|
||||
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
PackageInfo info(2030000, PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
string name = info.GetFullName();
|
||||
EXPECT_STREQ("org.opencv.lib_v23_armv7a", name.c_str());
|
||||
}
|
||||
|
||||
TEST(PackageInfo, FullNameArmv7Neon)
|
||||
{
|
||||
PackageInfo info("241", PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON);
|
||||
PackageInfo info(2040100, PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON);
|
||||
string name = info.GetFullName();
|
||||
#ifdef __SUPPORT_ARMEABI_V7A_FEATURES
|
||||
EXPECT_STREQ("org.opencv.lib_v24_armv7a_neon", name.c_str());
|
||||
@@ -29,14 +29,14 @@ TEST(PackageInfo, FullNameArmv7Neon)
|
||||
|
||||
TEST(PackageInfo, FullNameArmv7VFPv3)
|
||||
{
|
||||
PackageInfo info("233", PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3);
|
||||
PackageInfo info(2030300, PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3);
|
||||
string name = info.GetFullName();
|
||||
EXPECT_STREQ("org.opencv.lib_v23_armv7a", name.c_str());
|
||||
}
|
||||
|
||||
TEST(PackageInfo, FullNameArmv7VFPv3Neon)
|
||||
{
|
||||
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON);
|
||||
PackageInfo info(2030000, PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON);
|
||||
string name = info.GetFullName();
|
||||
#ifdef __SUPPORT_ARMEABI_V7A_FEATURES
|
||||
EXPECT_STREQ("org.opencv.lib_v23_armv7a_neon", name.c_str());
|
||||
@@ -47,21 +47,21 @@ TEST(PackageInfo, FullNameArmv7VFPv3Neon)
|
||||
|
||||
TEST(PackageInfo, FullNameArmv5)
|
||||
{
|
||||
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv5);
|
||||
PackageInfo info(2030000, PLATFORM_UNKNOWN, ARCH_ARMv5);
|
||||
string name = info.GetFullName();
|
||||
EXPECT_STREQ("org.opencv.lib_v23_armv5", name.c_str());
|
||||
}
|
||||
|
||||
TEST(PackageInfo, FullNameArmv6)
|
||||
{
|
||||
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv6);
|
||||
PackageInfo info(2030000, PLATFORM_UNKNOWN, ARCH_ARMv6);
|
||||
string name = info.GetFullName();
|
||||
EXPECT_STREQ("org.opencv.lib_v23_armv5", name.c_str());
|
||||
}
|
||||
|
||||
TEST(PackageInfo, FullNameArmv6VFPv3)
|
||||
{
|
||||
PackageInfo info("232", PLATFORM_UNKNOWN, ARCH_ARMv6 | FEATURES_HAS_VFPv3);
|
||||
PackageInfo info(2030200, PLATFORM_UNKNOWN, ARCH_ARMv6 | FEATURES_HAS_VFPv3);
|
||||
string name = info.GetFullName();
|
||||
#ifdef __SUPPORT_ARMEABI_FEATURES
|
||||
EXPECT_STREQ("org.opencv.lib_v23_armv5_vfpv3", name.c_str());
|
||||
@@ -72,7 +72,7 @@ TEST(PackageInfo, FullNameArmv6VFPv3)
|
||||
|
||||
TEST(PackageInfo, FullNameTegra3)
|
||||
{
|
||||
PackageInfo info("230", PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_NEON);
|
||||
PackageInfo info(2030000, PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_NEON);
|
||||
string name = info.GetFullName();
|
||||
#ifdef __SUPPORT_TEGRA3
|
||||
EXPECT_STREQ("org.opencv.lib_v23_tegra3", name.c_str());
|
||||
@@ -87,7 +87,7 @@ TEST(PackageInfo, FullNameTegra3)
|
||||
|
||||
TEST(PackageInfo, FullNameX86SSE2)
|
||||
{
|
||||
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSE2);
|
||||
PackageInfo info(2030000, PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSE2);
|
||||
string name = info.GetFullName();
|
||||
#ifdef __SUPPORT_INTEL_FEATURES
|
||||
EXPECT_STREQ("org.opencv.lib_v23_x86_sse2", name.c_str());
|
||||
@@ -99,7 +99,7 @@ TEST(PackageInfo, FullNameX86SSE2)
|
||||
#ifdef __SUPPORT_MIPS
|
||||
TEST(PackageInfo, FullNameMips)
|
||||
{
|
||||
PackageInfo info("243", PLATFORM_UNKNOWN, ARCH_MIPS);
|
||||
PackageInfo info(2040300, PLATFORM_UNKNOWN, ARCH_MIPS);
|
||||
string name = info.GetFullName();
|
||||
EXPECT_STREQ("org.opencv.lib_v24_mips", name.c_str());
|
||||
}
|
||||
@@ -108,21 +108,21 @@ TEST(PackageInfo, FullNameMips)
|
||||
TEST(PackageInfo, Armv7NeonFromFullName)
|
||||
{
|
||||
PackageInfo info("org.opencv.lib_v23_armv7a_neon", "/data/data/org.opencv.lib_v23_armv7_neon");
|
||||
EXPECT_EQ("230", info.GetVersion());
|
||||
EXPECT_EQ(2030000, info.GetVersion());
|
||||
EXPECT_EQ(ARCH_ARMv7 | FEATURES_HAS_NEON, info.GetCpuID());
|
||||
}
|
||||
|
||||
TEST(PackageInfo, Armv5FromFullName)
|
||||
{
|
||||
PackageInfo info("org.opencv.lib_v23_armv5", "/data/data/org.opencv.lib_v23_armv5");
|
||||
EXPECT_EQ("230", info.GetVersion());
|
||||
EXPECT_EQ(2030000, info.GetVersion());
|
||||
EXPECT_EQ(ARCH_ARMv5, info.GetCpuID());
|
||||
}
|
||||
|
||||
TEST(PackageInfo, Armv5VFPv3FromFullName)
|
||||
{
|
||||
PackageInfo info("org.opencv.lib_v23_armv5_vfpv3", "/data/data/org.opencv.lib_v23_armv5_vfpv3");
|
||||
EXPECT_EQ("230", info.GetVersion());
|
||||
EXPECT_EQ(2030000, info.GetVersion());
|
||||
EXPECT_EQ(ARCH_ARMv5 | FEATURES_HAS_VFPv3, info.GetCpuID());
|
||||
}
|
||||
|
||||
@@ -131,20 +131,20 @@ TEST(PackageInfo, X86SSE2FromFullName)
|
||||
PackageInfo info("org.opencv.lib_v24_x86_sse2", "/data/data/org.opencv.lib_v24_x86_sse2");
|
||||
EXPECT_EQ(PLATFORM_UNKNOWN, info.GetPlatform());
|
||||
EXPECT_EQ(ARCH_X86 | FEATURES_HAS_SSE2, info.GetCpuID());
|
||||
EXPECT_EQ("240", info.GetVersion());
|
||||
EXPECT_EQ(2040000, info.GetVersion());
|
||||
}
|
||||
|
||||
TEST(PackageInfo, Tegra2FromFullName)
|
||||
{
|
||||
PackageInfo info("org.opencv.lib_v23_tegra2", "/data/data/org.opencv.lib_v23_tegra2");
|
||||
EXPECT_EQ("230", info.GetVersion());
|
||||
EXPECT_EQ(2030000, info.GetVersion());
|
||||
EXPECT_EQ(PLATFORM_TEGRA2, info.GetPlatform());
|
||||
}
|
||||
|
||||
TEST(PackageInfo, Tegra3FromFullName)
|
||||
{
|
||||
PackageInfo info("org.opencv.lib_v24_tegra3", "/data/data/org.opencv.lib_v24_tegra3");
|
||||
EXPECT_EQ("240", info.GetVersion());
|
||||
EXPECT_EQ(2040000, info.GetVersion());
|
||||
EXPECT_EQ(PLATFORM_TEGRA3, info.GetPlatform());
|
||||
}
|
||||
|
||||
@@ -152,14 +152,28 @@ TEST(PackageInfo, Tegra3FromFullName)
|
||||
TEST(PackageInfo, MipsFromFullName)
|
||||
{
|
||||
PackageInfo info("org.opencv.lib_v24_mips", "/data/data/org.opencv.lib_v24_mips");
|
||||
EXPECT_EQ("240", info.GetVersion());
|
||||
EXPECT_EQ(2040000, info.GetVersion());
|
||||
EXPECT_EQ(ARCH_MIPS, info.GetCpuID());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(PackageInfo, Check2DigitRevision)
|
||||
{
|
||||
PackageInfo info("org.opencv.lib_v23_armv7a_neon", "/data/data/org.opencv.lib_v23_armv7_neon", "4.1");
|
||||
EXPECT_EQ(2030400, info.GetVersion());
|
||||
EXPECT_EQ(ARCH_ARMv7 | FEATURES_HAS_NEON, info.GetCpuID());
|
||||
}
|
||||
|
||||
TEST(PackageInfo, Check3DigitRevision)
|
||||
{
|
||||
PackageInfo info("org.opencv.lib_v23_armv7a_neon", "/data/data/org.opencv.lib_v23_armv7_neon", "4.1.5");
|
||||
EXPECT_EQ(2030401, info.GetVersion());
|
||||
EXPECT_EQ(ARCH_ARMv7 | FEATURES_HAS_NEON, info.GetCpuID());
|
||||
}
|
||||
|
||||
TEST(PackageInfo, Comparator1)
|
||||
{
|
||||
PackageInfo info1("240", PLATFORM_UNKNOWN, ARCH_X86);
|
||||
PackageInfo info1(2040000, PLATFORM_UNKNOWN, ARCH_X86);
|
||||
PackageInfo info2("org.opencv.lib_v24_x86", "/data/data/org.opencv.lib_v24_x86");
|
||||
EXPECT_STREQ(info1.GetFullName().c_str(), info2.GetFullName().c_str());
|
||||
EXPECT_EQ(info1, info2);
|
||||
@@ -167,7 +181,7 @@ TEST(PackageInfo, Comparator1)
|
||||
|
||||
TEST(PackageInfo, Comparator2)
|
||||
{
|
||||
PackageInfo info1("240", PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON | FEATURES_HAS_VFPv3);
|
||||
PackageInfo info1(2040000, PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON | FEATURES_HAS_VFPv3);
|
||||
#ifdef __SUPPORT_ARMEABI_V7A_FEATURES
|
||||
PackageInfo info2("org.opencv.lib_v24_armv7a_neon", "/data/data/org.opencv.lib_v24_armv7a_neon");
|
||||
#else
|
||||
@@ -180,7 +194,7 @@ TEST(PackageInfo, Comparator2)
|
||||
#ifdef __SUPPORT_TEGRA3
|
||||
TEST(PackageInfo, Comparator3)
|
||||
{
|
||||
PackageInfo info1("230", PLATFORM_TEGRA3, 0);
|
||||
PackageInfo info1(2030000, PLATFORM_TEGRA3, 0);
|
||||
PackageInfo info2("org.opencv.lib_v23_tegra3", "/data/data/org.opencv.lib_v23_tegra3");
|
||||
EXPECT_STREQ(info1.GetFullName().c_str(), info2.GetFullName().c_str());
|
||||
EXPECT_EQ(info1, info2);
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "IOpenCVEngine.h"
|
||||
#include <utils/String16.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -14,52 +13,52 @@ using namespace std;
|
||||
TEST(PackageManager, InstalledVersions)
|
||||
{
|
||||
PackageManagerStub pm;
|
||||
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
PackageInfo info(2030000, PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
pm.InstalledPackages.push_back(info);
|
||||
std::set<string> versions = pm.GetInstalledVersions();
|
||||
std::vector<int> versions = pm.GetInstalledVersions();
|
||||
EXPECT_EQ(1, versions.size());
|
||||
EXPECT_EQ("230", *versions.begin());
|
||||
EXPECT_EQ(2030000, *versions.begin());
|
||||
}
|
||||
|
||||
TEST(PackageManager, CheckVersionInstalled)
|
||||
{
|
||||
PackageManagerStub pm;
|
||||
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
PackageInfo info(2030000, PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
pm.InstalledPackages.push_back(info);
|
||||
EXPECT_TRUE(pm.CheckVersionInstalled("230", PLATFORM_UNKNOWN, ARCH_ARMv7));
|
||||
EXPECT_TRUE(pm.CheckVersionInstalled(2030000, PLATFORM_UNKNOWN, ARCH_ARMv7));
|
||||
}
|
||||
|
||||
TEST(PackageManager, InstallVersion)
|
||||
{
|
||||
PackageManagerStub pm;
|
||||
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv5);
|
||||
PackageInfo info(2030000, PLATFORM_UNKNOWN, ARCH_ARMv5);
|
||||
pm.InstalledPackages.push_back(info);
|
||||
EXPECT_TRUE(pm.InstallVersion("240", PLATFORM_UNKNOWN, ARCH_ARMv5));
|
||||
EXPECT_TRUE(pm.InstallVersion(2040000, PLATFORM_UNKNOWN, ARCH_ARMv5));
|
||||
EXPECT_EQ(2, pm.InstalledPackages.size());
|
||||
EXPECT_TRUE(pm.CheckVersionInstalled("240", PLATFORM_UNKNOWN, ARCH_ARMv5));
|
||||
EXPECT_TRUE(pm.CheckVersionInstalled(2040000, PLATFORM_UNKNOWN, ARCH_ARMv5));
|
||||
}
|
||||
|
||||
TEST(PackageManager, GetPackagePathForArmv5)
|
||||
{
|
||||
PackageManagerStub pm;
|
||||
EXPECT_TRUE(pm.InstallVersion("243", PLATFORM_UNKNOWN, ARCH_ARMv5));
|
||||
string path = pm.GetPackagePathByVersion("243", PLATFORM_UNKNOWN, ARCH_ARMv5);
|
||||
EXPECT_TRUE(pm.InstallVersion(2040300, PLATFORM_UNKNOWN, ARCH_ARMv5));
|
||||
string path = pm.GetPackagePathByVersion(2040300, PLATFORM_UNKNOWN, ARCH_ARMv5);
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v24_armv5/lib", path.c_str());
|
||||
}
|
||||
|
||||
TEST(PackageManager, GetPackagePathForArmv7)
|
||||
{
|
||||
PackageManagerStub pm;
|
||||
EXPECT_TRUE(pm.InstallVersion("230", PLATFORM_UNKNOWN, ARCH_ARMv7));
|
||||
string path = pm.GetPackagePathByVersion("230", PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
EXPECT_TRUE(pm.InstallVersion(2030000, PLATFORM_UNKNOWN, ARCH_ARMv7));
|
||||
string path = pm.GetPackagePathByVersion(2030000, PLATFORM_UNKNOWN, ARCH_ARMv7);
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v23_armv7a/lib", path.c_str());
|
||||
}
|
||||
|
||||
TEST(PackageManager, GetPackagePathForArmv7Neon)
|
||||
{
|
||||
PackageManagerStub pm;
|
||||
EXPECT_TRUE(pm.InstallVersion("230", PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON));
|
||||
string path = pm.GetPackagePathByVersion("230", PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON);
|
||||
EXPECT_TRUE(pm.InstallVersion(2030000, PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON));
|
||||
string path = pm.GetPackagePathByVersion(2030000, PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON);
|
||||
#ifdef __SUPPORT_ARMEABI_V7A_FEATURES
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v23_armv7a_neon/lib", path.c_str());
|
||||
#else
|
||||
@@ -70,16 +69,16 @@ TEST(PackageManager, GetPackagePathForArmv7Neon)
|
||||
TEST(PackageManager, GetPackagePathForX86)
|
||||
{
|
||||
PackageManagerStub pm;
|
||||
EXPECT_TRUE(pm.InstallVersion("230", PLATFORM_UNKNOWN, ARCH_X86));
|
||||
string path = pm.GetPackagePathByVersion("230", PLATFORM_UNKNOWN, ARCH_X86);
|
||||
EXPECT_TRUE(pm.InstallVersion(2030000, PLATFORM_UNKNOWN, ARCH_X86));
|
||||
string path = pm.GetPackagePathByVersion(2030000, PLATFORM_UNKNOWN, ARCH_X86);
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v23_x86/lib", path.c_str());
|
||||
}
|
||||
|
||||
TEST(PackageManager, GetPackagePathForX86SSE2)
|
||||
{
|
||||
PackageManagerStub pm;
|
||||
EXPECT_TRUE(pm.InstallVersion("230", PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSE2));
|
||||
string path = pm.GetPackagePathByVersion("230", PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSE2);
|
||||
EXPECT_TRUE(pm.InstallVersion(2030000, PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSE2));
|
||||
string path = pm.GetPackagePathByVersion(2030000, PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSE2);
|
||||
#ifdef __SUPPORT_INTEL_FEATURES
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v23_x86_sse2/lib", path.c_str());
|
||||
#else
|
||||
@@ -90,8 +89,8 @@ TEST(PackageManager, GetPackagePathForX86SSE2)
|
||||
TEST(PackageManager, GetPackagePathForTegra3)
|
||||
{
|
||||
PackageManagerStub pm;
|
||||
EXPECT_TRUE(pm.InstallVersion("230", PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_NEON));
|
||||
string path = pm.GetPackagePathByVersion("230", PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_NEON);
|
||||
EXPECT_TRUE(pm.InstallVersion(2030000, PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON));
|
||||
string path = pm.GetPackagePathByVersion(2030000, PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON);
|
||||
#ifdef __SUPPORT_TEGRA3
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v23_tegra3/lib", path.c_str());
|
||||
#else
|
||||
@@ -107,8 +106,8 @@ TEST(PackageManager, GetPackagePathForTegra3)
|
||||
TEST(PackageManager, GetPackagePathForMips)
|
||||
{
|
||||
PackageManagerStub pm;
|
||||
EXPECT_TRUE(pm.InstallVersion("243", PLATFORM_UNKNOWN, ARCH_MIPS));
|
||||
string path = pm.GetPackagePathByVersion("243", PLATFORM_UNKNOWN, ARCH_MIPS);
|
||||
EXPECT_TRUE(pm.InstallVersion(2040000, PLATFORM_UNKNOWN, ARCH_MIPS));
|
||||
string path = pm.GetPackagePathByVersion(2040000, PLATFORM_UNKNOWN, ARCH_MIPS);
|
||||
EXPECT_STREQ("/data/data/org.opencv.lib_v24_mips/lib", path.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
#ifndef __IPACKAGE_MANAGER__
|
||||
#define __IPACKAGE_MANAGER__
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class IPackageManager
|
||||
{
|
||||
public:
|
||||
virtual std::set<std::string> GetInstalledVersions() = 0;
|
||||
virtual bool CheckVersionInstalled(const std::string& version, int platform, int cpu_id) = 0;
|
||||
virtual bool InstallVersion(const std::string&, int platform, int cpu_id) = 0;
|
||||
virtual std::string GetPackagePathByVersion(const std::string&, int platform, int cpu_id) = 0;
|
||||
virtual std::vector<int> GetInstalledVersions() = 0;
|
||||
virtual bool CheckVersionInstalled(int version, int platform, int cpu_id) = 0;
|
||||
virtual bool InstallVersion(int version, int platform, int cpu_id) = 0;
|
||||
virtual std::string GetPackagePathByVersion(int version, int platform, int cpu_id) = 0;
|
||||
virtual ~IPackageManager(){};
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
android:id="@+id/textView1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Version: "
|
||||
android:text="Library version: "
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
android:id="@+id/EngineVersionCaption"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Version: "
|
||||
android:text="OpenCV Manager version: "
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -299,10 +299,9 @@ public class ManagerActivity extends Activity
|
||||
else
|
||||
NativeLibDir = "/data/data/" + mInstalledPackageInfo[i].packageName + "/lib";
|
||||
|
||||
OpenCVLibraryInfo NativeInfo = new OpenCVLibraryInfo(NativeLibDir);
|
||||
|
||||
if (PackageName.equals("org.opencv.engine"))
|
||||
{
|
||||
OpenCVLibraryInfo NativeInfo = new OpenCVLibraryInfo(NativeLibDir);
|
||||
if (NativeInfo.status())
|
||||
{
|
||||
PublicName = "Built-in OpenCV library";
|
||||
@@ -348,9 +347,7 @@ public class ManagerActivity extends Activity
|
||||
|
||||
if (null != ActivePackagePath)
|
||||
{
|
||||
int start = ActivePackagePath.indexOf(mInstalledPackageInfo[i].packageName);
|
||||
int stop = start + mInstalledPackageInfo[i].packageName.length();
|
||||
if (start >= 0 && ActivePackagePath.charAt(stop) == '/')
|
||||
if (ActivePackagePath.equals(NativeLibDir))
|
||||
{
|
||||
temp.put("Activity", "y");
|
||||
Tags = "active";
|
||||
@@ -405,13 +402,22 @@ public class ManagerActivity extends Activity
|
||||
if (OpenCVersion == null || PackageVersion == null)
|
||||
return "unknown";
|
||||
|
||||
int dot = PackageVersion.indexOf(".");
|
||||
if (dot == -1 || OpenCVersion.length() == 0)
|
||||
String[] revisions = PackageVersion.split("\\.");
|
||||
|
||||
if (revisions.length <= 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);
|
||||
if (revisions.length == 2)
|
||||
// the 2nd digit is revision
|
||||
return OpenCVersion.substring(0, OpenCVersion.length()-1) + "." +
|
||||
OpenCVersion.toCharArray()[OpenCVersion.length()-1] + "." +
|
||||
revisions[0] + " rev " + revisions[1];
|
||||
else
|
||||
// the 2nd digit is part of library version
|
||||
// the 3rd digit is revision
|
||||
return OpenCVersion.substring(0, OpenCVersion.length()-1) + "." +
|
||||
OpenCVersion.toCharArray()[OpenCVersion.length()-1] + "." +
|
||||
revisions[0] + "." + revisions[1] + " rev " + revisions[2];
|
||||
}
|
||||
|
||||
protected String ConvertPackageName(String Name, String Version)
|
||||
|
||||
@@ -14,20 +14,20 @@ 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
|
||||
adb install OpenCV-2.4.4-android-sdk/apk/OpenCV_2.4.4_Manager_2.6_<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 |
|
||||
+------------------------------+--------------+-----------------------------------------------------+
|
||||
+------------------------------+--------------+---------------------------------------------------+
|
||||
| Hardware Platform | Android ver. | Package name |
|
||||
+==============================+==============+===================================================+
|
||||
| armeabi-v7a (ARMv7-A + NEON) | >= 2.3 | OpenCV_2.4.4_Manager_2.6_armv7a-neon.apk |
|
||||
+------------------------------+--------------+---------------------------------------------------+
|
||||
| armeabi-v7a (ARMv7-A + NEON) | = 2.2 | OpenCV_2.4.4_Manager_2.6_armv7a-neon-android8.apk |
|
||||
+------------------------------+--------------+---------------------------------------------------+
|
||||
| armeabi (ARMv5, ARMv6) | >= 2.3 | OpenCV_2.4.4_Manager_2.6_armeabi.apk |
|
||||
+------------------------------+--------------+---------------------------------------------------+
|
||||
| Intel x86 | >= 2.3 | OpenCV_2.4.4_Manager_2.6_x86.apk |
|
||||
+------------------------------+--------------+---------------------------------------------------+
|
||||
| MIPS | >= 2.3 | OpenCV_2.4.4_Manager_2.6_mips.apk |
|
||||
+------------------------------+--------------+---------------------------------------------------+
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
if(IOS OR ANDROID)
|
||||
return()
|
||||
endif()
|
||||
|
||||
SET(OPENCV_HAARTRAINING_DEPS opencv_core opencv_imgproc opencv_highgui opencv_objdetect opencv_calib3d opencv_video opencv_features2d opencv_flann opencv_legacy)
|
||||
ocv_check_dependencies(${OPENCV_HAARTRAINING_DEPS})
|
||||
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
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)
|
||||
|
||||
@@ -360,7 +360,7 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id
|
||||
|
||||
if (is_buf_16u)
|
||||
{
|
||||
unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols +
|
||||
unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() +
|
||||
vi*sample_count + data_root->offset);
|
||||
for( int i = 0; i < num_valid; i++ )
|
||||
{
|
||||
@@ -373,7 +373,7 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id
|
||||
}
|
||||
else
|
||||
{
|
||||
int* idst_idx = buf->data.i + root->buf_idx*buf->cols +
|
||||
int* idst_idx = buf->data.i + root->buf_idx*get_length_subbuf() +
|
||||
vi*sample_count + root->offset;
|
||||
for( int i = 0; i < num_valid; i++ )
|
||||
{
|
||||
@@ -390,14 +390,14 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id
|
||||
const int* src_lbls = get_cv_labels(data_root, (int*)(uchar*)inn_buf);
|
||||
if (is_buf_16u)
|
||||
{
|
||||
unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols +
|
||||
unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() +
|
||||
(workVarCount-1)*sample_count + root->offset);
|
||||
for( int i = 0; i < count; i++ )
|
||||
udst[i] = (unsigned short)src_lbls[sidx[i]];
|
||||
}
|
||||
else
|
||||
{
|
||||
int* idst = buf->data.i + root->buf_idx*buf->cols +
|
||||
int* idst = buf->data.i + root->buf_idx*get_length_subbuf() +
|
||||
(workVarCount-1)*sample_count + root->offset;
|
||||
for( int i = 0; i < count; i++ )
|
||||
idst[i] = src_lbls[sidx[i]];
|
||||
@@ -407,14 +407,14 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id
|
||||
const int* sample_idx_src = get_sample_indices(data_root, (int*)(uchar*)inn_buf);
|
||||
if (is_buf_16u)
|
||||
{
|
||||
unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols +
|
||||
unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() +
|
||||
workVarCount*sample_count + root->offset);
|
||||
for( int i = 0; i < count; i++ )
|
||||
sample_idx_dst[i] = (unsigned short)sample_idx_src[sidx[i]];
|
||||
}
|
||||
else
|
||||
{
|
||||
int* sample_idx_dst = buf->data.i + root->buf_idx*buf->cols +
|
||||
int* sample_idx_dst = buf->data.i + root->buf_idx*get_length_subbuf() +
|
||||
workVarCount*sample_count + root->offset;
|
||||
for( int i = 0; i < count; i++ )
|
||||
sample_idx_dst[i] = sample_idx_src[sidx[i]];
|
||||
@@ -489,6 +489,10 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat
|
||||
int* idst = 0;
|
||||
unsigned short* udst = 0;
|
||||
|
||||
uint64 effective_buf_size = 0;
|
||||
int effective_buf_height = 0, effective_buf_width = 0;
|
||||
|
||||
|
||||
clear();
|
||||
shared = true;
|
||||
have_labels = true;
|
||||
@@ -548,13 +552,28 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat
|
||||
var_type->data.i[var_count] = cat_var_count;
|
||||
var_type->data.i[var_count+1] = cat_var_count+1;
|
||||
work_var_count = ( cat_var_count ? 0 : numPrecalcIdx ) + 1/*cv_lables*/;
|
||||
buf_size = (work_var_count + 1) * sample_count/*sample_indices*/;
|
||||
buf_count = 2;
|
||||
|
||||
if ( is_buf_16u )
|
||||
buf = cvCreateMat( buf_count, buf_size, CV_16UC1 );
|
||||
buf_size = -1; // the member buf_size is obsolete
|
||||
|
||||
effective_buf_size = (uint64)(work_var_count + 1)*(uint64)sample_count * buf_count; // this is the total size of "CvMat buf" to be allocated
|
||||
effective_buf_width = sample_count;
|
||||
effective_buf_height = work_var_count+1;
|
||||
|
||||
if (effective_buf_width >= effective_buf_height)
|
||||
effective_buf_height *= buf_count;
|
||||
else
|
||||
buf = cvCreateMat( buf_count, buf_size, CV_32SC1 );
|
||||
effective_buf_width *= buf_count;
|
||||
|
||||
if ((uint64)effective_buf_width * (uint64)effective_buf_height != effective_buf_size)
|
||||
{
|
||||
CV_Error(CV_StsBadArg, "The memory buffer cannot be allocated since its size exceeds integer fields limit");
|
||||
}
|
||||
|
||||
if ( is_buf_16u )
|
||||
buf = cvCreateMat( effective_buf_height, effective_buf_width, CV_16UC1 );
|
||||
else
|
||||
buf = cvCreateMat( effective_buf_height, effective_buf_width, CV_32SC1 );
|
||||
|
||||
cat_count = cvCreateMat( 1, cat_var_count + 1, CV_32SC1 );
|
||||
|
||||
@@ -609,7 +628,7 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat
|
||||
priors_mult = cvCloneMat( priors );
|
||||
counts = cvCreateMat( 1, get_num_classes(), CV_32SC1 );
|
||||
direction = cvCreateMat( 1, sample_count, CV_8UC1 );
|
||||
split_buf = cvCreateMat( 1, sample_count, CV_32SC1 );
|
||||
split_buf = cvCreateMat( 1, sample_count, CV_32SC1 );//TODO: make a pointer
|
||||
}
|
||||
|
||||
void CvCascadeBoostTrainData::free_train_data()
|
||||
@@ -652,10 +671,10 @@ void CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* o
|
||||
if ( vi < numPrecalcIdx )
|
||||
{
|
||||
if( !is_buf_16u )
|
||||
*sortedIndices = buf->data.i + n->buf_idx*buf->cols + vi*sample_count + n->offset;
|
||||
*sortedIndices = buf->data.i + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset;
|
||||
else
|
||||
{
|
||||
const unsigned short* shortIndices = (const unsigned short*)(buf->data.s + n->buf_idx*buf->cols +
|
||||
const unsigned short* shortIndices = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() +
|
||||
vi*sample_count + n->offset );
|
||||
for( int i = 0; i < nodeSampleCount; i++ )
|
||||
sortedIndicesBuf[i] = shortIndices[i];
|
||||
@@ -1027,6 +1046,7 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
|
||||
int newBufIdx = data->get_child_buf_idx( node );
|
||||
int workVarCount = data->get_work_var_count();
|
||||
CvMat* buf = data->buf;
|
||||
size_t length_buf_row = data->get_length_subbuf();
|
||||
cv::AutoBuffer<uchar> inn_buf(n*(3*sizeof(int)+sizeof(float)));
|
||||
int* tempBuf = (int*)(uchar*)inn_buf;
|
||||
bool splitInputData;
|
||||
@@ -1070,7 +1090,7 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
|
||||
if (data->is_buf_16u)
|
||||
{
|
||||
ushort *ldst, *rdst;
|
||||
ldst = (ushort*)(buf->data.s + left->buf_idx*buf->cols +
|
||||
ldst = (ushort*)(buf->data.s + left->buf_idx*length_buf_row +
|
||||
vi*scount + left->offset);
|
||||
rdst = (ushort*)(ldst + nl);
|
||||
|
||||
@@ -1096,9 +1116,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
|
||||
else
|
||||
{
|
||||
int *ldst, *rdst;
|
||||
ldst = buf->data.i + left->buf_idx*buf->cols +
|
||||
ldst = buf->data.i + left->buf_idx*length_buf_row +
|
||||
vi*scount + left->offset;
|
||||
rdst = buf->data.i + right->buf_idx*buf->cols +
|
||||
rdst = buf->data.i + right->buf_idx*length_buf_row +
|
||||
vi*scount + right->offset;
|
||||
|
||||
// split sorted
|
||||
@@ -1131,9 +1151,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
|
||||
|
||||
if (data->is_buf_16u)
|
||||
{
|
||||
unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*buf->cols +
|
||||
unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*length_buf_row +
|
||||
(workVarCount-1)*scount + left->offset);
|
||||
unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*buf->cols +
|
||||
unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*length_buf_row +
|
||||
(workVarCount-1)*scount + right->offset);
|
||||
|
||||
for( int i = 0; i < n; i++ )
|
||||
@@ -1154,9 +1174,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
|
||||
}
|
||||
else
|
||||
{
|
||||
int *ldst = buf->data.i + left->buf_idx*buf->cols +
|
||||
int *ldst = buf->data.i + left->buf_idx*length_buf_row +
|
||||
(workVarCount-1)*scount + left->offset;
|
||||
int *rdst = buf->data.i + right->buf_idx*buf->cols +
|
||||
int *rdst = buf->data.i + right->buf_idx*length_buf_row +
|
||||
(workVarCount-1)*scount + right->offset;
|
||||
|
||||
for( int i = 0; i < n; i++ )
|
||||
@@ -1184,9 +1204,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
|
||||
|
||||
if (data->is_buf_16u)
|
||||
{
|
||||
unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*buf->cols +
|
||||
unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*length_buf_row +
|
||||
workVarCount*scount + left->offset);
|
||||
unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*buf->cols +
|
||||
unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*length_buf_row +
|
||||
workVarCount*scount + right->offset);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
@@ -1205,9 +1225,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
|
||||
}
|
||||
else
|
||||
{
|
||||
int* ldst = buf->data.i + left->buf_idx*buf->cols +
|
||||
int* ldst = buf->data.i + left->buf_idx*length_buf_row +
|
||||
workVarCount*scount + left->offset;
|
||||
int* rdst = buf->data.i + right->buf_idx*buf->cols +
|
||||
int* rdst = buf->data.i + right->buf_idx*length_buf_row +
|
||||
workVarCount*scount + right->offset;
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
@@ -1352,6 +1372,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree )
|
||||
sampleIdx = data->get_sample_indices( data->data_root, sampleIdxBuf );
|
||||
}
|
||||
CvMat* buf = data->buf;
|
||||
size_t length_buf_row = data->get_length_subbuf();
|
||||
if( !tree ) // before training the first tree, initialize weights and other parameters
|
||||
{
|
||||
int* classLabelsBuf = (int*)cur_inn_buf_pos; cur_inn_buf_pos = (uchar*)(classLabelsBuf + n);
|
||||
@@ -1375,7 +1396,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree )
|
||||
|
||||
if (data->is_buf_16u)
|
||||
{
|
||||
unsigned short* labels = (unsigned short*)(buf->data.s + data->data_root->buf_idx*buf->cols +
|
||||
unsigned short* labels = (unsigned short*)(buf->data.s + data->data_root->buf_idx*length_buf_row +
|
||||
data->data_root->offset + (data->work_var_count-1)*data->sample_count);
|
||||
for( int i = 0; i < n; i++ )
|
||||
{
|
||||
@@ -1393,7 +1414,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree )
|
||||
}
|
||||
else
|
||||
{
|
||||
int* labels = buf->data.i + data->data_root->buf_idx*buf->cols +
|
||||
int* labels = buf->data.i + data->data_root->buf_idx*length_buf_row +
|
||||
data->data_root->offset + (data->work_var_count-1)*data->sample_count;
|
||||
|
||||
for( int i = 0; i < n; i++ )
|
||||
|
||||
@@ -56,12 +56,18 @@ 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)
|
||||
add_extra_compiler_option(-Werror=non-virtual-dtor)
|
||||
if(OPENCV_CAN_BREAK_BINARY_COMPATIBILITY)
|
||||
add_extra_compiler_option(-Werror=non-virtual-dtor)
|
||||
endif()
|
||||
add_extra_compiler_option(-Werror=address)
|
||||
add_extra_compiler_option(-Werror=sequence-point)
|
||||
add_extra_compiler_option(-Wformat)
|
||||
@@ -91,7 +97,7 @@ if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
endif()
|
||||
|
||||
# We need pthread's
|
||||
if(UNIX AND NOT ANDROID)
|
||||
if(UNIX AND NOT ANDROID AND NOT (APPLE AND CMAKE_COMPILER_IS_CLANGCXX))
|
||||
add_extra_compiler_option(-pthread)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -302,7 +302,7 @@ macro(add_android_project target path)
|
||||
COMMAND ${CMAKE_COMMAND} -E touch "${android_proj_bin_dir}/bin/${target}-debug.apk" # needed because ant does not update the timestamp of updated apk
|
||||
WORKING_DIRECTORY "${android_proj_bin_dir}"
|
||||
MAIN_DEPENDENCY "${android_proj_bin_dir}/${ANDROID_MANIFEST_FILE}"
|
||||
DEPENDS "${OpenCV_BINARY_DIR}/bin/.classes.jar.dephelper" opencv_java # as we are part of OpenCV we can just force this dependency
|
||||
DEPENDS "${OpenCV_BINARY_DIR}/bin/classes.jar.dephelper" opencv_java # as we are part of OpenCV we can just force this dependency
|
||||
DEPENDS ${android_proj_file_deps} ${JNI_LIB_NAME})
|
||||
endif()
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Cl
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(CUDA 4.2)
|
||||
find_package(CUDA 4.2 QUIET)
|
||||
|
||||
if(CUDA_FOUND)
|
||||
set(HAVE_CUDA 1)
|
||||
@@ -33,13 +33,48 @@ if(CUDA_FOUND)
|
||||
|
||||
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")
|
||||
set(_generations "Fermi" "Kepler")
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
list(APPEND _generations "Auto")
|
||||
endif()
|
||||
set(CUDA_GENERATION "" CACHE STRING "Build CUDA device code only for specific GPU architecture. Leave empty to build for all architectures.")
|
||||
if( CMAKE_VERSION VERSION_GREATER "2.8" )
|
||||
set_property( CACHE CUDA_GENERATION PROPERTY STRINGS "" ${_generations} )
|
||||
endif()
|
||||
|
||||
if(CUDA_GENERATION)
|
||||
if(NOT ";${_generations};" MATCHES ";${CUDA_GENERATION};")
|
||||
string(REPLACE ";" ", " _generations "${_generations}")
|
||||
message(FATAL_ERROR "ERROR: ${_generations} Generations are suppered.")
|
||||
endif()
|
||||
unset(CUDA_ARCH_BIN CACHE)
|
||||
unset(CUDA_ARCH_PTX CACHE)
|
||||
endif()
|
||||
|
||||
set(__cuda_arch_ptx "")
|
||||
if(CUDA_GENERATION STREQUAL "Fermi")
|
||||
set(__cuda_arch_bin "2.0 2.1(2.0)")
|
||||
elseif(CUDA_GENERATION STREQUAL "Kepler")
|
||||
set(__cuda_arch_bin "3.0")
|
||||
elseif(CUDA_GENERATION STREQUAL "Auto")
|
||||
execute_process( COMMAND "${CUDA_NVCC_EXECUTABLE}" "${OpenCV_SOURCE_DIR}/cmake/OpenCVDetectCudaArch.cu" "--run"
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
|
||||
RESULT_VARIABLE _nvcc_res OUTPUT_VARIABLE _nvcc_out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT _nvcc_res EQUAL 0)
|
||||
message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.")
|
||||
else()
|
||||
set(__cuda_arch_bin "${_nvcc_out}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED __cuda_arch_bin)
|
||||
set(__cuda_arch_bin "1.1 1.2 1.3 2.0 2.1(2.0) 3.0")
|
||||
set(__cuda_arch_ptx "2.0 3.0")
|
||||
endif()
|
||||
|
||||
set(CUDA_ARCH_BIN ${__cuda_arch_bin} CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported")
|
||||
set(CUDA_ARCH_PTX ${__cuda_arch_ptx} CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for")
|
||||
|
||||
string(REGEX REPLACE "\\." "" ARCH_BIN_NO_POINTS "${CUDA_ARCH_BIN}")
|
||||
string(REGEX REPLACE "\\." "" ARCH_PTX_NO_POINTS "${CUDA_ARCH_PTX}")
|
||||
@@ -83,13 +118,8 @@ if(CUDA_FOUND)
|
||||
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()
|
||||
|
||||
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm")
|
||||
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --target-cpu-architecture=ARM")
|
||||
endif()
|
||||
|
||||
# These vars will be processed in other scripts
|
||||
|
||||
@@ -5,15 +5,17 @@ if(CMAKE_CL_64)
|
||||
set(MSVC64 1)
|
||||
endif()
|
||||
|
||||
if(NOT APPLE)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(CMAKE_COMPILER_IS_GNUCXX 1)
|
||||
set(ENABLE_PRECOMPILED_HEADERS OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set(CMAKE_COMPILER_IS_GNUCC 1)
|
||||
set(ENABLE_PRECOMPILED_HEADERS OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(CMAKE_COMPILER_IS_GNUCXX 1)
|
||||
set(CMAKE_COMPILER_IS_CLANGCXX 1)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set(CMAKE_COMPILER_IS_GNUCC 1)
|
||||
set(CMAKE_COMPILER_IS_CLANGCC 1)
|
||||
endif()
|
||||
|
||||
if((CMAKE_COMPILER_IS_CLANGCXX OR CMAKE_COMPILER_IS_CLANGCC) AND NOT CMAKE_GENERATOR MATCHES "Xcode")
|
||||
set(ENABLE_PRECOMPILED_HEADERS OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
@@ -44,16 +46,24 @@ if(MSVC AND CMAKE_C_COMPILER MATCHES "icc")
|
||||
set(CV_ICC __INTEL_COMPILER_FOR_WINDOWS)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR (UNIX AND CV_ICC))
|
||||
set(CV_COMPILER_IS_GNU TRUE)
|
||||
else()
|
||||
set(CV_COMPILER_IS_GNU FALSE)
|
||||
endif()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Detect GNU version:
|
||||
# ----------------------------------------------------------------------------
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
if(CMAKE_COMPILER_IS_CLANGCXX)
|
||||
set(CMAKE_GCC_REGEX_VERSION "4.2.1")
|
||||
set(CMAKE_OPENCV_GCC_VERSION_MAJOR 4)
|
||||
set(CMAKE_OPENCV_GCC_VERSION_MINOR 2)
|
||||
set(CMAKE_OPENCV_GCC_VERSION 42)
|
||||
set(CMAKE_OPENCV_GCC_VERSION_NUM 402)
|
||||
|
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -v
|
||||
ERROR_VARIABLE CMAKE_OPENCV_CLANG_VERSION_FULL
|
||||
ERROR_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
string(REGEX MATCH "version.*$" CMAKE_OPENCV_CLANG_VERSION_FULL "${CMAKE_OPENCV_CLANG_VERSION_FULL}")
|
||||
string(REGEX MATCH "[0-9]+\\.[0-9]+" CMAKE_CLANG_REGEX_VERSION "${CMAKE_OPENCV_CLANG_VERSION_FULL}")
|
||||
|
||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
|
||||
OUTPUT_VARIABLE CMAKE_OPENCV_GCC_VERSION_FULL
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#include <stdio.h>
|
||||
int main()
|
||||
{
|
||||
int count = 0;
|
||||
if (cudaSuccess != cudaGetDeviceCount(&count)){return -1;}
|
||||
if (count == 0) {return -1;}
|
||||
for (int device = 0; device < count; ++device)
|
||||
{
|
||||
cudaDeviceProp prop;
|
||||
if (cudaSuccess != cudaGetDeviceProperties(&prop, device)){ continue;}
|
||||
printf("%d.%d ", prop.major, prop.minor);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,78 +1,154 @@
|
||||
if(APPLE)
|
||||
set(OPENCL_FOUND YES)
|
||||
set(OPENCL_LIBRARIES "-framework OpenCL")
|
||||
set(OPENCL_FOUND YES)
|
||||
set(OPENCL_LIBRARIES "-framework OpenCL")
|
||||
else()
|
||||
#find_package(OpenCL QUIET)
|
||||
if(WITH_OPENCLAMDFFT)
|
||||
find_path(CLAMDFFT_INCLUDE_DIR
|
||||
NAMES clAmdFft.h)
|
||||
find_library(CLAMDFFT_LIBRARIES
|
||||
NAMES clAmdFft.Runtime)
|
||||
find_package(OpenCL QUIET)
|
||||
if(WITH_OPENCLAMDFFT)
|
||||
set(CLAMDFFT_SEARCH_PATH $ENV{CLAMDFFT_PATH})
|
||||
if(NOT CLAMDFFT_SEARCH_PATH)
|
||||
if(WIN32)
|
||||
set( CLAMDFFT_SEARCH_PATH "C:\\Program Files (x86)\\AMD\\clAmdFft" )
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_OPENCLAMDBLAS)
|
||||
find_path(CLAMDBLAS_INCLUDE_DIR
|
||||
NAMES clAmdBlas.h)
|
||||
find_library(CLAMDBLAS_LIBRARIES
|
||||
NAMES clAmdBlas)
|
||||
endif()
|
||||
# Try AMD/ATI Stream SDK
|
||||
if (NOT OPENCL_FOUND)
|
||||
set(ENV_AMDSTREAMSDKROOT $ENV{AMDAPPSDKROOT})
|
||||
set(ENV_OPENCLROOT $ENV{OPENCLROOT})
|
||||
set(ENV_CUDA_PATH $ENV{CUDA_PATH})
|
||||
if(ENV_AMDSTREAMSDKROOT)
|
||||
set(OPENCL_INCLUDE_SEARCH_PATH ${ENV_AMDSTREAMSDKROOT}/include)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_AMDSTREAMSDKROOT}/lib/x86)
|
||||
else()
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_AMDSTREAMSDKROOT}/lib/x86_64)
|
||||
endif()
|
||||
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)
|
||||
else()
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_CUDA_PATH}/lib/x64)
|
||||
endif()
|
||||
elseif(ENV_OPENCLROOT AND UNIX)
|
||||
set(OPENCL_INCLUDE_SEARCH_PATH ${ENV_OPENCLROOT}/inc)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} /usr/lib)
|
||||
else()
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} /usr/lib64)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(OPENCL_INCLUDE_SEARCH_PATH)
|
||||
find_path(OPENCL_INCLUDE_DIR
|
||||
NAMES CL/cl.h OpenCL/cl.h
|
||||
PATHS ${OPENCL_INCLUDE_SEARCH_PATH}
|
||||
NO_DEFAULT_PATH)
|
||||
else()
|
||||
find_path(OPENCL_INCLUDE_DIR
|
||||
NAMES CL/cl.h OpenCL/cl.h)
|
||||
endif()
|
||||
|
||||
if(OPENCL_LIB_SEARCH_PATH)
|
||||
find_library(OPENCL_LIBRARY NAMES OpenCL PATHS ${OPENCL_LIB_SEARCH_PATH} NO_DEFAULT_PATH)
|
||||
else()
|
||||
find_library(OPENCL_LIBRARY NAMES OpenCL)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(
|
||||
OPENCL
|
||||
DEFAULT_MSG
|
||||
OPENCL_LIBRARY OPENCL_INCLUDE_DIR
|
||||
)
|
||||
|
||||
if(OPENCL_FOUND)
|
||||
set(OPENCL_LIBRARIES ${OPENCL_LIBRARY})
|
||||
set(HAVE_OPENCL 1)
|
||||
else()
|
||||
set(OPENCL_LIBRARIES)
|
||||
endif()
|
||||
set( CLAMDFFT_INCLUDE_SEARCH_PATH ${CLAMDFFT_SEARCH_PATH}/include )
|
||||
if(UNIX)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(CLAMDFFT_LIB_SEARCH_PATH /usr/lib)
|
||||
else()
|
||||
set(CLAMDFFT_LIB_SEARCH_PATH /usr/lib64)
|
||||
endif()
|
||||
else()
|
||||
set(HAVE_OPENCL 1)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(CLAMDFFT_LIB_SEARCH_PATH ${CLAMDFFT_SEARCH_PATH}\\lib32\\import)
|
||||
else()
|
||||
set(CLAMDFFT_LIB_SEARCH_PATH ${CLAMDFFT_SEARCH_PATH}\\lib64\\import)
|
||||
endif()
|
||||
endif()
|
||||
find_path(CLAMDFFT_INCLUDE_DIR
|
||||
NAMES clAmdFft.h
|
||||
PATHS ${CLAMDFFT_INCLUDE_SEARCH_PATH}
|
||||
PATH_SUFFIXES clAmdFft
|
||||
NO_DEFAULT_PATH)
|
||||
find_library(CLAMDFFT_LIBRARY
|
||||
NAMES clAmdFft.Runtime
|
||||
PATHS ${CLAMDFFT_LIB_SEARCH_PATH}
|
||||
NO_DEFAULT_PATH)
|
||||
if(CLAMDFFT_LIBRARY)
|
||||
set(CLAMDFFT_LIBRARIES ${CLAMDFFT_LIBRARY})
|
||||
else()
|
||||
set(CLAMDFFT_LIBRARIES "")
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_OPENCLAMDBLAS)
|
||||
set(CLAMDBLAS_SEARCH_PATH $ENV{CLAMDBLAS_PATH})
|
||||
if(NOT CLAMDBLAS_SEARCH_PATH)
|
||||
if(WIN32)
|
||||
set( CLAMDBLAS_SEARCH_PATH "C:\\Program Files (x86)\\AMD\\clAmdBlas" )
|
||||
endif()
|
||||
endif()
|
||||
set( CLAMDBLAS_INCLUDE_SEARCH_PATH ${CLAMDBLAS_SEARCH_PATH}/include )
|
||||
if(UNIX)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(CLAMDBLAS_LIB_SEARCH_PATH /usr/lib)
|
||||
else()
|
||||
set(CLAMDBLAS_LIB_SEARCH_PATH /usr/lib64)
|
||||
endif()
|
||||
else()
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(CLAMDBLAS_LIB_SEARCH_PATH ${CLAMDBLAS_SEARCH_PATH}\\lib32\\import)
|
||||
else()
|
||||
set(CLAMDBLAS_LIB_SEARCH_PATH ${CLAMDBLAS_SEARCH_PATH}\\lib64\\import)
|
||||
endif()
|
||||
endif()
|
||||
find_path(CLAMDBLAS_INCLUDE_DIR
|
||||
NAMES clAmdBlas.h
|
||||
PATHS ${CLAMDBLAS_INCLUDE_SEARCH_PATH}
|
||||
PATH_SUFFIXES clAmdBlas
|
||||
NO_DEFAULT_PATH)
|
||||
find_library(CLAMDBLAS_LIBRARY
|
||||
NAMES clAmdBlas
|
||||
PATHS ${CLAMDBLAS_LIB_SEARCH_PATH}
|
||||
NO_DEFAULT_PATH)
|
||||
if(CLAMDBLAS_LIBRARY)
|
||||
set(CLAMDBLAS_LIBRARIES ${CLAMDBLAS_LIBRARY})
|
||||
else()
|
||||
set(CLAMDBLAS_LIBRARIES "")
|
||||
endif()
|
||||
endif()
|
||||
# Try AMD/ATI Stream SDK
|
||||
if (NOT OPENCL_FOUND)
|
||||
set(ENV_AMDSTREAMSDKROOT $ENV{AMDAPPSDKROOT})
|
||||
set(ENV_AMDAPPSDKROOT $ENV{AMDAPPSDKROOT})
|
||||
set(ENV_OPENCLROOT $ENV{OPENCLROOT})
|
||||
set(ENV_CUDA_PATH $ENV{CUDA_PATH})
|
||||
set(ENV_INTELOCLSDKROOT $ENV{INTELOCLSDKROOT})
|
||||
if(ENV_AMDSTREAMSDKROOT)
|
||||
set(OPENCL_INCLUDE_SEARCH_PATH ${ENV_AMDAPPSDKROOT}/include)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_AMDAPPSDKROOT}/lib/x86)
|
||||
else()
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_AMDAPPSDKROOT}/lib/x86_64)
|
||||
endif()
|
||||
elseif(ENV_AMDSTREAMSDKROOT)
|
||||
set(OPENCL_INCLUDE_SEARCH_PATH ${ENV_AMDSTREAMSDKROOT}/include)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_AMDSTREAMSDKROOT}/lib/x86)
|
||||
else()
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_AMDSTREAMSDKROOT}/lib/x86_64)
|
||||
endif()
|
||||
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)
|
||||
else()
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_CUDA_PATH}/lib/x64)
|
||||
endif()
|
||||
elseif(ENV_OPENCLROOT AND UNIX)
|
||||
set(OPENCL_INCLUDE_SEARCH_PATH ${ENV_OPENCLROOT}/inc)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} /usr/lib)
|
||||
else()
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} /usr/lib64)
|
||||
endif()
|
||||
elseif(ENV_INTELOCLSDKROOT)
|
||||
set(OPENCL_INCLUDE_SEARCH_PATH ${ENV_INTELOCLSDKROOT}/include)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_INTELOCLSDKROOT}/lib/x86)
|
||||
else()
|
||||
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_INTELOCLSDKROOT}/lib/x64)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(OPENCL_INCLUDE_SEARCH_PATH)
|
||||
find_path(OPENCL_INCLUDE_DIR
|
||||
NAMES CL/cl.h OpenCL/cl.h
|
||||
PATHS ${OPENCL_INCLUDE_SEARCH_PATH}
|
||||
NO_DEFAULT_PATH)
|
||||
else()
|
||||
find_path(OPENCL_INCLUDE_DIR
|
||||
NAMES CL/cl.h OpenCL/cl.h)
|
||||
endif()
|
||||
|
||||
if(OPENCL_LIB_SEARCH_PATH)
|
||||
find_library(OPENCL_LIBRARY NAMES OpenCL PATHS ${OPENCL_LIB_SEARCH_PATH} NO_DEFAULT_PATH)
|
||||
else()
|
||||
find_library(OPENCL_LIBRARY NAMES OpenCL)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(
|
||||
OPENCL
|
||||
DEFAULT_MSG
|
||||
OPENCL_LIBRARY OPENCL_INCLUDE_DIR
|
||||
)
|
||||
|
||||
if(OPENCL_FOUND)
|
||||
set(OPENCL_LIBRARIES ${OPENCL_LIBRARY})
|
||||
set(HAVE_OPENCL 1)
|
||||
else()
|
||||
set(OPENCL_LIBRARIES)
|
||||
endif()
|
||||
else()
|
||||
set(HAVE_OPENCL 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -19,18 +19,25 @@ unset(HAVE_SPHINX CACHE)
|
||||
if(PYTHON_EXECUTABLE)
|
||||
if(PYTHON_VERSION_STRING)
|
||||
set(PYTHON_VERSION_MAJOR_MINOR "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
|
||||
string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" PYTHON_VERSION_FULL "${PYTHON_VERSION_STRING}")
|
||||
set(PYTHON_VERSION_FULL "${PYTHON_VERSION_STRING}")
|
||||
else()
|
||||
execute_process(COMMAND ${PYTHON_EXECUTABLE} --version
|
||||
ERROR_VARIABLE PYTHON_VERSION_FULL
|
||||
ERROR_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
string(REGEX MATCH "[0-9]+.[0-9]+" PYTHON_VERSION_MAJOR_MINOR "${PYTHON_VERSION_FULL}")
|
||||
string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" PYTHON_VERSION_FULL "${PYTHON_VERSION_FULL}")
|
||||
endif()
|
||||
|
||||
if("${PYTHON_VERSION_FULL}" MATCHES "[0-9]+.[0-9]+.[0-9]+")
|
||||
set(PYTHON_VERSION_FULL "${CMAKE_MATCH_0}")
|
||||
elseif("${PYTHON_VERSION_FULL}" MATCHES "[0-9]+.[0-9]+")
|
||||
set(PYTHON_VERSION_FULL "${CMAKE_MATCH_0}")
|
||||
else()
|
||||
unset(PYTHON_VERSION_FULL)
|
||||
endif()
|
||||
|
||||
if(NOT ANDROID AND NOT IOS)
|
||||
if(CMAKE_VERSION VERSION_GREATER 2.8.8)
|
||||
if(CMAKE_VERSION VERSION_GREATER 2.8.8 AND PYTHON_VERSION_FULL)
|
||||
find_host_package(PythonLibs ${PYTHON_VERSION_FULL} EXACT)
|
||||
else()
|
||||
find_host_package(PythonLibs ${PYTHON_VERSION_FULL})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
if(ANDROID AND NOT MIPS)
|
||||
if(BUILD_TBB)
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/tbb")
|
||||
include_directories(SYSTEM ${TBB_INCLUDE_DIRS})
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} tbb)
|
||||
@@ -22,7 +22,7 @@ endif()
|
||||
|
||||
if(NOT HAVE_TBB)
|
||||
set(TBB_DEFAULT_INCLUDE_DIRS
|
||||
"/opt/intel/tbb" "/usr/local/include" "/usr/include"
|
||||
"/opt/intel/tbb/include" "/usr/local/include" "/usr/include"
|
||||
"C:/Program Files/Intel/TBB" "C:/Program Files (x86)/Intel/TBB"
|
||||
"C:/Program Files (x86)/tbb/include"
|
||||
"C:/Program Files (x86)/tbb/include"
|
||||
|
||||
@@ -16,7 +16,7 @@ endif()
|
||||
# Source package, for "make package_source"
|
||||
# ----------------------------------------------------------------------------
|
||||
if(BUILD_PACKAGE)
|
||||
set(TARBALL_NAME "${CMAKE_PROJECT_NAME}-${OPENCV_VERSION_MAJOR}.${OPENCV_VERSION_MINOR}.${OPENCV_VERSION_PATCH}")
|
||||
set(TARBALL_NAME "${CMAKE_PROJECT_NAME}-${OPENCV_VERSION}")
|
||||
if (NOT WIN32)
|
||||
if(APPLE)
|
||||
set(TAR_CMD gnutar)
|
||||
|
||||
@@ -7,11 +7,6 @@ if(WITH_TBB)
|
||||
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVDetectTBB.cmake")
|
||||
endif(WITH_TBB)
|
||||
|
||||
# --- C= ---
|
||||
if(WITH_CSTRIPES)
|
||||
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVDetectCStripes.cmake")
|
||||
endif(WITH_CSTRIPES)
|
||||
|
||||
# --- IPP ---
|
||||
ocv_clear_vars(IPP_FOUND)
|
||||
if(WITH_IPP)
|
||||
@@ -32,7 +27,7 @@ endif(WITH_CUDA)
|
||||
# --- Eigen ---
|
||||
if(WITH_EIGEN)
|
||||
find_path(EIGEN_INCLUDE_PATH "Eigen/Core"
|
||||
PATHS /usr/local /opt /usr $ENV{EIGEN_ROOT}/include ENV ProgramFiles ENV ProgramW6432
|
||||
PATHS /usr/local /opt /usr 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)
|
||||
@@ -44,41 +39,34 @@ if(WITH_EIGEN)
|
||||
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()
|
||||
# --- C= ---
|
||||
if(WITH_CSTRIPES AND NOT HAVE_TBB)
|
||||
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVDetectCStripes.cmake")
|
||||
else()
|
||||
set(HAVE_CSTRIPES 0)
|
||||
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)
|
||||
# --- OpenMP ---
|
||||
if(NOT HAVE_TBB AND NOT HAVE_CSTRIPES)
|
||||
set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/omptest.cpp")
|
||||
FILE(WRITE "${_fname}" "#ifndef _OPENMP\n#error\n#endif\nint main() { return 0; }\n")
|
||||
TRY_COMPILE(HAVE_OPENMP "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp" "${_fname}")
|
||||
else()
|
||||
set(HAVE_OPENMP 0)
|
||||
endif()
|
||||
|
||||
# --- GCD ---
|
||||
if(APPLE AND NOT HAVE_TBB AND NOT HAVE_CSTRIPES AND NOT HAVE_OPENMP)
|
||||
set(HAVE_GCD 1)
|
||||
else()
|
||||
set(HAVE_GCD 0)
|
||||
endif()
|
||||
|
||||
# --- Concurrency ---
|
||||
if(MSVC AND NOT HAVE_TBB AND NOT HAVE_CSTRIPES AND NOT HAVE_OPENMP)
|
||||
set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/concurrencytest.cpp")
|
||||
FILE(WRITE "${_fname}" "#if _MSC_VER < 1600\n#error\n#endif\nint main() { return 0; }\n")
|
||||
TRY_COMPILE(HAVE_CONCURRENCY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp" "${_fname}")
|
||||
else()
|
||||
set(HAVE_CONCURRENCY 0)
|
||||
endif()
|
||||
|
||||
@@ -56,6 +56,19 @@ 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)
|
||||
@@ -72,11 +85,12 @@ if(WITH_XINE)
|
||||
endif(WITH_XINE)
|
||||
|
||||
# --- V4L ---
|
||||
ocv_clear_vars(HAVE_LIBV4L HAVE_CAMV4L HAVE_CAMV4L2)
|
||||
ocv_clear_vars(HAVE_LIBV4L HAVE_CAMV4L HAVE_CAMV4L2 HAVE_VIDEOIO)
|
||||
if(WITH_V4L)
|
||||
CHECK_MODULE(libv4l1 HAVE_LIBV4L)
|
||||
CHECK_INCLUDE_FILE(linux/videodev.h HAVE_CAMV4L)
|
||||
CHECK_INCLUDE_FILE(linux/videodev2.h HAVE_CAMV4L2)
|
||||
CHECK_INCLUDE_FILE(sys/videoio.h HAVE_VIDEOIO)
|
||||
endif(WITH_V4L)
|
||||
|
||||
# --- OpenNI ---
|
||||
|
||||
@@ -20,7 +20,7 @@ if(ANDROID)
|
||||
endif()
|
||||
|
||||
# setup lists of camera libs
|
||||
foreach(abi ARMEABI ARMEABI_V7A X86)
|
||||
foreach(abi ARMEABI ARMEABI_V7A X86 MIPS)
|
||||
ANDROID_GET_ABI_RAWNAME(${abi} ndkabi)
|
||||
if(BUILD_ANDROID_CAMERA_WRAPPER)
|
||||
if(ndkabi STREQUAL ANDROID_NDK_ABI_NAME)
|
||||
|
||||
@@ -53,6 +53,10 @@ if(OpenCV_LIB_COMPONENTS)
|
||||
list(REMOVE_ITEM OPENCV_MODULES_CONFIGCMAKE ${OpenCV_LIB_COMPONENTS})
|
||||
endif()
|
||||
|
||||
if(BUILD_FAT_JAVA_LIB AND HAVE_opencv_java)
|
||||
list(APPEND OPENCV_MODULES_CONFIGCMAKE opencv_java)
|
||||
endif()
|
||||
|
||||
macro(ocv_generate_dependencies_map_configcmake suffix configuration)
|
||||
set(OPENCV_DEPENDENCIES_MAP_${suffix} "")
|
||||
set(OPENCV_PROCESSED_LIBS "")
|
||||
@@ -126,8 +130,13 @@ configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.
|
||||
set(OpenCV_INCLUDE_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OPENCV_INCLUDE_INSTALL_PATH}/opencv" "\${OpenCV_INSTALL_PATH}/${OPENCV_INCLUDE_INSTALL_PATH}\"")
|
||||
|
||||
set(OpenCV2_INCLUDE_DIRS_CONFIGCMAKE "\"\"")
|
||||
set(OpenCV_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OPENCV_LIB_INSTALL_PATH}\"")
|
||||
set(OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OPENCV_3P_LIB_INSTALL_PATH}\"")
|
||||
if(ANDROID)
|
||||
set(OpenCV_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/sdk/native/libs/\${ANDROID_NDK_ABI_NAME}\"")
|
||||
set(OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/sdk/native/3rdparty/libs/\${ANDROID_NDK_ABI_NAME}\"")
|
||||
else()
|
||||
set(OpenCV_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OPENCV_LIB_INSTALL_PATH}\"")
|
||||
set(OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OPENCV_3P_LIB_INSTALL_PATH}\"")
|
||||
endif()
|
||||
if(INSTALL_TO_MANGLED_PATHS)
|
||||
string(REPLACE "OpenCV" "OpenCV-${OPENCV_VERSION}" OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "${OPENCV_3P_LIB_INSTALL_PATH}")
|
||||
set(OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE}\"")
|
||||
|
||||
@@ -164,6 +164,9 @@ macro(ocv_module_disable module)
|
||||
set(HAVE_${__modname} OFF CACHE INTERNAL "Module ${__modname} can not be built in current configuration")
|
||||
set(OPENCV_MODULE_${__modname}_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "Location of ${__modname} module sources")
|
||||
set(OPENCV_MODULES_DISABLED_FORCE "${OPENCV_MODULES_DISABLED_FORCE}" CACHE INTERNAL "List of OpenCV modules which can not be build in current configuration")
|
||||
if(BUILD_${__modname})
|
||||
# touch variable controlling build of the module to suppress "unused variable" CMake warning
|
||||
endif()
|
||||
unset(__modname)
|
||||
return() # leave the current folder
|
||||
endmacro()
|
||||
@@ -171,6 +174,7 @@ endmacro()
|
||||
|
||||
# Internal macro; partly disables OpenCV module
|
||||
macro(__ocv_module_turn_off the_module)
|
||||
list(REMOVE_ITEM OPENCV_MODULES_DISABLED_AUTO "${the_module}")
|
||||
list(APPEND OPENCV_MODULES_DISABLED_AUTO "${the_module}")
|
||||
list(REMOVE_ITEM OPENCV_MODULES_BUILD "${the_module}")
|
||||
list(REMOVE_ITEM OPENCV_MODULES_PUBLIC "${the_module}")
|
||||
@@ -190,7 +194,7 @@ macro(__ocv_flatten_module_required_dependencies the_module)
|
||||
break()
|
||||
elseif(";${OPENCV_MODULES_DISABLED_USER};${OPENCV_MODULES_DISABLED_AUTO};" MATCHES ";${__dep};")
|
||||
__ocv_module_turn_off(${the_module}) # depends on disabled module
|
||||
break()
|
||||
list(APPEND __flattened_deps "${__dep}")
|
||||
elseif(";${OPENCV_MODULES_BUILD};" MATCHES ";${__dep};")
|
||||
if(";${__resolved_deps};" MATCHES ";${__dep};")
|
||||
list(APPEND __flattened_deps "${__dep}") # all dependencies of this module are already resolved
|
||||
@@ -259,6 +263,7 @@ macro(__ocv_flatten_module_dependencies)
|
||||
foreach(m ${OPENCV_MODULES_BUILD})
|
||||
set(HAVE_${m} ON CACHE INTERNAL "Module ${m} will be built in current configuration")
|
||||
__ocv_flatten_module_required_dependencies(${m})
|
||||
set(OPENCV_MODULE_${m}_DEPS ${OPENCV_MODULE_${m}_DEPS} CACHE INTERNAL "Flattened required dependencies of ${m} module")
|
||||
endforeach()
|
||||
|
||||
foreach(m ${OPENCV_MODULES_BUILD})
|
||||
@@ -283,7 +288,7 @@ macro(__ocv_flatten_module_dependencies)
|
||||
ocv_list_unique(OPENCV_MODULES_BUILD_)
|
||||
|
||||
set(OPENCV_MODULES_PUBLIC ${OPENCV_MODULES_PUBLIC} CACHE INTERNAL "List of OpenCV modules marked for export")
|
||||
set(OPENCV_MODULES_BUILD ${OPENCV_MODULES_BUILD_} CACHE INTERNAL "List of OpenCV modules included into the build")
|
||||
set(OPENCV_MODULES_BUILD ${OPENCV_MODULES_BUILD_} CACHE INTERNAL "List of OpenCV modules included into the build")
|
||||
set(OPENCV_MODULES_DISABLED_AUTO ${OPENCV_MODULES_DISABLED_AUTO} CACHE INTERNAL "List of OpenCV modules implicitly disabled due to dependencies")
|
||||
endmacro()
|
||||
|
||||
@@ -456,6 +461,7 @@ macro(ocv_create_module)
|
||||
OUTPUT_NAME "${the_module}${OPENCV_DLLVERSION}"
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
INSTALL_NAME_DIR lib
|
||||
)
|
||||
@@ -465,7 +471,7 @@ macro(ocv_create_module)
|
||||
# Android SDK build scripts can include only .so files into final .apk
|
||||
# As result we should not set version properties for Android
|
||||
set_target_properties(${the_module} PROPERTIES
|
||||
VERSION ${OPENCV_VERSION}
|
||||
VERSION ${OPENCV_LIBVERSION}
|
||||
SOVERSION ${OPENCV_SOVERSION}
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -64,6 +64,13 @@ MACRO(ocv_check_compiler_flag LANG FLAG RESULT)
|
||||
else()
|
||||
FILE(WRITE "${_fname}" "#pragma\nint main(void) { return 0; }\n")
|
||||
endif()
|
||||
elseif("_${LANG}_" MATCHES "_OBJCXX_")
|
||||
set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.mm")
|
||||
if("${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
|
||||
FILE(WRITE "${_fname}" "int main() { return 0; }\n")
|
||||
else()
|
||||
FILE(WRITE "${_fname}" "#pragma\nint main() { return 0; }\n")
|
||||
endif()
|
||||
else()
|
||||
unset(_fname)
|
||||
endif()
|
||||
@@ -100,6 +107,8 @@ macro(ocv_check_flag_support lang flag varname)
|
||||
set(_lang CXX)
|
||||
elseif("_${lang}_" MATCHES "_C_")
|
||||
set(_lang C)
|
||||
elseif("_${lang}_" MATCHES "_OBJCXX_")
|
||||
set(_lang OBJCXX)
|
||||
else()
|
||||
set(_lang ${lang})
|
||||
endif()
|
||||
@@ -132,7 +141,7 @@ macro(ocv_warnings_disable)
|
||||
set(${var} "${${var}} ${warning}")
|
||||
endforeach()
|
||||
endforeach()
|
||||
elseif(CV_COMPILER_IS_GNU AND _gxx_warnings AND _flag_vars)
|
||||
elseif((CMAKE_COMPILER_IS_GNUCXX OR (UNIX AND CV_ICC)) AND _gxx_warnings AND _flag_vars)
|
||||
foreach(var ${_flag_vars})
|
||||
foreach(warning ${_gxx_warnings})
|
||||
if(NOT warning MATCHES "^-Wno-")
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
SET(OPENCV_VERSION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/modules/core/include/opencv2/core/version.hpp")
|
||||
FILE(STRINGS "${OPENCV_VERSION_FILE}" OPENCV_VERSION_PARTS REGEX "#define CV_.+OR_VERSION[ ]+[0-9]+" )
|
||||
FILE(STRINGS "${OPENCV_VERSION_FILE}" OPENCV_VERSION_PARTS REGEX "#define CV_VERSION_[A-Z]+[ ]+[0-9]+" )
|
||||
|
||||
string(REGEX REPLACE ".+CV_MAJOR_VERSION[ ]+([0-9]+).*" "\\1" OPENCV_VERSION_MAJOR "${OPENCV_VERSION_PARTS}")
|
||||
string(REGEX REPLACE ".+CV_MINOR_VERSION[ ]+([0-9]+).*" "\\1" OPENCV_VERSION_MINOR "${OPENCV_VERSION_PARTS}")
|
||||
string(REGEX REPLACE ".+CV_SUBMINOR_VERSION[ ]+([0-9]+).*" "\\1" OPENCV_VERSION_PATCH "${OPENCV_VERSION_PARTS}")
|
||||
string(REGEX REPLACE ".+CV_VERSION_EPOCH[ ]+([0-9]+).*" "\\1" OPENCV_VERSION_MAJOR "${OPENCV_VERSION_PARTS}")
|
||||
string(REGEX REPLACE ".+CV_VERSION_MAJOR[ ]+([0-9]+).*" "\\1" OPENCV_VERSION_MINOR "${OPENCV_VERSION_PARTS}")
|
||||
string(REGEX REPLACE ".+CV_VERSION_MINOR[ ]+([0-9]+).*" "\\1" OPENCV_VERSION_PATCH "${OPENCV_VERSION_PARTS}")
|
||||
string(REGEX REPLACE ".+CV_VERSION_REVISION[ ]+([0-9]+).*" "\\1" OPENCV_VERSION_TWEAK "${OPENCV_VERSION_PARTS}")
|
||||
|
||||
set(OPENCV_VERSION "${OPENCV_VERSION_MAJOR}.${OPENCV_VERSION_MINOR}.${OPENCV_VERSION_PATCH}")
|
||||
if(OPENCV_VERSION_TWEAK GREATER 0)
|
||||
set(OPENCV_VERSION "${OPENCV_VERSION}.${OPENCV_VERSION_TWEAK}")
|
||||
endif()
|
||||
|
||||
set(OPENCV_SOVERSION "${OPENCV_VERSION_MAJOR}.${OPENCV_VERSION_MINOR}")
|
||||
set(OPENCV_LIBVERSION "${OPENCV_VERSION_MAJOR}.${OPENCV_VERSION_MINOR}.${OPENCV_VERSION_PATCH}")
|
||||
|
||||
# create a dependency on version file
|
||||
# we never use output of the following command but cmake will rerun automatically if the version file changes
|
||||
|
||||
@@ -42,7 +42,7 @@ else
|
||||
OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@
|
||||
endif
|
||||
ifeq ($(TARGET_ARCH_ABI),mips)
|
||||
OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB@
|
||||
OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE@
|
||||
OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@
|
||||
endif
|
||||
endif
|
||||
@@ -57,6 +57,9 @@ ifeq (${OPENCV_CAMERA_MODULES},on)
|
||||
ifeq ($(TARGET_ARCH_ABI),x86)
|
||||
OPENCV_CAMERA_MODULES:=@OPENCV_CAMERA_LIBS_X86_CONFIGCMAKE@
|
||||
endif
|
||||
ifeq ($(TARGET_ARCH_ABI),mips)
|
||||
OPENCV_CAMERA_MODULES:=@OPENCV_CAMERA_LIBS_MIPS_CONFIGCMAKE@
|
||||
endif
|
||||
else
|
||||
OPENCV_CAMERA_MODULES:=
|
||||
endif
|
||||
@@ -89,14 +92,20 @@ define add_opencv_camera_module
|
||||
include $(PREBUILT_SHARED_LIBRARY)
|
||||
endef
|
||||
|
||||
ifeq ($(OPENCV_INSTALL_MODULES),on)
|
||||
$(foreach module,$(OPENCV_LIBS),$(eval $(call add_opencv_module,$(module))))
|
||||
endif
|
||||
$(foreach module,$(OPENCV_3RDPARTY_COMPONENTS),$(eval $(call add_opencv_3rdparty_component,$(module))))
|
||||
$(foreach module,$(OPENCV_CAMERA_MODULES),$(eval $(call add_opencv_camera_module,$(module))))
|
||||
ifeq ($(OPENCV_MK_$(OPENCV_TARGET_ARCH_ABI)_ALREADY_INCLUDED),)
|
||||
ifeq ($(OPENCV_INSTALL_MODULES),on)
|
||||
$(foreach module,$(OPENCV_LIBS),$(eval $(call add_opencv_module,$(module))))
|
||||
endif
|
||||
|
||||
ifneq ($(OPENCV_BASEDIR),)
|
||||
OPENCV_LOCAL_C_INCLUDES += $(foreach mod, $(OPENCV_MODULES), $(OPENCV_BASEDIR)/modules/$(mod)/include)
|
||||
$(foreach module,$(OPENCV_3RDPARTY_COMPONENTS),$(eval $(call add_opencv_3rdparty_component,$(module))))
|
||||
$(foreach module,$(OPENCV_CAMERA_MODULES),$(eval $(call add_opencv_camera_module,$(module))))
|
||||
|
||||
ifneq ($(OPENCV_BASEDIR),)
|
||||
OPENCV_LOCAL_C_INCLUDES += $(foreach mod, $(OPENCV_MODULES), $(OPENCV_BASEDIR)/modules/$(mod)/include)
|
||||
endif
|
||||
|
||||
#turn off module installation to prevent their redefinition
|
||||
OPENCV_MK_$(OPENCV_TARGET_ARCH_ABI)_ALREADY_INCLUDED:=on
|
||||
endif
|
||||
|
||||
ifeq ($(OPENCV_LOCAL_CFLAGS),)
|
||||
|
||||
@@ -22,10 +22,11 @@
|
||||
# - OpenCV_INCLUDE_DIRS : The OpenCV include directories.
|
||||
# - OpenCV_COMPUTE_CAPABILITIES : The version of compute capability
|
||||
# - OpenCV_ANDROID_NATIVE_API_LEVEL : Minimum required level of Android API
|
||||
# - OpenCV_VERSION : The version of this OpenCV build. Example: "@OPENCV_VERSION@"
|
||||
# - OpenCV_VERSION_MAJOR : Major version part of OpenCV_VERSION. Example: "@OPENCV_VERSION_MAJOR@"
|
||||
# - OpenCV_VERSION_MINOR : Minor version part of OpenCV_VERSION. Example: "@OPENCV_VERSION_MINOR@"
|
||||
# - OpenCV_VERSION_PATCH : Patch version part of OpenCV_VERSION. Example: "@OPENCV_VERSION_PATCH@"
|
||||
# - OpenCV_VERSION : The version of this OpenCV build: "@OPENCV_VERSION@"
|
||||
# - OpenCV_VERSION_MAJOR : Major version part of OpenCV_VERSION: "@OPENCV_VERSION_MAJOR@"
|
||||
# - OpenCV_VERSION_MINOR : Minor version part of OpenCV_VERSION: "@OPENCV_VERSION_MINOR@"
|
||||
# - OpenCV_VERSION_PATCH : Patch version part of OpenCV_VERSION: "@OPENCV_VERSION_PATCH@"
|
||||
# - OpenCV_VERSION_TWEAK : Tweak version part of OpenCV_VERSION: "@OPENCV_VERSION_TWEAK@"
|
||||
#
|
||||
# Advanced variables:
|
||||
# - OpenCV_SHARED
|
||||
@@ -41,8 +42,9 @@
|
||||
set(OpenCV_COMPUTE_CAPABILITIES @OpenCV_CUDA_CC_CONFIGCMAKE@)
|
||||
|
||||
set(OpenCV_CUDA_VERSION @OpenCV_CUDA_VERSION@)
|
||||
set(OpenCV_USE_CUBLAS @HAVE_CUBLAS@)
|
||||
set(OpenCV_USE_CUFFT @HAVE_CUFFT@)
|
||||
set(OpenCV_USE_CUBLAS @HAVE_CUBLAS@)
|
||||
set(OpenCV_USE_CUFFT @HAVE_CUFFT@)
|
||||
set(OpenCV_USE_NVCUVID @HAVE_NVCUVID@)
|
||||
|
||||
# Android API level from which OpenCV has been compiled is remembered
|
||||
set(OpenCV_ANDROID_NATIVE_API_LEVEL @OpenCV_ANDROID_NATIVE_API_LEVEL_CONFIGCMAKE@)
|
||||
@@ -99,6 +101,7 @@ SET(OpenCV_VERSION @OPENCV_VERSION@)
|
||||
SET(OpenCV_VERSION_MAJOR @OPENCV_VERSION_MAJOR@)
|
||||
SET(OpenCV_VERSION_MINOR @OPENCV_VERSION_MINOR@)
|
||||
SET(OpenCV_VERSION_PATCH @OPENCV_VERSION_PATCH@)
|
||||
SET(OpenCV_VERSION_TWEAK @OPENCV_VERSION_TWEAK@)
|
||||
|
||||
# ====================================================================
|
||||
# Link libraries: e.g. libopencv_core.so, opencv_imgproc220d.lib, etc...
|
||||
@@ -148,6 +151,7 @@ endif()
|
||||
# ==============================================================
|
||||
if(NOT OpenCV_FIND_COMPONENTS)
|
||||
set(OpenCV_FIND_COMPONENTS ${OpenCV_LIB_COMPONENTS})
|
||||
list(REMOVE_ITEM OpenCV_FIND_COMPONENTS opencv_java)
|
||||
if(GTest_FOUND OR GTEST_FOUND)
|
||||
list(REMOVE_ITEM OpenCV_FIND_COMPONENTS opencv_ts)
|
||||
endif()
|
||||
@@ -183,7 +187,7 @@ set(OpenCV_FIND_COMPONENTS ${OpenCV_FIND_COMPONENTS_})
|
||||
# Resolve dependencies
|
||||
# ==============================================================
|
||||
if(OpenCV_USE_MANGLED_PATHS)
|
||||
set(OpenCV_LIB_SUFFIX ".${OpenCV_VERSION}")
|
||||
set(OpenCV_LIB_SUFFIX ".${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.${OpenCV_VERSION_PATCH}")
|
||||
else()
|
||||
set(OpenCV_LIB_SUFFIX "")
|
||||
endif()
|
||||
@@ -198,7 +202,7 @@ foreach(__opttype OPT DBG)
|
||||
#indicate that this module is also found
|
||||
string(TOUPPER "${__cvdep}" __cvdep)
|
||||
set(${__cvdep}_FOUND 1)
|
||||
else()
|
||||
elseif(EXISTS "${OpenCV_3RDPARTY_LIB_DIR_${__opttype}}/${OpenCV_${__cvdep}_LIBNAME_${__opttype}}")
|
||||
list(APPEND OpenCV_LIBS_${__opttype} "${OpenCV_3RDPARTY_LIB_DIR_${__opttype}}/${OpenCV_${__cvdep}_LIBNAME_${__opttype}}")
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -216,17 +220,18 @@ foreach(__opttype OPT DBG)
|
||||
else()
|
||||
#TODO: duplicates are annoying but they should not be the problem
|
||||
endif()
|
||||
# fix hard coded paths for CUDA libraries under Windows
|
||||
if(WIN32 AND OpenCV_CUDA_VERSION AND NOT OpenCV_SHARED)
|
||||
|
||||
# CUDA
|
||||
if(OpenCV_CUDA_VERSION AND (CMAKE_CROSSCOMPILING OR (WIN32 AND NOT OpenCV_SHARED)))
|
||||
if(NOT CUDA_FOUND)
|
||||
find_package(CUDA ${OpenCV_CUDA_VERSION} EXACT REQUIRED)
|
||||
else()
|
||||
if(NOT CUDA_VERSION_STRING VERSION_EQUAL OpenCV_CUDA_VERSION)
|
||||
message(FATAL_ERROR "OpenCV static library compiled with CUDA ${OpenCV_CUDA_VERSION} support. Please, use the same version or rebuild OpenCV with CUDA ${CUDA_VERSION_STRING}")
|
||||
message(FATAL_ERROR "OpenCV static library was compiled with CUDA ${OpenCV_CUDA_VERSION} support. Please, use the same version or rebuild OpenCV with CUDA ${CUDA_VERSION_STRING}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY} ${CUDA_nvcuvid_LIBRARY} ${CUDA_nvcuvenc_LIBRARY})
|
||||
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
|
||||
|
||||
if(OpenCV_USE_CUBLAS)
|
||||
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_CUBLAS_LIBRARIES})
|
||||
@@ -236,6 +241,13 @@ foreach(__opttype OPT DBG)
|
||||
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_CUFFT_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(OpenCV_USE_NVCUVID)
|
||||
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_nvcuvid_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_nvcuvenc_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
@@ -293,3 +305,11 @@ else()
|
||||
SET(OpenCV_LIB_DIR ${OpenCV_LIB_DIR_OPT} ${OpenCV_3RDPARTY_LIB_DIR_OPT})
|
||||
endif()
|
||||
set(OpenCV_LIBRARIES ${OpenCV_LIBS})
|
||||
|
||||
if(CMAKE_CROSSCOMPILING AND OpenCV_SHARED AND (CMAKE_SYSTEM_NAME MATCHES "Linux"))
|
||||
foreach(dir ${OpenCV_LIB_DIR})
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,${dir}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath-link,${dir}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-rpath-link,${dir}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
/* V4L2 capturing support */
|
||||
#cmakedefine HAVE_CAMV4L2
|
||||
|
||||
/* V4L2 capturing support in videoio.h */
|
||||
#cmakedefine HAVE_VIDEOIO
|
||||
|
||||
/* V4L/V4L2 capturing support via libv4l */
|
||||
#cmakedefine HAVE_LIBV4L
|
||||
|
||||
@@ -58,6 +61,9 @@
|
||||
/* 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
|
||||
|
||||
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+16
-9
@@ -60,7 +60,7 @@ if(BUILD_DOCS AND HAVE_SPHINX)
|
||||
|
||||
configure_file("${OpenCV_SOURCE_DIR}/modules/refman.rst.in" "${OpenCV_SOURCE_DIR}/modules/refman.rst" IMMEDIATE @ONLY)
|
||||
|
||||
file(GLOB_RECURSE OPENCV_FILES_UG user_guide/*.rst)
|
||||
file(GLOB_RECURSE OPENCV_FILES_UG user_guide/*.rst)
|
||||
file(GLOB_RECURSE OPENCV_FILES_TUT tutorials/*.rst)
|
||||
file(GLOB_RECURSE OPENCV_FILES_TUT_PICT tutorials/*.png tutorials/*.jpg)
|
||||
|
||||
@@ -74,14 +74,21 @@ if(BUILD_DOCS AND HAVE_SPHINX)
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/mymath.sty ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/patch_refman_latex.py" opencv2refman.tex
|
||||
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/patch_refman_latex.py" opencv2manager.tex
|
||||
COMMAND ${PDFLATEX_COMPILER} opencv2refman.tex
|
||||
COMMAND ${PDFLATEX_COMPILER} opencv2refman.tex
|
||||
COMMAND ${PDFLATEX_COMPILER} opencv2manager.tex
|
||||
COMMAND ${PDFLATEX_COMPILER} opencv2manager.tex
|
||||
COMMAND ${PDFLATEX_COMPILER} opencv_user.tex
|
||||
COMMAND ${PDFLATEX_COMPILER} opencv_user.tex
|
||||
COMMAND ${PDFLATEX_COMPILER} opencv_tutorials.tex
|
||||
COMMAND ${PDFLATEX_COMPILER} opencv_tutorials.tex
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Generating opencv2refman.pdf"
|
||||
COMMAND ${PDFLATEX_COMPILER} -interaction=batchmode opencv2refman.tex
|
||||
COMMAND ${PDFLATEX_COMPILER} -interaction=batchmode opencv2refman.tex
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Generating opencv2manager.pdf"
|
||||
COMMAND ${PDFLATEX_COMPILER} -interaction=batchmode opencv2manager.tex
|
||||
COMMAND ${PDFLATEX_COMPILER} -interaction=batchmode opencv2manager.tex
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Generating opencv_user.pdf"
|
||||
COMMAND ${PDFLATEX_COMPILER} -interaction=batchmode opencv_user.tex
|
||||
COMMAND ${PDFLATEX_COMPILER} -interaction=batchmode opencv_user.tex
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Generating opencv_tutorials.pdf"
|
||||
COMMAND ${PDFLATEX_COMPILER} -interaction=batchmode opencv_tutorials.tex
|
||||
COMMAND ${PDFLATEX_COMPILER} -interaction=batchmode opencv_tutorials.tex
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Generating opencv_cheatsheet.pdf"
|
||||
COMMAND ${PDFLATEX_COMPILER} -interaction=batchmode "${CMAKE_CURRENT_SOURCE_DIR}/opencv_cheatsheet.tex"
|
||||
COMMAND ${PDFLATEX_COMPILER} -interaction=batchmode "${CMAKE_CURRENT_SOURCE_DIR}/opencv_cheatsheet.tex"
|
||||
DEPENDS ${OPENCV_DOC_DEPS}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating the PDF Manuals"
|
||||
|
||||
@@ -38,7 +38,7 @@ doc_signatures_whitelist = [
|
||||
"CvArr", "CvFileStorage",
|
||||
# other
|
||||
"InputArray", "OutputArray",
|
||||
]
|
||||
] + ["CvSubdiv2D", "CvQuadEdge2D", "CvSubdiv2DPoint", "cvDrawContours"]
|
||||
|
||||
defines = ["cvGraphEdgeIdx", "cvFree", "CV_Assert", "cvSqrt", "cvGetGraphVtx", "cvGraphVtxIdx",
|
||||
"cvCaptureFromFile", "cvCaptureFromCAM", "cvCalcBackProjectPatch", "cvCalcBackProject",
|
||||
@@ -116,6 +116,8 @@ def compareSignatures(f, s):
|
||||
sarg = arg[1]
|
||||
ftype = re.sub(r"\b(cv|std)::", "", (farg[0] or ""))
|
||||
stype = re.sub(r"\b(cv|std)::", "", (sarg[0] or ""))
|
||||
ftype = re.sub(r"\s+(\*|&)$", "\\1", ftype)
|
||||
stype = re.sub(r"\s+(\*|&)$", "\\1", stype)
|
||||
if ftype != stype:
|
||||
return False, "type of argument #" + str(idx+1) + " mismatch"
|
||||
fname = farg[1] or "arg" + str(idx)
|
||||
@@ -151,6 +153,7 @@ def formatSignature(s):
|
||||
if idx > 0:
|
||||
_str += ", "
|
||||
argtype = re.sub(r"\bcv::", "", arg[0])
|
||||
argtype = re.sub(r"\s+(\*|&)$", "\\1", arg[0])
|
||||
bidx = argtype.find('[')
|
||||
if bidx < 0:
|
||||
_str += argtype + " "
|
||||
|
||||
+9
-6
@@ -44,21 +44,24 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'OpenCV'
|
||||
copyright = u'2011-2012, opencv dev team'
|
||||
copyright = u'2011-2013, opencv dev team'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
|
||||
version_file = open("../modules/core/include/opencv2/core/version.hpp", "rt").read()
|
||||
version_major = re.search("^W*#\W*define\W+CV_MAJOR_VERSION\W+(\d+)\W*$", version_file, re.MULTILINE).group(1)
|
||||
version_minor = re.search("^W*#\W*define\W+CV_MINOR_VERSION\W+(\d+)\W*$", version_file, re.MULTILINE).group(1)
|
||||
version_patch = re.search("^W*#\W*define\W+CV_SUBMINOR_VERSION\W+(\d+)\W*$", version_file, re.MULTILINE).group(1)
|
||||
version_epoch = re.search("^W*#\W*define\W+CV_VERSION_EPOCH\W+(\d+)\W*$", version_file, re.MULTILINE).group(1)
|
||||
version_major = re.search("^W*#\W*define\W+CV_VERSION_MAJOR\W+(\d+)\W*$", version_file, re.MULTILINE).group(1)
|
||||
version_minor = re.search("^W*#\W*define\W+CV_VERSION_MINOR\W+(\d+)\W*$", version_file, re.MULTILINE).group(1)
|
||||
version_patch = re.search("^W*#\W*define\W+CV_VERSION_REVISION\W+(\d+)\W*$", version_file, re.MULTILINE).group(1)
|
||||
|
||||
# The short X.Y version.
|
||||
version = version_major + '.' + version_minor
|
||||
version = version_epoch + '.' + version_major
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = version_major + '.' + version_minor + '.' + version_patch
|
||||
release = version_epoch + '.' + version_major + '.' + version_minor
|
||||
if version_patch:
|
||||
release = release + '.' + version_patch
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
+57
-4
@@ -992,6 +992,11 @@ class DefinitionParser(object):
|
||||
return rv
|
||||
|
||||
def _parse_signature(self):
|
||||
if r'CvStatModel::train' in self.definition:
|
||||
# hack to skip parsing of problematic definition
|
||||
self.pos = self.end
|
||||
return [ArgumentDefExpr("const Mat&", "train_data", None), ArgumentDefExpr(None, self.definition[self.definition.find("["):-1], None)], False, True
|
||||
|
||||
self.skip_ws()
|
||||
if not self.skip_string('('):
|
||||
self.fail('expected parentheses for function')
|
||||
@@ -1075,6 +1080,17 @@ class DefinitionParser(object):
|
||||
value = None
|
||||
return MemberObjDefExpr(name, visibility, static, typename, value)
|
||||
|
||||
def parse_enum_member_object(self):
|
||||
visibility, static = self._parse_visibility_static()
|
||||
typename = None
|
||||
name = self._parse_type()
|
||||
self.skip_ws()
|
||||
if self.skip_string('='):
|
||||
value = self.read_rest().strip()
|
||||
else:
|
||||
value = None
|
||||
return MemberObjDefExpr(name, visibility, static, typename, value)
|
||||
|
||||
def parse_function(self):
|
||||
visibility, static = self._parse_visibility_static()
|
||||
if self.skip_word('explicit'):
|
||||
@@ -1180,6 +1196,8 @@ class OCVObject(ObjectDescription):
|
||||
def add_target_and_index(self, sigobj, sig, signode):
|
||||
theid = sig#obj.get_id()
|
||||
theid = re.sub(r" +", " ", theid)
|
||||
if self.objtype == 'emember':
|
||||
theid = re.sub(r" ?=.*", "", theid)
|
||||
theid = re.sub(r"=[^,()]+\([^)]*?\)[^,)]*(,|\))", "\\1", theid)
|
||||
theid = re.sub(r"=\w*[^,)(]+(,|\))", "\\1", theid)
|
||||
theid = theid.replace("( ", "(").replace(" )", ")")
|
||||
@@ -1293,6 +1311,25 @@ class OCVTypeObject(OCVObject):
|
||||
signode += nodes.Text(' ')
|
||||
self.attach_name(signode, obj.name)
|
||||
|
||||
class OCVEnumObject(OCVObject):
|
||||
|
||||
def get_index_text(self, name):
|
||||
if self.objtype == 'enum':
|
||||
return _('%s (enum)') % name
|
||||
return ''
|
||||
|
||||
def parse_definition(self, parser):
|
||||
return parser.parse_type_object()
|
||||
|
||||
def describe_signature(self, signode, obj):
|
||||
self.attach_modifiers(signode, obj)
|
||||
signode += addnodes.desc_annotation('enum ', 'enum ')
|
||||
if obj.typename is not None:
|
||||
self.attach_type(signode, obj.typename)
|
||||
signode += nodes.Text(' ')
|
||||
self.attach_name(signode, obj.name)
|
||||
|
||||
|
||||
class OCVMemberObject(OCVObject):
|
||||
ismember = True
|
||||
|
||||
@@ -1309,12 +1346,20 @@ class OCVMemberObject(OCVObject):
|
||||
|
||||
def describe_signature(self, signode, obj):
|
||||
self.attach_modifiers(signode, obj)
|
||||
self.attach_type(signode, obj.typename)
|
||||
signode += nodes.Text(' ')
|
||||
if obj.typename:
|
||||
self.attach_type(signode, obj.typename)
|
||||
signode += nodes.Text(' ')
|
||||
self.attach_name(signode, obj.name)
|
||||
if obj.value is not None:
|
||||
signode += nodes.Text(u' = ' + obj.value)
|
||||
|
||||
class OCVEnumMemberObject(OCVMemberObject):
|
||||
def parse_definition(self, parser):
|
||||
# parent_class = self.env.temp_data.get('ocv:parent')
|
||||
# if parent_class is None:
|
||||
# parser.fail("missing parent structure/class")
|
||||
return parser.parse_enum_member_object()
|
||||
|
||||
class OCVFunctionObject(OCVObject):
|
||||
|
||||
def attach_function(self, node, func):
|
||||
@@ -1448,7 +1493,9 @@ class OCVDomain(Domain):
|
||||
'pyfunction': ObjType(l_('pyfunction'), 'pyfunc'),
|
||||
'pyoldfunction': ObjType(l_('pyoldfunction'), 'pyoldfunc'),
|
||||
'member': ObjType(l_('member'), 'member'),
|
||||
'type': ObjType(l_('type'), 'type')
|
||||
'emember': ObjType(l_('emember'), 'emember'),
|
||||
'type': ObjType(l_('type'), 'type'),
|
||||
'enum': ObjType(l_('enum'), 'enum')
|
||||
}
|
||||
|
||||
directives = {
|
||||
@@ -1460,7 +1507,9 @@ class OCVDomain(Domain):
|
||||
'pyfunction': OCVPyModulelevel,
|
||||
'pyoldfunction': OCVPyOldModulelevel,
|
||||
'member': OCVMemberObject,
|
||||
'emember': OCVEnumMemberObject,
|
||||
'type': OCVTypeObject,
|
||||
'enum': OCVEnumObject,
|
||||
'namespace': OCVCurrentNamespace
|
||||
}
|
||||
roles = {
|
||||
@@ -1475,7 +1524,9 @@ class OCVDomain(Domain):
|
||||
'pyfunc' : OCVPyXRefRole(),
|
||||
'pyoldfunc' : OCVPyXRefRole(),
|
||||
'member': OCVXRefRole(),
|
||||
'type': OCVXRefRole()
|
||||
'emember': OCVXRefRole(),
|
||||
'type': OCVXRefRole(),
|
||||
'enum': OCVXRefRole()
|
||||
}
|
||||
initial_data = {
|
||||
'objects': {}, # fullname -> docname, objtype
|
||||
@@ -1563,7 +1614,9 @@ class OCVDomain(Domain):
|
||||
'pyfunction': _('Python function'),
|
||||
'pyoldfunction': _('Legacy Python function'),
|
||||
'member': _('C++ member'),
|
||||
'emember': _('enum member'),
|
||||
'type': _('C/C++ type'),
|
||||
'enum': _('C/C++ enum'),
|
||||
'namespace': _('C++ namespace'),
|
||||
}.get(type.lname, _('%s %s') % (self.label, type.lname))
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
\usepackage[pdftex]{color,graphicx}
|
||||
\usepackage[landscape]{geometry}
|
||||
\usepackage{hyperref}
|
||||
\usepackage[T1]{fontenc}
|
||||
\hypersetup{colorlinks=true, filecolor=black, linkcolor=black, urlcolor=blue, citecolor=black}
|
||||
\graphicspath{{./images/}}
|
||||
|
||||
@@ -214,7 +215,7 @@
|
||||
\> \texttt{for(int y = 1; y < image.rows-1; y++) \{}\\
|
||||
\> \> \texttt{Vec3b* prevRow = image.ptr<Vec3b>(y-1);}\\
|
||||
\> \> \texttt{Vec3b* nextRow = image.ptr<Vec3b>(y+1);}\\
|
||||
\> \> \texttt{for(int x = 0; y < image.cols; x++)}\\
|
||||
\> \> \texttt{for(int x = 0; x < image.cols; x++)}\\
|
||||
\> \> \> \texttt{for(int c = 0; c < 3; c++)}\\
|
||||
\> \> \> \texttt{ dyImage.at<Vec3b>(y,x)[c] =}\\
|
||||
\> \> \> \texttt{ saturate\_cast<uchar>(}\\
|
||||
|
||||
+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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -53,8 +53,8 @@ As usual, after the not-so-lengthy explanation, let's go to the code:
|
||||
std::cout<<"* Enter alpha [0-1]: ";
|
||||
std::cin>>input;
|
||||
|
||||
/// We use the alpha provided by the user iff it is between 0 and 1
|
||||
if( alpha >= 0 && alpha <= 1 )
|
||||
/// We use the alpha provided by the user if it is between 0 and 1
|
||||
if( input >= 0.0 && input <= 1.0 )
|
||||
{ alpha = input; }
|
||||
|
||||
/// Read image ( same size, same type )
|
||||
@@ -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,15 +117,17 @@ 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:
|
||||
|
||||
@@ -141,32 +143,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*
|
||||
@@ -174,17 +176,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:
|
||||
|
||||
@@ -200,43 +202,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:
|
||||
|
||||
@@ -252,11 +254,12 @@ 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,24 +10,26 @@ 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:
|
||||
|
||||
@@ -36,7 +38,7 @@ Image Processing
|
||||
|
||||
|
||||
Pixel Transforms
|
||||
-----------------
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
@@ -45,30 +47,32 @@ 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
|
||||
=====
|
||||
|
||||
* The following code performs the operation :math:`g(i,j) = \alpha \cdot f(i,j) + \beta` :
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
* The following code performs the operation :math:`g(i,j) = \alpha \cdot f(i,j) + \beta` :
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -83,37 +87,38 @@ 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
|
||||
@@ -128,42 +133,41 @@ 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.
|
||||
|
||||
@@ -171,7 +175,7 @@ Explanation
|
||||
#. Finally, we create windows and show the images, the usual way.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
|
||||
namedWindow("Original Image", 1);
|
||||
namedWindow("New Image", 1);
|
||||
|
||||
@@ -181,9 +185,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);
|
||||
@@ -205,6 +209,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*.
|
||||
|
||||
The file automatically closes when the :xmlymlpers:`FileStorage <filestorage>` objects is destroyed. However, you may explicitly call for this by using the *release* function:
|
||||
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:
|
||||
|
||||
.. 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
|
||||
|
||||
|
||||
+42
-40
@@ -6,26 +6,28 @@ Mat - The Basic Image Container
|
||||
Goal
|
||||
====
|
||||
|
||||
We have multiple ways to acquire digital images from the real world: digital cameras, scanners, computed tomography or magnetic resonance imaging to just name a few. In every case what we (humans) see are images. However, when transforming this to our digital devices what we record are numerical values for each of the points of the image.
|
||||
We have multiple ways to acquire digital images from the real world: digital cameras, scanners, computed tomography, and magnetic resonance imaging to name a few. In every case what we (humans) see are images. However, when transforming this to our digital devices what we record are numerical values for each of the points of the image.
|
||||
|
||||
.. image:: images/MatBasicImageForComputer.jpg
|
||||
:alt: A matrix of the mirror of a car
|
||||
:align: center
|
||||
|
||||
For example in the above image you can see that the mirror of the care is nothing more than a matrix containing all the intensity values of the pixel points. Now, how we get and store the pixels values may vary according to what fits best our need, in the end all images inside a computer world may be reduced to numerical matrices and some other information's describing the matric itself. *OpenCV* is a computer vision library whose main focus is to process and manipulate these information to find out further ones. Therefore, the first thing you need to learn and get accommodated with is how OpenCV stores and handles images.
|
||||
For example in the above image you can see that the mirror of the car is nothing more than a matrix containing all the intensity values of the pixel points. How we get and store the pixels values may vary according to our needs, but in the end all images inside a computer world may be reduced to numerical matrices and other information describing the matrix itself. *OpenCV* is a computer vision library whose main focus is to process and manipulate this information. Therefore, the first thing you need to be familiar with is how OpenCV stores and handles images.
|
||||
|
||||
*Mat*
|
||||
=====
|
||||
|
||||
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.
|
||||
OpenCV has been around since 2001. In those days the library was built around a *C* interface and to store the image in the memory they used a C structure called *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 memory management. It builds on the assumption that the user is responsible for taking care of memory allocation and deallocation. While this is not a problem with smaller programs, once your code base grows it will be more of a struggle to handle all this rather than focusing on 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 easier for the user through automatic memory management (more or less). The good news is that C++ is fully compatible with C so no compatibility issues can arise from making the change. Therefore, OpenCV 2.0 introduced a new C++ interface which offered a new way of doing things which means you do not need to fiddle with memory management, making your code concise (less to write, to achieve more). The main downside of the C++ interface is that many embedded development systems at the moment support only C. Therefore, unless you are targeting embedded platforms, there's no point to 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.
|
||||
The first thing you need to know about *Mat* is that you no longer need to manually allocate its memory 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, which has already allocated the required space for the matrix, this will be reused. In other words we use at all times only as much memory as we need 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.
|
||||
*Mat* is basically a class with 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 (taking 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 orders of magnitude.
|
||||
|
||||
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.
|
||||
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. Because of this, passing 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 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 pointers point to the same address. Moreover, the copy operators **will only copy the headers** and the pointer to the large matrix, not the data itself.
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
@@ -37,21 +39,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, and making a modification using any of them will affect all the other ones as well. 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 is that you can create headers which refer to only 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.
|
||||
Now you may ask if the matrix itself may belong to multiple *Mat* objects who takes responsibility for cleaning it up when it's no longer needed. The short answer is: the last object that used it. This is handled by using a reference counting mechanism. 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. Sometimes you will want to copy the matrix itself too, so OpenCV provides the :basicstructures:`clone() <mat-clone>` and :basicstructures:`copyTo() <mat-copyto>` functions.
|
||||
|
||||
.. 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:
|
||||
@@ -59,38 +61,38 @@ Now modifying *F* or *G* will not affect the matrix pointed by the *Mat* header.
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
* Output image allocation for OpenCV functions is automatic (unless specified otherwise).
|
||||
* No need to think about memory freeing with OpenCVs C++ interface.
|
||||
* The assignment operator and the copy constructor (*ctor*)copies only the header.
|
||||
* Use the :basicstructures:`clone()<mat-clone>` or the :basicstructures:`copyTo() <mat-copyto>` function to copy the underlying matrix of an image.
|
||||
* You do not need to think about memory management with OpenCVs C++ interface.
|
||||
* The assignment operator and the copy constructor only copies the header.
|
||||
* The underlying matrix of an image may be copied using the :basicstructures:`clone()<mat-clone>` and :basicstructures:`copyTo() <mat-copyto>` functions.
|
||||
|
||||
*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 where 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 methods to choose from. Each of them breaks it down to three or four basic components and we can use the combination of these to create the others. The most popular one is RGB, mainly because this is also how our eye builds up colors. 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:
|
||||
There are, however, many other 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. You might, for example, dismiss the last component, making your algorithm less sensible to the 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.
|
||||
Each of the building components has their own valid domains. This leads to the data type used. How we store a component defines the 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.
|
||||
|
||||
Creating explicitly a *Mat* object
|
||||
Creating a *Mat* object explicitly
|
||||
==================================
|
||||
|
||||
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 have already learned 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 do this using the << operator of *Mat*. 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:
|
||||
Although *Mat* works really well as an 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,13 +105,13 @@ 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 constructed according to the following convention:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The channel number]
|
||||
|
||||
For instance, *CV_8UC3* means we use unsigned char types that are 8 bit long and each pixel has three items of this to form the three channels. This are predefined for up to four channel numbers. The :basicstructures:`Scalar <scalar>` is four element short vector. Specify this and you can initialize all matrix points with a custom value. However if you need more you can create the type with the upper macro and putting the channel number in parenthesis as you can see below.
|
||||
For instance, *CV_8UC3* means we use unsigned char types that are 8 bit long and each pixel has three of these to form the three channels. This are predefined for up to four channel numbers. The :basicstructures:`Scalar <scalar>` is four element short vector. Specify this and you can initialize all matrix points with a custom value. If you need more you can create the type with the upper macro, setting the channel number in parenthesis as you can see below.
|
||||
|
||||
+ Use C\\C++ arrays and initialize via constructor
|
||||
|
||||
@@ -174,9 +176,9 @@ 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:
|
||||
You can fill out a matrix with random values using the :operationsOnArrays:`randu() <randu>` function. You need to give the lower and upper value for the random values:
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/mat_the_basic_image_container/mat_the_basic_image_container.cpp
|
||||
:language: cpp
|
||||
@@ -184,14 +186,14 @@ Although *Mat* is a great class as image container it is also a general matrix c
|
||||
:lines: 57-58
|
||||
|
||||
|
||||
Print out formatting
|
||||
====================
|
||||
Output 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. OpenCV, however, allows you to format your matrix output:
|
||||
|
||||
.. 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 +215,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
|
||||
@@ -246,14 +248,14 @@ In the above examples you could see the default formatting option. Nevertheless,
|
||||
:alt: Default Output
|
||||
:align: center
|
||||
|
||||
Print for other common items
|
||||
Output of other common items
|
||||
============================
|
||||
|
||||
OpenCV offers support for print of other common OpenCV data structures too via the << operator like:
|
||||
OpenCV offers support for output of other common OpenCV data structures too via the << operator:
|
||||
|
||||
.. 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
|
||||
@@ -298,9 +300,9 @@ OpenCV offers support for print of other common OpenCV data structures too via t
|
||||
:alt: Default Output
|
||||
:align: center
|
||||
|
||||
Most of the samples here have been included into a small console application. You can download it from :download:`here <../../../../samples/cpp/tutorial_code/core/mat_the_basic_image_container/mat_the_basic_image_container.cpp>` or in the core section of the cpp samples.
|
||||
Most of the samples here have been included in a small console application. You can download it from :download:`here <../../../../samples/cpp/tutorial_code/core/mat_the_basic_image_container/mat_the_basic_image_container.cpp>` or in the core section of the cpp samples.
|
||||
|
||||
A quick video demonstration of this you can find on `YouTube <https://www.youtube.com/watch?v=1tibU7vGWpk>`_.
|
||||
You can also find a quick video demonstration of this on `YouTube <https://www.youtube.com/watch?v=1tibU7vGWpk>`_.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
|
||||
@@ -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,9 +3,11 @@
|
||||
.. |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
|
||||
.. |Author_AlexB| unicode:: Alexandre U+0020 Benoit
|
||||
|
||||
.. |Author_EricCh| unicode:: Eric U+0020 Christiansen
|
||||
.. |Author_AndreyP| unicode:: Andrey U+0020 Pavlenko
|
||||
.. |Author_AlexS| unicode:: Alexander U+0020 Smorkalov
|
||||
|
||||
+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.
|
||||
|
||||
@@ -32,6 +32,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/nonfree/features2d.hpp"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
|
||||
+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
|
||||
|
||||
+2
-121
@@ -22,127 +22,8 @@ Code
|
||||
|
||||
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/TrackingMotion/cornerDetector_Demo.cpp>`_
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
/// Global variables
|
||||
Mat src, src_gray;
|
||||
Mat myHarris_dst; Mat myHarris_copy; Mat Mc;
|
||||
Mat myShiTomasi_dst; Mat myShiTomasi_copy;
|
||||
|
||||
int myShiTomasi_qualityLevel = 50;
|
||||
int myHarris_qualityLevel = 50;
|
||||
int max_qualityLevel = 100;
|
||||
|
||||
double myHarris_minVal; double myHarris_maxVal;
|
||||
double myShiTomasi_minVal; double myShiTomasi_maxVal;
|
||||
|
||||
RNG rng(12345);
|
||||
|
||||
char* myHarris_window = "My Harris corner detector";
|
||||
char* myShiTomasi_window = "My Shi Tomasi corner detector";
|
||||
|
||||
/// Function headers
|
||||
void myShiTomasi_function( int, void* );
|
||||
void myHarris_function( int, void* );
|
||||
|
||||
/** @function main */
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
/// Load source image and convert it to gray
|
||||
src = imread( argv[1], 1 );
|
||||
cvtColor( src, src_gray, CV_BGR2GRAY );
|
||||
|
||||
/// Set some parameters
|
||||
int blockSize = 3; int apertureSize = 3;
|
||||
|
||||
/// My Harris matrix -- Using cornerEigenValsAndVecs
|
||||
myHarris_dst = Mat::zeros( src_gray.size(), CV_32FC(6) );
|
||||
Mc = Mat::zeros( src_gray.size(), CV_32FC1 );
|
||||
|
||||
cornerEigenValsAndVecs( src_gray, myHarris_dst, blockSize, apertureSize, BORDER_DEFAULT );
|
||||
|
||||
/* calculate Mc */
|
||||
for( int j = 0; j < src_gray.rows; j++ )
|
||||
{ for( int i = 0; i < src_gray.cols; i++ )
|
||||
{
|
||||
float lambda_1 = myHarris_dst.at<float>( j, i, 0 );
|
||||
float lambda_2 = myHarris_dst.at<float>( j, i, 1 );
|
||||
Mc.at<float>(j,i) = lambda_1*lambda_2 - 0.04*pow( ( lambda_1 + lambda_2 ), 2 );
|
||||
}
|
||||
}
|
||||
|
||||
minMaxLoc( Mc, &myHarris_minVal, &myHarris_maxVal, 0, 0, Mat() );
|
||||
|
||||
/* Create Window and Trackbar */
|
||||
namedWindow( myHarris_window, CV_WINDOW_AUTOSIZE );
|
||||
createTrackbar( " Quality Level:", myHarris_window, &myHarris_qualityLevel, max_qualityLevel,
|
||||
myHarris_function );
|
||||
myHarris_function( 0, 0 );
|
||||
|
||||
/// My Shi-Tomasi -- Using cornerMinEigenVal
|
||||
myShiTomasi_dst = Mat::zeros( src_gray.size(), CV_32FC1 );
|
||||
cornerMinEigenVal( src_gray, myShiTomasi_dst, blockSize, apertureSize, BORDER_DEFAULT );
|
||||
|
||||
minMaxLoc( myShiTomasi_dst, &myShiTomasi_minVal, &myShiTomasi_maxVal, 0, 0, Mat() );
|
||||
|
||||
/* Create Window and Trackbar */
|
||||
namedWindow( myShiTomasi_window, CV_WINDOW_AUTOSIZE );
|
||||
createTrackbar( " Quality Level:", myShiTomasi_window, &myShiTomasi_qualityLevel, max_qualityLevel,
|
||||
myShiTomasi_function );
|
||||
myShiTomasi_function( 0, 0 );
|
||||
|
||||
waitKey(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/** @function myShiTomasi_function */
|
||||
void myShiTomasi_function( int, void* )
|
||||
{
|
||||
myShiTomasi_copy = src.clone();
|
||||
|
||||
if( myShiTomasi_qualityLevel < 1 ) { myShiTomasi_qualityLevel = 1; }
|
||||
|
||||
for( int j = 0; j < src_gray.rows; j++ )
|
||||
{ for( int i = 0; i < src_gray.cols; i++ )
|
||||
{
|
||||
if( myShiTomasi_dst.at<float>(j,i) > myShiTomasi_minVal + ( myShiTomasi_maxVal -
|
||||
myShiTomasi_minVal )*myShiTomasi_qualityLevel/max_qualityLevel )
|
||||
{ circle( myShiTomasi_copy, Point(i,j), 4, Scalar( rng.uniform(0,255),
|
||||
rng.uniform(0,255), rng.uniform(0,255) ), -1, 8, 0 ); }
|
||||
}
|
||||
}
|
||||
imshow( myShiTomasi_window, myShiTomasi_copy );
|
||||
}
|
||||
|
||||
/** @function myHarris_function */
|
||||
void myHarris_function( int, void* )
|
||||
{
|
||||
myHarris_copy = src.clone();
|
||||
|
||||
if( myHarris_qualityLevel < 1 ) { myHarris_qualityLevel = 1; }
|
||||
|
||||
for( int j = 0; j < src_gray.rows; j++ )
|
||||
{ for( int i = 0; i < src_gray.cols; i++ )
|
||||
{
|
||||
if( Mc.at<float>(j,i) > myHarris_minVal + ( myHarris_maxVal - myHarris_minVal )
|
||||
*myHarris_qualityLevel/max_qualityLevel )
|
||||
{ circle( myHarris_copy, Point(i,j), 4, Scalar( rng.uniform(0,255), rng.uniform(0,255),
|
||||
rng.uniform(0,255) ), -1, 8, 0 ); }
|
||||
}
|
||||
}
|
||||
imshow( myHarris_window, myHarris_copy );
|
||||
}
|
||||
|
||||
|
||||
.. literalinclude:: ../../../../../samples/cpp/tutorial_code/TrackingMotion/cornerDetector_Demo.cpp
|
||||
:language: cpp
|
||||
|
||||
Explanation
|
||||
============
|
||||
|
||||
@@ -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
@@ -7,7 +7,7 @@ Squeeze out every little computation power from your system by using the power o
|
||||
|
||||
.. include:: ../../definitions/tocDefinitions.rst
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
@@ -18,7 +18,7 @@ Squeeze out every little computation power from your system by using the power o
|
||||
|
||||
*Author:* |Author_BernatG|
|
||||
|
||||
This will give a good grasp on how to approach coding on the GPU module, once you already know how to handle the other modules. As a test case it will port the similarity methods from the tutorial :ref:`videoInputPSNRMSSIM` to the GPU.
|
||||
This will give a good grasp on how to approach coding on the GPU module, once you already know how to handle the other modules. As a test case it will port the similarity methods from the tutorial :ref:`videoInputPSNRMSSIM` to the GPU.
|
||||
|
||||
=============== ======================================================
|
||||
|
||||
|
||||
@@ -3,30 +3,30 @@
|
||||
*highgui* module. High Level GUI and Media
|
||||
------------------------------------------
|
||||
|
||||
This section contains valuable tutorials about how to read/save your image/video files and how to use the built-in graphical user interface of the library.
|
||||
This section contains valuable tutorials about how to read/save your image/video files and how to use the built-in graphical user interface of the library.
|
||||
|
||||
.. include:: ../../definitions/tocDefinitions.rst
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
=============== ======================================================
|
||||
|Beginners_5| *Title:* :ref:`Adding_Trackbars`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
We will learn how to add a Trackbar to our applications
|
||||
|
||||
|
||||
=============== ======================================================
|
||||
|
||||
|
||||
.. |Beginners_5| image:: images/Adding_Trackbars_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
@@ -34,7 +34,7 @@ This section contains valuable tutorials about how to read/save your image/video
|
||||
|hVideoInput| *Title:* :ref:`videoInputPSNRMSSIM`
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_BernatG|
|
||||
|
||||
You will learn how to read video streams, and how to calculate similarity values such as PSNR or SSIM.
|
||||
@@ -45,7 +45,7 @@ This section contains valuable tutorials about how to read/save your image/video
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ Adding a Trackbar to our applications!
|
||||
|
||||
* In the previous tutorials (about *linear blending* and the *brightness and contrast adjustments*) you might have noted that we needed to give some **input** to our programs, such as :math:`\alpha` and :math:`beta`. We accomplished that by entering this data using the Terminal
|
||||
|
||||
* Well, it is time to use some fancy GUI tools. OpenCV provides some GUI utilities (*highgui.h*) for you. An example of this is a **Trackbar**
|
||||
* Well, it is time to use some fancy GUI tools. OpenCV provides some GUI utilities (*highgui.h*) for you. An example of this is a **Trackbar**
|
||||
|
||||
.. image:: images/Adding_Trackbars_Tutorial_Trackbar.png
|
||||
:alt: Trackbar example
|
||||
:align: center
|
||||
:align: center
|
||||
|
||||
* In this tutorial we will just modify our two previous programs so that they get the input information from the trackbar.
|
||||
|
||||
@@ -19,7 +19,7 @@ Goals
|
||||
|
||||
In this tutorial you will learn how to:
|
||||
|
||||
* Add a Trackbar in an OpenCV window by using :create_trackbar:`createTrackbar <>`
|
||||
* Add a Trackbar in an OpenCV window by using :create_trackbar:`createTrackbar <>`
|
||||
|
||||
Code
|
||||
=====
|
||||
@@ -33,13 +33,13 @@ Let's modify the program made in the tutorial :ref:`Adding_Images`. We will let
|
||||
|
||||
using namespace cv;
|
||||
|
||||
/// Global Variables
|
||||
/// Global Variables
|
||||
const int alpha_slider_max = 100;
|
||||
int alpha_slider;
|
||||
int alpha_slider;
|
||||
double alpha;
|
||||
double beta;
|
||||
double beta;
|
||||
|
||||
/// Matrices to store images
|
||||
/// Matrices to store images
|
||||
Mat src1;
|
||||
Mat src2;
|
||||
Mat dst;
|
||||
@@ -49,12 +49,12 @@ Let's modify the program made in the tutorial :ref:`Adding_Images`. We will let
|
||||
* @brief Callback for trackbar
|
||||
*/
|
||||
void on_trackbar( int, void* )
|
||||
{
|
||||
{
|
||||
alpha = (double) alpha_slider/alpha_slider_max ;
|
||||
beta = ( 1.0 - alpha );
|
||||
|
||||
addWeighted( src1, alpha, src2, beta, 0.0, dst);
|
||||
|
||||
|
||||
imshow( "Linear Blend", dst );
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ Let's modify the program made in the tutorial :ref:`Adding_Images`. We will let
|
||||
if( !src1.data ) { printf("Error loading src1 \n"); return -1; }
|
||||
if( !src2.data ) { printf("Error loading src2 \n"); return -1; }
|
||||
|
||||
/// Initialize values
|
||||
/// Initialize values
|
||||
alpha_slider = 0;
|
||||
|
||||
/// Create Windows
|
||||
@@ -75,13 +75,13 @@ Let's modify the program made in the tutorial :ref:`Adding_Images`. We will let
|
||||
|
||||
/// Create Trackbars
|
||||
char TrackbarName[50];
|
||||
sprintf( TrackbarName, "Alpha x %d", alpha_slider_max );
|
||||
sprintf( TrackbarName, "Alpha x %d", alpha_slider_max );
|
||||
|
||||
createTrackbar( TrackbarName, "Linear Blend", &alpha_slider, alpha_slider_max, on_trackbar );
|
||||
|
||||
/// Show some stuff
|
||||
on_trackbar( alpha_slider, 0 );
|
||||
|
||||
|
||||
/// Wait until user press some key
|
||||
waitKey(0);
|
||||
return 0;
|
||||
@@ -113,7 +113,7 @@ We only analyze the code that is related to Trackbar:
|
||||
createTrackbar( TrackbarName, "Linear Blend", &alpha_slider, alpha_slider_max, on_trackbar );
|
||||
|
||||
Note the following:
|
||||
|
||||
|
||||
* Our Trackbar has a label **TrackbarName**
|
||||
* The Trackbar is located in the window named **"Linear Blend"**
|
||||
* The Trackbar values will be in the range from :math:`0` to **alpha_slider_max** (the minimum limit is always **zero**).
|
||||
@@ -125,21 +125,21 @@ We only analyze the code that is related to Trackbar:
|
||||
.. code-block:: cpp
|
||||
|
||||
void on_trackbar( int, void* )
|
||||
{
|
||||
{
|
||||
alpha = (double) alpha_slider/alpha_slider_max ;
|
||||
beta = ( 1.0 - alpha );
|
||||
|
||||
addWeighted( src1, alpha, src2, beta, 0.0, dst);
|
||||
|
||||
|
||||
imshow( "Linear Blend", dst );
|
||||
}
|
||||
|
||||
Note that:
|
||||
|
||||
* We use the value of **alpha_slider** (integer) to get a double value for **alpha**.
|
||||
|
||||
* We use the value of **alpha_slider** (integer) to get a double value for **alpha**.
|
||||
* **alpha_slider** is updated each time the trackbar is displaced by the user.
|
||||
* We define *src1*, *src2*, *dist*, *alpha*, *alpha_slider* and *beta* as global variables, so they can be used everywhere.
|
||||
|
||||
|
||||
Result
|
||||
=======
|
||||
|
||||
@@ -147,13 +147,13 @@ Result
|
||||
|
||||
.. image:: images/Adding_Trackbars_Tutorial_Result_0.jpg
|
||||
:alt: Adding Trackbars - Windows Linux
|
||||
:align: center
|
||||
:align: center
|
||||
|
||||
* As a manner of practice, you can also add 02 trackbars for the program made in :ref:`Basic_Linear_Transform`. One trackbar to set :math:`\alpha` and another for :math:`\beta`. The output might look like:
|
||||
|
||||
.. image:: images/Adding_Trackbars_Tutorial_Result_1.jpg
|
||||
:alt: Adding Trackbars - Lena
|
||||
:align: center
|
||||
:align: center
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ Today it is common to have a digital video recording system at your disposal. Th
|
||||
The source code
|
||||
===============
|
||||
|
||||
As a test case where to show off these using OpenCV I've created a small program that reads in two video files and performs a similarity check between them. This is something you could use to check just how well a new video compressing algorithms works. Let there be a reference (original) video like :download:`this small Megamind clip <../../../../samples/cpp/tutorial_code/highgui/video-input-psnr-ssim/video/Megamind.avi>` and :download:`a compressed version of it <../../../../samples/cpp/tutorial_code/highgui/video-input-psnr-ssim/video/Megamind_bugy.avi>`. You may also find the source code and these video file in the :file:`samples/cpp/tutorial_code/highgui/video-input-psnr-ssim/` folder of the OpenCV source library.
|
||||
As a test case where to show off these using OpenCV I've created a small program that reads in two video files and performs a similarity check between them. This is something you could use to check just how well a new video compressing algorithms works. Let there be a reference (original) video like :download:`this small Megamind clip <../../../../samples/cpp/tutorial_code/HighGUI/video-input-psnr-ssim/video/Megamind.avi>` and :download:`a compressed version of it <../../../../samples/cpp/tutorial_code/HighGUI/video-input-psnr-ssim/video/Megamind_bugy.avi>`. You may also find the source code and these video file in the :file:`samples/cpp/tutorial_code/HighGUI/video-input-psnr-ssim/` folder of the OpenCV source library.
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/HighGUI/video-input-psnr-ssim/video-input-psnr-ssim.cpp
|
||||
:language: cpp
|
||||
@@ -64,7 +64,7 @@ Closing the video is automatic when the objects destructor is called. However, i
|
||||
captRefrnc >> frameReference;
|
||||
captUndTst.open(frameUnderTest);
|
||||
|
||||
The upper read operations will leave empty the *Mat* objects if no frame could be acquired (either cause the video stream was closed or you got to the end of the video file). We can check this with a simple if:
|
||||
The upper read operations will leave empty the *Mat* objects if no frame could be acquired (either cause the video stream was closed or you got to the end of the video file). We can check this with a simple if:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -111,7 +111,7 @@ Then the PSNR is expressed as:
|
||||
|
||||
PSNR = 10 \cdot \log_{10} \left( \frac{MAX_I^2}{MSE} \right)
|
||||
|
||||
Here the :math:`MAX_I^2` is the maximum valid value for a pixel. In case of the simple single byte image per pixel per channel this is 255. When two images are the same the MSE will give zero, resulting in an invalid divide by zero operation in the PSNR formula. In this case the PSNR is undefined and as we'll need to handle this case separately. The transition to a logarithmic scale is made because the pixel values have a very wide dynamic range. All this translated to OpenCV and a C++ function looks like:
|
||||
Here the :math:`MAX_I^2` is the maximum valid value for a pixel. In case of the simple single byte image per pixel per channel this is 255. When two images are the same the MSE will give zero, resulting in an invalid divide by zero operation in the PSNR formula. In this case the PSNR is undefined and as we'll need to handle this case separately. The transition to a logarithmic scale is made because the pixel values have a very wide dynamic range. All this translated to OpenCV and a C++ function looks like:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -136,13 +136,13 @@ Here the :math:`MAX_I^2` is the maximum valid value for a pixel. In case of the
|
||||
}
|
||||
}
|
||||
|
||||
Typically result values are anywhere between 30 and 50 for video compression, where higher is better. If the images significantly differ you'll get much lower ones like 15 and so. This similarity check is easy and fast to calculate, however in practice it may turn out somewhat inconsistent with human eye perception. The **structural similarity** algorithm aims to correct this.
|
||||
Typically result values are anywhere between 30 and 50 for video compression, where higher is better. If the images significantly differ you'll get much lower ones like 15 and so. This similarity check is easy and fast to calculate, however in practice it may turn out somewhat inconsistent with human eye perception. The **structural similarity** algorithm aims to correct this.
|
||||
|
||||
Describing the methods goes well beyond the purpose of this tutorial. For that I invite you to read the article introducing it. Nevertheless, you can get a good image of it by looking at the OpenCV implementation below.
|
||||
Describing the methods goes well beyond the purpose of this tutorial. For that I invite you to read the article introducing it. Nevertheless, you can get a good image of it by looking at the OpenCV implementation below.
|
||||
|
||||
.. seealso::
|
||||
|
||||
SSIM is described more in-depth in the: "Z. Wang, A. C. Bovik, H. R. Sheikh and E. P. Simoncelli, "Image quality assessment: From error visibility to structural similarity," IEEE Transactions on Image Processing, vol. 13, no. 4, pp. 600-612, Apr. 2004." article.
|
||||
SSIM is described more in-depth in the: "Z. Wang, A. C. Bovik, H. R. Sheikh and E. P. Simoncelli, "Image quality assessment: From error visibility to structural similarity," IEEE Transactions on Image Processing, vol. 13, no. 4, pp. 600-612, Apr. 2004." article.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -162,7 +162,7 @@ Describing the methods goes well beyond the purpose of this tutorial. For that I
|
||||
|
||||
/***********************PRELIMINARY COMPUTING ******************************/
|
||||
|
||||
Mat mu1, mu2; //
|
||||
Mat mu1, mu2; //
|
||||
GaussianBlur(I1, mu1, Size(11, 11), 1.5);
|
||||
GaussianBlur(I2, mu2, Size(11, 11), 1.5);
|
||||
|
||||
@@ -199,7 +199,7 @@ Describing the methods goes well beyond the purpose of this tutorial. For that I
|
||||
return mssim;
|
||||
}
|
||||
|
||||
This will return a similarity index for each channel of the image. This value is between zero and one, where one corresponds to perfect fit. Unfortunately, the many Gaussian blurring is quite costly, so while the PSNR may work in a real time like environment (24 frame per second) this will take significantly more than to accomplish similar performance results.
|
||||
This will return a similarity index for each channel of the image. This value is between zero and one, where one corresponds to perfect fit. Unfortunately, the many Gaussian blurring is quite costly, so while the PSNR may work in a real time like environment (24 frame per second) this will take significantly more than to accomplish similar performance results.
|
||||
|
||||
Therefore, the source code presented at the start of the tutorial will perform the PSNR measurement for each frame, and the SSIM only for the frames where the PSNR falls below an input value. For visualization purpose we show both images in an OpenCV window and print the PSNR and MSSIM values to the console. Expect to see something like:
|
||||
|
||||
@@ -207,7 +207,7 @@ Therefore, the source code presented at the start of the tutorial will perform t
|
||||
:alt: A sample output
|
||||
:align: center
|
||||
|
||||
You may observe a runtime instance of this on the `YouTube here <https://www.youtube.com/watch?v=iOcNljutOgg>`_.
|
||||
You may observe a runtime instance of this on the `YouTube here <https://www.youtube.com/watch?v=iOcNljutOgg>`_.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
|
||||
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
@@ -39,7 +39,7 @@ Morphological Operations
|
||||
:align: center
|
||||
|
||||
Dilation
|
||||
~~~~~~~~
|
||||
^^^^^^^^^
|
||||
|
||||
* This operations consists of convoluting an image :math:`A` with some kernel (:math:`B`), which can have any shape or size, usually a square or circle.
|
||||
|
||||
@@ -54,7 +54,7 @@ Dilation
|
||||
The background (bright) dilates around the black regions of the letter.
|
||||
|
||||
Erosion
|
||||
~~~~~~~
|
||||
^^^^^^^^
|
||||
|
||||
* This operation is the sister of dilation. What this does is to compute a local minimum over the area of the kernel.
|
||||
|
||||
@@ -112,21 +112,21 @@ This tutorial code's is shown lines below. You can also download it from `here <
|
||||
|
||||
/// Create Erosion Trackbar
|
||||
createTrackbar( "Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Erosion Demo",
|
||||
&erosion_elem, max_elem,
|
||||
Erosion );
|
||||
&erosion_elem, max_elem,
|
||||
Erosion );
|
||||
|
||||
createTrackbar( "Kernel size:\n 2n +1", "Erosion Demo",
|
||||
&erosion_size, max_kernel_size,
|
||||
Erosion );
|
||||
&erosion_size, max_kernel_size,
|
||||
Erosion );
|
||||
|
||||
/// Create Dilation Trackbar
|
||||
createTrackbar( "Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Dilation Demo",
|
||||
&dilation_elem, max_elem,
|
||||
Dilation );
|
||||
&dilation_elem, max_elem,
|
||||
Dilation );
|
||||
|
||||
createTrackbar( "Kernel size:\n 2n +1", "Dilation Demo",
|
||||
&dilation_size, max_kernel_size,
|
||||
Dilation );
|
||||
&dilation_size, max_kernel_size,
|
||||
Dilation );
|
||||
|
||||
/// Default start
|
||||
Erosion( 0, 0 );
|
||||
@@ -145,8 +145,8 @@ This tutorial code's is shown lines below. You can also download it from `here <
|
||||
else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }
|
||||
|
||||
Mat element = getStructuringElement( erosion_type,
|
||||
Size( 2*erosion_size + 1, 2*erosion_size+1 ),
|
||||
Point( erosion_size, erosion_size ) );
|
||||
Size( 2*erosion_size + 1, 2*erosion_size+1 ),
|
||||
Point( erosion_size, erosion_size ) );
|
||||
|
||||
/// Apply the erosion operation
|
||||
erode( src, erosion_dst, element );
|
||||
@@ -162,8 +162,8 @@ This tutorial code's is shown lines below. You can also download it from `here <
|
||||
else if( dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; }
|
||||
|
||||
Mat element = getStructuringElement( dilation_type,
|
||||
Size( 2*dilation_size + 1, 2*dilation_size+1 ),
|
||||
Point( dilation_size, dilation_size ) );
|
||||
Size( 2*dilation_size + 1, 2*dilation_size+1 ),
|
||||
Point( dilation_size, dilation_size ) );
|
||||
/// Apply the dilation operation
|
||||
dilate( src, dilation_dst, element );
|
||||
imshow( "Dilation Demo", dilation_dst );
|
||||
@@ -201,8 +201,8 @@ Explanation
|
||||
else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }
|
||||
|
||||
Mat element = getStructuringElement( erosion_type,
|
||||
Size( 2*erosion_size + 1, 2*erosion_size+1 ),
|
||||
Point( erosion_size, erosion_size ) );
|
||||
Size( 2*erosion_size + 1, 2*erosion_size+1 ),
|
||||
Point( erosion_size, erosion_size ) );
|
||||
/// Apply the erosion operation
|
||||
erode( src, erosion_dst, element );
|
||||
imshow( "Erosion Demo", erosion_dst );
|
||||
@@ -216,17 +216,17 @@ Explanation
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
Mat element = getStructuringElement( erosion_type,
|
||||
Size( 2*erosion_size + 1, 2*erosion_size+1 ),
|
||||
Point( erosion_size, erosion_size ) );
|
||||
Mat element = getStructuringElement( erosion_type,
|
||||
Size( 2*erosion_size + 1, 2*erosion_size+1 ),
|
||||
Point( erosion_size, erosion_size ) );
|
||||
|
||||
We can choose any of three shapes for our kernel:
|
||||
|
||||
.. container:: enumeratevisibleitemswithsquare
|
||||
|
||||
+ Rectangular box: MORPH_RECT
|
||||
+ Cross: MORPH_CROSS
|
||||
+ Ellipse: MORPH_ELLIPSE
|
||||
+ Rectangular box: MORPH_RECT
|
||||
+ Cross: MORPH_CROSS
|
||||
+ Ellipse: MORPH_ELLIPSE
|
||||
|
||||
Then, we just have to specify the size of our kernel and the *anchor point*. If not specified, it is assumed to be in the center.
|
||||
|
||||
@@ -251,8 +251,8 @@ The code is below. As you can see, it is completely similar to the snippet of co
|
||||
else if( dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; }
|
||||
|
||||
Mat element = getStructuringElement( dilation_type,
|
||||
Size( 2*dilation_size + 1, 2*dilation_size+1 ),
|
||||
Point( dilation_size, dilation_size ) );
|
||||
Size( 2*dilation_size + 1, 2*dilation_size+1 ),
|
||||
Point( dilation_size, dilation_size ) );
|
||||
/// Apply the dilation operation
|
||||
dilate( src, dilation_dst, element );
|
||||
imshow( "Dilation Demo", dilation_dst );
|
||||
|
||||
+13
-13
@@ -159,35 +159,35 @@ Code
|
||||
if( display_caption( "Homogeneous Blur" ) != 0 ) { return 0; }
|
||||
|
||||
for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
|
||||
{ blur( src, dst, Size( i, i ), Point(-1,-1) );
|
||||
{ blur( src, dst, Size( i, i ), Point(-1,-1) );
|
||||
if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
|
||||
|
||||
/// Applying Gaussian blur
|
||||
if( display_caption( "Gaussian Blur" ) != 0 ) { return 0; }
|
||||
|
||||
for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
|
||||
{ GaussianBlur( src, dst, Size( i, i ), 0, 0 );
|
||||
{ GaussianBlur( src, dst, Size( i, i ), 0, 0 );
|
||||
if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
|
||||
|
||||
/// Applying Median blur
|
||||
if( display_caption( "Median Blur" ) != 0 ) { return 0; }
|
||||
if( display_caption( "Median Blur" ) != 0 ) { return 0; }
|
||||
|
||||
for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
|
||||
{ medianBlur ( src, dst, i );
|
||||
for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
|
||||
{ medianBlur ( src, dst, i );
|
||||
if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
|
||||
|
||||
/// Applying Bilateral Filter
|
||||
if( display_caption( "Bilateral Blur" ) != 0 ) { return 0; }
|
||||
/// Applying Bilateral Filter
|
||||
if( display_caption( "Bilateral Blur" ) != 0 ) { return 0; }
|
||||
|
||||
for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
|
||||
{ bilateralFilter ( src, dst, i, i*2, i/2 );
|
||||
for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
|
||||
{ bilateralFilter ( src, dst, i, i*2, i/2 );
|
||||
if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
|
||||
|
||||
/// Wait until user press a key
|
||||
display_caption( "End: Press a key!" );
|
||||
/// Wait until user press a key
|
||||
display_caption( "End: Press a key!" );
|
||||
|
||||
waitKey(0);
|
||||
return 0;
|
||||
waitKey(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int display_caption( char* caption )
|
||||
|
||||
@@ -94,7 +94,7 @@ Code
|
||||
* Loads an image
|
||||
* Convert the original to HSV format and separate only *Hue* channel to be used for the Histogram (using the OpenCV function :mix_channels:`mixChannels <>`)
|
||||
* Let the user to enter the number of bins to be used in the calculation of the histogram.
|
||||
* Calculate the histogram (and update it if the bins change) and the backprojection of the same image.
|
||||
* Calculate the histogram (and update it if the bins change) and the backprojection of the same image.
|
||||
* Display the backprojection and the histogram in windows.
|
||||
|
||||
* **Downloadable code**:
|
||||
|
||||
@@ -124,34 +124,34 @@ Code
|
||||
|
||||
for( int j = 0; j < src.rows; j++ )
|
||||
{ for( int i = 0; i < src.cols; i++ )
|
||||
{
|
||||
{
|
||||
switch( ind )
|
||||
{
|
||||
case 0:
|
||||
if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 )
|
||||
{
|
||||
case 0:
|
||||
if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 )
|
||||
{
|
||||
map_x.at<float>(j,i) = 2*( i - src.cols*0.25 ) + 0.5 ;
|
||||
map_y.at<float>(j,i) = 2*( j - src.rows*0.25 ) + 0.5 ;
|
||||
}
|
||||
else
|
||||
{ map_x.at<float>(j,i) = 0 ;
|
||||
map_y.at<float>(j,i) = 0 ;
|
||||
map_x.at<float>(j,i) = 2*( i - src.cols*0.25 ) + 0.5 ;
|
||||
map_y.at<float>(j,i) = 2*( j - src.rows*0.25 ) + 0.5 ;
|
||||
}
|
||||
else
|
||||
{ map_x.at<float>(j,i) = 0 ;
|
||||
map_y.at<float>(j,i) = 0 ;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
map_x.at<float>(j,i) = i ;
|
||||
map_y.at<float>(j,i) = src.rows - j ;
|
||||
break;
|
||||
case 1:
|
||||
map_x.at<float>(j,i) = i ;
|
||||
map_y.at<float>(j,i) = src.rows - j ;
|
||||
break;
|
||||
case 2:
|
||||
map_x.at<float>(j,i) = src.cols - i ;
|
||||
map_y.at<float>(j,i) = j ;
|
||||
break;
|
||||
map_x.at<float>(j,i) = src.cols - i ;
|
||||
map_y.at<float>(j,i) = j ;
|
||||
break;
|
||||
case 3:
|
||||
map_x.at<float>(j,i) = src.cols - i ;
|
||||
map_y.at<float>(j,i) = src.rows - j ;
|
||||
break;
|
||||
map_x.at<float>(j,i) = src.cols - i ;
|
||||
map_y.at<float>(j,i) = src.rows - j ;
|
||||
break;
|
||||
} // end of switch
|
||||
}
|
||||
}
|
||||
}
|
||||
ind++;
|
||||
}
|
||||
@@ -241,34 +241,34 @@ Explanation
|
||||
|
||||
for( int j = 0; j < src.rows; j++ )
|
||||
{ for( int i = 0; i < src.cols; i++ )
|
||||
{
|
||||
{
|
||||
switch( ind )
|
||||
{
|
||||
case 0:
|
||||
if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 )
|
||||
{
|
||||
case 0:
|
||||
if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 )
|
||||
{
|
||||
map_x.at<float>(j,i) = 2*( i - src.cols*0.25 ) + 0.5 ;
|
||||
map_y.at<float>(j,i) = 2*( j - src.rows*0.25 ) + 0.5 ;
|
||||
}
|
||||
else
|
||||
{ map_x.at<float>(j,i) = 0 ;
|
||||
map_y.at<float>(j,i) = 0 ;
|
||||
map_x.at<float>(j,i) = 2*( i - src.cols*0.25 ) + 0.5 ;
|
||||
map_y.at<float>(j,i) = 2*( j - src.rows*0.25 ) + 0.5 ;
|
||||
}
|
||||
else
|
||||
{ map_x.at<float>(j,i) = 0 ;
|
||||
map_y.at<float>(j,i) = 0 ;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
map_x.at<float>(j,i) = i ;
|
||||
map_y.at<float>(j,i) = src.rows - j ;
|
||||
break;
|
||||
case 1:
|
||||
map_x.at<float>(j,i) = i ;
|
||||
map_y.at<float>(j,i) = src.rows - j ;
|
||||
break;
|
||||
case 2:
|
||||
map_x.at<float>(j,i) = src.cols - i ;
|
||||
map_y.at<float>(j,i) = j ;
|
||||
break;
|
||||
map_x.at<float>(j,i) = src.cols - i ;
|
||||
map_y.at<float>(j,i) = j ;
|
||||
break;
|
||||
case 3:
|
||||
map_x.at<float>(j,i) = src.cols - i ;
|
||||
map_y.at<float>(j,i) = src.rows - j ;
|
||||
break;
|
||||
map_x.at<float>(j,i) = src.cols - i ;
|
||||
map_y.at<float>(j,i) = src.rows - j ;
|
||||
break;
|
||||
} // end of switch
|
||||
}
|
||||
}
|
||||
}
|
||||
ind++;
|
||||
}
|
||||
|
||||
@@ -154,13 +154,13 @@ This tutorial code's is shown lines below. You can also download it from `here <
|
||||
|
||||
/// Create Trackbar to select kernel type
|
||||
createTrackbar( "Element:\n 0: Rect - 1: Cross - 2: Ellipse", window_name,
|
||||
&morph_elem, max_elem,
|
||||
Morphology_Operations );
|
||||
&morph_elem, max_elem,
|
||||
Morphology_Operations );
|
||||
|
||||
/// Create Trackbar to choose kernel size
|
||||
createTrackbar( "Kernel size:\n 2n +1", window_name,
|
||||
&morph_size, max_kernel_size,
|
||||
Morphology_Operations );
|
||||
&morph_size, max_kernel_size,
|
||||
Morphology_Operations );
|
||||
|
||||
/// Default start
|
||||
Morphology_Operations( 0, 0 );
|
||||
@@ -211,16 +211,16 @@ Explanation
|
||||
.. code-block:: cpp
|
||||
|
||||
createTrackbar( "Element:\n 0: Rect - 1: Cross - 2: Ellipse", window_name,
|
||||
&morph_elem, max_elem,
|
||||
Morphology_Operations );
|
||||
&morph_elem, max_elem,
|
||||
Morphology_Operations );
|
||||
|
||||
* The final trackbar **"Kernel Size"** returns the size of the kernel to be used (**morph_size**)
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
createTrackbar( "Kernel size:\n 2n +1", window_name,
|
||||
&morph_size, max_kernel_size,
|
||||
Morphology_Operations );
|
||||
&morph_size, max_kernel_size,
|
||||
Morphology_Operations );
|
||||
|
||||
|
||||
* Every time we move any slider, the user's function **Morphology_Operations** will be called to effectuate a new morphology operation and it will update the output image based on the current trackbar values.
|
||||
|
||||
@@ -129,7 +129,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
|
||||
c = waitKey(10);
|
||||
|
||||
if( (char)c == 27 )
|
||||
{ break; }
|
||||
{ break; }
|
||||
if( (char)c == 'u' )
|
||||
{ pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 ) );
|
||||
printf( "** Zoom In: Image x 2 \n" );
|
||||
@@ -188,7 +188,7 @@ Explanation
|
||||
c = waitKey(10);
|
||||
|
||||
if( (char)c == 27 )
|
||||
{ break; }
|
||||
{ break; }
|
||||
if( (char)c == 'u' )
|
||||
{ pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 ) );
|
||||
printf( "** Zoom In: Image x 2 \n" );
|
||||
|
||||
@@ -7,502 +7,502 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
.. include:: ../../definitions/tocDefinitions.rst
|
||||
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
===================== ==============================================
|
||||
|ImageProcessing_1| **Title:** :ref:`Smoothing`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Let's take a look at some basic linear filters!
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |ImageProcessing_1| image:: images/Smoothing_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
===================== ==============================================
|
||||
|ImageProcessing_2| **Title:** :ref:`Morphology_1`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
Author: |Author_AnaH|
|
||||
|
||||
|
||||
Let's *change* the shape of objects!
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |ImageProcessing_2| image:: images/Morphology_1_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
================= ==================================================
|
||||
|Morphology_2| **Title:** :ref:`Morphology_2`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Here we investigate different morphology operators
|
||||
|
||||
|
||||
================= ==================================================
|
||||
|
||||
|
||||
.. |Morphology_2| image:: images/Morphology_2_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|Pyramids| **Title:** :ref:`Pyramids`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
What if I need a bigger/smaller image?
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |Pyramids| image:: images/Pyramids_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|Threshold| **Title:** :ref:`Basic_Threshold`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
After so much processing, it is time to decide which pixels stay!
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |Threshold| image:: images/Threshold_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
===================== ==============================================
|
||||
|Filter_2D| **Title:** :ref:`filter_2d`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Where we learn to design our own filters by using OpenCV functions
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |Filter_2D| image:: images/imgtrans/Filter_2D_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
===================== ==============================================
|
||||
|CopyMakeBorder| **Title:** :ref:`copyMakeBorderTutorial`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Where we learn how to pad our images!
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |CopyMakeBorder| image:: images/imgtrans/CopyMakeBorder_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|SobelDerivatives| **Title:** :ref:`sobel_derivatives`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Where we learn how to calculate gradients and use them to detect edges!
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |SobelDerivatives| image:: images/imgtrans/Sobel_Derivatives_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|LaplaceOperator| **Title:** :ref:`laplace_operator`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Where we learn about the *Laplace* operator and how to detect edges with it.
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |LaplaceOperator| image:: images/imgtrans/Laplace_Operator_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|CannyDetector| **Title:** :ref:`canny_detector`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Where we learn a sophisticated alternative to detect edges.
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |CannyDetector| image:: images/imgtrans/Canny_Detector_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|HoughLines| **Title:** :ref:`hough_lines`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Where we learn how to detect lines
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |HoughLines| image:: images/imgtrans/Hough_Lines_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|HoughCircle| **Title:** :ref:`hough_circle`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Where we learn how to detect circles
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |HoughCircle| image:: images/imgtrans/Hough_Circle_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|Remap| **Title:** :ref:`remap`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Where we learn how to manipulate pixels locations
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |Remap| image:: images/imgtrans/Remap_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|WarpAffine| **Title:** :ref:`warp_affine`
|
||||
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
|
||||
Where we learn how to rotate, translate and scale our images
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |WarpAffine| image:: images/imgtrans/Warp_Affine_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|HistEqualization| **Title:** :ref:`histogram_equalization`
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
Where we learn how to improve the contrast in our images
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |HistEqualization| image:: images/histograms/Histogram_Equalization_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|HistCalculation| **Title:** :ref:`histogram_calculation`
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
Where we learn how to create and generate histograms
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |HistCalculation| image:: images/histograms/Histogram_Calculation_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|HistComparison| **Title:** :ref:`histogram_comparison`
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
Where we learn to calculate metrics between histograms
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |HistComparison| image:: images/histograms/Histogram_Comparison_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|BackProjection| **Title:** :ref:`back_projection`
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
Where we learn how to use histograms to find similar objects in images
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |BackProjection| image:: images/histograms/Back_Projection_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|TemplateMatching| **Title:** :ref:`template_matching`
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
Where we learn how to match templates in an image
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |TemplateMatching| image:: images/histograms/Template_Matching_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|FindContours| **Title:** :ref:`find_contours`
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
Where we learn how to find contours of objects in our image
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |FindContours| image:: images/shapedescriptors/Find_Contours_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|Hull| **Title:** :ref:`hull`
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
Where we learn how to get hull contours and draw them!
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |Hull| image:: images/shapedescriptors/Hull_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|BRC| **Title:** :ref:`bounding_rects_circles`
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
Where we learn how to obtain bounding boxes and circles for our contours.
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |BRC| image:: images/shapedescriptors/Bounding_Rects_Circles_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|BRE| **Title:** :ref:`bounding_rotated_ellipses`
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
Where we learn how to obtain rotated bounding boxes and ellipses for our contours.
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |BRE| image:: images/shapedescriptors/Bounding_Rotated_Ellipses_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
+
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|MU| **Title:** :ref:`moments`
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
Where we learn to calculate the moments of an image
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |MU| image:: images/shapedescriptors/Moments_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
|
||||
+
|
||||
+
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
.. cssclass:: toctableopencv
|
||||
|
||||
|
||||
|
||||
|
||||
===================== ==============================================
|
||||
|PPT| **Title:** :ref:`point_polygon_test`
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
Where we learn how to calculate distances from the image to contours
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
|
||||
.. |PPT| image:: images/shapedescriptors/Point_Polygon_Test_Tutorial_Cover.jpg
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
@@ -174,12 +174,12 @@ The tutorial code's is shown lines below. You can also download it from `here <h
|
||||
|
||||
/// Create Trackbar to choose type of Threshold
|
||||
createTrackbar( trackbar_type,
|
||||
window_name, &threshold_type,
|
||||
max_type, Threshold_Demo );
|
||||
window_name, &threshold_type,
|
||||
max_type, Threshold_Demo );
|
||||
|
||||
createTrackbar( trackbar_value,
|
||||
window_name, &threshold_value,
|
||||
max_value, Threshold_Demo );
|
||||
window_name, &threshold_value,
|
||||
max_value, Threshold_Demo );
|
||||
|
||||
/// Call the function to initialize
|
||||
Threshold_Demo( 0, 0 );
|
||||
@@ -190,7 +190,7 @@ The tutorial code's is shown lines below. You can also download it from `here <h
|
||||
int c;
|
||||
c = waitKey( 20 );
|
||||
if( (char)c == 27 )
|
||||
{ break; }
|
||||
{ break; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -245,12 +245,12 @@ Explanation
|
||||
.. code-block:: cpp
|
||||
|
||||
createTrackbar( trackbar_type,
|
||||
window_name, &threshold_type,
|
||||
max_type, Threshold_Demo );
|
||||
window_name, &threshold_type,
|
||||
max_type, Threshold_Demo );
|
||||
|
||||
createTrackbar( trackbar_value,
|
||||
window_name, &threshold_value,
|
||||
max_value, Threshold_Demo );
|
||||
window_name, &threshold_value,
|
||||
max_value, Threshold_Demo );
|
||||
|
||||
* Wait until the user enters the threshold value, the type of thresholding (or until the program exits)
|
||||
|
||||
|
||||
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