-
Notifications
You must be signed in to change notification settings - Fork 0
/
fake.py
92 lines (83 loc) · 2.83 KB
/
fake.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
import os
import cv2
import numpy as np
import requests
import pyfakewebcam
def get_mask(frame, bodypix_url='http://localhost:9000'):
_, data = cv2.imencode(".jpg", frame)
r = requests.post(
url=bodypix_url,
data=data.tobytes(),
headers={'Content-Type': 'application/octet-stream'})
mask = np.frombuffer(r.content, dtype=np.uint8)
mask = mask.reshape((frame.shape[0], frame.shape[1]))
return mask
def post_process_mask(mask):
mask = cv2.dilate(mask, np.ones((10,10), np.uint8) , iterations=1)
mask = cv2.blur(mask.astype(float), (30,30))
return mask
def shift_image(img, dx, dy):
img = np.roll(img, dy, axis=0)
img = np.roll(img, dx, axis=1)
if dy>0:
img[:dy, :] = 0
elif dy<0:
img[dy:, :] = 0
if dx>0:
img[:, :dx] = 0
elif dx<0:
img[:, dx:] = 0
return img
def hologram_effect(img):
# add a blue tint
holo = cv2.applyColorMap(img, cv2.COLORMAP_WINTER)
# add a halftone effect
bandLength, bandGap = 2, 3
for y in range(holo.shape[0]):
if y % (bandLength+bandGap) < bandLength:
holo[y,:,:] = holo[y,:,:] * np.random.uniform(0.1, 0.3)
# add some ghosting
holo_blur = cv2.addWeighted(holo, 0.2, shift_image(holo.copy(), 5, 5), 0.8, 0)
holo_blur = cv2.addWeighted(holo_blur, 0.4, shift_image(holo.copy(), -5, -5), 0.6, 0)
# combine with the original color, oversaturated
out = cv2.addWeighted(img, 0.5, holo_blur, 0.6, 0)
return out
def get_frame(cap, background_scaled):
_, frame = cap.read()
# fetch the mask with retries (the app needs to warmup and we're lazy)
# e v e n t u a l l y c o n s i s t e n t
mask = None
while mask is None:
try:
mask = get_mask(frame)
except:
print("mask request failed, retrying")
# post-process mask and frame
mask = post_process_mask(mask)
frame = hologram_effect(frame)
# composite the foreground and background
inv_mask = 1-mask
for c in range(frame.shape[2]):
frame[:,:,c] = frame[:,:,c]*mask + background_scaled[:,:,c]*inv_mask
return frame
# setup access to the *real* webcam
cap = cv2.VideoCapture('/dev/video0')
height, width = 480, 640
cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
cap.set(cv2.CAP_PROP_FPS, 30)
# setup the fake camera
fake = pyfakewebcam.FakeWebcam('/dev/video20', width, height)
# load the virtual background
background = cv2.imread("/opt/background.jpg")
background_scaled = cv2.resize(background, (width, height))
write_frame = True
# frames forever
while True:
frame = get_frame(cap, background_scaled)
# fake webcam expects RGB
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
if write_frame:
write_frame = False
cv2.imwrite('/opt/frame.jpg', frame)
fake.schedule_frame(frame)