Skip to content

Instantly share code, notes, and snippets.

@acrylic-origami
Last active January 18, 2022 10:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save acrylic-origami/d46b4d102d9c7c439c1d79cbe4236c88 to your computer and use it in GitHub Desktop.
Save acrylic-origami/d46b4d102d9c7c439c1d79cbe4236c88 to your computer and use it in GitHub Desktop.
Intensity -> Radial mapping for SWIM waveform generation from single LED SWMs
Display the source blob
Display the rendered blob
Raw
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