|
|
import cv2 |
|
|
import mediapipe as mp |
|
|
import numpy as np |
|
|
import streamlit as st |
|
|
from PIL import Image |
|
|
|
|
|
st.title("Custom_Hand_Gesture_Recognition") |
|
|
|
|
|
uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "png", "jpeg"]) |
|
|
|
|
|
if uploaded_file is not None: |
|
|
|
|
|
img = Image.open(uploaded_file) |
|
|
|
|
|
|
|
|
img = np.array(img) |
|
|
|
|
|
|
|
|
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) |
|
|
|
|
|
img = cv2.resize(img,(256,256)) |
|
|
|
|
|
|
|
|
st.image(img, channels="BGR") |
|
|
mp_hands = mp.solutions.hands |
|
|
|
|
|
|
|
|
hands = mp_hands.Hands(static_image_mode=True, max_num_hands=2, min_detection_confidence=0.1) |
|
|
|
|
|
|
|
|
mp_drawing = mp.solutions.drawing_utils |
|
|
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) |
|
|
results = hands.process(img) |
|
|
def calculate_angle(a,b,c): |
|
|
a = np.array(a) |
|
|
b = np.array(b) |
|
|
c = np.array(c) |
|
|
|
|
|
radians = np.arctan2(c[1]-b[1], c[0]-b[0]) - np.arctan2(a[1]-b[1], a[0]-b[0]) |
|
|
angle = np.abs(radians*180.0/np.pi) |
|
|
|
|
|
if angle >180.0: |
|
|
angle = 360-angle |
|
|
return angle |
|
|
def distance(a, b, width, height): |
|
|
distance = np.sqrt(((b[0] - a[0]) * width) ** 2 + ((b[1] - a[1]) * height) ** 2) |
|
|
return distance |
|
|
if results.multi_hand_landmarks: |
|
|
|
|
|
for i in results.multi_hand_landmarks: |
|
|
mp_drawing.draw_landmarks(img, i, mp_hands.HAND_CONNECTIONS, |
|
|
mp_drawing.DrawingSpec(color=(245,117,66), thickness=2, circle_radius=2), |
|
|
mp_drawing.DrawingSpec(color=(245,66,230), thickness=2, circle_radius=2)) |
|
|
st.image(img) |
|
|
|
|
|
for hand_no, hand_landmarks in enumerate(results.multi_hand_landmarks): |
|
|
|
|
|
first = [hand_landmarks.landmark[mp_hands.HandLandmark(6).value].x,hand_landmarks.landmark[mp_hands.HandLandmark(6).value].y] |
|
|
mid = [(hand_landmarks.landmark[mp_hands.HandLandmark(5).value].x + hand_landmarks.landmark[mp_hands.HandLandmark(9).value].x)/2,(hand_landmarks.landmark[mp_hands.HandLandmark(5).value].y + hand_landmarks.landmark[mp_hands.HandLandmark(9).value].y)/2] |
|
|
last = [hand_landmarks.landmark[mp_hands.HandLandmark(10).value].x,hand_landmarks.landmark[mp_hands.HandLandmark(10).value].y] |
|
|
|
|
|
|
|
|
|
|
|
ring_top = [hand_landmarks.landmark[mp_hands.HandLandmark(16).value].x,hand_landmarks.landmark[mp_hands.HandLandmark(16).value].y] |
|
|
pinky_top = [hand_landmarks.landmark[mp_hands.HandLandmark(20).value].x,hand_landmarks.landmark[mp_hands.HandLandmark(20).value].y] |
|
|
thumb_top = [hand_landmarks.landmark[mp_hands.HandLandmark(4).value].x,hand_landmarks.landmark[mp_hands.HandLandmark(4).value].y] |
|
|
height,width,_ = img.shape |
|
|
thumb_ring_dist = distance(ring_top,thumb_top,width,height) |
|
|
thumb_pinky_dist = distance(pinky_top,thumb_top,width,height) |
|
|
st.write('Distance between thumb and ring finger is',thumb_ring_dist) |
|
|
st.write('Distance between thumb and pinky finger is',thumb_pinky_dist) |
|
|
if thumb_pinky_dist <= 25 and thumb_ring_dist <= 25: |
|
|
angle = calculate_angle(first,mid,last) |
|
|
st.write('angle is ',angle) |
|
|
if angle >= 50: |
|
|
st.write('The fingers are opened') |
|
|
elif angle < 50: |
|
|
st.write('The fingers are closed') |
|
|
else: |
|
|
st.write('error') |