From 7faa44057e0802fc5a98eda8798cb0e0a42a1972 Mon Sep 17 00:00:00 2001 From: Andol Li Date: Sun, 27 Jan 2013 19:05:27 +0200 Subject: [PATCH] opencv: add handdetect plugin, initial implementation The handdetect plugin is for detecting hand gestures using opencv. It was created in the course of the Google Summer of Code. https://bugzilla.gnome.org/show_bug.cgi?id=685655 --- ext/opencv/fist.xml | 2125 ++++++++++++++++++++ ext/opencv/gsthanddetect.c | 762 +++++++ ext/opencv/gsthanddetect.h | 117 ++ ext/opencv/palm.xml | 1512 ++++++++++++++ tests/examples/opencv/gsthanddetect_test.c | 174 ++ 5 files changed, 4690 insertions(+) create mode 100644 ext/opencv/fist.xml create mode 100644 ext/opencv/gsthanddetect.c create mode 100644 ext/opencv/gsthanddetect.h create mode 100644 ext/opencv/palm.xml create mode 100644 tests/examples/opencv/gsthanddetect_test.c diff --git a/ext/opencv/fist.xml b/ext/opencv/fist.xml new file mode 100644 index 0000000000..843a9a3401 --- /dev/null +++ b/ext/opencv/fist.xml @@ -0,0 +1,2125 @@ + + + + + 24 24 + + <_> + + + <_> + + <_> + + + + <_> + 3 3 9 16 -1. + <_> + 3 7 9 8 2. + 0 + -0.0223442204296589 + 0.7737345099449158 + -0.9436557292938232 + <_> + + <_> + + + + <_> + 0 9 12 5 -1. + <_> + 6 9 6 5 2. + 0 + -9.3714958056807518e-003 + 0.5525149106979370 + -0.9004204869270325 + -0.3911409080028534 + -1 + -1 + <_> + + + <_> + + <_> + + + + <_> + 12 14 12 10 -1. + <_> + 12 14 6 5 2. + <_> + 18 19 6 5 2. + 0 + 0.0127444602549076 + -0.7241874933242798 + 0.5557708144187927 + <_> + + <_> + + + + <_> + 2 4 16 8 -1. + <_> + 2 8 16 4 2. + 0 + -0.0203973893076181 + 0.3255875110626221 + -0.9134256243705750 + <_> + + <_> + + + + <_> + 9 6 15 14 -1. + <_> + 9 13 15 7 2. + 0 + 1.5015050303190947e-003 + -0.8422530293464661 + 0.2950277030467987 + <_> + + <_> + + + + <_> + 0 10 10 5 -1. + <_> + 5 10 5 5 2. + 0 + -9.5540005713701248e-003 + 0.2949278056621552 + -0.8186870813369751 + <_> + + <_> + + + + <_> + 8 0 16 6 -1. + <_> + 8 0 16 3 2. + 1 + -9.0454015880823135e-003 + -0.9253956079483032 + 0.2449316978454590 + -0.8027257919311523 + 0 + -1 + <_> + + + <_> + + <_> + + + + <_> + 11 9 9 6 -1. + <_> + 14 12 3 6 3. + 1 + 0.0339135192334652 + -0.6010565757751465 + 0.5952491760253906 + <_> + + <_> + + + + <_> + 15 1 8 10 -1. + <_> + 15 6 8 5 2. + 0 + -6.3976310193538666e-003 + 0.2902083992958069 + -0.9008722901344299 + <_> + + <_> + + + + <_> + 12 23 12 1 -1. + <_> + 18 23 6 1 2. + 0 + 3.5964029375463724e-003 + -0.6108912825584412 + 0.3585815131664276 + <_> + + <_> + + + + <_> + 0 8 16 11 -1. + <_> + 8 8 8 11 2. + 0 + 3.1002631294541061e-004 + 0.2521544992923737 + -0.9231098890304565 + -0.6695849895477295 + 1 + -1 + <_> + + + <_> + + <_> + + + + <_> + 12 22 12 2 -1. + <_> + 18 22 6 2 2. + 0 + 8.9982077479362488e-003 + -0.6216139197349548 + 0.5311666131019592 + <_> + + <_> + + + + <_> + 6 7 10 5 -1. + <_> + 6 7 5 5 2. + 1 + 5.8961678296327591e-003 + 0.3589088022708893 + -0.8741096854209900 + <_> + + <_> + + + + <_> + 10 8 3 2 -1. + <_> + 10 9 3 1 2. + 0 + -7.3489747592248023e-005 + 0.2021690011024475 + -0.8340616226196289 + <_> + + <_> + + + + <_> + 15 15 3 4 -1. + <_> + 15 15 3 2 2. + 1 + -1.3183970004320145e-003 + -0.8218436241149902 + 0.2309758067131043 + -0.9460288882255554 + 2 + -1 + <_> + + + <_> + + <_> + + + + <_> + 4 18 20 6 -1. + <_> + 4 18 10 3 2. + <_> + 14 21 10 3 2. + 0 + 5.8955969288945198e-003 + -0.7554979920387268 + 0.3239434063434601 + <_> + + <_> + + + + <_> + 3 1 20 14 -1. + <_> + 3 1 10 7 2. + <_> + 13 8 10 7 2. + 0 + 8.6170788854360580e-003 + -0.7028874754905701 + 0.2782224118709564 + <_> + + <_> + + + + <_> + 2 11 3 9 -1. + <_> + 3 14 1 3 9. + 0 + -1.5837070532143116e-003 + -0.7751926779747009 + 0.2773326933383942 + <_> + + <_> + + + + <_> + 0 4 12 20 -1. + <_> + 0 4 6 10 2. + <_> + 6 14 6 10 2. + 0 + 7.9292394220829010e-003 + -0.7723438143730164 + 0.2167312055826187 + <_> + + <_> + + + + <_> + 16 15 6 2 -1. + <_> + 16 15 6 1 2. + 1 + -1.4443190302699804e-003 + -0.8843228220939636 + 0.2078661024570465 + <_> + + <_> + + + + <_> + 11 8 7 2 -1. + <_> + 11 9 7 1 2. + 0 + -4.8251380212605000e-004 + 0.2337501049041748 + -0.6776664853096008 + <_> + + <_> + + + + <_> + 20 15 4 6 -1. + <_> + 22 15 2 6 2. + 0 + 8.0077340826392174e-003 + -0.3731102049350739 + 0.5163818001747131 + -1.0588489770889282 + 3 + -1 + <_> + + + <_> + + <_> + + + + <_> + 14 19 1 2 -1. + <_> + 14 20 1 1 2. + 0 + -5.8145709772361442e-005 + 0.3404448032379150 + -0.6792302131652832 + <_> + + <_> + + + + <_> + 0 6 2 7 -1. + <_> + 1 6 1 7 2. + 0 + -1.1419489746913314e-003 + 0.3598371148109436 + -0.5890597105026245 + <_> + + <_> + + + + <_> + 8 0 10 2 -1. + <_> + 8 0 5 2 2. + 1 + 5.8654937893152237e-003 + -0.9622359871864319 + 0.1721540987491608 + <_> + + <_> + + + + <_> + 5 8 16 7 -1. + <_> + 13 8 8 7 2. + 0 + 1.1028599692508578e-004 + -0.7706093192100525 + 0.2389315962791443 + <_> + + <_> + + + + <_> + 2 9 14 12 -1. + <_> + 9 9 7 12 2. + 0 + 0.0145609602332115 + 0.1552716046571732 + -0.8984915018081665 + -0.7966647148132324 + 4 + -1 + <_> + + + <_> + + <_> + + + + <_> + 2 11 6 10 -1. + <_> + 2 11 3 5 2. + <_> + 5 16 3 5 2. + 0 + 3.9159432053565979e-003 + -0.7370954751968384 + 0.2886646091938019 + <_> + + <_> + + + + <_> + 0 3 4 9 -1. + <_> + 2 3 2 9 2. + 0 + -4.6402178704738617e-003 + 0.3129867017269135 + -0.5601897239685059 + <_> + + <_> + + + + <_> + 7 10 10 8 -1. + <_> + 12 10 5 8 2. + 0 + -4.2656981386244297e-003 + -0.8286197781562805 + 0.2132489979267120 + <_> + + <_> + + + + <_> + 8 16 16 8 -1. + <_> + 8 16 8 4 2. + <_> + 16 20 8 4 2. + 0 + 7.9925684258341789e-003 + -0.6752548217773438 + 0.2340082973241806 + <_> + + <_> + + + + <_> + 4 13 6 3 -1. + <_> + 6 15 2 3 3. + 1 + -6.2725958414375782e-003 + -0.7839264273643494 + 0.2019792944192886 + <_> + + <_> + + + + <_> + 13 3 11 18 -1. + <_> + 13 12 11 9 2. + 0 + -0.0288890209048986 + -0.7889788150787354 + 0.1651563942432404 + <_> + + <_> + + + + <_> + 10 7 5 4 -1. + <_> + 10 9 5 2 2. + 0 + -1.5122259501367807e-003 + 0.1971655040979385 + -0.7596625089645386 + <_> + + <_> + + + + <_> + 11 17 6 3 -1. + <_> + 13 18 2 1 9. + 0 + 4.3620187789201736e-003 + 0.1344974040985107 + -0.9309347271919251 + <_> + + <_> + + + + <_> + 12 7 12 17 -1. + <_> + 15 7 6 17 2. + 0 + -3.2192119397222996e-003 + 0.2437663972377777 + -0.6044244170188904 + -1.0856239795684814 + 5 + -1 + <_> + + + <_> + + <_> + + + + <_> + 14 18 1 2 -1. + <_> + 14 19 1 1 2. + 0 + -4.3883759644813836e-005 + 0.3130159080028534 + -0.6793813705444336 + <_> + + <_> + + + + <_> + 3 11 6 12 -1. + <_> + 3 11 3 6 2. + <_> + 6 17 3 6 2. + 0 + 6.2022951897233725e-004 + -0.8423554897308350 + 0.1801322996616364 + <_> + + <_> + + + + <_> + 22 13 2 7 -1. + <_> + 23 13 1 7 2. + 0 + 1.0972339659929276e-003 + -0.4771775007247925 + 0.3450973927974701 + <_> + + <_> + + + + <_> + 16 15 1 2 -1. + <_> + 16 15 1 1 2. + 1 + -2.6349889230914414e-004 + -0.7629253864288330 + 0.2153723984956741 + <_> + + <_> + + + + <_> + 0 5 22 18 -1. + <_> + 0 14 22 9 2. + 0 + -0.0542980991303921 + -0.8849576711654663 + 0.1730009019374847 + <_> + + <_> + + + + <_> + 13 19 3 3 -1. + <_> + 14 20 1 1 9. + 0 + -2.1721520461142063e-003 + -0.8367894887924194 + 0.1638997048139572 + <_> + + <_> + + + + <_> + 15 0 5 2 -1. + <_> + 15 1 5 1 2. + 0 + -1.6347350319847465e-003 + 0.3731253147125244 + -0.4079189002513886 + <_> + + <_> + + + + <_> + 5 15 4 5 -1. + <_> + 5 15 2 5 2. + 1 + -2.9642079025506973e-003 + -0.7973154187202454 + 0.1886135041713715 + -0.8849025964736939 + 6 + -1 + <_> + + + <_> + + <_> + + + + <_> + 12 16 2 8 -1. + <_> + 12 20 2 4 2. + 0 + -2.6686030905693769e-003 + 0.2950133979320526 + -0.6534382104873657 + <_> + + <_> + + + + <_> + 0 18 2 4 -1. + <_> + 1 18 1 4 2. + 0 + -7.9764809925109148e-004 + 0.3938421010971069 + -0.4435322880744934 + <_> + + <_> + + + + <_> + 8 3 12 4 -1. + <_> + 8 3 12 2 2. + 1 + -5.1704752258956432e-003 + -0.7686781883239746 + 0.2110860049724579 + <_> + + <_> + + + + <_> + 6 17 3 2 -1. + <_> + 7 18 1 2 3. + 1 + -1.5294969780370593e-003 + -0.8944628238677979 + 0.1583137959241867 + <_> + + <_> + + + + <_> + 1 0 10 6 -1. + <_> + 6 0 5 6 2. + 0 + -6.3780639320611954e-003 + 0.3393965959548950 + -0.4529472887516022 + <_> + + <_> + + + + <_> + 12 9 3 2 -1. + <_> + 12 10 3 1 2. + 0 + -2.6243639877066016e-004 + 0.2850841879844666 + -0.4983885884284973 + <_> + + <_> + + + + <_> + 11 1 12 11 -1. + <_> + 11 1 6 11 2. + 1 + 0.0361888185143471 + 0.2132015973329544 + -0.7394319772720337 + <_> + + <_> + + + + <_> + 21 13 2 10 -1. + <_> + 21 18 2 5 2. + 0 + 7.7682351693511009e-003 + -0.4052247107028961 + 0.4112299978733063 + <_> + + <_> + + + + <_> + 15 16 1 2 -1. + <_> + 15 16 1 1 2. + 1 + -2.3738530580885708e-004 + -0.7753518819808960 + 0.1911296993494034 + <_> + + <_> + + + + <_> + 0 11 8 8 -1. + <_> + 0 11 4 4 2. + <_> + 4 15 4 4 2. + 0 + 4.2231627739965916e-003 + -0.7229338884353638 + 0.1739158928394318 + -1.0250910520553589 + 7 + -1 + <_> + + + <_> + + <_> + + + + <_> + 11 11 7 6 -1. + <_> + 11 13 7 2 3. + 0 + 2.9137390665709972e-003 + -0.5349493026733398 + 0.3337337076663971 + <_> + + <_> + + + + <_> + 12 17 3 3 -1. + <_> + 13 18 1 1 9. + 0 + -1.6270120395347476e-003 + -0.8804692029953003 + 0.1722342073917389 + <_> + + <_> + + + + <_> + 0 9 2 2 -1. + <_> + 1 9 1 2 2. + 0 + -2.9037619242444634e-004 + 0.2734786868095398 + -0.5733091235160828 + <_> + + <_> + + + + <_> + 13 17 1 2 -1. + <_> + 13 18 1 1 2. + 0 + -1.4552129869116470e-005 + 0.2491019070148468 + -0.5995762944221497 + <_> + + <_> + + + + <_> + 7 0 17 18 -1. + <_> + 7 9 17 9 2. + 0 + 0.0141834802925587 + 0.1507173925638199 + -0.8961830139160156 + <_> + + <_> + + + + <_> + 8 11 8 2 -1. + <_> + 8 11 8 1 2. + 1 + -5.8600129705155268e-005 + 0.1771630048751831 + -0.7106314897537231 + <_> + + <_> + + + + <_> + 18 17 6 7 -1. + <_> + 21 17 3 7 2. + 0 + 7.3492531664669514e-003 + -0.5106546878814697 + 0.2574213147163391 + <_> + + <_> + + + + <_> + 2 19 8 1 -1. + <_> + 6 19 4 1 2. + 0 + -1.7738100141286850e-003 + -0.8705360293388367 + 0.1460683941841126 + -0.9740471243858337 + 8 + -1 + <_> + + + <_> + + <_> + + + + <_> + 12 10 10 6 -1. + <_> + 12 10 5 3 2. + <_> + 17 13 5 3 2. + 0 + -8.5521116852760315e-003 + 0.3413020968437195 + -0.4556924998760223 + <_> + + <_> + + + + <_> + 5 20 18 4 -1. + <_> + 5 20 9 2 2. + <_> + 14 22 9 2 2. + 0 + 2.9570560436695814e-003 + -0.5616099834442139 + 0.2246744036674500 + <_> + + <_> + + + + <_> + 1 10 22 5 -1. + <_> + 12 10 11 5 2. + 0 + -0.0195402801036835 + -0.8423789739608765 + 0.1363316029310226 + <_> + + <_> + + + + <_> + 1 11 12 1 -1. + <_> + 1 11 6 1 2. + 1 + -3.2073149923235178e-003 + -0.7569847702980042 + 0.1883326023817062 + <_> + + <_> + + + + <_> + 12 0 12 24 -1. + <_> + 12 6 12 12 2. + 0 + -8.4488727152347565e-003 + 0.1382011026144028 + -0.8026102185249329 + <_> + + <_> + + + + <_> + 4 15 5 6 -1. + <_> + 4 17 5 2 3. + 0 + 1.1350389831932262e-004 + -0.7027189135551453 + 0.1435786038637161 + <_> + + <_> + + + + <_> + 12 2 6 4 -1. + <_> + 14 4 2 4 3. + 1 + -5.8187649119645357e-004 + -0.4507982134819031 + 0.2510882019996643 + <_> + + <_> + + + + <_> + 0 7 2 17 -1. + <_> + 1 7 1 17 2. + 0 + -0.0161978900432587 + 0.6447368860244751 + -0.2079977989196777 + <_> + + <_> + + + + <_> + 13 15 3 9 -1. + <_> + 14 15 1 9 3. + 0 + 6.6894508199766278e-004 + 0.1998561024665833 + -0.7483944892883301 + <_> + + <_> + + + + <_> + 13 18 3 3 -1. + <_> + 14 19 1 1 9. + 0 + -1.8372290069237351e-003 + -0.8788912892341614 + 0.1146014034748077 + <_> + + <_> + + + + <_> + 17 17 1 2 -1. + <_> + 17 18 1 1 2. + 0 + -4.3397278204793110e-005 + 0.2129840999841690 + -0.5028128027915955 + -1.4024209976196289 + 9 + -1 + <_> + + + <_> + + <_> + + + + <_> + 10 11 4 12 -1. + <_> + 10 11 2 6 2. + <_> + 12 17 2 6 2. + 0 + -2.0713880658149719e-003 + 0.2486661970615387 + -0.5756726861000061 + <_> + + <_> + + + + <_> + 12 23 12 1 -1. + <_> + 18 23 6 1 2. + 0 + 3.6768750287592411e-003 + -0.5755078196525574 + 0.2280506044626236 + <_> + + <_> + + + + <_> + 13 10 3 4 -1. + <_> + 13 10 3 2 2. + 1 + -3.0887479078955948e-004 + 0.2362288981676102 + -0.6454687118530273 + <_> + + <_> + + + + <_> + 0 0 24 24 -1. + <_> + 0 0 12 12 2. + <_> + 12 12 12 12 2. + 0 + -0.0257820300757885 + -0.7496209144592285 + 0.1617882996797562 + <_> + + <_> + + + + <_> + 2 10 2 6 -1. + <_> + 2 13 2 3 2. + 0 + -1.2850989587605000e-003 + -0.7813286781311035 + 0.1440877020359039 + <_> + + <_> + + + + <_> + 0 11 2 6 -1. + <_> + 0 14 2 3 2. + 0 + 3.3493789378553629e-003 + 0.1375873982906342 + -0.7505543231964111 + <_> + + <_> + + + + <_> + 0 1 24 1 -1. + <_> + 8 1 8 1 3. + 0 + -2.6788329705595970e-003 + 0.2596372067928314 + -0.4255296885967255 + <_> + + <_> + + + + <_> + 13 7 4 2 -1. + <_> + 13 8 4 1 2. + 0 + -2.8834199838456698e-005 + 0.1635348945856094 + -0.7050843238830566 + <_> + + <_> + + + + <_> + 0 13 3 10 -1. + <_> + 1 13 1 10 3. + 0 + -1.6196980141103268e-003 + 0.3419960141181946 + -0.3415850102901459 + <_> + + <_> + + + + <_> + 1 10 10 10 -1. + <_> + 6 10 5 10 2. + 0 + 1.0517919436097145e-003 + 0.1479195058345795 + -0.7929052114486694 + <_> + + <_> + + + + <_> + 9 0 4 6 -1. + <_> + 9 0 4 3 2. + 1 + -2.4886541068553925e-003 + -0.8937227129936218 + 0.1043419018387795 + -1.1141099929809570 + 10 + -1 + <_> + + + <_> + + <_> + + + + <_> + 16 18 1 2 -1. + <_> + 16 19 1 1 2. + 0 + -5.7590808864915743e-005 + 0.2734906971454620 + -0.6426038742065430 + <_> + + <_> + + + + <_> + 21 14 2 8 -1. + <_> + 22 14 1 8 2. + 0 + 7.1206100983545184e-004 + -0.5435984134674072 + 0.2552855014801025 + <_> + + <_> + + + + <_> + 0 7 21 9 -1. + <_> + 7 10 7 3 9. + 0 + -0.3888005912303925 + 0.6930956840515137 + -0.1862079948186874 + <_> + + <_> + + + + <_> + 16 16 1 4 -1. + <_> + 16 17 1 2 2. + 0 + 2.5288251345045865e-004 + 0.2914173901081085 + -0.5620415806770325 + <_> + + <_> + + + + <_> + 19 15 2 6 -1. + <_> + 17 17 2 2 3. + 1 + -2.1006830502301455e-003 + -0.6822040081024170 + 0.1185996010899544 + <_> + + <_> + + + + <_> + 6 0 15 4 -1. + <_> + 6 1 15 2 2. + 0 + -3.2310429960489273e-003 + 0.3972072899341583 + -0.2774995863437653 + <_> + + <_> + + + + <_> + 9 16 1 4 -1. + <_> + 9 17 1 2 2. + 0 + 1.4478569937637076e-005 + -0.5476933717727661 + 0.2119608968496323 + <_> + + <_> + + + + <_> + 8 20 8 2 -1. + <_> + 8 20 4 1 2. + <_> + 12 21 4 1 2. + 0 + -9.0244162129238248e-004 + -0.8646997213363648 + 0.1194489970803261 + <_> + + <_> + + + + <_> + 0 9 3 14 -1. + <_> + 1 9 1 14 3. + 0 + -1.5906910412013531e-003 + 0.2919914126396179 + -0.3928124904632568 + <_> + + <_> + + + + <_> + 11 1 11 4 -1. + <_> + 11 1 11 2 2. + 1 + 7.4913240969181061e-003 + 0.2679530084133148 + -0.4020768105983734 + -1.0776710510253906 + 11 + -1 + <_> + + + <_> + + <_> + + + + <_> + 15 20 1 2 -1. + <_> + 15 21 1 1 2. + 0 + -7.1240079705603421e-005 + 0.2823083102703095 + -0.4779424071311951 + <_> + + <_> + + + + <_> + 2 18 1 2 -1. + <_> + 2 18 1 1 2. + 1 + -2.6417701155878603e-004 + 0.3084900975227356 + -0.4036655128002167 + <_> + + <_> + + + + <_> + 0 14 12 6 -1. + <_> + 0 16 12 2 3. + 0 + 5.2890321239829063e-004 + -0.7423822879791260 + 0.1605536937713623 + <_> + + <_> + + + + <_> + 4 10 2 14 -1. + <_> + 4 10 1 7 2. + <_> + 5 17 1 7 2. + 0 + 3.8283021422103047e-004 + -0.6108828783035278 + 0.1794416010379791 + <_> + + <_> + + + + <_> + 22 3 2 15 -1. + <_> + 23 3 1 15 2. + 0 + 5.4077422246336937e-003 + -0.2767061889171600 + 0.4017147123813629 + <_> + + <_> + + + + <_> + 4 17 3 1 -1. + <_> + 5 18 1 1 3. + 1 + -8.2620367174968123e-004 + -0.8456827998161316 + 0.1641048043966293 + <_> + + <_> + + + + <_> + 21 6 3 9 -1. + <_> + 21 9 3 3 3. + 0 + -8.9606801047921181e-003 + -0.6698572039604187 + 0.1270485967397690 + <_> + + <_> + + + + <_> + 1 7 23 4 -1. + <_> + 1 9 23 2 2. + 0 + -3.0286349356174469e-003 + 0.1227105036377907 + -0.7880274057388306 + <_> + + <_> + + + + <_> + 4 3 20 20 -1. + <_> + 4 13 20 10 2. + 0 + -0.0262723900377750 + -0.7226560711860657 + 0.1347829997539520 + <_> + + <_> + + + + <_> + 14 13 7 4 -1. + <_> + 14 15 7 2 2. + 0 + -5.0153239862993360e-004 + 0.2890014052391052 + -0.3537223935127258 + <_> + + <_> + + + + <_> + 2 6 2 2 -1. + <_> + 2 6 2 1 2. + 1 + -1.9847620569635183e-004 + 0.2491115033626556 + -0.4667024016380310 + -1.1201709508895874 + 12 + -1 + <_> + + + <_> + + <_> + + + + <_> + 13 15 6 4 -1. + <_> + 13 17 6 2 2. + 0 + -1.6098109772428870e-003 + 0.2436411976814270 + -0.5425583124160767 + <_> + + <_> + + + + <_> + 17 0 7 24 -1. + <_> + 17 8 7 8 3. + 0 + 3.0391800682991743e-003 + 0.1427879035472870 + -0.7677937150001526 + <_> + + <_> + + + + <_> + 3 7 20 8 -1. + <_> + 13 7 10 8 2. + 0 + -0.0111625995486975 + -0.7964649796485901 + 0.1309580951929092 + <_> + + <_> + + + + <_> + 0 7 22 1 -1. + <_> + 11 7 11 1 2. + 0 + -1.6689340118318796e-003 + 0.2306797951459885 + -0.4947401881217957 + <_> + + <_> + + + + <_> + 7 9 8 2 -1. + <_> + 7 10 8 1 2. + 0 + -8.8481552666053176e-004 + 0.2005017995834351 + -0.5158239006996155 + <_> + + <_> + + + + <_> + 2 0 3 18 -1. + <_> + 2 6 3 6 3. + 0 + -2.6040559168905020e-003 + 0.1298092007637024 + -0.7818121910095215 + <_> + + <_> + + + + <_> + 2 13 3 5 -1. + <_> + 3 13 1 5 3. + 0 + -2.3444599355570972e-004 + -0.5695487260818481 + 0.1478334069252014 + <_> + + <_> + + + + <_> + 14 16 3 4 -1. + <_> + 15 16 1 4 3. + 0 + 8.4604357834905386e-004 + 0.1037243008613586 + -0.8308842182159424 + <_> + + <_> + + + + <_> + 10 0 12 3 -1. + <_> + 10 1 12 1 3. + 0 + -2.4807569570839405e-003 + 0.3425926864147186 + -0.2719523906707764 + <_> + + <_> + + + + <_> + 15 16 3 1 -1. + <_> + 16 17 1 1 3. + 1 + -1.1127090547233820e-003 + -0.8275328278541565 + 0.1176175028085709 + <_> + + <_> + + + + <_> + 22 13 2 5 -1. + <_> + 23 13 1 5 2. + 0 + 1.4298419700935483e-003 + -0.3477616012096405 + 0.2652699053287506 + <_> + + <_> + + + + <_> + 11 14 4 6 -1. + <_> + 11 16 4 2 3. + 0 + -1.4572150539606810e-003 + -0.8802363276481628 + 0.1092033982276917 + -1.0063530206680298 + 13 + -1 + <_> + + + <_> + + <_> + + + + <_> + 14 15 1 2 -1. + <_> + 14 16 1 1 2. + 0 + -1.4507149899145588e-005 + 0.2605004012584686 + -0.4580149054527283 + <_> + + <_> + + + + <_> + 6 3 6 5 -1. + <_> + 6 3 3 5 2. + 1 + 0.0136784398928285 + -0.7149971723556519 + 0.1477705985307694 + <_> + + <_> + + + + <_> + 2 8 1 2 -1. + <_> + 2 8 1 1 2. + 1 + -7.3151881224475801e-005 + 0.2058611065149307 + -0.4995836019515991 + <_> + + <_> + + + + <_> + 9 17 4 4 -1. + <_> + 9 18 4 2 2. + 0 + -6.7043182207271457e-004 + -0.7319483757019043 + 0.1358278989791870 + <_> + + <_> + + + + <_> + 10 6 4 5 -1. + <_> + 11 6 2 5 2. + 0 + -1.1992789804935455e-003 + 0.4456472992897034 + -0.2521241009235382 + <_> + + <_> + + + + <_> + 2 21 12 2 -1. + <_> + 8 21 6 2 2. + 0 + -0.0117351496592164 + -0.7972438931465149 + 0.1424607038497925 + <_> + + <_> + + + + <_> + 12 8 12 15 -1. + <_> + 16 8 4 15 3. + 0 + -4.7361929900944233e-003 + 0.1624221056699753 + -0.5223402976989746 + <_> + + <_> + + + + <_> + 0 3 20 20 -1. + <_> + 0 13 20 10 2. + 0 + -0.1084595024585724 + -0.7962973713874817 + 0.1265926957130432 + <_> + + <_> + + + + <_> + 16 17 4 2 -1. + <_> + 16 17 4 1 2. + 1 + -3.2293208641931415e-004 + -0.7129234075546265 + 0.0899520069360733 + <_> + + <_> + + + + <_> + 21 14 2 5 -1. + <_> + 21 14 1 5 2. + 1 + 2.5980910286307335e-003 + -0.2800100147724152 + 0.3197942078113556 + <_> + + <_> + + + + <_> + 12 0 12 8 -1. + <_> + 12 0 12 4 2. + 1 + -7.5798099860548973e-003 + -0.7153301239013672 + 0.1406804025173187 + <_> + + <_> + + + + <_> + 17 0 7 24 -1. + <_> + 17 6 7 12 2. + 0 + -8.4003582596778870e-003 + 0.1168404966592789 + -0.6506950259208679 + <_> + + <_> + + + + <_> + 13 10 3 6 -1. + <_> + 13 12 3 2 3. + 0 + 3.6820198874920607e-003 + -0.2631436884403229 + 0.3865979909896851 + -1.0373339653015137 + 14 + -1 + <_> + + + <_> + + <_> + + + + <_> + 8 11 9 9 -1. + <_> + 11 14 3 3 9. + 0 + 0.0240733902901411 + -0.4794333875179291 + 0.2617827057838440 + <_> + + <_> + + + + <_> + 17 18 7 6 -1. + <_> + 17 21 7 3 2. + 0 + 1.9582170061767101e-003 + -0.4434475898742676 + 0.2301298975944519 + <_> + + <_> + + + + <_> + 9 8 4 2 -1. + <_> + 9 9 4 1 2. + 0 + -2.0559200493153185e-004 + 0.1224080994725227 + -0.7277694940567017 + <_> + + <_> + + + + <_> + 7 7 7 6 -1. + <_> + 7 9 7 2 3. + 0 + 1.0637210216373205e-003 + -0.1582341045141220 + 0.6447200775146484 + <_> + + <_> + + + + <_> + 2 9 1 9 -1. + <_> + 2 12 1 3 3. + 0 + -3.5040560760535300e-004 + -0.5160586237907410 + 0.2033808976411820 + <_> + + <_> + + + + <_> + 1 0 1 20 -1. + <_> + 1 10 1 10 2. + 0 + -1.5382179990410805e-003 + 0.2029495984315872 + -0.5412080287933350 + <_> + + <_> + + + + <_> + 5 11 4 3 -1. + <_> + 5 11 2 3 2. + 1 + 4.2215911671519279e-003 + 0.1420246958732605 + -0.6884710788726807 + <_> + + <_> + + + + <_> + 1 6 14 13 -1. + <_> + 8 6 7 13 2. + 0 + 4.0536639280617237e-003 + 0.0946411192417145 + -0.8890265226364136 + <_> + + <_> + + + + <_> + 11 6 6 4 -1. + <_> + 13 6 2 4 3. + 0 + 3.9104130119085312e-003 + -0.2211245000362396 + 0.4553441107273102 + <_> + + <_> + + + + <_> + 15 20 2 2 -1. + <_> + 15 20 2 1 2. + 1 + -5.8839347911998630e-004 + -0.7423400878906250 + 0.1466006040573120 + <_> + + <_> + + + + <_> + 11 7 11 2 -1. + <_> + 11 8 11 1 2. + 0 + 4.7331111272796988e-004 + 0.0803736001253128 + -0.8416292071342468 + <_> + + <_> + + + + <_> + 14 0 7 4 -1. + <_> + 14 1 7 2 2. + 0 + -1.4589539496228099e-003 + 0.2730404138565064 + -0.2989330887794495 + -0.9257612824440002 + 15 + -1 + diff --git a/ext/opencv/gsthanddetect.c b/ext/opencv/gsthanddetect.c new file mode 100644 index 0000000000..223a18595e --- /dev/null +++ b/ext/opencv/gsthanddetect.c @@ -0,0 +1,762 @@ +/* + * GStreamer hand gesture detection plugins + * Copyright (C) 2012 Andol Li <> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/** + * SECTION:video-filter-handdetect + * + * FIXME:operates hand gesture detection in video streams and images, + * and enable media operation e.g. play/stop/fast forward/back rewind. + * + * + * Example launch line + * |[ + * gst-launch autovideosrc ! ffmpegcolorspace ! "video/x-raw-rgb, width=320, height=240" ! \ + videoscale ! handdetect ! ffmpegcolorspace ! xvimagesink + * ]| + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +/* interfaces */ +#include +/* element header */ +#include "gsthanddetect.h" +/* gst */ +#include +#include +#include "gstopencvutils.h" +/* debugging */ +#include + +GST_DEBUG_CATEGORY_STATIC (gst_handdetect_debug); +#define GST_CAT_DEFAULT gst_handdetect_debug + +/* define HAAR files */ +#define HAAR_FILE_FIST "/usr/local/share/opencv/haarcascades/fist.xml" +#define HAAR_FILE_PALM "/usr/local/share/opencv/haarcascades/palm.xml" + +/* Filter signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_DISPLAY, + PROP_PROFILE_FIST, + PROP_PROFILE_PALM, + PROP_ROI_X, + PROP_ROI_Y, + PROP_ROI_WIDTH, + PROP_ROI_HEIGHT +}; + +/* the capabilities of the inputs and outputs */ +static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) + ); +static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) + ); + +static void gst_handdetect_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_handdetect_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); +static gboolean gst_handdetect_set_caps (GstOpencvVideoFilter * transform, + gint in_width, gint in_height, gint in_depth, gint in_channels, + gint out_width, gint out_height, gint out_depth, gint out_channels); +static GstFlowReturn gst_handdetect_transform_ip (GstOpencvVideoFilter * + transform, GstBuffer * buffer, IplImage * img); + +static void gst_handdetect_load_profile (GstHanddetect * filter); + +static void gst_handdetect_init_interfaces (GType type); +static void +gst_handdetect_implements_interface_init (GstImplementsInterfaceClass * klass); +static void gst_handdetect_navigation_interface_init (gpointer g_iface, + gpointer iface_data); +static gboolean gst_handdetect_interface_supported (GstImplementsInterface * + iface, GType type); +static void gst_handdetect_navigation_send_event (GstNavigation * navigation, + GstStructure * structure); +static gboolean gst_handdetect_handle_pad_event (GstPad * pad, + GstEvent * event); + +GST_BOILERPLATE_FULL (GstHanddetect, gst_handdetect, GstOpencvVideoFilter, + GST_TYPE_OPENCV_VIDEO_FILTER, gst_handdetect_init_interfaces); + +static void +gst_handdetect_init_interfaces (GType type) +{ + static const GInterfaceInfo iface_info = { + (GInterfaceInitFunc) gst_handdetect_implements_interface_init, + NULL, + NULL, + }; + g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE, + &iface_info); + static const GInterfaceInfo navigation_info = { + (GInterfaceInitFunc) gst_handdetect_navigation_interface_init, + NULL, + NULL, + }; + g_type_add_interface_static (type, GST_TYPE_NAVIGATION, &navigation_info); +} + +static void +gst_handdetect_navigation_interface_init (gpointer g_iface, gpointer iface_data) +{ + GstNavigationInterface *iface = (GstNavigationInterface *) g_iface; + iface->send_event = gst_handdetect_navigation_send_event; +} + +static gboolean +gst_handdetect_interface_supported (GstImplementsInterface * iface, GType type) +{ + if (type == GST_TYPE_NAVIGATION) + return TRUE; + return FALSE; +} + +static void +gst_handdetect_implements_interface_init (GstImplementsInterfaceClass * klass) +{ + klass->supported = gst_handdetect_interface_supported; +} + +/* FIXME: this function used to parse the region of interests coordinates + * sending from applications when the hand gestures reach the defined regions of interests, + * at this moment this function is not doing anything significantly + * but will be CHANGED when the gstreamer is patched with new hand gesture events + */ +static void +gst_handdetect_navigation_send_event (GstNavigation * navigation, + GstStructure * structure) +{ + GstHanddetect *filter = GST_HANDDETECT (navigation); + GstPad *peer; + + if ((peer = gst_pad_get_peer (GST_BASE_TRANSFORM_CAST (filter)->sinkpad))) { + GstEvent *event; + event = gst_event_new_navigation (structure); + gst_pad_send_event (peer, event); + gst_object_unref (peer); + } +} + +/* handle element pad event */ +/* no PRACTICAL USE at the moment + * this function is used to debug the fist-move/palm-move event + * will CHANGE in the future + */ +static gboolean +gst_handdetect_handle_pad_event (GstPad * pad, GstEvent * event) +{ + const GstStructure *s = gst_event_get_structure (event); + const gchar *name = gst_structure_get_string (s, "event"); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_EOS: + break; + case GST_EVENT_NAVIGATION:{ + if (g_str_equal (name, "fist-move")) { + GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)), + "Fist-move event\n "); + uint x, y; + gst_structure_get_uint (s, "x", &x); + gst_structure_get_uint (s, "y", &y); + GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)), + "Fist Pos:[%d, %d]\n", x, y); + } else if (g_str_equal (name, "palm-move")) { + GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)), + "Palm-move event\n "); + uint x, y; + gst_structure_get_uint (s, "x", &x); + gst_structure_get_uint (s, "y", &y); + GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)), + "Palm Pos:[%d, %d]\n", x, y); + } else if (g_str_equal (name, "mouse-move")) { + gdouble x, y; + gst_structure_get_double (s, "pointer_x", &x); + gst_structure_get_double (s, "pointer_y", &y); + GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)), + "Mouse-move [%f, %f]\n", x, y); + } else if (g_str_equal (name, "mouse-button-press")) { + GST_DEBUG ("Mouse botton press\n"); + } else if (g_str_equal (name, "mouse-button-release")) { + GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)), + "Mouse button release\n"); + } + break; + } + default: + break; + } + return gst_pad_event_default (pad, event); +} + +/* clean opencv images and parameters */ +static void +gst_handdetect_finalise (GObject * obj) +{ + GstHanddetect *filter = GST_HANDDETECT (obj); + + if (filter->cvImage) + cvReleaseImage (&filter->cvImage); + if (filter->cvGray) + cvReleaseImage (&filter->cvGray); + g_free (filter->profile_fist); + g_free (filter->profile_palm); + + G_OBJECT_CLASS (parent_class)->finalize (obj); +} + +/* GObject vmethod implementations */ +static void +gst_handdetect_base_init (gpointer gclass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); + + gst_element_class_set_details_simple (element_class, + "hand detect", + "Filter/Effect/Video", + "Performs hand gesture detection on videos, providing detected hand positions via bus message and navigation event, and deals with hand gesture events", + "Andol Li <>"); + + gst_element_class_add_static_pad_template (element_class, &src_factory); + gst_element_class_add_static_pad_template (element_class, &sink_factory); +} + +/* initialise the HANDDETECT class */ +static void +gst_handdetect_class_init (GstHanddetectClass * klass) +{ + GObjectClass *gobject_class; + GstOpencvVideoFilterClass *gstopencvbasefilter_class; + + gobject_class = (GObjectClass *) klass; + gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass; + + gstopencvbasefilter_class->cv_trans_ip_func = gst_handdetect_transform_ip; + gstopencvbasefilter_class->cv_set_caps = gst_handdetect_set_caps; + + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_handdetect_finalise); + gobject_class->set_property = gst_handdetect_set_property; + gobject_class->get_property = gst_handdetect_get_property; + + g_object_class_install_property (gobject_class, + PROP_DISPLAY, + g_param_spec_boolean ("display", + "Display", + "Whether the detected hands are highlighted in output frame", + TRUE, G_PARAM_READWRITE) + ); + g_object_class_install_property (gobject_class, + PROP_PROFILE_FIST, + g_param_spec_string ("profile_fist", + "Profile_fist", + "Location of HAAR cascade file (fist gesture)", + HAAR_FILE_FIST, G_PARAM_READWRITE) + ); + g_object_class_install_property (gobject_class, + PROP_PROFILE_PALM, + g_param_spec_string ("profile_palm", + "Profile_palm", + "Location of HAAR cascade file (palm gesture)", + HAAR_FILE_PALM, G_PARAM_READWRITE) + ); + g_object_class_install_property (gobject_class, + PROP_ROI_X, + g_param_spec_uint ("ROI_X", + "ROI_X", + "X of left-top pointer in region of interest \nGestures in the defined region of interest will emit messages", + 0, UINT_MAX, 0, G_PARAM_READWRITE) + ); + g_object_class_install_property (gobject_class, + PROP_ROI_Y, + g_param_spec_uint ("ROI_Y", + "ROI_Y", + "Y of left-top pointer in region of interest \nGestures in the defined region of interest will emit messages", + 0, UINT_MAX, 0, G_PARAM_READWRITE) + ); + g_object_class_install_property (gobject_class, + PROP_ROI_WIDTH, + g_param_spec_uint ("ROI_WIDTH", + "ROI_WIDTH", + "WIDTH of left-top pointer in region of interest \nGestures in the defined region of interest will emit messages", + 0, UINT_MAX, 0, G_PARAM_READWRITE) + ); + g_object_class_install_property (gobject_class, + PROP_ROI_HEIGHT, + g_param_spec_uint ("ROI_HEIGHT", + "ROI_HEIGHT", + "HEIGHT of left-top pointer in region of interest \nGestures in the defined region of interest will emit messages", + 0, UINT_MAX, 0, G_PARAM_READWRITE) + ); +} + +/* initialise the new element + * instantiate pads and add them to element + * set pad call-back functions + * initialise instance structure + */ +static void +gst_handdetect_init (GstHanddetect * filter, GstHanddetectClass * gclass) +{ + GstBaseTransform *trans = GST_BASE_TRANSFORM_CAST (filter); + + gst_pad_set_event_function (trans->srcpad, + GST_DEBUG_FUNCPTR (gst_handdetect_handle_pad_event)); + + filter->profile_fist = g_strdup (HAAR_FILE_FIST); + filter->profile_palm = g_strdup (HAAR_FILE_PALM); + filter->roi_x = 0; + filter->roi_y = 0; + filter->roi_width = 0; + filter->roi_height = 0; + filter->display = TRUE; + + gst_handdetect_load_profile (filter); + + gst_opencv_video_filter_set_in_place (GST_OPENCV_VIDEO_FILTER_CAST (filter), + TRUE); +} + +static void +gst_handdetect_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstHanddetect *filter = GST_HANDDETECT (object); + + switch (prop_id) { + case PROP_PROFILE_FIST: + g_free (filter->profile_fist); + filter->profile_fist = g_value_dup_string (value); + gst_handdetect_load_profile (filter); + break; + case PROP_PROFILE_PALM: + g_free (filter->profile_palm); + filter->profile_palm = g_value_dup_string (value); + gst_handdetect_load_profile (filter); + break; + case PROP_DISPLAY: + filter->display = g_value_get_boolean (value); + break; + case PROP_ROI_X: + filter->roi_x = g_value_get_uint (value); + break; + case PROP_ROI_Y: + filter->roi_y = g_value_get_uint (value); + break; + case PROP_ROI_WIDTH: + filter->roi_width = g_value_get_uint (value); + break; + case PROP_ROI_HEIGHT: + filter->roi_height = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_handdetect_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstHanddetect *filter = GST_HANDDETECT (object); + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_boolean (value, filter->display); + break; + case PROP_PROFILE_FIST: + g_value_set_string (value, filter->profile_fist); + break; + case PROP_PROFILE_PALM: + g_value_set_string (value, filter->profile_palm); + break; + case PROP_ROI_X: + g_value_set_uint (value, filter->roi_x); + break; + case PROP_ROI_Y: + g_value_set_uint (value, filter->roi_y); + break; + case PROP_ROI_WIDTH: + g_value_set_uint (value, filter->roi_width); + break; + case PROP_ROI_HEIGHT: + g_value_set_uint (value, filter->roi_height); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/* GstElement vmethod implementations */ +/* this function handles the link with other elements */ +static gboolean +gst_handdetect_set_caps (GstOpencvVideoFilter * transform, + gint in_width, gint in_height, gint in_depth, gint in_channels, + gint out_width, gint out_height, gint out_depth, gint out_channels) +{ + GstHanddetect *filter; + filter = GST_HANDDETECT (transform); + + if (filter->cvGray) + cvReleaseImage (&filter->cvGray); + filter->cvGray = + cvCreateImage (cvSize (in_width, in_height), IPL_DEPTH_8U, 1); + if (filter->cvImage) + cvReleaseImage (&filter->cvImage); + filter->cvImage = + cvCreateImage (cvSize (in_width, in_height), IPL_DEPTH_8U, 3); + + if (!filter->cvStorage) + filter->cvStorage = cvCreateMemStorage (0); + else + cvClearMemStorage (filter->cvStorage); + if (!filter->cvStorage_palm) + filter->cvStorage_palm = cvCreateMemStorage (0); + else + cvClearMemStorage (filter->cvStorage_palm); + return TRUE; +} + +/* Hand detection function + * This function does the actual processing 'of hand detect and display' + */ +static GstFlowReturn +gst_handdetect_transform_ip (GstOpencvVideoFilter * transform, + GstBuffer * buffer, IplImage * img) +{ + GstHanddetect *filter = GST_HANDDETECT (transform); + CvSeq *hands; + CvRect *r; + GstStructure *s; + GstMessage *m; + int i; + + filter->cvImage->imageData = (char *) GST_BUFFER_DATA (buffer); + /* 320 x 240 is with the best detect accuracy, if not, give info */ + if (filter->cvImage->width != 320 || filter->cvImage->height != 240) + GST_INFO_OBJECT (filter, + "WARNING: resize to 320 x 240 to have best detect accuracy.\n"); + /* cvt to gray colour space for hand detect */ + cvCvtColor (filter->cvImage, filter->cvGray, CV_RGB2GRAY); + cvClearMemStorage (filter->cvStorage); + + /* check detection cascades */ + if (!filter->cvCascade_fist || !filter->cvCascade_palm) + return GST_FLOW_OK; + + /* detect FIST gesture fist */ + hands = + cvHaarDetectObjects (filter->cvGray, filter->cvCascade_fist, + filter->cvStorage, 1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize (24, 24) +#if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2) + , cvSize (0, 0) +#endif + ); + + /* if FIST gesture detected */ + if (hands && hands->total > 0) { + /* set frame buffer writable */ + if (filter->display) { + buffer = gst_buffer_make_writable (buffer); + GST_DEBUG_OBJECT (filter, "%d FIST gestures detected\n", + (int) hands->total); + } + /* Go through all detected FIST gestures to get the best one + * prev_r => previous hand + * best_r => best hand in this frame + */ + /* set min_distance for init comparison */ + int min_distance = filter->cvImage->width + filter->cvImage->height; + /* Init filter->prev_r */ + CvRect temp_r = cvRect (0, 0, 0, 0); + if (filter->prev_r == NULL) + filter->prev_r = &temp_r; + /* Get the best FIST gesture */ + for (i = 0; i < (hands ? hands->total : 0); i++) { + r = (CvRect *) cvGetSeqElem (hands, i); + int distance = (int) sqrt (pow ((r->x - filter->prev_r->x), + 2) + pow ((r->y - filter->prev_r->y), 2)); + if (distance <= min_distance) { + min_distance = distance; + filter->best_r = r; + } + } + /* Save best_r as prev_r for next frame comparison */ + filter->prev_r = (CvRect *) filter->best_r; + /* send msg to app/bus if the detected gesture falls in the region of interest */ + /* get center point of gesture */ + CvPoint c = + cvPoint (filter->best_r->x + filter->best_r->width / 2, + filter->best_r->y + filter->best_r->height / 2); + /* send message: + * if the center point is in the region of interest, OR, + * if the region of interest remains default as (0,0,0,0)*/ + if ((c.x >= filter->roi_x && c.x <= (filter->roi_x + filter->roi_width) + && c.y >= filter->roi_y + && c.y <= (filter->roi_y + filter->roi_height)) + || (filter->roi_x == 0 + && filter->roi_y == 0 + && filter->roi_width == 0 && filter->roi_height == 0)) { + /* Define structure for message post */ + s = gst_structure_new ("hand-gesture", + "gesture", G_TYPE_STRING, "fist", + "x", G_TYPE_UINT, + (uint) (filter->best_r->x + filter->best_r->width * 0.5), "y", + G_TYPE_UINT, + (uint) (filter->best_r->y + filter->best_r->height * 0.5), "width", + G_TYPE_UINT, (uint) filter->best_r->width, "height", G_TYPE_UINT, + (uint) filter->best_r->height, NULL); + /* Init message element */ + m = gst_message_new_element (GST_OBJECT (filter), s); + /* Send message */ + gst_element_post_message (GST_ELEMENT (filter), m); + +#if 0 + /* send event + * here we use mouse-move event instead of fist-move or palm-move event + * !!! this will CHANGE in the future !!! + * !!! by adding gst_navigation_send_hand_detect_event() in navigation.c !!! + */ + gst_navigation_send_mouse_event (GST_NAVIGATION (filter), + "mouse-move", + 0, + (double) (filter->best_r->x + filter->best_r->width * 0.5), + (double) (filter->best_r->y + filter->best_r->height * 0.5)); +#endif + } + /* Check filter->display, + * If TRUE, displaying red circle marker in the out frame */ + if (filter->display) { + CvPoint center; + int radius; + center.x = cvRound ((filter->best_r->x + filter->best_r->width * 0.5)); + center.y = cvRound ((filter->best_r->y + filter->best_r->height * 0.5)); + radius = + cvRound ((filter->best_r->width + filter->best_r->height) * 0.25); + cvCircle (filter->cvImage, center, radius, CV_RGB (0, 0, 200), 1, 8, 0); + } + } else { + /* if NO FIST gesture, detecting PALM gesture */ + hands = + cvHaarDetectObjects (filter->cvGray, filter->cvCascade_palm, + filter->cvStorage, 1.1, 3, CV_HAAR_DO_CANNY_PRUNING, cvSize (24, 24) +#if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2) + , cvSize (0, 0) +#endif + ); + /* if PALM detected */ + if (hands && hands->total > 0) { + /* set frame buffer writable */ + if (filter->display) { + buffer = gst_buffer_make_writable (buffer); + GST_DEBUG_OBJECT (filter, "%d PALM gestures detected\n", + (int) hands->total); + } + /* Go through all detected PALM gestures to get the best one + * prev_r => previous hand + * best_r => best hand in this frame + */ + /* suppose a min_distance for init comparison */ + int min_distance = filter->cvImage->width + filter->cvImage->height; + /* Init filter->prev_r */ + CvRect temp_r = cvRect (0, 0, 0, 0); + if (filter->prev_r == NULL) + filter->prev_r = &temp_r; + /* Get the best PALM gesture */ + for (i = 0; i < (hands ? hands->total : 0); i++) { + r = (CvRect *) cvGetSeqElem (hands, i); + int distance = (int) sqrt (pow ((r->x - filter->prev_r->x), + 2) + pow ((r->y - filter->prev_r->y), 2)); + if (distance <= min_distance) { + min_distance = distance; + filter->best_r = r; + } + } + /* Save best_r as prev_r for next frame comparison */ + filter->prev_r = (CvRect *) filter->best_r; + + /* send msg to app/bus if the detected gesture falls in the region of interest */ + /* get center point of gesture */ + CvPoint c = + cvPoint (filter->best_r->x + filter->best_r->width / 2, + filter->best_r->y + filter->best_r->height / 2); + /* send message: + * if the center point is in the region of interest, OR, + * if the region of interest remains default as (0,0,0,0)*/ + if ((c.x >= filter->roi_x && c.x <= (filter->roi_x + filter->roi_width) + && c.y >= filter->roi_y + && c.y <= (filter->roi_y + filter->roi_height)) + || (filter->roi_x == 0 + && filter->roi_y == 0 + && filter->roi_width == 0 && filter->roi_height == 0)) { + /* Define structure for message post */ + s = gst_structure_new ("hand-gesture", + "gesture", G_TYPE_STRING, "palm", + "x", G_TYPE_UINT, + (uint) (filter->best_r->x + filter->best_r->width * 0.5), "y", + G_TYPE_UINT, + (uint) (filter->best_r->y + filter->best_r->height * 0.5), "width", + G_TYPE_UINT, (uint) filter->best_r->width, "height", G_TYPE_UINT, + (uint) filter->best_r->height, NULL); + /* Init message element */ + m = gst_message_new_element (GST_OBJECT (filter), s); + /* Send message */ + gst_element_post_message (GST_ELEMENT (filter), m); + +#if 0 + /* send event + * here we use mouse-move event instead of fist-move or palm-move event + * !!! this will CHANGE in the future !!! + * !!! by adding gst_navigation_send_hand_detect_event() in navigation.c !!! + */ + gst_navigation_send_mouse_event (GST_NAVIGATION (filter), + "mouse-move", + 0, + (double) (filter->best_r->x + filter->best_r->width * 0.5), + (double) (filter->best_r->y + filter->best_r->height * 0.5)); + + /* or use another way to send upstream navigation event for debug + * + * GstEvent *event = + * gst_event_new_navigation (gst_structure_new + * ("application/x-gst-navigation", "event", G_TYPE_STRING, + * "mouse-move", + * "button", G_TYPE_INT, 0, + * "pointer_x", G_TYPE_DOUBLE, + * (double) (filter->best_r->x + filter->best_r->width * 0.5), + * "pointer_y", G_TYPE_DOUBLE, + * (double) (filter->best_r->y + filter->best_r->height * 0.5), + * NULL)); + * gst_pad_send_event (GST_BASE_TRANSFORM_CAST (filter)->srcpad, event); + */ +#endif + } + /* Check filter->display, + * If TRUE, displaying red circle marker in the out frame */ + if (filter->display) { + CvPoint center; + int radius; + center.x = cvRound ((filter->best_r->x + filter->best_r->width * 0.5)); + center.y = cvRound ((filter->best_r->y + filter->best_r->height * 0.5)); + radius = + cvRound ((filter->best_r->width + filter->best_r->height) * 0.25); + cvCircle (filter->cvImage, center, radius, CV_RGB (0, 0, 200), 1, 8, 0); + } + } + } + + /* Push out the incoming buffer */ + return GST_FLOW_OK; +} + +static void +gst_handdetect_load_profile (GstHanddetect * filter) +{ + GST_DEBUG_OBJECT (filter, "Loading profiles...\n"); + filter->cvCascade_fist = + (CvHaarClassifierCascade *) cvLoad (filter->profile_fist, 0, 0, 0); + filter->cvCascade_palm = + (CvHaarClassifierCascade *) cvLoad (filter->profile_palm, 0, 0, 0); + if (!filter->cvCascade_fist || !filter->cvCascade_palm) + GST_WARNING_OBJECT (filter, + "WARNING: Could not load HAAR classifier cascade: %s.\n", + filter->profile_fist); + else + GST_DEBUG_OBJECT (filter, "Loaded profile %s\n", filter->profile_fist); + if (!filter->cvCascade_palm) + GST_WARNING_OBJECT (filter, + "WARNING: Could not load HAAR classifier cascade: %s.\n", + filter->profile_palm); + else + GST_DEBUG_OBJECT (filter, "Loaded profile %s\n", filter->profile_palm); +} + +/* Entry point to initialize the plug-in + * Initialize the plug-in itself + * Register the element factories and other features + */ +static gboolean +gst_handdetect_plugin_init (GstPlugin * plugin) +{ + GST_DEBUG_CATEGORY_INIT (gst_handdetect_debug, + "handdetect", + 0, + "Performs hand gesture detection (fist and palm), providing detected hand positions via bus messages/navigation events, and dealing with hand events"); + return gst_element_register (plugin, "handdetect", GST_RANK_NONE, + GST_TYPE_HANDDETECT); +} + +/* PACKAGE: this is usually set by autotools depending on some _INIT macro + * in configure.ac and then written into and defined in config.h, but we can + * just set it ourselves here in case someone doesn't use autotools to + * compile this code. GST_PLUGIN_DEFINE needs PACKAGE to be defined. + */ +#ifndef PACKAGE +#define PACKAGE "gst_handdetect" +#endif + +/* + * Gstreamer looks for this structure to register handdetect + */ +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "handdetect", + "Detect hand gestures for media operations", + gst_handdetect_plugin_init, VERSION, "LGPL", "GStreamer", + "http://gstreamer.net/") diff --git a/ext/opencv/gsthanddetect.h b/ext/opencv/gsthanddetect.h new file mode 100644 index 0000000000..1d4a6831d1 --- /dev/null +++ b/ext/opencv/gsthanddetect.h @@ -0,0 +1,117 @@ +/* + * GStreamer + * Copyright (C) 2005 Thomas Vander Stichele + * Copyright (C) 2005 Ronald S. Bultje + * Copyright (C) 2012 andol li <> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_HANDDETECT_H__ +#define __GST_HANDDETECT_H__ + +#ifndef VERSION +#define VERSION "0.10.36" /* for GST_PLUGIN_DEFINE use */ +#endif + +#include +#include +#include +#include +#include +#include "gstopencvvideofilter.h" +/* opencv */ +#include +#include +#include +#if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2) +#include +#endif + +G_BEGIN_DECLS +/* #defines don't like whitespacey bits */ +#define GST_TYPE_HANDDETECT \ + (gst_handdetect_get_type()) +#define GST_HANDDETECT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_HANDDETECT,GstHanddetect)) +#define GST_HANDDETECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_HANDDETECT,GstHanddetectClass)) +#define GST_IS_HANDDETECT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_HANDDETECT)) +#define GST_IS_HANDDETECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_HANDDETECT)) +typedef struct _GstHanddetect GstHanddetect; +typedef struct _GstHanddetectClass GstHanddetectClass; + +struct _GstHanddetect +{ + GstOpencvVideoFilter element; + + gboolean display; + gchar *profile_fist; + gchar *profile_palm; + /* region of interest */ + uint roi_x; + uint roi_y; + uint roi_width; + uint roi_height; + + /* opencv + * cvImage - image from video cam, + * cvGray - cvt cvImage to gray colour + */ + IplImage *cvImage; + IplImage *cvGray; + CvHaarClassifierCascade *cvCascade_fist; + CvHaarClassifierCascade *cvCascade_palm; + CvMemStorage *cvStorage; + CvMemStorage *cvStorage_palm; + CvRect *prev_r; + CvRect *best_r; +}; + +struct _GstHanddetectClass +{ + GstOpencvVideoFilterClass parent_class; +}; + +GType gst_handdetect_get_type (void); + +G_END_DECLS +#endif /* __GST_HANDDETECT_H__ */ diff --git a/ext/opencv/palm.xml b/ext/opencv/palm.xml new file mode 100644 index 0000000000..38916e1cd6 --- /dev/null +++ b/ext/opencv/palm.xml @@ -0,0 +1,1512 @@ + + + + + + 20 20 + + <_> + + + <_> + + <_> + + + + <_> + 14 0 6 16 -1. + <_> + 17 0 3 16 2. + 0 + 3.8681671023368835e-002 + -9.8028910160064697e-001 + 1 + <_> + + + + <_> + 6 4 7 8 -1. + <_> + 6 8 7 4 2. + 0 + -2.6647120714187622e-002 + -1. + 9.4076812267303467e-001 + <_> + + <_> + + + + <_> + 12 0 8 17 -1. + <_> + 16 0 4 17 2. + 0 + 6.1131078749895096e-002 + -9.0244722366333008e-001 + 1 + <_> + + + + <_> + 7 6 9 5 -1. + <_> + 10 9 3 5 3. + 1 + -3.3309649676084518e-002 + -5.8893251419067383e-001 + 9.1832017898559570e-001 + <_> + + <_> + + + + <_> + 1 0 18 4 -1. + <_> + 7 0 6 4 3. + 0 + -5.0153050571680069e-002 + 7.9939717054367065e-001 + 1 + <_> + + + + <_> + 6 6 6 3 -1. + <_> + 8 6 2 3 3. + 0 + -1.8358040601015091e-002 + 8.4302067756652832e-001 + -9.3710541725158691e-001 + <_> + + <_> + + + + <_> + 0 3 6 8 -1. + <_> + 3 3 3 8 2. + 0 + -3.6677200347185135e-002 + 8.2961827516555786e-001 + 1 + <_> + + + + <_> + 11 3 6 14 -1. + <_> + 11 3 3 7 2. + <_> + 14 10 3 7 2. + 0 + -4.3658491224050522e-002 + 8.0457127094268799e-001 + -8.9302337169647217e-001 + <_> + + <_> + + + + <_> + 16 3 4 16 -1. + <_> + 18 3 2 16 2. + 0 + 2.5138080120086670e-002 + 1 + 7.4585878849029541e-001 + <_> + + + + <_> + 0 1 9 6 -1. + <_> + 3 3 3 2 9. + 0 + -6.6900141537189484e-002 + 8.4059208631515503e-001 + -8.8331997394561768e-001 + <_> + + <_> + + + + <_> + 10 9 3 3 -1. + <_> + 11 9 1 3 3. + 0 + 1.7255060374736786e-003 + 1 + 7.7119922637939453e-001 + <_> + + + + <_> + 12 1 4 4 -1. + <_> + 14 1 2 4 2. + 0 + 8.4419725462794304e-003 + -8.4468692541122437e-001 + 7.2725939750671387e-001 + <_> + + <_> + + + + <_> + 13 7 6 6 -1. + <_> + 16 7 3 6 2. + 0 + 3.2117430120706558e-002 + 1 + 6.4971947669982910e-001 + <_> + + + + <_> + 13 5 4 14 -1. + <_> + 13 5 2 7 2. + <_> + 15 12 2 7 2. + 0 + 2.6627309620380402e-002 + -8.6625558137893677e-001 + 8.9164018630981445e-001 + 4.6676799654960632e-001 + -1 + -1 + <_> + + + <_> + + <_> + + + + <_> + 1 2 4 11 -1. + <_> + 3 2 2 11 2. + 0 + -2.6734400540590286e-002 + 1 + -6.5627342462539673e-001 + <_> + + + + <_> + 14 0 6 19 -1. + <_> + 17 0 3 19 2. + 0 + 7.8886173665523529e-002 + -6.7220860719680786e-001 + 8.6547261476516724e-001 + <_> + + <_> + + + + <_> + 0 3 2 12 -1. + <_> + 1 3 1 12 2. + 0 + -2.2544919047504663e-003 + 1 + -5.3239947557449341e-001 + <_> + + + + <_> + 2 9 10 10 -1. + <_> + 7 9 5 10 2. + 0 + -4.5755971223115921e-002 + -9.6904259920120239e-001 + 7.0433187484741211e-001 + <_> + + <_> + + + + <_> + 7 6 3 5 -1. + <_> + 8 6 1 5 3. + 0 + 5.2909408695995808e-003 + 1 + 6.8145847320556641e-001 + <_> + + + + <_> + 7 0 4 12 -1. + <_> + 8 0 2 12 2. + 0 + -1.3724939897656441e-002 + 6.2345337867736816e-001 + -6.6262710094451904e-001 + <_> + + <_> + + + + <_> + 12 4 8 10 -1. + <_> + 16 4 4 10 2. + 0 + 1.1801239848136902e-001 + 1 + 5.4585951566696167e-001 + <_> + + + + <_> + 10 6 4 12 -1. + <_> + 10 6 2 6 2. + <_> + 12 12 2 6 2. + 0 + -3.9759848266839981e-002 + 7.7439647912979126e-001 + -6.9461721181869507e-001 + <_> + + <_> + + + + <_> + 5 6 5 14 -1. + <_> + 5 13 5 7 2. + 0 + 1.7409030115231872e-003 + -8.0978208780288696e-001 + 1 + <_> + + + + <_> + 6 6 12 14 -1. + <_> + 6 13 12 7 2. + 0 + 1.6339950263500214e-001 + 4.9990290403366089e-001 + -9.4595247507095337e-001 + <_> + + <_> + + + + <_> + 6 0 4 1 -1. + <_> + 6 0 2 1 2. + 1 + 7.5461310334503651e-003 + 1 + 6.3170629739761353e-001 + <_> + + + + <_> + 5 3 4 10 -1. + <_> + 5 3 2 5 2. + <_> + 7 8 2 5 2. + 0 + -2.2127110511064529e-002 + 6.1635309457778931e-001 + -6.7650932073593140e-001 + <_> + + <_> + + + + <_> + 10 8 4 4 -1. + <_> + 11 8 2 4 2. + 0 + 7.2129550389945507e-003 + 1 + 6.0694038867950439e-001 + <_> + + + + <_> + 9 7 3 4 -1. + <_> + 10 7 1 4 3. + 0 + 5.9658549726009369e-003 + -7.1250128746032715e-001 + 5.0982707738876343e-001 + <_> + + <_> + + + + <_> + 13 1 4 10 -1. + <_> + 13 1 2 10 2. + 1 + -1.3171000173315406e-003 + 1 + -7.0088720321655273e-001 + <_> + + + + <_> + 12 7 2 10 -1. + <_> + 12 7 2 5 2. + 1 + 1.0129069909453392e-002 + 6.0936927795410156e-001 + -9.5784842967987061e-001 + <_> + + <_> + + + + <_> + 1 6 2 11 -1. + <_> + 2 6 1 11 2. + 0 + -2.3017649073153734e-003 + 4.1956830024719238e-001 + 1 + <_> + + + + <_> + 2 5 3 6 -1. + <_> + 3 5 1 6 3. + 0 + 4.4859871268272400e-003 + -8.9829748868942261e-001 + 5.8359438180923462e-001 + <_> + + <_> + + + + <_> + 18 4 2 1 -1. + <_> + 19 4 1 1 2. + 0 + 9.6589370514266193e-005 + 1 + 3.0583730340003967e-001 + <_> + + + + <_> + 16 12 4 2 -1. + <_> + 17 12 2 2 2. + 0 + -7.5696231797337532e-003 + 8.4811502695083618e-001 + -8.0426692962646484e-001 + <_> + + <_> + + + + <_> + 8 5 3 4 -1. + <_> + 9 5 1 4 3. + 0 + 5.9972028248012066e-003 + 1 + 6.7728942632675171e-001 + <_> + + + + <_> + 6 1 3 15 -1. + <_> + 7 6 1 5 9. + 0 + 2.7960389852523804e-002 + -6.5531158447265625e-001 + 5.2915072441101074e-001 + <_> + + <_> + + + + <_> + 12 0 8 19 -1. + <_> + 16 0 4 19 2. + 0 + 1.0068819671869278e-001 + -9.0510547161102295e-001 + 1 + <_> + + + + <_> + 0 0 9 18 -1. + <_> + 0 6 9 6 3. + 0 + -1.3593779876828194e-002 + 4.7082710266113281e-001 + -8.6754322052001953e-001 + <_> + + <_> + + + + <_> + 7 2 5 16 -1. + <_> + 7 10 5 8 2. + 0 + 4.1386592201888561e-003 + 1 + 3.7525629997253418e-001 + <_> + + + + <_> + 6 1 8 4 -1. + <_> + 6 1 4 2 2. + <_> + 10 3 4 2 2. + 0 + 4.4159390963613987e-003 + -8.9145201444625854e-001 + 3.3699101209640503e-001 + <_> + + <_> + + + + <_> + 15 3 3 4 -1. + <_> + 16 3 1 4 3. + 0 + 1.1704630014719442e-004 + 1 + 3.1077799201011658e-001 + <_> + + + + <_> + 13 5 3 4 -1. + <_> + 14 5 1 4 3. + 0 + 5.5624791420996189e-003 + -8.1615281105041504e-001 + 5.3901451826095581e-001 + <_> + + <_> + + + + <_> + 14 9 6 5 -1. + <_> + 17 9 3 5 2. + 0 + 3.4512840211391449e-002 + 1 + 2.6539298892021179e-001 + <_> + + + + <_> + 8 5 4 3 -1. + <_> + 9 5 2 3 2. + 0 + 9.8612513393163681e-003 + -7.9879987239837646e-001 + 7.1010297536849976e-001 + <_> + + <_> + + + + <_> + 7 2 6 3 -1. + <_> + 9 2 2 3 3. + 0 + -1.7420940101146698e-002 + 7.8878182172775269e-001 + 1 + <_> + + + + <_> + 8 1 4 6 -1. + <_> + 9 1 2 6 2. + 0 + 9.4648143276572227e-003 + -8.6975818872451782e-001 + 6.4330947399139404e-001 + <_> + + <_> + + + + <_> + 4 3 16 9 -1. + <_> + 12 3 8 9 2. + 0 + 1.5069990418851376e-002 + 1 + 3.4470221400260925e-001 + <_> + + + + <_> + 6 3 4 8 -1. + <_> + 6 3 2 4 2. + <_> + 8 7 2 4 2. + 0 + 2.7276139706373215e-002 + -8.8079357147216797e-001 + 7.6766937971115112e-001 + <_> + + <_> + + + + <_> + 1 1 4 19 -1. + <_> + 3 1 2 19 2. + 0 + -1.2894829735159874e-002 + 3.7631559371948242e-001 + 1 + <_> + + + + <_> + 1 11 4 2 -1. + <_> + 2 11 2 2 2. + 0 + -5.7455319911241531e-003 + 8.3922427892684937e-001 + -9.8424279689788818e-001 + 1.5381850004196167e+000 + 0 + -1 + <_> + + + <_> + + <_> + + + + <_> + 0 0 11 15 -1. + <_> + 0 5 11 5 3. + 0 + -2.5208670645952225e-002 + 1 + -7.3783451318740845e-001 + <_> + + + + <_> + 0 1 1 18 -1. + <_> + 0 10 1 9 2. + 0 + -3.5002389922738075e-003 + 6.0456407070159912e-001 + -5.2267402410507202e-001 + <_> + + <_> + + + + <_> + 4 5 8 15 -1. + <_> + 8 5 4 15 2. + 0 + 3.2608121633529663e-002 + 1 + -8.9341151714324951e-001 + <_> + + + + <_> + 2 9 10 11 -1. + <_> + 7 9 5 11 2. + 0 + -5.2253220230340958e-002 + -9.2110282182693481e-001 + 5.5714380741119385e-001 + <_> + + <_> + + + + <_> + 7 17 3 2 -1. + <_> + 8 17 1 2 3. + 0 + 2.2503470536321402e-003 + 1 + -8.8232368230819702e-001 + <_> + + + + <_> + 4 16 10 3 -1. + <_> + 9 16 5 3 2. + 0 + 1.1138039641082287e-002 + 4.5365229249000549e-001 + -8.7354677915573120e-001 + <_> + + <_> + + + + <_> + 5 16 6 2 -1. + <_> + 8 16 3 2 2. + 0 + -5.7771787978708744e-003 + -8.0953860282897949e-001 + 1 + <_> + + + + <_> + 2 16 9 3 -1. + <_> + 5 17 3 1 9. + 0 + -1.3786350376904011e-002 + -6.6583162546157837e-001 + 4.9925059080123901e-001 + <_> + + <_> + + + + <_> + 19 0 1 4 -1. + <_> + 19 2 1 2 2. + 0 + 8.4821821656078100e-004 + 1 + -7.2904092073440552e-001 + <_> + + + + <_> + 6 4 8 13 -1. + <_> + 10 4 4 13 2. + 0 + -6.0129031538963318e-002 + -9.4193089008331299e-001 + 4.8614209890365601e-001 + <_> + + <_> + + + + <_> + 11 4 4 4 -1. + <_> + 12 4 2 4 2. + 0 + 6.3089472241699696e-003 + 1 + 5.6043982505798340e-001 + <_> + + + + <_> + 5 6 3 3 -1. + <_> + 6 6 1 3 3. + 0 + 4.8291720449924469e-003 + -6.1950987577438354e-001 + 3.2476270198822021e-001 + <_> + + <_> + + + + <_> + 9 2 7 9 -1. + <_> + 6 5 7 3 3. + 1 + -7.1375720202922821e-002 + -9.0404188632965088e-001 + 1 + <_> + + + + <_> + 3 19 6 1 -1. + <_> + 6 19 3 1 2. + 0 + 3.4400189761072397e-003 + 3.8457119464874268e-001 + -8.8946622610092163e-001 + <_> + + <_> + + + + <_> + 3 19 9 1 -1. + <_> + 6 19 3 1 3. + 0 + -4.9882400780916214e-003 + -8.6565148830413818e-001 + 1 + <_> + + + + <_> + 5 11 5 4 -1. + <_> + 5 11 5 2 2. + 1 + 1.0913630016148090e-002 + 4.5251420140266418e-001 + -6.9369602203369141e-001 + <_> + + <_> + + + + <_> + 7 5 3 2 -1. + <_> + 8 5 1 2 3. + 0 + 2.4461629800498486e-003 + 1 + 5.2243071794509888e-001 + <_> + + + + <_> + 14 0 1 12 -1. + <_> + 14 6 1 6 2. + 0 + -3.0945599079132080e-002 + 8.5188317298889160e-001 + -5.3872317075729370e-001 + <_> + + <_> + + + + <_> + 2 13 8 4 -1. + <_> + 6 13 4 4 2. + 0 + -1.4446619898080826e-002 + -8.6957198381423950e-001 + 1 + <_> + + + + <_> + 3 13 8 5 -1. + <_> + 7 13 4 5 2. + 0 + 1.5233219601213932e-002 + 4.5263200998306274e-001 + -8.1135600805282593e-001 + <_> + + <_> + + + + <_> + 4 19 12 1 -1. + <_> + 8 19 4 1 3. + 0 + -2.5891559198498726e-003 + -5.7905787229537964e-001 + 1 + <_> + + + + <_> + 7 19 2 1 -1. + <_> + 8 19 1 1 2. + 0 + 1.0837919544428587e-003 + 5.3870928287506104e-001 + -9.7009569406509399e-001 + <_> + + <_> + + + + <_> + 4 5 8 6 -1. + <_> + 8 5 4 6 2. + 0 + 1.7036350443959236e-002 + 1 + -8.4595912694931030e-001 + <_> + + + + <_> + 6 4 10 5 -1. + <_> + 11 4 5 5 2. + 0 + -2.2440670058131218e-002 + -9.3406337499618530e-001 + 4.2693048715591431e-001 + -1.3793849945068359e-001 + 1 + -1 + <_> + + + <_> + + <_> + + + + <_> + 4 4 12 16 -1. + <_> + 8 4 4 16 3. + 0 + -6.7628182470798492e-002 + -7.4111908674240112e-001 + 1 + <_> + + + + <_> + 7 17 3 3 -1. + <_> + 8 18 1 1 9. + 0 + -6.5513071604073048e-003 + -8.7756520509719849e-001 + 5.7063782215118408e-001 + <_> + + <_> + + + + <_> + 4 5 4 4 -1. + <_> + 5 5 2 4 2. + 0 + -1.0421309620141983e-002 + 7.8666269779205322e-001 + 1 + <_> + + + + <_> + 8 2 3 15 -1. + <_> + 9 7 1 5 9. + 0 + 3.5120330750942230e-002 + -5.1232081651687622e-001 + 5.7854127883911133e-001 + <_> + + <_> + + + + <_> + 3 19 6 1 -1. + <_> + 6 19 3 1 2. + 0 + 2.3085731081664562e-003 + 1 + -7.6840782165527344e-001 + <_> + + + + <_> + 10 5 6 6 -1. + <_> + 10 5 3 6 2. + 1 + -3.6485549062490463e-002 + -5.9415107965469360e-001 + 4.8120400309562683e-001 + <_> + + <_> + + + + <_> + 10 7 4 4 -1. + <_> + 11 7 2 4 2. + 0 + 3.8993770722299814e-003 + 1 + 4.4938841462135315e-001 + <_> + + + + <_> + 12 12 4 6 -1. + <_> + 14 12 2 6 2. + 0 + -1.7095550894737244e-002 + 5.8982378244400024e-001 + -6.3544249534606934e-001 + <_> + + <_> + + + + <_> + 8 16 2 2 -1. + <_> + 8 16 2 1 2. + 1 + -2.6509580202400684e-003 + -7.4674302339553833e-001 + 1 + <_> + + + + <_> + 16 0 4 1 -1. + <_> + 18 0 2 1 2. + 0 + -1.0701370192691684e-003 + -7.6775008440017700e-001 + 4.3917599320411682e-001 + <_> + + <_> + + + + <_> + 9 8 4 2 -1. + <_> + 10 8 2 2 2. + 0 + 4.8490660265088081e-003 + 1 + 6.1948227882385254e-001 + <_> + + + + <_> + 3 8 6 3 -1. + <_> + 5 8 2 3 3. + 0 + -2.1174849942326546e-002 + 6.9238477945327759e-001 + -5.7607620954513550e-001 + <_> + + <_> + + + + <_> + 12 2 6 18 -1. + <_> + 12 2 3 9 2. + <_> + 15 11 3 9 2. + 0 + -9.1728113591670990e-002 + 7.8373330831527710e-001 + 1 + <_> + + + + <_> + 8 4 12 14 -1. + <_> + 8 4 6 7 2. + <_> + 14 11 6 7 2. + 0 + 6.3391521573066711e-002 + -4.9195569753646851e-001 + 6.5842992067337036e-001 + <_> + + <_> + + + + <_> + 0 0 11 12 -1. + <_> + 0 4 11 4 3. + 0 + -2.4108730256557465e-002 + 1 + -6.2276291847229004e-001 + <_> + + + + <_> + 0 5 14 10 -1. + <_> + 0 10 14 5 2. + 0 + 5.2185848355293274e-002 + 5.4080730676651001e-001 + -6.3984328508377075e-001 + <_> + + <_> + + + + <_> + 8 5 3 2 -1. + <_> + 9 5 1 2 3. + 0 + 3.9632301777601242e-003 + 1 + 6.6911828517913818e-001 + <_> + + + + <_> + 7 4 3 3 -1. + <_> + 8 5 1 1 9. + 0 + 3.7253440823405981e-003 + -6.4084410667419434e-001 + 4.2938518524169922e-001 + <_> + + <_> + + + + <_> + 19 0 1 4 -1. + <_> + 19 1 1 2 2. + 0 + 4.5805040281265974e-004 + 1 + -7.0981818437576294e-001 + <_> + + + + <_> + 19 0 1 4 -1. + <_> + 19 1 1 2 2. + 0 + -4.3362649739719927e-004 + -4.2568281292915344e-001 + 6.4837968349456787e-001 + <_> + + <_> + + + + <_> + 3 5 2 7 -1. + <_> + 4 5 1 7 2. + 0 + -8.8344682008028030e-003 + 5.6010240316390991e-001 + 1 + <_> + + + + <_> + 7 0 6 7 -1. + <_> + 7 0 3 7 2. + 1 + 1.0024249553680420e-002 + 4.0823331475257874e-001 + -6.0941112041473389e-001 + <_> + + <_> + + + + <_> + 0 18 4 2 -1. + <_> + 2 18 2 2 2. + 0 + -2.7991709066554904e-004 + -4.4562909007072449e-001 + 1 + <_> + + + + <_> + 8 8 12 8 -1. + <_> + 12 8 4 8 3. + 0 + -4.0251381695270538e-002 + 6.8400329351425171e-001 + -5.5093038082122803e-001 + <_> + + <_> + + + + <_> + 0 14 1 3 -1. + <_> + 0 15 1 1 3. + 0 + 1.1060229735448956e-003 + 1 + -8.7556070089340210e-001 + <_> + + + + <_> + 5 18 6 1 -1. + <_> + 8 18 3 1 2. + 0 + -2.9391210991889238e-003 + -6.4071631431579590e-001 + 4.2237558960914612e-001 + <_> + + <_> + + + + <_> + 14 11 2 2 -1. + <_> + 14 11 1 2 2. + 1 + 5.3266989998519421e-003 + 1 + 6.7434668540954590e-001 + <_> + + + + <_> + 13 11 3 4 -1. + <_> + 14 11 1 4 3. + 0 + 1.9711100321728736e-004 + -7.0805662870407104e-001 + 2.7415850758552551e-001 + -1.4657120406627655e-001 + 2 + -1 + <_> + + + <_> + + <_> + + + + <_> + 10 4 7 10 -1. + <_> + 10 9 7 5 2. + 0 + 6.1874971725046635e-003 + 1 + 1.0000289678573608e+000 + <_> + + + + <_> + 8 5 12 12 -1. + <_> + 8 5 6 6 2. + <_> + 14 11 6 6 2. + 0 + -1.6684630513191223e-001 + 1. + -6.4018201828002930e-001 + <_> + + <_> + + + + <_> + 10 3 4 12 -1. + <_> + 10 9 4 6 2. + 0 + -4.3528191745281219e-003 + -4.7489950060844421e-001 + 1 + <_> + + + + <_> + 11 17 1 2 -1. + <_> + 11 17 1 1 2. + 1 + 2.4391049519181252e-003 + 9.2672532796859741e-001 + -9.3789821863174438e-001 + <_> + + <_> + + + + <_> + 3 5 2 3 -1. + <_> + 2 6 2 1 3. + 1 + -6.1387829482555389e-003 + -7.3620361089706421e-001 + 1 + <_> + + + + <_> + 14 3 2 3 -1. + <_> + 14 4 2 1 3. + 0 + 2.7482500299811363e-003 + 8.0812031030654907e-001 + -7.5801301002502441e-001 + <_> + + <_> + + + + <_> + 2 6 3 3 -1. + <_> + 2 7 3 1 3. + 0 + -6.8063312210142612e-004 + -4.8606950044631958e-001 + 1 + <_> + + + + <_> + 7 18 3 2 -1. + <_> + 8 18 1 2 3. + 0 + -3.4882400650531054e-003 + -9.6335417032241821e-001 + 9.3141609430313110e-001 + <_> + + <_> + + + + <_> + 6 9 3 1 -1. + <_> + 7 10 1 1 3. + 1 + 3.7412709207274020e-004 + 1 + 7.7949160337448120e-001 + <_> + + + + <_> + 1 12 6 2 -1. + <_> + 3 12 2 2 3. + 0 + -2.1708080021198839e-004 + -7.3272567987442017e-001 + 7.3104548454284668e-001 + -6.0141628980636597e-001 + 3 + -1 + diff --git a/tests/examples/opencv/gsthanddetect_test.c b/tests/examples/opencv/gsthanddetect_test.c new file mode 100644 index 0000000000..2a2187bb77 --- /dev/null +++ b/tests/examples/opencv/gsthanddetect_test.c @@ -0,0 +1,174 @@ +/* + *============================================================================ + *Name : gsthanddetect_app.c + *Author : Andol Li, andol@andol.info + *Version : 0.1 + *Copyright : @2012, gstreamer + *Description : gsteramer handdetect plugin demo application in C, part work of GSoc 2012 project + *============================================================================ + */ + +#include +#include +#include +#include +#include +#include + +#define PROFILE_FIST "/usr/local/share/opencv/haarcascades/fist.xml" +#define PROFILE_PALM "/usr/local/share/opencv/haarcascades/palm.xml" + +GstElement *playbin, + *pipeline, + *v4l2src, *videoscale, *ffmpegcolorspace_in, *handdetect, *ffmpegcolorspace_out, *xvimagesink; + +static GstBusSyncHandler +bus_sync_handler(GstBus *bus, GstMessage *message, GstPipeline *pipeline) +{ + /* select msg */ + if(GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT || + !gst_structure_has_name(message->structure, "hand-gesture") ) + return GST_BUS_PASS; + + /* parse msg structure */ + const GstStructure *structure = message->structure; + + /* if PALM gesture detected */ + if (structure && + strcmp (gst_structure_get_name (structure), "hand-gesture") == 0 && + strcmp (gst_structure_get_string (structure, "gesture"), "palm") == 0) { + /* media operation - closed palm to stop media play*/ + gst_element_set_state (playbin, GST_STATE_PAUSED); + } + + /* if FIST gesture detected */ + if (structure && + strcmp (gst_structure_get_name (structure), "hand-gesture") == 0 && + strcmp (gst_structure_get_string (structure, "gesture"), "fist") == 0){ + /* print message type and structure name */ + g_print("%s{{%s}}\n", gst_message_type_get_name(message->type), gst_structure_get_name(structure)); + /* print msg structure names&values */ + int i; + for(i = 0; i < gst_structure_n_fields(structure); i++){ + const gchar *name = gst_structure_nth_field_name(structure, i); + GType type = gst_structure_get_field_type(structure, name); + const GValue *value = gst_structure_get_value(structure, name); + type == G_TYPE_STRING ? + g_print("-%s[%s]{%s}\n", name, g_type_name(type), g_value_get_string(value)) : + g_print("-%s[%s]{%d}\n", name, g_type_name(type), g_value_get_uint(value)); + } + g_print("\n"); + + /* get X,Y positions in frame */ + const GValue *x_value = gst_structure_get_value(structure, "x"); + gint x = g_value_get_uint(x_value); + const GValue *y_value = gst_structure_get_value(structure, "y"); + gint y = g_value_get_uint(y_value); + + /* set object volumes [0-10] based on Y */ + g_object_set(G_OBJECT(playbin), "volume", (gdouble)(10 - y/24 ), NULL); + + /* seek playback positions */ + gint64 position, length; + GstFormat format = GST_FORMAT_TIME; + gst_element_query_duration(playbin, &format, &length); + /* Width = 320 is specified in caps */ + position = (gint64) length * x / 320; + gst_element_set_state(playbin, GST_STATE_PAUSED); + gst_element_seek(GST_ELEMENT(playbin), + 1.0, + format, + GST_SEEK_FLAG_FLUSH, + GST_SEEK_TYPE_SET, + position, + GST_SEEK_TYPE_NONE, + GST_CLOCK_TIME_NONE ); + gst_element_set_state(GST_ELEMENT(playbin), GST_STATE_PLAYING); + } + + gst_message_unref(message); + return GST_BUS_DROP; +} + +int main(gint argc, gchar **argv) { + static GMainLoop *loop; + loop = g_main_loop_new(NULL, FALSE); + /* video source */ + gchar *video_device = "/dev/video0"; + gchar *video_file = "file:///home/javauser/workspace/gitfiles/gsthanddetect_app/video.avi"; + /* bus */ + GstBus *bus; + /* caps */ + GstCaps *caps; + + /* init gst */ + gst_init(&argc, &argv); + + /* init elements */ + playbin = gst_element_factory_make("playbin2", "app_playbin"); + pipeline = gst_pipeline_new("app_pipeline"); + v4l2src = gst_element_factory_make("v4l2src", "app_v4l2src"); + videoscale = gst_element_factory_make("videoscale", "app_videoscale"); + ffmpegcolorspace_in = gst_element_factory_make("ffmpegcolorspace", "app_ffmpegcolorspace_in"); + handdetect = gst_element_factory_make("handdetect", "app_handdetect"); + ffmpegcolorspace_out = gst_element_factory_make("ffmpegcolorspace", "app_ffmpegcolorspace_out"); + xvimagesink = gst_element_factory_make("xvimagesink", "app_xvimagesink"); + + /* check init results */ + if(!playbin || !pipeline || !v4l2src || !videoscale || !ffmpegcolorspace_in + || !handdetect || !ffmpegcolorspace_out || !xvimagesink) + g_error("ERROR: element init failed.\n"); + + /* set values */ + g_object_set (G_OBJECT(playbin), "uri", video_file, NULL); + g_object_set (G_OBJECT(v4l2src), "device", video_device, NULL); + g_object_set (G_OBJECT (handdetect), "profile_fist", PROFILE_FIST, NULL); + g_object_set (G_OBJECT (handdetect), "profile_palm", PROFILE_PALM, NULL); + + /* set caps */ + caps = gst_caps_from_string("video/x-raw-rgb, width=320, height=240, framerate=(fraction)30/1"); + + /* set bus */ + bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); + gst_bus_set_sync_handler(bus, (GstBusSyncHandler) bus_sync_handler, pipeline); + gst_object_unref(bus); + + /* add elements to pipeline */ + gst_bin_add_many(GST_BIN(pipeline), + v4l2src, + videoscale, + ffmpegcolorspace_in, + handdetect, + ffmpegcolorspace_out, + xvimagesink, + NULL); + + /* negotiate caps */ + if(!gst_element_link_filtered( v4l2src, videoscale, caps)){ + g_printerr("ERROR:v4l2src -> videoscale caps\n"); + return 0; } + gst_caps_unref(caps); + + /* link elements */ + gst_element_link_many( + videoscale, + ffmpegcolorspace_in, + handdetect, + ffmpegcolorspace_out, + xvimagesink, + NULL); + + /* change states */ + gst_element_set_state(pipeline, GST_STATE_PLAYING); + + /* start main loop */ + g_main_loop_run(loop); + + /* clean all */ + gst_element_set_state(pipeline, GST_STATE_NULL); + gst_object_unref(GST_OBJECT(pipeline)); + gst_element_set_state(playbin, GST_STATE_NULL); + gst_object_unref(GST_OBJECT(playbin)); + + return 0; +} -- 2.34.1