Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Hand Gesture Detection Python Script #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,7 @@ Description
- tictactoe <br />
A cli-based tictactoe game to play with the computer. <br/>
[Rounak Vyas](http://www.github.com/itsron717)

- handgestures <br />
Simple Hand Gesture Detection System to identify numbers with OpenCV. <br/>
[Akash Ramjyothi](https://github.com/Akash-Ramjyothi)
10 changes: 10 additions & 0 deletions scripts/handgestures/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Hand Gesture Detection

Simple Hand Gesture Detection System to identify numbers with OpenCV.

## Sample Demo:

![ezgif com-gif-maker (2)](https://user-images.githubusercontent.com/54114888/94371093-7ee5e700-0111-11eb-9c11-642847acebf6.gif)

## Usage
`python main.py`
112 changes: 112 additions & 0 deletions scripts/handgestures/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Imports
import numpy as np
import cv2
import math

# Open Camera
capture = cv2.VideoCapture(0)

while capture.isOpened():

# Capture frames from the camera
ret, frame = capture.read()

# Get hand data from the rectangle sub window
cv2.rectangle(frame, (100, 100), (300, 300), (0, 255, 0), 0)
crop_image = frame[100:300, 100:300]

# Apply Gaussian blur
blur = cv2.GaussianBlur(crop_image, (3, 3), 0)

# Change color-space from BGR -> HSV
hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)

# Create a binary image with where white will be skin colors and rest is black
mask2 = cv2.inRange(hsv, np.array([2, 0, 0]), np.array([20, 255, 255]))

# Kernel for morphological transformation
kernel = np.ones((5, 5))

# Apply morphological transformations to filter out the background noise
dilation = cv2.dilate(mask2, kernel, iterations=1)
erosion = cv2.erode(dilation, kernel, iterations=1)

# Apply Gaussian Blur and Threshold
filtered = cv2.GaussianBlur(erosion, (3, 3), 0)
ret, thresh = cv2.threshold(filtered, 127, 255, 0)

# Show threshold image
cv2.imshow("Thresholded", thresh)

# Find contours
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

try:
# Find contour with maximum area
contour = max(contours, key=lambda x: cv2.contourArea(x))

# Create bounding rectangle around the contour
x, y, w, h = cv2.boundingRect(contour)
cv2.rectangle(crop_image, (x, y), (x + w, y + h), (0, 0, 255), 0)

# Find convex hull
hull = cv2.convexHull(contour)

# Draw contour
drawing = np.zeros(crop_image.shape, np.uint8)
cv2.drawContours(drawing, [contour], -1, (0, 255, 0), 0)
cv2.drawContours(drawing, [hull], -1, (0, 0, 255), 0)

# Find convexity defects
hull = cv2.convexHull(contour, returnPoints=False)
defects = cv2.convexityDefects(contour, hull)

# Use cosine rule to find angle of the far point from the start and end point i.e. the convex points (the finger
# tips) for all defects
count_defects = 0

for i in range(defects.shape[0]):
s, e, f, d = defects[i, 0]
start = tuple(contour[s][0])
end = tuple(contour[e][0])
far = tuple(contour[f][0])

a = math.sqrt((end[0] - start[0]) * 2 + (end[1] - start[1]) * 2)
b = math.sqrt((far[0] - start[0]) * 2 + (far[1] - start[1]) * 2)
c = math.sqrt((end[0] - far[0]) * 2 + (end[1] - far[1]) * 2)
angle = (math.acos((b * 2 + c * 2 - a ** 2) / (2 * b * c)) * 180) / 3.14

# if angle > 90 draw a circle at the far point
if angle <= 90:
count_defects += 1
cv2.circle(crop_image, far, 1, [0, 0, 255], -1)

cv2.line(crop_image, start, end, [0, 255, 0], 2)

# Print number of fingers
if count_defects == 0:
cv2.putText(frame, "ONE", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 2,(0,0,255),2)
elif count_defects == 1:
cv2.putText(frame, "TWO", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 2,(0,0,255), 2)
elif count_defects == 2:
cv2.putText(frame, "THREE", (5, 50), cv2.FONT_HERSHEY_SIMPLEX, 2,(0,0,255), 2)
elif count_defects == 3:
cv2.putText(frame, "FOUR", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 2,(0,0,255), 2)
elif count_defects == 4:
cv2.putText(frame, "FIVE", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 2,(0,0,255), 2)
else:
pass
except:
pass

# Show required images
cv2.imshow("Gesture", frame)
all_image = np.hstack((drawing, crop_image))
cv2.imshow('Contours', all_image)

# Close the camera if 'q' is pressed
if cv2.waitKey(1) == ord('q'):
break

capture.release()
cv2.destroyAllWindows()