Skip to content

Instantly share code, notes, and snippets.

@acrylic-origami
Last active Jan 18, 2022
Embed
What would you like to do?
Intensity -> Radial mapping for SWIM waveform generation from single LED SWMs
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
#!/usr/bin/env python
from PIL import Image, ImageFilter, ImageOps
import numpy as np
import math
import scipy.sparse
import cv2
import pdb
import sys
import pyvirtualcam
V = cv2.VideoCapture(0)
DOWNSCALE = 2
H, W = int(V.get(cv2.CAP_PROP_FRAME_HEIGHT) / DOWNSCALE), int(V.get(cv2.CAP_PROP_FRAME_WIDTH) / DOWNSCALE)
with pyvirtualcam.Camera(width=W, height=H, fps=20, fmt=pyvirtualcam.PixelFormat.BGR) as Vout:
codec = cv2.VideoWriter_fourcc(*'MP4V')
SKIP = 4
YX = np.mgrid[0:H,0:W]
C = (0, np.zeros((2,))) # weight, coord
ALPHA = 0.95 # exponential factor
SCALE = 1
frame = 0
frame_buf = np.zeros((H, W, 3, 2))
while V.isOpened():
frame += 1
valid, im_raw = V.read()
if not valid:
break
# if frame % SKIP == 0:
# continue
im_raw = im_raw[(DOWNSCALE-1)::DOWNSCALE,(DOWNSCALE-1)::DOWNSCALE]
im = im_raw[:,:,0] # blue only
Etot = max(1, im.sum()) # max(1, im_thresh.sum())
alpha_ = np.arctan(C[0] / Etot * math.tan(ALPHA * math.pi / 2)) / (math.pi / 2)
C = (
alpha_ * C[0] + (1 - alpha_) * Etot,
alpha_ * C[1] + (1 - alpha_) * np.sum(im * YX, axis=(1,2)) / Etot
)
c_ = C[1][:,np.newaxis]
BLUR_SIZE = 5
imflat = im.flatten().astype(np.uint32) # * (BLUR_SIZE ** 2)
xy_ = np.maximum((c_ + (YX.reshape((2,-1)) - c_) * (1 + imflat / 256) * SCALE).astype(np.int32), 0)
gray_raw = scipy.sparse.coo_matrix((imflat, xy_)).toarray() # np.sqrt(imflat) * (255 / np.sqrt(255))
frame_out = np.zeros((H, W, 3))
frame_out[:,:,0:2] = gray_raw[:H, :W, np.newaxis] # np.tile( # duplicates are summed together
# Image.fromarray(frame_out).show()
# sys.stdout.write('\r%d' % frame)
frame_buf[:,:,:,frame%(frame_buf.shape[3])] = frame_out
frame_out_b = np.minimum(255, frame_buf.sum(axis=3)).astype(np.uint8)
frame_comp = cv2.add(cv2.boxFilter(frame_out_b, -1, (3,3), normalize=False), im_raw)
cv2.circle(frame_comp, C[1][::-1].astype(np.uint32), 3, (0, 0, 255), -1)
Vout.send(frame_comp)
sys.stdout.write('\r%d' % frame)
V.release()
cv2.destroyAllWindows()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment