From f65949c7e7ef9ff547e428434457cc24f0aa7c02 Mon Sep 17 00:00:00 2001 From: Bryan Cantos Date: Mon, 26 Sep 2016 17:36:17 -0400 Subject: [PATCH] Add files via upload --- Detection.py | 34 +++++++ Detection.pyc | Bin 0 -> 1303 bytes KeyboardInput.py | 82 +++++++++++++++++ KeyboardInput.pyc | Bin 0 -> 3612 bytes README.txt | 9 ++ circle.png | Bin 0 -> 52958 bytes common.py | 220 ++++++++++++++++++++++++++++++++++++++++++++++ common.pyc | Bin 0 -> 11352 bytes handtracing.py | 142 ++++++++++++++++++++++++++++++ 9 files changed, 487 insertions(+) create mode 100644 Detection.py create mode 100644 Detection.pyc create mode 100644 KeyboardInput.py create mode 100644 KeyboardInput.pyc create mode 100644 README.txt create mode 100644 circle.png create mode 100644 common.py create mode 100644 common.pyc create mode 100644 handtracing.py diff --git a/Detection.py b/Detection.py new file mode 100644 index 0000000..365f9bf --- /dev/null +++ b/Detection.py @@ -0,0 +1,34 @@ +import cv2 +import numpy as np +from common import anorm2, draw_str + +def skin_detect( cap ): + circle = cv2.imread("circle.png") + circle = cv2.resize( circle, (30, 30)) + while(True): + # Capture frame-by-frame + ret, frame = cap.read() + frame = cv2.flip(frame, 1) + + x_offset=y_offset=50 + height, width, channels = frame.shape + y_offset = height / 2 + x_offset = width / 2 + + frame[y_offset:y_offset+circle.shape[0], x_offset:x_offset+circle.shape[1]] = circle + + draw_str(frame, (20, 20), "Place palm over red circle and press 'a' key") + cv2.imshow( 'frame', frame) + + if cv2.waitKey(1) & 0xFF == ord('a'): + ret, frame = cap.read() + frame = cv2.flip( frame, 1) + hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) + cv2.destroyAllWindows() + skin_base = hsv[ x_offset + 10, y_offset + 10] + return skin_base + + if cv2.waitKey(1) & 0xFF == ord('q'): + cap.release() + cv2.destroyAllWindows() + return \ No newline at end of file diff --git a/Detection.pyc b/Detection.pyc new file mode 100644 index 0000000000000000000000000000000000000000..509183bf2e0f9250d050eb8462ff11b8a070b988 GIT binary patch literal 1303 zcmb_b&2G~`5T3Q2KR2Z%qLdzh94e6m>LE9vLWNWU3Di~zv{Ga#GTu$Ht^c~aNg9-# z0un;vDR@L4pvO($7$Ed>O<5{ogu+ zzGHC*Viyt*`W_@D=$C+T7e1kDnPPe^598%EK1VIeY044+|f96!AAZMiuP4Ku3t@ib=?^NQaZ}UGBmeeOsG2mLu(>jHHTU zv6rVK`2bBx!;@_iG-HVigx1YR;iKk- zn41y?3{{v2d5xN(#Gxcgt6thWRB#e;VG@(2Yi*FDiz1q~?M;)35+S!L(#Vg((0zQT zCWT@*2^q#Rx7>Oh=AuiqH}QI$&2X#$vrw8hSRtj)6t}lGnwm})XUeQ2*g1ZC+#S4p z)os7-otoQ-aDg{Fo4<(TGnw*irfni6Vi9W5qT5~+8|Id*I1~#hVY>Erp?~CRkPU}g z7)v?-Wzdf_7IHK;w(yzcW?U3C4%1Y`+9n$7si~o-zL4qQ1JR-ZR_G_Fb)E+AwNN@Z zo~1$shgmd9L~3+!qOuXrA(81Qm`a_i>^wLWMnpzt>0UlJRKCs1ElPvadnkZyum-C+ z4c2gc)O_YUZD*5hIuFrmuq{OHF%K==VJ$k^E(O~z(n*4;sq^&aOtK`&(k=pEr_#NT d+Mgc&MMn%-STqNNv(}=J?EY=X~EcXPo@si}PRnK6=!q$&<(TZ4~<#jK*I; zJ)#DYAvz4`Fh_@ZYUD}hNUxL5({Ds$qF)*X8Br8lqH#ctInutdOr3yqF&kPTU6OIW zV=n8MCtaTDsAL@rr01ohDoZV79gC!^Gcy*mjwRAdTxl$mUKVGC^olsEq*ujRBfTaL z0tu*IyMmCTfAH+O65O4{MM<0?Q$*7p6nhN@Xfy&c00H3#)GRV4z@P!A#G$KtEx@>l zXVuCuj!ml-hkes(xp}Gd6Fuy4l}Dvv+%>KMFHU0b^i0S3zNmZPTn>H1feg{fD6XMO zQ)9nHb@Qv{zBQ?BJ{ZL&ZQf1V!@h}~ZSJK>Hx2v!DDF0YjqD&z4x2xlg{+i zbTeRJxp-Xoq^+S?mXgOs#I}J4&T|3r!h3<(AWjb&GL%OQ$5asG zEy&T*NB-;BF>QU`%H7a~s*0Lo#?%tbv#|4uYq78dM#ZsR5_B6_`Yja8+nP$M8VGkH zrq=d(Io-hMS@b67G{a56=|V-tOhtT_o{dDuHB(|DPOIz6j+SoY_#PS;+^Pn*_=6`J94OAz?=6;>%8k;!Rvqd{?pbbrj2o zpDAr~F5?P|e-p(%g>iBNBfH|lISp8|W1`a>XU!8NNlCounCSP{d=jg z7BBq>t4orm+%n{KJ$U<-Nx*NTmy%F8M?&G{Bowj7SrS;kFJ?l$k0DbE)CXMs5JoUp zjHbH5hQn7Ma|eny7XUC{ddl=nXbm9d3+*h#{5F0#6w&!7aG*dh@_;=kHJ||W&v>G3 zugp9q>_(h#Bi3GxS5mx+`jo3EGv)$f;{5l0&piwue+|!;`31T8fIn^a`FY)F{=^z@ zCK|~vF6|*4f&azf+{V71Ne*a|d?7SVJx|k=x|viWA^!2k;^ez>6LHoLq7HNS6Y6q- z{>L5j=f!dbUGjrSQq(Alb+0Ebeh#Ex-tuP%V|<$1d$7Ix@Sd99`aaFMbl7&o)cE^R zmgGxP(%OEE|0?`-a+TkeiB;X?>St^|hq-v|GP~dS|2e+nbZXy$spgk+>xH#oV{W6k NQAR0M%9RSr+`pUTud)CD literal 0 HcmV?d00001 diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..388ac55 --- /dev/null +++ b/README.txt @@ -0,0 +1,9 @@ +This is the final Project that both Andrew Chandradata and I worked on. + +We created a program that uses the web camera available to detect hand gestures and use them as inputs for the computer + +Moving the and left is Control + Shift + Tab +Moving the hand right is Control + Tab +Moving the hand up is Alt + Tab + +To run this program, first you need to download the latest version of Python 2 as well as Open CV and then you can either use the the Python IDLE, go to handtracing.py and click run module or you can use your terminal and type "Python handtracing.py" \ No newline at end of file diff --git a/circle.png b/circle.png new file mode 100644 index 0000000000000000000000000000000000000000..bfb971fd97d807025f632f7da4c7cf501c53b13b GIT binary patch literal 52958 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
    J~9y3@?6u2lRC~+si6A3~o{2M`%*Tl4^rF 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�QRb%3qXf> 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 z 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 0 and y1-y0 > 0: + self.drag_rect = (x0, y0, x1, y1) + else: + rect = self.drag_rect + self.drag_start = None + self.drag_rect = None + if rect: + self.callback(rect) + def draw(self, vis): + if not self.drag_rect: + return False + x0, y0, x1, y1 = self.drag_rect + cv2.rectangle(vis, (x0, y0), (x1, y1), (0, 255, 0), 2) + return True + @property + def dragging(self): + return self.drag_rect is not None + + +def grouper(n, iterable, fillvalue=None): + '''grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx''' + args = [iter(iterable)] * n + return it.izip_longest(fillvalue=fillvalue, *args) + +def mosaic(w, imgs): + '''Make a grid from images. + + w -- number of grid columns + imgs -- images (must have same size and format) + ''' + imgs = iter(imgs) + img0 = imgs.next() + pad = np.zeros_like(img0) + imgs = it.chain([img0], imgs) + rows = grouper(w, imgs, pad) + return np.vstack(map(np.hstack, rows)) + +def getsize(img): + h, w = img.shape[:2] + return w, h + +def mdot(*args): + return reduce(np.dot, args) + +def draw_keypoints(vis, keypoints, color = (0, 255, 255)): + for kp in keypoints: + x, y = kp.pt + cv2.circle(vis, (int(x), int(y)), 2, color) diff --git a/common.pyc b/common.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26a8c5ec89ed7b0a2e44c067d5a4106936f3cfda GIT binary patch literal 11352 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 K(qw6 0: + + img0, img1 = old_final, final + + #p0 is position of points in old image + p0 = np.float32([tr[-1] for tr in tracks]).reshape(-1, 1, 2) + #p1 is position of points in new image + p1, st, err = cv2.calcOpticalFlowPyrLK(img0, img1, p0, None, **lk_params) + p0r, st, err = cv2.calcOpticalFlowPyrLK(img1, img0, p1, None, **lk_params) + d = abs(p0-p0r).reshape(-1, 2).max(-1) + + good = d < 1 + + #finds new points + new_tracks = [] + for tr, (x, y), good_flag in zip(tracks, p1.reshape(-1, 2), good): + if not good_flag: + continue + tr.append((x, y)) + if len(tr) > track_len: + del tr[0] + new_tracks.append(tr) + cv2.circle(vis, (x, y), 2, (255, 0, 255), -1) + + tracks = new_tracks + cv2.polylines(vis, [np.int32(tr) for tr in tracks], False, (255, 0, 0)) + + #draw_str(vis, (20, 20), 'track count: %d' % len(tracks)) + draw_str(vis, (20, 20), "If you don't see blue lines tracking your fingers, skin calibration failed." ) + + if frame_idx % detect_interval == 0: + mask = np.zeros_like(final) + mask[:] = 255 + for x, y in [np.int32(tr[-1]) for tr in tracks]: + cv2.circle(mask, (x, y), 5, (125, 125, 125), -1) + p = cv2.goodFeaturesToTrack(final, mask = mask, **feature_params) + if p is not None: + for x, y in np.float32(p).reshape(-1, 2): + tracks.append([(x, y)]) + + + frame_idx += 1 + old_final = final + + + for tr in tracks: + if tr[0][0] - tr[len(tr) - 1][0] > motion_length: #LEFT + if motion_cooldown < 0: + kb.CtrlShiftTab() + motion_cooldown = cd_duration + break + + elif tr[0][0] - tr[len(tr) - 1][0] < -motion_length: #RIGHT + if motion_cooldown < 0: + kb.CtrlTab() + motion_cooldown = cd_duration + break + elif tr[0][1] - tr[len(tr) - 1][1] > motion_length: #UP + if motion_cooldown < 0: + kb.AltTab() + motion_cooldown = cd_duration + break + else: + motion_cooldown -= 1 + + cv2.imshow('lk_track', vis) + + if cv2.waitKey(1) & 0xFF == ord('q'): + break + + + # When everything done, release the capture + cap.release() + cv2.destroyAllWindows()