-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path4_overlay_magic_circle.py
159 lines (122 loc) · 5.04 KB
/
4_overlay_magic_circle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import cv2
import mediapipe as mp
cap = cv2.VideoCapture(0)
mpHands = mp.solutions.hands
hands = mpHands.Hands()
mpDraw = mp.solutions.drawing_utils
orange = (0, 140, 255)
coorx = [0] * 21
coory = [0] * 21
wrist = thumb_tip = index_mcp = index_tip = midle_mcp = midle_tip = ring_tip = pinky_tip = (0,0)
shield = cv2.imread('magic_circle.png',-1)
def moveData():
global wrist
global thumb_tip
global index_mcp
global index_tip
global midle_mcp
global midle_tip
global ring_tip
global pinky_tip
wrist = coorx[0],coory[0]
thumb_tip = coorx[4],coory[4]
index_mcp = coorx[5],coory[5]
index_tip = coorx[8],coory[8]
midle_mcp = coorx[9],coory[9]
midle_tip = coorx[12],coory[12]
ring_tip = coorx[16],coory[16]
pinky_tip = coorx[20],coory[20]
def shiningLine(back_img, coor1, coor2, color, size):
#draw dot
cv2.circle(img, coor1, size+1, color, cv2.FILLED)
cv2.circle(img, coor2, size+1, color, cv2.FILLED)
#draw color line
cv2.line(back_img, coor1, coor2, color, size)
#draw white line
cv2.line(back_img, coor1, coor2, (255, 255, 255), round(size/2))
def drawLine():
#draw line
shiningLine(img, thumb_tip, index_tip, orange, 2)
shiningLine(img, thumb_tip, midle_tip, orange, 2)
shiningLine(img, thumb_tip, ring_tip, orange, 2)
shiningLine(img, thumb_tip, pinky_tip, orange, 2)
def drawPentagram():
#draw pentagram
shiningLine(img, index_tip, midle_tip, orange, 2)
shiningLine(img, index_tip, ring_tip, orange, 2)
shiningLine(img, index_tip, pinky_tip, orange, 2)
shiningLine(img, midle_tip, ring_tip, orange, 2)
shiningLine(img, midle_tip, pinky_tip, orange, 2)
shiningLine(img, ring_tip, pinky_tip, orange, 2)
def calculateDistance(coor1,coor2):
x1,y1,x2,y2 = coor1[0],coor1[1],coor2[0],coor2[1]
dist = ((x2 - x1)**2 + (y2 - y1)**2)**(1.0/2)
return dist
def overlay_transparent(background_img, img_to_overlay_t, x, y, overlay_size=None):
bg_img = background_img.copy()
if overlay_size is not None:
img_to_overlay_t = cv2.resize(img_to_overlay_t.copy(), overlay_size)
# Extract the alpha mask of the RGBA image, convert to RGB
b,g,r,a = cv2.split(img_to_overlay_t)
overlay_color = cv2.merge((b,g,r))
# Apply some simple filtering to remove edge noise
mask = cv2.medianBlur(a,5)
h, w, _ = overlay_color.shape
roi = bg_img[y:y+h, x:x+w]
# Black-out the area behind the logo in our original ROI
img1_bg = cv2.bitwise_and(roi.copy(),roi.copy(),mask = cv2.bitwise_not(mask))
# Mask out the logo from the logo image.
img2_fg = cv2.bitwise_and(overlay_color,overlay_color,mask = mask)
# Update the original image with our new ROI
bg_img[y:y+h, x:x+w] = cv2.add(img1_bg, img2_fg)
return bg_img
while True:
success, img = cap.read()
img = cv2.flip(img,1)
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
results = hands.process(imgRGB)
if results.multi_hand_landmarks:
for handLms in results.multi_hand_landmarks:
for id, lm in enumerate(handLms.landmark):
h, w, c = img.shape
# coorx, coory = int(lm.x * w), int(lm.y * h)
# cv2.circle(img, (coorx,coory), 6, (0,255,0), cv2.FILLED)
coorx[id], coory[id] = int(lm.x * w), int(lm.y * h)
moveData()
drawLine()
palm = calculateDistance(wrist, index_mcp)
distance = calculateDistance(index_tip, pinky_tip)
ratio = distance/palm
if(ratio > 1):
drawPentagram()
if(ratio > 1.5):
#find the center of the hand A.K.A the center of the shield
centerx = midle_mcp[0]
centery = midle_mcp[1]
#determine the diameter of the shield
shield_size = 3.0
diameter = round(palm*shield_size)
#calculate top left corner
x1 = round(centerx - (diameter/2))
y1 = round(centery - (diameter/2))
h, w, c = img.shape
#keep the shield inside the frame
if x1<0:
x1 = 0
elif x1>w:
x1 = w
if y1<0:
y1 = 0
elif y1>h:
y1 = h
if x1+diameter > w:
diameter = w-x1
if y1+diameter > h:
diameter = h-y1
shield_size = diameter,diameter
#if diameter is exist, add shield
if(diameter != 0):
img = overlay_transparent(img, shield, x1, y1, shield_size)
# mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)
cv2.imshow("Image", img)
cv2.waitKey(1)