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
1 parent
df60873
commit 3e2133a
Showing
9 changed files
with
781 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,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/ |
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,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) |
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,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)) |
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,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) | ||
|
Oops, something went wrong.