Skip to content
Draft
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
62 changes: 31 additions & 31 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
def get_args():
"""
Parse command-line arguments for the hand gesture recognition application.

Returns:
argparse.Namespace: Parsed arguments containing:
- device: Camera device ID (default: 0)
Expand Down Expand Up @@ -74,10 +74,10 @@ def get_args():
return args


def main():
def main(): # noqa: C901
"""
Main function that runs the hand gesture recognition application.

This function:
1. Initializes the camera and MediaPipe hand detection
2. Loads the gesture classification models
Expand Down Expand Up @@ -207,7 +207,7 @@ def main():
keyboard.press('right')
elif hand_sign_id == 3:
keyboard.press('left')

# Update the previous_hand_sign_id for next iteration
elif hand_sign_id == 2:
keyboard.press('up')
Expand Down Expand Up @@ -258,11 +258,11 @@ def main():
def select_mode(key, mode):
"""
Select the application mode based on keyboard input.

Args:
key (int): The ASCII value of the pressed key
mode (int): Current mode (0=normal, 1=keypoint logging, 2=point history logging)

Returns:
tuple: (number, mode) where:
- number: Selected number (0-9) or -1 if no number key pressed
Expand All @@ -283,12 +283,12 @@ def select_mode(key, mode):
def calc_bounding_rect(image, landmarks):
"""
Calculate the bounding rectangle for detected hand landmarks.

Args:
image (numpy.ndarray): Input image
landmarks (mediapipe.framework.formats.landmark_pb2.NormalizedLandmarkList):
landmarks (mediapipe.framework.formats.landmark_pb2.NormalizedLandmarkList):
Hand landmarks from MediaPipe

Returns:
list: Bounding rectangle coordinates [x1, y1, x2, y2]
"""
Expand All @@ -312,12 +312,12 @@ def calc_bounding_rect(image, landmarks):
def calc_landmark_list(image, landmarks):
"""
Convert MediaPipe hand landmarks to a list of pixel coordinates.

Args:
image (numpy.ndarray): Input image
landmarks (mediapipe.framework.formats.landmark_pb2.NormalizedLandmarkList):
landmarks (mediapipe.framework.formats.landmark_pb2.NormalizedLandmarkList):
Hand landmarks from MediaPipe

Returns:
list: List of [x, y] coordinates for each landmark point
"""
Expand All @@ -339,13 +339,13 @@ def calc_landmark_list(image, landmarks):
def pre_process_landmark(landmark_list):
"""
Pre-process landmark coordinates for model input.

Converts absolute coordinates to relative coordinates, normalizes them,
and flattens the list for classifier input.

Args:
landmark_list (list): List of [x, y] landmark coordinates

Returns:
list: Normalized and flattened landmark coordinates
"""
Expand Down Expand Up @@ -374,13 +374,13 @@ def pre_process_landmark(landmark_list):
def pre_process_point_history(image, point_history):
"""
Pre-process point history for gesture classification.

Converts point history to relative coordinates normalized by image dimensions.

Args:
image (numpy.ndarray): Input image
point_history (collections.deque): History of finger tip positions

Returns:
list: Normalized and flattened point history coordinates
"""
Expand Down Expand Up @@ -409,7 +409,7 @@ def pre_process_point_history(image, point_history):
def logging_csv(number, mode, landmark_list, point_history_list):
"""
Log landmark or point history data to CSV files for training.

Args:
number (int): Label number (0-9)
mode (int): Logging mode (0=off, 1=keypoint, 2=point history)
Expand All @@ -431,14 +431,14 @@ def logging_csv(number, mode, landmark_list, point_history_list):
return


def draw_landmarks(image, landmark_point):
def draw_landmarks(image, landmark_point): # noqa: C901
"""
Draw hand landmarks and connections on the image.

Args:
image (numpy.ndarray): Image to draw on
landmark_point (list): List of [x, y] landmark coordinates

Returns:
numpy.ndarray: Image with landmarks drawn
"""
Expand Down Expand Up @@ -632,12 +632,12 @@ def draw_landmarks(image, landmark_point):
def draw_bounding_rect(use_brect, image, brect):
"""
Draw a bounding rectangle around the detected hand.

Args:
use_brect (bool): Whether to draw the bounding rectangle
image (numpy.ndarray): Image to draw on
brect (list): Bounding rectangle coordinates [x1, y1, x2, y2]

Returns:
numpy.ndarray: Image with bounding rectangle drawn
"""
Expand All @@ -653,15 +653,15 @@ def draw_info_text(image, brect, handedness, hand_sign_text,
finger_gesture_text):
"""
Draw information text showing detected hand and gesture on the image.

Args:
image (numpy.ndarray): Image to draw on
brect (list): Bounding rectangle coordinates
handedness (mediapipe.framework.formats.classification_pb2.ClassificationList):
handedness (mediapipe.framework.formats.classification_pb2.ClassificationList):
Hand classification (Left/Right)
hand_sign_text (str): Detected hand sign label
finger_gesture_text (str): Detected finger gesture label

Returns:
numpy.ndarray: Image with information text drawn
"""
Expand All @@ -687,11 +687,11 @@ def draw_info_text(image, brect, handedness, hand_sign_text,
def draw_point_history(image, point_history):
"""
Draw the point history trail on the image.

Args:
image (numpy.ndarray): Image to draw on
point_history (collections.deque): History of finger tip positions

Returns:
numpy.ndarray: Image with point history drawn
"""
Expand All @@ -706,13 +706,13 @@ def draw_point_history(image, point_history):
def draw_info(image, fps, mode, number):
"""
Draw FPS and mode information on the image.

Args:
image (numpy.ndarray): Image to draw on
fps (float): Current frames per second
mode (int): Current application mode
number (int): Selected label number

Returns:
numpy.ndarray: Image with information drawn
"""
Expand Down
10 changes: 5 additions & 5 deletions model/keypoint_classifier/keypoint_classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
class KeyPointClassifier(object):
"""
Classify hand gestures from preprocessed landmark keypoints.

This classifier uses a TensorFlow Lite model to identify hand gestures
based on normalized hand landmark positions.

Attributes:
interpreter (tf.lite.Interpreter): TensorFlow Lite interpreter for the model
input_details (list): Input tensor details
Expand All @@ -29,7 +29,7 @@ def __init__(
):
"""
Initialize the keypoint classifier.

Args:
model_path (str, optional): Path to the TensorFlow Lite model file.
Defaults to 'model/keypoint_classifier/keypoint_classifier.tflite'.
Expand All @@ -49,11 +49,11 @@ def __call__(
):
"""
Classify a hand gesture from landmark keypoints.

Args:
landmark_list (list): Preprocessed and normalized landmark coordinates
as a flat list of floats.

Returns:
int: The index of the predicted gesture class.
"""
Expand Down
10 changes: 5 additions & 5 deletions model/point_history_classifier/point_history_classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
class PointHistoryClassifier(object):
"""
Classify finger gestures from point history data.

This classifier uses a TensorFlow Lite model to identify finger movement
patterns based on a sequence of finger tip positions over time.

Attributes:
interpreter (tf.lite.Interpreter): TensorFlow Lite interpreter for the model
input_details (list): Input tensor details
Expand All @@ -33,7 +33,7 @@ def __init__(
):
"""
Initialize the point history classifier.

Args:
model_path (str, optional): Path to the TensorFlow Lite model file.
Defaults to 'model/point_history_classifier/point_history_classifier.tflite'.
Expand All @@ -60,11 +60,11 @@ def __call__(
):
"""
Classify a finger gesture from point history data.

Args:
point_history (list): Preprocessed and normalized point history coordinates
as a flat list of floats.

Returns:
int: The index of the predicted gesture class, or invalid_value if
confidence is below the threshold.
Expand Down
10 changes: 5 additions & 5 deletions utils/cvfpscalc.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
class CvFpsCalc(object):
"""
Calculate frames per second (FPS) using a moving average.

This class tracks frame times and calculates FPS based on a rolling
average of the most recent frame durations.

Attributes:
_start_tick (int): The starting tick count from OpenCV
_freq (float): Tick frequency conversion factor to milliseconds
Expand All @@ -23,7 +23,7 @@ class CvFpsCalc(object):
def __init__(self, buffer_len=1):
"""
Initialize the FPS calculator.

Args:
buffer_len (int, optional): Number of frames to average for FPS calculation.
Larger values provide smoother but less responsive FPS measurements.
Expand All @@ -36,9 +36,9 @@ def __init__(self, buffer_len=1):
def get(self):
"""
Calculate and return the current FPS.

This method should be called once per frame to update the FPS calculation.

Returns:
float: The calculated frames per second, rounded to 2 decimal places.
"""
Expand Down