brogelio commited on
Commit
46007cf
1 Parent(s): 41255dc

Update Application File

Browse files
.idea/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
.idea/air_draw.iml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$" />
5
+ <orderEntry type="jdk" jdkName="Python 3.9 (rtgesrec) (2)" jdkType="Python SDK" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ </component>
8
+ </module>
.idea/inspectionProfiles/Project_Default.xml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
5
+ <option name="ignoredErrors">
6
+ <list>
7
+ <option value="N813" />
8
+ </list>
9
+ </option>
10
+ </inspection_tool>
11
+ </profile>
12
+ </component>
.idea/inspectionProfiles/profiles_settings.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <settings>
3
+ <option name="USE_PROJECT_PROFILE" value="false" />
4
+ <version value="1.0" />
5
+ </settings>
6
+ </component>
.idea/misc.xml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (rtgesrec) (2)" project-jdk-type="Python SDK" />
4
+ </project>
.idea/modules.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/air_draw.iml" filepath="$PROJECT_DIR$/.idea/air_draw.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
app.py CHANGED
@@ -1,7 +1,180 @@
 
 
 
 
 
1
  import gradio as gr
2
 
3
- def greet(name):
4
- return "Hello " + name + "!!"
5
 
6
- iface = gr.Interface(fn=greet, inputs="text", outputs="text")
7
- iface.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ from PIL import Image
4
+ import mediapipe as mp
5
+ import time
6
  import gradio as gr
7
 
8
+ DOMINANT_HAND = "Right"
 
9
 
10
+ # width, height = 1280, 720
11
+ width_, height_, = 256, 144
12
+
13
+ drawing_flag = False
14
+ sleepy_time = time.time()
15
+
16
+ output_frames = []
17
+
18
+
19
+ def find_hands(brain, img):
20
+ img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # opencv image is in BGR form but mp is trained with RGB
21
+ results = brain.process(
22
+ img_rgb) # process finds the hands and outputs classification and 21 landmarks for each hand
23
+ all_hands = [] # initializing array to hold the dictionary for the hands
24
+ h, w, _ = img.shape # get height and width of image for scaling
25
+ if results.multi_hand_landmarks:
26
+ for hand_type, hand_lms in zip(results.multi_handedness,
27
+ results.multi_hand_landmarks): # elegant solution for mp list object traversal
28
+ hand = {} # initializing dict for each hand
29
+ lm_list = [] # landmarks array for all 21 point of the hand
30
+ for lm in hand_lms.landmark:
31
+ px, py, pz = int(lm.x * w), int(lm.y * h), int(
32
+ lm.z * w) # scaling landmark points to image size for frame coordinates
33
+ lm_list.append([px, py, pz])
34
+
35
+ hand["lm_list"] = lm_list # add "lm_list" key for all landmark points of the hand
36
+ hand["type"] = hand_type.classification[0].label # adds the label (left/right) for the hand
37
+ all_hands.append(hand) # appends the dict
38
+ return all_hands
39
+
40
+
41
+ def is_drawing(index, thumb): # proximity function with arbitrary threshold
42
+ npindex = np.array((index[0], index[1]))
43
+ npthumb = np.array((thumb[0], thumb[1]))
44
+ if np.linalg.norm(npindex - npthumb) < 30:
45
+ return True
46
+ else:
47
+ return False
48
+
49
+
50
+ def save(landmarks): # brute force finger orientation checking
51
+ if landmarks[8][1] < landmarks[6][1]:
52
+ if landmarks[12][1] < landmarks[10][1]:
53
+ if landmarks[16][1] < landmarks[14][1]:
54
+ if landmarks[20][1] < landmarks[18][1]:
55
+ return True
56
+ else:
57
+ return False
58
+
59
+
60
+ def clear(landmarks): # brute force finger orientation checking
61
+ if landmarks[4][1] < landmarks[3][1] < landmarks[2][1] < landmarks[8][1]:
62
+ return True
63
+ else:
64
+ return False
65
+
66
+
67
+ def show(video): # main
68
+ cam = cv2.VideoCapture(video) # get the video file from path
69
+ width = cam.get(cv2.CAP_PROP_FRAME_WIDTH)
70
+ height = cam.get(cv2.CAP_PROP_FRAME_HEIGHT)
71
+
72
+ detector = mp.solutions.hands.Hands(min_detection_confidence=0.8) # initialize detector
73
+ # paper = np.zeros((width, height, 4), np.uint8)
74
+ paper = np.zeros((int(height), int(width), 3), dtype=np.uint8) # create blank page
75
+ paper.fill(255)
76
+
77
+ past_holder = () # hold previous index coordinates
78
+ palette = cv2.imread('palette.jpg')
79
+
80
+ page_num = 0 # iterating for saving (not a viable function for gradio)
81
+
82
+ color = (0, 0, 0)
83
+
84
+ global sleepy_time # get sleep time for multiple gestures
85
+
86
+ # runny = 1
87
+ while cam.isOpened():
88
+ # runny -= 1
89
+ x, rgb_image = cam.read()
90
+ rgb_image_f = cv2.flip(np.asanyarray(rgb_image), 1) # mirrored video
91
+
92
+ hands = find_hands(detector, rgb_image_f)
93
+
94
+ if x: # return flag for cv2
95
+ try: # for error handling
96
+ if hands:
97
+ hand1 = hands[0] if hands[0]["type"] == DOMINANT_HAND else hands[1]
98
+ lm_list1 = hand1["lm_list"] # List of 21 Landmarks
99
+ handedness = hand1["type"]
100
+
101
+ if handedness == DOMINANT_HAND:
102
+ idx_coords = lm_list1[8][0], lm_list1[8][1] # 0 is width (bigger)
103
+ # print(idx_coords)
104
+ cv2.circle(rgb_image_f, idx_coords, 5, color, cv2.FILLED)
105
+
106
+ if idx_coords[1] < 72: # brute force but should be extremely marginally faster lol
107
+ if idx_coords[0] < 142: # red
108
+ color = (0, 0, 255)
109
+ if 142 < idx_coords[0] < 285: # orange
110
+ color = (0, 115, 255)
111
+ if 285 < idx_coords[0] < 426: # yellow
112
+ color = (0, 229, 255)
113
+ if 426 < idx_coords[0] < 569: # green
114
+ color = (0, 195, 88)
115
+ if 569 < idx_coords[0] < 711: # blue
116
+ color = (195, 85, 0)
117
+ if 711 < idx_coords[0] < 853: # indigo
118
+ color = (195, 0, 68)
119
+ if 853 < idx_coords[0] < 996: # violet
120
+ color = (195, 0, 143)
121
+ if 996 < idx_coords[0] < 1137: # black
122
+ color = (0, 0, 0)
123
+ if 1137 < idx_coords[0]: # white / eraser
124
+ color = (255, 255, 255)
125
+
126
+ if len(past_holder) and drawing_flag: # start drawing
127
+ cv2.line(paper, past_holder, idx_coords, color, 5)
128
+ cv2.line(rgb_image_f, past_holder, idx_coords, color, 5)
129
+ # paper[idx_coords[0]][idx_coords[1]][0] = 255
130
+ # paper[idx_coords[0]][idx_coords[1]][3] = 255
131
+ cv2.circle(rgb_image_f, idx_coords, 5, color, cv2.FILLED)
132
+
133
+ if save(lm_list1) and time.time() - sleepy_time > 3: # save / output
134
+ paper[0:height_, w - width_: w] = 255
135
+ paper = cv2.cvtColor(paper, cv2.COLOR_BGR2RGB)
136
+ im = Image.fromarray(paper)
137
+ im.save("paper%s.png" % page_num)
138
+ print("saved")
139
+ sleepy_time = time.time()
140
+ paper = cv2.cvtColor(paper, cv2.COLOR_RGB2BGR)
141
+ page_num += 1
142
+ return paper
143
+
144
+ if clear(lm_list1) and time.time() - sleepy_time > 3: # reset paper
145
+ paper = np.zeros((height, width, 3), dtype=np.uint8)
146
+ paper.fill(255)
147
+ print("page cleared")
148
+ sleepy_time = time.time()
149
+
150
+ past_holder = idx_coords
151
+
152
+ if is_drawing(idx_coords, lm_list1[4]): # 4 is thumb
153
+ drawing_flag = True
154
+ else:
155
+ drawing_flag = False
156
+
157
+ except:
158
+ pass
159
+
160
+ finally:
161
+ rgb_image_f[0:72, ] = palette
162
+ presenter = cv2.resize(rgb_image_f, (width_, height_))
163
+ h, w, _ = rgb_image_f.shape
164
+ paper[0:height_, w - width_: w] = presenter
165
+
166
+ # output_frames.append(paper)
167
+
168
+ # cv2.imshow("Image", rgb_image_f)
169
+ # cv2.imshow("paper", paper)
170
+ # key = cv2.waitKey(1)
171
+ # if key & 0xFF == ord('q') or key == 27: # Press esc or 'q' to close the image window
172
+ # break
173
+
174
+ else:
175
+ break
176
+
177
+
178
+ iface = gr.Interface(fn=show, inputs=gr.inputs.Video(source="webcam", type="mp4"), outputs='image')
179
+
180
+ iface.launch(share=True)