forked from d3x-at/a1111-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwebcam.py
More file actions
163 lines (126 loc) · 4.38 KB
/
Copy pathwebcam.py
File metadata and controls
163 lines (126 loc) · 4.38 KB
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
160
161
162
163
'''
usage: python3 webcam.py
'''
import base64
from io import BytesIO
from threading import Thread
import pygame.camera
import pygame.image
import requests
URL = "http://127.0.0.1:7860"
PAYLOAD = {
"prompt": "a puppy dog",
"steps": 15,
"denoising_strength": 0.75
}
# Set to True to send frames to the img2img api
DO_IMG2IMG = False
# Save img2img frames to disk
SAVE_FRAMES = False
# The camera to use
CAMERA_INDEX = 0
# The resolution to request from the camera
CAMERA_RESOLUTION = (640, 480)
# Set crop dimensions (x, y, width, height) to crop the camera image
# e.g.: CAMERA_CROP = (100, 0, 384, 512)
CAMERA_CROP = None
def to_base64(frame):
# convert frame surface to base64 encoded PNG
with BytesIO() as buffer:
pygame.image.save(frame, buffer, "img.png")
return base64.b64encode(buffer.getvalue()).decode('utf-8')
def from_base64(base64_image, frame_no: int, save_to_disk: bool = False):
with BytesIO(base64.b64decode(base64_image)) as buffer:
if save_to_disk:
with open(f"{frame_no:08d}.png", "wb") as fp:
fp.write(buffer.getbuffer())
return pygame.image.load(buffer)
class Game:
run = True
crop = None
frame_no = 0
@property
def width(self):
return self.crop[2] if self.crop else self.frame_width
@property
def height(self):
return self.crop[3] if self.crop else self.frame_height
def __init__(self):
pygame.camera.init()
cameras = pygame.camera.list_cameras()
print(f"Using camera {cameras[CAMERA_INDEX]}")
self.webcam = pygame.camera.Camera(cameras[CAMERA_INDEX], CAMERA_RESOLUTION)
self.webcam.start()
frame = self.webcam.get_image()
self.frame_width = frame.get_width()
self.frame_height = frame.get_height()
if CAMERA_CROP:
x, y, width, height = CAMERA_CROP
width = min(width, self.frame_width)
height = min(height, self.frame_height)
x = min(x, self.frame_width - width)
y = min(y, self.frame_height - height)
self.crop = (x, y, width, height)
self.screen = pygame.display.set_mode((self.width, self.height))
print(f"Resolution: {self.frame_width}x{self.frame_height}")
if self.crop:
print(f"Crop to: {self.crop}")
pygame.display.set_caption("pyGame Camera View")
def run(self):
t = Thread(target=self.process)
t.start()
while t.is_alive():
for e in pygame.event.get():
if e.type == pygame.QUIT:
self.run = False
t.join(.01)
def process(self):
while self.run:
self.frame_no += 1
# grab frame
frame = self.webcam.get_image()
# crop
if self.crop:
frame = frame.subsurface(self.crop)
# process frame with img2img
if DO_IMG2IMG:
frame = self.img2img(frame)
# draw frame
self.screen.blit(frame, (0, 0))
# update display
pygame.display.flip()
def img2img(self, frame: pygame.Surface):
base64_image = to_base64(frame)
# assemble payload
payload = {
'width': self.width,
'height': self.height,
**PAYLOAD,
'init_images': [base64_image],
'alwayson_scripts': {
'controlnet': {'args': [
{
"module": "depth_midas",
"model": "control_v11f1p_sd15_depth [cfd03158]",
"control_mode": 0,
"weight": 0.5,
"input_image": base64_image,
},
{
"module": "canny",
"model": "control_v11p_sd15_canny [d14c016b]",
"control_mode": 0,
"weight": 0.5,
"input_image": base64_image,
}
]}
}
}
# call img2img API
response = requests.post(f'{URL}/sdapi/v1/img2img', json=payload)
if not response.ok:
raise RuntimeError("post request failed")
result = response.json()
return from_base64(result['images'][0], self.frame_no, SAVE_FRAMES)
if __name__ == "__main__":
Game().run()