|
| 1 | +import cv2 |
| 2 | +import numpy as np |
| 3 | +import mediapipe as mp |
| 4 | +from collections import deque |
| 5 | + |
| 6 | +bpoints = [deque(maxlen=1024)] |
| 7 | +gpoints = [deque(maxlen=1024)] |
| 8 | +rpoints = [deque(maxlen=1024)] |
| 9 | +ypoints = [deque(maxlen=1024)] |
| 10 | + |
| 11 | +blue_index = 0 |
| 12 | +green_index = 0 |
| 13 | +red_index = 0 |
| 14 | +yellow_index = 0 |
| 15 | + |
| 16 | +colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (0, 255, 255)] |
| 17 | +colorIndex = 0 |
| 18 | + |
| 19 | +paintWindow = np.zeros((471,636,3)) + 255 |
| 20 | +paintWindow = cv2.rectangle(paintWindow, (40,1), (140,65), (0,0,0), 2) |
| 21 | +paintWindow = cv2.rectangle(paintWindow, (160,1), (255,65), (255,0,0), 2) |
| 22 | +paintWindow = cv2.rectangle(paintWindow, (275,1), (370,65), (0,255,0), 2) |
| 23 | +paintWindow = cv2.rectangle(paintWindow, (390,1), (485,65), (0,0,255), 2) |
| 24 | +paintWindow = cv2.rectangle(paintWindow, (505,1), (600,65), (0,255,255), 2) |
| 25 | + |
| 26 | +paintWindow = cv2.rectangle(paintWindow, (40, 1), (140, 65), (255, 255, 255), -1) # Clear (white) |
| 27 | +paintWindow = cv2.rectangle(paintWindow, (160, 1), (255, 65), (255, 0, 0), -1) # Blue |
| 28 | +paintWindow = cv2.rectangle(paintWindow, (275, 1), (370, 65), (0, 255, 0), -1) # Green |
| 29 | +paintWindow = cv2.rectangle(paintWindow, (390, 1), (485, 65), (0, 0, 255), -1) # Red |
| 30 | +paintWindow = cv2.rectangle(paintWindow, (505, 1), (600, 65), (0, 255, 255), -1) # Yellow |
| 31 | + |
| 32 | +cv2.putText(paintWindow, "CLEAR", (49, 33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 2, cv2.LINE_AA) |
| 33 | +cv2.putText(paintWindow, "BLUE", (185, 33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA) |
| 34 | +cv2.putText(paintWindow, "GREEN", (298, 33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA) |
| 35 | +cv2.putText(paintWindow, "RED", (420, 33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA) |
| 36 | +cv2.putText(paintWindow, "YELLOW", (520, 33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (150, 150, 150), 2, cv2.LINE_AA) |
| 37 | +cv2.namedWindow('Paint', cv2.WINDOW_AUTOSIZE) |
| 38 | + |
| 39 | +# Initialize Mediapipe for hand detection |
| 40 | +mpHands = mp.solutions.hands |
| 41 | +hands = mpHands.Hands(max_num_hands=1, min_detection_confidence=0.7) |
| 42 | +mpDraw = mp.solutions.drawing_utils |
| 43 | + |
| 44 | +cap = cv2.VideoCapture(0) |
| 45 | +ret = True |
| 46 | + |
| 47 | +while ret: |
| 48 | + |
| 49 | + ret, frame = cap.read() |
| 50 | + |
| 51 | + # Flip the frame vertically |
| 52 | + frame = cv2.flip(frame, 1) |
| 53 | + |
| 54 | + framergb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) |
| 55 | + cv2.putText(paintWindow, "CLEAR", (49,33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 2, cv2.LINE_AA) |
| 56 | + cv2.putText(paintWindow, "BLUE", (185,33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 2, cv2.LINE_AA) |
| 57 | + cv2.putText(paintWindow, "GREEN", (298,33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 2, cv2.LINE_AA) |
| 58 | + cv2.putText(paintWindow, "RED", (420,33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 2, cv2.LINE_AA) |
| 59 | + cv2.putText(paintWindow, "YELLOW", (520,33), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (150,150,150), 2, cv2.LINE_AA) |
| 60 | + |
| 61 | + # Get hand landmark prediction |
| 62 | + result = hands.process(framergb) |
| 63 | + |
| 64 | + # Post-process the result |
| 65 | + if result.multi_hand_landmarks: |
| 66 | + landmarks = [] |
| 67 | + for handslms in result.multi_hand_landmarks: |
| 68 | + for lm in handslms.landmark: |
| 69 | + lmx = int(lm.x * 640) |
| 70 | + lmy = int(lm.y * 480) |
| 71 | + landmarks.append([lmx, lmy]) |
| 72 | + |
| 73 | + # Drawing landmarks on frames |
| 74 | + mpDraw.draw_landmarks(frame, handslms, mpHands.HAND_CONNECTIONS) |
| 75 | + |
| 76 | + # Extracting hand landmarks for finger and thumb |
| 77 | + fore_finger = (landmarks[8][0],landmarks[8][1]) |
| 78 | + center = fore_finger |
| 79 | + thumb = (landmarks[4][0],landmarks[4][1]) |
| 80 | + |
| 81 | + # Detecting thumb movement to switch colors |
| 82 | + if (thumb[1]-center[1]<30): |
| 83 | + bpoints.append(deque(maxlen=512)) |
| 84 | + blue_index += 1 |
| 85 | + gpoints.append(deque(maxlen=512)) |
| 86 | + green_index += 1 |
| 87 | + rpoints.append(deque(maxlen=512)) |
| 88 | + red_index += 1 |
| 89 | + ypoints.append(deque(maxlen=512)) |
| 90 | + yellow_index += 1 |
| 91 | + |
| 92 | + elif center[1] <= 65: |
| 93 | + if 40 <= center[0] <= 140: # Clear Button |
| 94 | + bpoints = [deque(maxlen=512)] |
| 95 | + gpoints = [deque(maxlen=512)] |
| 96 | + rpoints = [deque(maxlen=512)] |
| 97 | + ypoints = [deque(maxlen=512)] |
| 98 | + |
| 99 | + blue_index = 0 |
| 100 | + green_index = 0 |
| 101 | + red_index = 0 |
| 102 | + yellow_index = 0 |
| 103 | + |
| 104 | + paintWindow[67:,:,:] = 255 |
| 105 | + elif 160 <= center[0] <= 255: |
| 106 | + colorIndex = 0 # Blue |
| 107 | + elif 275 <= center[0] <= 370: |
| 108 | + colorIndex = 1 # Green |
| 109 | + elif 390 <= center[0] <= 485: |
| 110 | + colorIndex = 2 # Red |
| 111 | + elif 505 <= center[0] <= 600: |
| 112 | + colorIndex = 3 # Yellow |
| 113 | + else : |
| 114 | + if colorIndex == 0: |
| 115 | + bpoints[blue_index].appendleft(center) |
| 116 | + elif colorIndex == 1: |
| 117 | + gpoints[green_index].appendleft(center) |
| 118 | + elif colorIndex == 2: |
| 119 | + rpoints[red_index].appendleft(center) |
| 120 | + elif colorIndex == 3: |
| 121 | + ypoints[yellow_index].appendleft(center) |
| 122 | + |
| 123 | + |
| 124 | + else: |
| 125 | + bpoints.append(deque(maxlen=512)) |
| 126 | + blue_index += 1 |
| 127 | + gpoints.append(deque(maxlen=512)) |
| 128 | + green_index += 1 |
| 129 | + rpoints.append(deque(maxlen=512)) |
| 130 | + red_index += 1 |
| 131 | + ypoints.append(deque(maxlen=512)) |
| 132 | + yellow_index += 1 |
| 133 | + |
| 134 | + points = [bpoints, gpoints, rpoints, ypoints] |
| 135 | + |
| 136 | + for i in range(len(points)): |
| 137 | + for j in range(len(points[i])): |
| 138 | + for k in range(1, len(points[i][j])): |
| 139 | + if points[i][j][k - 1] is None or points[i][j][k] is None: |
| 140 | + continue |
| 141 | + cv2.line(frame, points[i][j][k - 1], points[i][j][k], colors[i], 2) |
| 142 | + cv2.line(paintWindow, points[i][j][k - 1], points[i][j][k], colors[i], 2) |
| 143 | + |
| 144 | + cv2.imshow("Output", frame) |
| 145 | + cv2.imshow("Paint", paintWindow) |
| 146 | + |
| 147 | + if cv2.waitKey(1) == ord('q'): |
| 148 | + break |
| 149 | + |
| 150 | +cap.release() |
| 151 | +cv2.destroyAllWindows() |
| 152 | + |
0 commit comments