Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
jackersson committed Nov 19, 2017
1 parent df60873 commit 3e2133a
Show file tree
Hide file tree
Showing 9 changed files with 781 additions and 0 deletions.
106 changes: 106 additions & 0 deletions .gitignore
@@ -0,0 +1,106 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
.vscode/
summary/

# videos
*.mov

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# dotenv
.env

# virtualenv
.venv
venv/
ENV/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
50 changes: 50 additions & 0 deletions draw_utils.py
@@ -0,0 +1,50 @@
import cv2
import numpy as np

#draws contours in image
def draw_contours(image, box):
cv2.drawContours(image,[box],0,(100,0,255),2)

#plot hull points in contour
def plot_hulls(image, hulls, color=(255, 0,0)):
for hpt in hulls:
pt = hpt[0]
cv2.circle(frame, (pt[0], pt[1]), 5, color, -1)

#plot centroid point of contour
def plot_center(frame, center, color=(0, 255, 0)):
cv2.circle(frame, center, 5, color, -1)

#plot start, middle, end point of defect and connect it with lines
def plot_defects(frame, defects, contour, color=(0, 255, 0)):
if defects is not None and len(defects) > 0:
for i in range(len(defects)):
s,e,f,d = defects[i,0]
start = tuple(contour[s][0])
end = tuple(contour[e][0])
far = tuple(contour[f][0])
cv2.line(frame, start, far,(255,255,255),1)
cv2.line(frame, far, end,(255,255,255),1)

cv2.circle(frame, start, 2, color, -1)
cv2.circle(frame, end, 2, color, -1)
cv2.circle(frame, far, 2, (255, 0, 255), -1)

#plot fingers like plot defects
def plot_fingers(frame, fingers, contour, color=(0, 255, 0)):
if fingers is not None and len(fingers) > 0:
for i in range(len(fingers)):
s,e,f = fingers[i]

far = tuple(contour[f][0])
if (s != -1 ):
start = tuple(contour[s][0])
cv2.line(frame, start, far,(255,255,0),1)
cv2.circle(frame, start, 2, (0, 0, 255), -1)

if (e != -1 ):
end = tuple(contour[e][0])
cv2.line(frame, far, end,(255,255,0),1)
cv2.circle(frame, end, 2, (255,0,0), -1)

cv2.circle(frame, far, 2, (0, 255, 0), -1)
62 changes: 62 additions & 0 deletions hand_detector.py
@@ -0,0 +1,62 @@
import cv2
import numpy as np

from utils import *
from hand_utils import *
from imageproc import *
from draw_utils import *

class HandDetector:

def __init__(self):
self.reset()

def reset(self):
self.polygon = None #approx. polygon that fits entire contour
self.hand_contour = None #full contour points
self.hulls = None #peak points of contour
self.defect = None
self.fingers = None
self.far_finger = None #the far finger point
self.fingers_count = None
self.center = None


def detect(self, colored_mask):
self.reset()

gray = grayscale(colored_mask)
ret, thresholded = cv2.threshold(gray, 0, 255, 0)


max_contour = get_max_countour(thresholded)

self.hand_contour = max_contour
if self.hand_contour is None:
return None

bounding_rect = get_bound_box(max_contour)
self.hulls = hull(max_contour) # returns index in contour and point itself
hulls_no_pts = hull(max_contour, False) #returns only index in contour

self.polygon = get_polygon(self.hulls, 10)
self.center = centroid(max_contour)
self.defect = defects(max_contour, hulls_no_pts)

#try to find possible finger points
fingers = eliminate_defects(bounding_rect, self.defect, max_contour)

#check if finger only one
check_one_finger(fingers, max_contour, bounding_rect, hulls_no_pts, self.center )

#remove redundant fingers
if fingers is not None and len(fingers) > 0:
self.fingers, self.far_finger, self.fingers_count = get_target_fingers(fingers,max_contour, bounding_rect )

def plot(self, frame):
if self.hand_contour is not None:
#draw_contours(frame, self.hand_contour)
#plot_hulls(frame, self.hulls)
#plot_center(frame, self.center)
plot_fingers(frame, self.fingers, self.hand_contour, (0,0,255))
#plot_defects(frame, self.defect, self.hand_contour, (0, 255, 0))
79 changes: 79 additions & 0 deletions hand_extraction.py
@@ -0,0 +1,79 @@
import cv2
import numpy as np
import math

from utils import *

class HandExtraction:
def __init__(self):
self.trained_hand = False
self.hand_row_nw = None
self.hand_row_se = None
self.hand_col_nw = None
self.hand_col_se = None
self.hand_hist = None

def draw_hand_rect(self, frame):
rows,cols = frame.shape[:2]
dels = 20
#change distance between rects
self.hand_row_nw = np.array([6*rows/dels,6*rows/dels,6*rows/dels,
9*rows/dels,9*rows/dels,9*rows/dels,
12*rows/dels,12*rows/dels,12*rows/dels], dtype=np.int16)

self.hand_col_nw = np.array([9*cols/dels,10*cols/dels,11*cols/dels,
9*cols/dels,10*cols/dels,11*cols/dels,
9*cols/dels,10*cols/dels,11*cols/dels], dtype=np.int16)

self.hand_row_se = self.hand_row_nw + 50 #change height of rects
self.hand_col_se = self.hand_col_nw + 30 #change width of rects

size = self.hand_row_nw.size
for i in range(size):
cv2.rectangle(frame,(self.hand_col_nw[i],self.hand_row_nw[i]),(self.hand_col_se[i],self.hand_row_se[i]),(0,255,0),1)

black = np.zeros(frame.shape, dtype=frame.dtype)
frame_final = np.vstack([black, frame])
return frame_final

def train_hand(self, frame):
self.trained_hand = True
return self.set_hand_hist(frame)

#calculate color range for hand extraction based on colors from rects
def set_hand_hist(self, frame):
hsv = ycbcr(frame)
roi = np.zeros([90,10,3], dtype=hsv.dtype)

size = self.hand_row_nw.size
for i in range(size):
roi[i*10:i*10+10,0:10] = hsv[self.hand_row_nw[i]:self.hand_row_nw[i]+10, self.hand_col_nw[i]:self.hand_col_nw[i]+10]


temp_lo = []
temp_hi = []
for i in range(0, 3):
croped = roi[:, :, i].copy()
blured = gaussian_blur(croped, 9).flatten()
temp_lo.append(min(blured))
temp_hi.append(max(blured))


'''
temp_lo = []
temp_hi = []
for i in range(0, 2):
croped = roi[:, :, i].copy()
blured = gaussian_blur(croped, 9).flatten()
mul_min, mul_max = 1.0, 1.0
#if (i == 1):
#mul_min, mul_max = 0.95, 1.03
temp_lo.append(int (min(blured) * mul_min))
temp_hi.append(int (max(blured) * mul_max))
#temp_lo.append(0)
#temp_hi.append(255)
'''
return np.array(temp_lo), np.array(temp_hi)

0 comments on commit 3e2133a

Please sign in to comment.