You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
4.1 KiB

5 months ago
import torch
import SpoutGL
from itertools import islice, cycle, repeat
import array
from random import randint
import time
from OpenGL import GL
from multiprocessing import Queue
import numpy as np
5 months ago
from PIL import Image
5 months ago
TARGET_FPS = 30
SEND_WIDTH = 512
SEND_HEIGHT = 512
5 months ago
alpha_cache = np.full((512, 512, 1), 255, dtype=np.uint8)
5 months ago
def spout_buffer_to_tensor(buffer, width, height):
5 months ago
# np_buffer = np.asarray(buffer, dtype=np.uint8)
np_buffer=np.frombuffer(buffer, dtype=np.uint8)
5 months ago
image_bgra = np_buffer.reshape((height, width, 4))
image_rgb = image_bgra[..., [2, 1, 0]]
image_float = image_rgb.astype(np.float32) / 255.0
5 months ago
# image_normalized = (image_float * 2.0) - 1.0
5 months ago
tensor = torch.from_numpy(image_float).permute(2, 0, 1)
5 months ago
del np_buffer # Free memory
del image_bgra # Free memory
del image_rgb # Free memory
del image_float # Free memory
5 months ago
return tensor.unsqueeze(0)
def get_spout_image(queue, wwidth: int, wheight: int) -> None:
with SpoutGL.SpoutReceiver() as receiver:
receiver.setReceiverName("Spout DX11 Sender")
5 months ago
image_bgra = np.zeros((SEND_HEIGHT, SEND_WIDTH, 4), dtype=np.uint8)
5 months ago
while True:
5 months ago
result = receiver.receiveImage(image_bgra, GL.GL_RGBA, False, 0)
5 months ago
# print("Receive result", result)
if receiver.isUpdated():
5 months ago
continue
# width = receiver.getSenderWidth()
# height = receiver.getSenderHeight()
# image_bgra = array.array('B', [0] * (width * height * 4)) # Correctly reallocate buffer with updated size
# print("Spout Receiver updated, Buffer size", width, height)
# if buffer and result and not SpoutGL.helpers.isBufferEmpty(buffer):
if SpoutGL.helpers.isBufferEmpty(image_bgra):
continue
# pixels=spout_buffer_to_tensor(buffer, width, height)
5 months ago
# print("get_spout_image", pixels.shape)
5 months ago
image_rgb_array= image_bgra[:, :, [2, 1, 0]]
pixels=Image.fromarray(image_rgb_array, 'RGB')
queue.put(pixels, block=False)
5 months ago
# Wait until the next frame is ready
# Wait time is in milliseconds; note that 0 will return immediately
# receiver.waitFrameSync("SpoutSender", 10000)
5 months ago
5 months ago
def randcolor():
return randint(0, 255)
def tensor_to_spout_image(tensor):
image = tensor.squeeze(0)
5 months ago
if image.device.type != "cpu":
image = image.cpu()
image = image.permute(1, 2, 0).numpy()
5 months ago
5 months ago
if image.min() < 0:
image = (image + 1) / 2 # Scale from [-1, 1] to [0, 1]
image = np.clip(image * 255, 0, 255).astype(np.uint8)
5 months ago
5 months ago
# h, w, _ = image_np.shape
# alpha = np.full((h, w, 1), 255, dtype=np.uint8)
image_rgba = np.concatenate((image, alpha_cache), axis=-1)
5 months ago
image_bgra = image_rgba[..., [2, 1, 0, 3]]
5 months ago
del image # Free memory
5 months ago
return np.ascontiguousarray(image_bgra) # Ensure the array is contiguous in memory
def send_spout_image(queue: Queue, width: int, height: int)->None:
with SpoutGL.SpoutSender() as sender:
sender.setSenderName("StreamDiffusion")
5 months ago
5 months ago
while True:
# Check if there are images in the queue
if not queue.empty():
5 months ago
output_image = queue.get(block=False)
# pixels = tensor_to_spout_image(image)
output_bgr_array = np.array(output_image, dtype=np.uint8)[:, :, ::-1]
output_bgra_array = np.zeros((SEND_HEIGHT, SEND_WIDTH, 4), dtype=np.uint8)
output_bgra_array[:, :, :3] = output_bgr_array
output_bgra_array[:, :, 3] = 255
buffer = output_bgra_array
result = sender.sendImage(buffer, width, height, GL.GL_RGBA, False, 0)
5 months ago
# print("Send result", result)
# Indicate that a frame is ready to read
sender.setFrameSync("StreamDiffusion")
5 months ago
5 months ago
# Wait for next send attempt
# time.sleep(1./TARGET_FPS)