Skip to content
Merged
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
55 changes: 55 additions & 0 deletions Air_Canvas/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Hand Gesture Controlled Paint Application 🎨

![Python](https://img.shields.io/badge/Python-3776AB?style=for-the-badge&logo=python&logoColor=white)
![OpenCV](https://img.shields.io/badge/OpenCV-27338e?style=for-the-badge&logo=OpenCV&logoColor=white)
![Mediapipe](https://img.shields.io/badge/Mediapipe-00c853?style=for-the-badge&logo=Mediapipe&logoColor=white)

A hand gesture controlled paint application using Python, OpenCV, and Mediapipe. This project allows users to draw on a virtual canvas using hand gestures, making use of hand landmarks for color selection and drawing.

## Features ✨
- Draw with different colors using hand gestures.
- Clear the canvas with a hand gesture.
- Switch colors by moving the thumb close to the index finger.

## Demo 🖼️
![Demo Image](result.png)

## Installation 🛠️
1. Clone the repository:
```bash
git clone https://github.com/harshaparida/Hand_cv_sketch.git
cd Hand_cv_sketch
```

2. Create and activate a virtual environment (optional but recommended):
```bash
python -m venv venv
source venv/bin/activate # On Windows use `venv\Scripts\activate`
```

3. Install the required dependencies:
```bash
pip install -r requirements.txt
```

## Usage 🚀
1. Run the application:
```bash
python main.py
```

2. Use your index finger to draw on the screen.
3. Use the buttons on the top of the canvas to change colors or clear the screen.

## Libraries Used 📚
- [OpenCV](https://opencv.org/) - Open Source Computer Vision Library
- [Mediapipe](https://mediapipe.dev/) - Cross-platform ML solutions for live and streaming media
- [NumPy](https://numpy.org/) - The fundamental package for scientific computing with Python

## Acknowledgments 🙏
- Thanks to the developers of [OpenCV](https://opencv.org/) and [Mediapipe](https://mediapipe.dev/) for providing the tools necessary to build this project.


---

Made with ❤️ by [Harsha](https://github.com/harshaparida)
152 changes: 152 additions & 0 deletions Air_Canvas/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import cv2
import numpy as np
import mediapipe as mp
from collections import deque

bpoints = [deque(maxlen=1024)]
gpoints = [deque(maxlen=1024)]
rpoints = [deque(maxlen=1024)]
ypoints = [deque(maxlen=1024)]

blue_index = 0
green_index = 0
red_index = 0
yellow_index = 0

colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (0, 255, 255)]
colorIndex = 0

paintWindow = np.zeros((471,636,3)) + 255
paintWindow = cv2.rectangle(paintWindow, (40,1), (140,65), (0,0,0), 2)
paintWindow = cv2.rectangle(paintWindow, (160,1), (255,65), (255,0,0), 2)
paintWindow = cv2.rectangle(paintWindow, (275,1), (370,65), (0,255,0), 2)
paintWindow = cv2.rectangle(paintWindow, (390,1), (485,65), (0,0,255), 2)
paintWindow = cv2.rectangle(paintWindow, (505,1), (600,65), (0,255,255), 2)

paintWindow = cv2.rectangle(paintWindow, (40, 1), (140, 65), (255, 255, 255), -1) # Clear (white)
paintWindow = cv2.rectangle(paintWindow, (160, 1), (255, 65), (255, 0, 0), -1) # Blue
paintWindow = cv2.rectangle(paintWindow, (275, 1), (370, 65), (0, 255, 0), -1) # Green
paintWindow = cv2.rectangle(paintWindow, (390, 1), (485, 65), (0, 0, 255), -1) # Red
paintWindow = cv2.rectangle(paintWindow, (505, 1), (600, 65), (0, 255, 255), -1) # Yellow

cv2.putText(paintWindow, "CLEAR", (49, 33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 2, cv2.LINE_AA)
cv2.putText(paintWindow, "BLUE", (185, 33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)
cv2.putText(paintWindow, "GREEN", (298, 33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)
cv2.putText(paintWindow, "RED", (420, 33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)
cv2.putText(paintWindow, "YELLOW", (520, 33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (150, 150, 150), 2, cv2.LINE_AA)
cv2.namedWindow('Paint', cv2.WINDOW_AUTOSIZE)

# Initialize Mediapipe for hand detection
mpHands = mp.solutions.hands
hands = mpHands.Hands(max_num_hands=1, min_detection_confidence=0.7)
mpDraw = mp.solutions.drawing_utils

cap = cv2.VideoCapture(0)
ret = True

while ret:

ret, frame = cap.read()

# Flip the frame vertically
frame = cv2.flip(frame, 1)

framergb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
cv2.putText(paintWindow, "CLEAR", (49,33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 2, cv2.LINE_AA)
cv2.putText(paintWindow, "BLUE", (185,33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 2, cv2.LINE_AA)
cv2.putText(paintWindow, "GREEN", (298,33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 2, cv2.LINE_AA)
cv2.putText(paintWindow, "RED", (420,33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 2, cv2.LINE_AA)
cv2.putText(paintWindow, "YELLOW", (520,33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (150,150,150), 2, cv2.LINE_AA)

# Get hand landmark prediction
result = hands.process(framergb)

# Post-process the result
if result.multi_hand_landmarks:
landmarks = []
for handslms in result.multi_hand_landmarks:
for lm in handslms.landmark:
lmx = int(lm.x * 640)
lmy = int(lm.y * 480)
landmarks.append([lmx, lmy])

# Drawing landmarks on frames
mpDraw.draw_landmarks(frame, handslms, mpHands.HAND_CONNECTIONS)

# Extracting hand landmarks for finger and thumb
fore_finger = (landmarks[8][0],landmarks[8][1])
center = fore_finger
thumb = (landmarks[4][0],landmarks[4][1])

# Detecting thumb movement to switch colors
if (thumb[1]-center[1]<30):
bpoints.append(deque(maxlen=512))
blue_index += 1
gpoints.append(deque(maxlen=512))
green_index += 1
rpoints.append(deque(maxlen=512))
red_index += 1
ypoints.append(deque(maxlen=512))
yellow_index += 1

elif center[1] <= 65:
if 40 <= center[0] <= 140: # Clear Button
bpoints = [deque(maxlen=512)]
gpoints = [deque(maxlen=512)]
rpoints = [deque(maxlen=512)]
ypoints = [deque(maxlen=512)]

blue_index = 0
green_index = 0
red_index = 0
yellow_index = 0

paintWindow[67:,:,:] = 255
elif 160 <= center[0] <= 255:
colorIndex = 0 # Blue
elif 275 <= center[0] <= 370:
colorIndex = 1 # Green
elif 390 <= center[0] <= 485:
colorIndex = 2 # Red
elif 505 <= center[0] <= 600:
colorIndex = 3 # Yellow
else :
if colorIndex == 0:
bpoints[blue_index].appendleft(center)
elif colorIndex == 1:
gpoints[green_index].appendleft(center)
elif colorIndex == 2:
rpoints[red_index].appendleft(center)
elif colorIndex == 3:
ypoints[yellow_index].appendleft(center)


else:
bpoints.append(deque(maxlen=512))
blue_index += 1
gpoints.append(deque(maxlen=512))
green_index += 1
rpoints.append(deque(maxlen=512))
red_index += 1
ypoints.append(deque(maxlen=512))
yellow_index += 1

points = [bpoints, gpoints, rpoints, ypoints]

for i in range(len(points)):
for j in range(len(points[i])):
for k in range(1, len(points[i][j])):
if points[i][j][k - 1] is None or points[i][j][k] is None:
continue
cv2.line(frame, points[i][j][k - 1], points[i][j][k], colors[i], 2)
cv2.line(paintWindow, points[i][j][k - 1], points[i][j][k], colors[i], 2)

cv2.imshow("Output", frame)
cv2.imshow("Paint", paintWindow)

if cv2.waitKey(1) == ord('q'):
break

cap.release()
cv2.destroyAllWindows()

8 changes: 8 additions & 0 deletions Air_Canvas/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Run this command to install
# pip install -r requirements.txt


opencv-python
mediapipe
numpy

Binary file added Air_Canvas/result.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.