-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
487 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import ctypes | ||
|
||
|
||
SendInput = ctypes.windll.user32.SendInput | ||
|
||
class Motion: | ||
none, left, right, up, down = range(5) | ||
|
||
# C struct redefinitions | ||
PUL = ctypes.POINTER(ctypes.c_ulong) | ||
class KeyBdInput(ctypes.Structure): | ||
_fields_ = [("wVk", ctypes.c_ushort), | ||
("wScan", ctypes.c_ushort), | ||
("dwFlags", ctypes.c_ulong), | ||
("time", ctypes.c_ulong), | ||
("dwExtraInfo", PUL)] | ||
|
||
class HardwareInput(ctypes.Structure): | ||
_fields_ = [("uMsg", ctypes.c_ulong), | ||
("wParamL", ctypes.c_short), | ||
("wParamH", ctypes.c_ushort)] | ||
|
||
class MouseInput(ctypes.Structure): | ||
_fields_ = [("dx", ctypes.c_long), | ||
("dy", ctypes.c_long), | ||
("mouseData", ctypes.c_ulong), | ||
("dwFlags", ctypes.c_ulong), | ||
("time",ctypes.c_ulong), | ||
("dwExtraInfo", PUL)] | ||
|
||
class Input_I(ctypes.Union): | ||
_fields_ = [("ki", KeyBdInput), | ||
("mi", MouseInput), | ||
("hi", HardwareInput)] | ||
|
||
class Input(ctypes.Structure): | ||
_fields_ = [("type", ctypes.c_ulong), | ||
("ii", Input_I)] | ||
|
||
# Actuals Functions | ||
|
||
def PressKey(hexKeyCode): | ||
|
||
extra = ctypes.c_ulong(0) | ||
ii_ = Input_I() | ||
ii_.ki = KeyBdInput( hexKeyCode, 0x48, 0, 0, ctypes.pointer(extra) ) | ||
x = Input( ctypes.c_ulong(1), ii_ ) | ||
SendInput(1, ctypes.pointer(x), ctypes.sizeof(x)) | ||
|
||
def ReleaseKey(hexKeyCode): | ||
|
||
extra = ctypes.c_ulong(0) | ||
ii_ = Input_I() | ||
ii_.ki = KeyBdInput( hexKeyCode, 0x48, 0x0002, 0, ctypes.pointer(extra) ) | ||
x = Input( ctypes.c_ulong(1), ii_ ) | ||
SendInput(1, ctypes.pointer(x), ctypes.sizeof(x)) | ||
|
||
|
||
def AltTab(): | ||
|
||
PressKey(0x012) #Alt | ||
PressKey(0x09) #Tab | ||
ReleaseKey(0x09) #~Tab | ||
ReleaseKey(0x012) #~Alt | ||
|
||
|
||
def CtrlTab(): | ||
|
||
PressKey(0xA2) #Ctrl | ||
PressKey(0x09) #Tab | ||
ReleaseKey(0x09) #~Tab | ||
ReleaseKey(0xA2) #~Ctrl | ||
|
||
def CtrlShiftTab(): | ||
|
||
PressKey(0xA2) #Ctrl | ||
PressKey(0xA1) #Shift | ||
PressKey(0x09) #Tab | ||
ReleaseKey(0x09) #~Tab | ||
ReleaseKey(0xA2) #~Ctrl | ||
ReleaseKey(0xA1) #~Shift | ||
|
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
#!/usr/bin/env python | ||
|
||
''' | ||
This module contains some common routines used by other samples. | ||
''' | ||
|
||
import numpy as np | ||
import cv2 | ||
|
||
# built-in modules | ||
import os | ||
import itertools as it | ||
from contextlib import contextmanager | ||
|
||
image_extensions = ['.bmp', '.jpg', '.jpeg', '.png', '.tif', '.tiff', '.pbm', '.pgm', '.ppm'] | ||
|
||
class Bunch(object): | ||
def __init__(self, **kw): | ||
self.__dict__.update(kw) | ||
def __str__(self): | ||
return str(self.__dict__) | ||
|
||
def splitfn(fn): | ||
path, fn = os.path.split(fn) | ||
name, ext = os.path.splitext(fn) | ||
return path, name, ext | ||
|
||
def anorm2(a): | ||
return (a*a).sum(-1) | ||
def anorm(a): | ||
return np.sqrt( anorm2(a) ) | ||
|
||
def homotrans(H, x, y): | ||
xs = H[0, 0]*x + H[0, 1]*y + H[0, 2] | ||
ys = H[1, 0]*x + H[1, 1]*y + H[1, 2] | ||
s = H[2, 0]*x + H[2, 1]*y + H[2, 2] | ||
return xs/s, ys/s | ||
|
||
def to_rect(a): | ||
a = np.ravel(a) | ||
if len(a) == 2: | ||
a = (0, 0, a[0], a[1]) | ||
return np.array(a, np.float64).reshape(2, 2) | ||
|
||
def rect2rect_mtx(src, dst): | ||
src, dst = to_rect(src), to_rect(dst) | ||
cx, cy = (dst[1] - dst[0]) / (src[1] - src[0]) | ||
tx, ty = dst[0] - src[0] * (cx, cy) | ||
M = np.float64([[ cx, 0, tx], | ||
[ 0, cy, ty], | ||
[ 0, 0, 1]]) | ||
return M | ||
|
||
|
||
def lookat(eye, target, up = (0, 0, 1)): | ||
fwd = np.asarray(target, np.float64) - eye | ||
fwd /= anorm(fwd) | ||
right = np.cross(fwd, up) | ||
right /= anorm(right) | ||
down = np.cross(fwd, right) | ||
R = np.float64([right, down, fwd]) | ||
tvec = -np.dot(R, eye) | ||
return R, tvec | ||
|
||
def mtx2rvec(R): | ||
w, u, vt = cv2.SVDecomp(R - np.eye(3)) | ||
p = vt[0] + u[:,0]*w[0] # same as np.dot(R, vt[0]) | ||
c = np.dot(vt[0], p) | ||
s = np.dot(vt[1], p) | ||
axis = np.cross(vt[0], vt[1]) | ||
return axis * np.arctan2(s, c) | ||
|
||
def draw_str(dst, (x, y), s): | ||
cv2.putText(dst, s, (x+1, y+1), cv2.FONT_HERSHEY_PLAIN, 1.0, (0, 0, 0), thickness = 2, lineType=cv2.LINE_AA) | ||
cv2.putText(dst, s, (x, y), cv2.FONT_HERSHEY_PLAIN, 1.0, (255, 255, 255), lineType=cv2.LINE_AA) | ||
|
||
class Sketcher: | ||
def __init__(self, windowname, dests, colors_func): | ||
self.prev_pt = None | ||
self.windowname = windowname | ||
self.dests = dests | ||
self.colors_func = colors_func | ||
self.dirty = False | ||
self.show() | ||
cv2.setMouseCallback(self.windowname, self.on_mouse) | ||
|
||
def show(self): | ||
cv2.imshow(self.windowname, self.dests[0]) | ||
|
||
def on_mouse(self, event, x, y, flags, param): | ||
pt = (x, y) | ||
if event == cv2.EVENT_LBUTTONDOWN: | ||
self.prev_pt = pt | ||
elif event == cv2.EVENT_LBUTTONUP: | ||
self.prev_pt = None | ||
|
||
if self.prev_pt and flags & cv2.EVENT_FLAG_LBUTTON: | ||
for dst, color in zip(self.dests, self.colors_func()): | ||
cv2.line(dst, self.prev_pt, pt, color, 5) | ||
self.dirty = True | ||
self.prev_pt = pt | ||
self.show() | ||
|
||
|
||
# palette data from matplotlib/_cm.py | ||
_jet_data = {'red': ((0., 0, 0), (0.35, 0, 0), (0.66, 1, 1), (0.89,1, 1), | ||
(1, 0.5, 0.5)), | ||
'green': ((0., 0, 0), (0.125,0, 0), (0.375,1, 1), (0.64,1, 1), | ||
(0.91,0,0), (1, 0, 0)), | ||
'blue': ((0., 0.5, 0.5), (0.11, 1, 1), (0.34, 1, 1), (0.65,0, 0), | ||
(1, 0, 0))} | ||
|
||
cmap_data = { 'jet' : _jet_data } | ||
|
||
def make_cmap(name, n=256): | ||
data = cmap_data[name] | ||
xs = np.linspace(0.0, 1.0, n) | ||
channels = [] | ||
eps = 1e-6 | ||
for ch_name in ['blue', 'green', 'red']: | ||
ch_data = data[ch_name] | ||
xp, yp = [], [] | ||
for x, y1, y2 in ch_data: | ||
xp += [x, x+eps] | ||
yp += [y1, y2] | ||
ch = np.interp(xs, xp, yp) | ||
channels.append(ch) | ||
return np.uint8(np.array(channels).T*255) | ||
|
||
def nothing(*arg, **kw): | ||
pass | ||
|
||
def clock(): | ||
return cv2.getTickCount() / cv2.getTickFrequency() | ||
|
||
@contextmanager | ||
def Timer(msg): | ||
print msg, '...', | ||
start = clock() | ||
try: | ||
yield | ||
finally: | ||
print "%.2f ms" % ((clock()-start)*1000) | ||
|
||
class StatValue: | ||
def __init__(self, smooth_coef = 0.5): | ||
self.value = None | ||
self.smooth_coef = smooth_coef | ||
def update(self, v): | ||
if self.value is None: | ||
self.value = v | ||
else: | ||
c = self.smooth_coef | ||
self.value = c * self.value + (1.0-c) * v | ||
|
||
class RectSelector: | ||
def __init__(self, win, callback): | ||
self.win = win | ||
self.callback = callback | ||
cv2.setMouseCallback(win, self.onmouse) | ||
self.drag_start = None | ||
self.drag_rect = None | ||
def onmouse(self, event, x, y, flags, param): | ||
x, y = np.int16([x, y]) # BUG | ||
if event == cv2.EVENT_LBUTTONDOWN: | ||
self.drag_start = (x, y) | ||
if self.drag_start: | ||
if flags & cv2.EVENT_FLAG_LBUTTON: | ||
xo, yo = self.drag_start | ||
x0, y0 = np.minimum([xo, yo], [x, y]) | ||
x1, y1 = np.maximum([xo, yo], [x, y]) | ||
self.drag_rect = None | ||
if x1-x0 > 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) |
Binary file not shown.
Oops, something went wrong.