Skip to content

Instantly share code, notes, and snippets.

@SqrtRyan
Created March 1, 2026 03:05
Show Gist options
  • Select an option

  • Save SqrtRyan/4d29c50eb739ab1f254d2a4173c048ff to your computer and use it in GitHub Desktop.

Select an option

Save SqrtRyan/4d29c50eb739ab1f254d2a4173c048ff to your computer and use it in GitHub Desktop.
import rp
# https://gist.github.com/SqrtRyan/c33e4e40ccf74714a20c229a13c717fe
from PIL import Image
import rp
import cv2
import numpy as np
import torch
import torchvision.transforms as T
def approximate_matrix_by_rank(matrix, rank):
numpy_mode = rp.is_numpy_array(matrix)
rows, cols = matrix.shape
if rank > min(rows, cols):
return matrix
matrix_torch = (
matrix
if rp.is_torch_tensor(matrix)
else torch.tensor(matrix, dtype=torch.float32).to("mps")
)
U, S, V = torch.linalg.svd(matrix_torch)
S = torch.diag(S[:rank])
U = U[:, :rank]
V = V[:rank, :]
approximated_matrix_torch = U @ S @ V
approximated_matrix = (
approximated_matrix_torch.cpu().numpy()
if numpy_mode
else approximated_matrix_torch
)
return approximated_matrix
def apply_frequency_space_func(matrix, func, *args, **kwargs):
matrix_torch = torch.tensor(matrix, dtype=torch.float32).to("mps")
fft_matrix = torch.fft.fft2(matrix_torch)
fft_matrix = func(fft_matrix, *args, **kwargs)
output = torch.fft.irfft2(fft_matrix, s=matrix_torch.shape[-2:])
rp.cv_imshow(rp.full_range(fft_matrix.imag))
if rp.is_numpy_array(matrix):
output = output.cpu().numpy()
return output
def approximate_matrix_by_rank_fourier(matrix, rank):
# return apply_frequency_space_func(matrix, lambda x:x**1.6/1000)#, rank=1)
return apply_frequency_space_func(matrix, approximate_matrix_by_rank, rank=rank)
def get_image():
out = rp.load_image_from_webcam()
# out=load_image('https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png',use_cache=True)
SIZE = 512
#SIZE = 256
#SIZE = 128
out = rp.resize_image_to_fit(out, height=SIZE, width=SIZE)
# out = resize_image_to_fit(out, height=100, width=100)
out = rp.as_rgb_image(out)
#out = as_grayscale_image(out)
out = rp.as_float_image(out)
# return create_diagonal_sinusoid(SIZE,frequency=10,theta=gtoc())
return out
def create_diagonal_sinusoid(size=128, frequency=5, theta=0):
x = np.arange(size)
y = np.arange(size)
X, Y = np.meshgrid(x, y)
sinusoid = np.sin(
2 * np.pi * frequency * (np.cos(theta) * X + np.sin(theta) * Y) / size
)
return sinusoid.astype(np.float32)
ERRORS = []
ERROR_LEN = 100
image = get_image()
image *= 0
I = 0
while True:
cam_image = get_image()
RANK = 5
# img_fapprox=apply_image_function_per_channel(approximate_matrix_by_rank_fourier, cam_image, RANK)
img_approx = rp.apply_image_function_per_channel(
approximate_matrix_by_rank, cam_image, RANK
)
# print(((img_fapprox-img_approx)**2).max())
# display_image(
# vertically_concatenated_images(
# cam_image,
# img_approx,
# img_fapprox,
# )
# )
# continue
# image *= 0
# cam_image=cam_image>0
# cam_image=cam_image/3
# cam_image=cam_image+.5-cam_image.max()/2
delta = cam_image - image
# delta *= 0.1
delta *= 0.7
delta = rp.apply_image_function_per_channel(approximate_matrix_by_rank, delta, RANK)
image += delta
error = np.abs(delta).sum()
print(I, error)
I += 1
dimage = rp.tiled_images(
rp.labeled_images(
[
img_approx,
image,
delta / 2 + 0.5,
rp.full_range(delta),
],
["Rank %i" % RANK, "Approx", "Delta", "Full-Range Delta"],font='Futura'
),
border_thickness=0,
)
dimageW = rp.get_image_width(dimage)
ERRORS.append(error)
# print(ERRORS)
# if len(ERRORS) > 2:
ERRORS = ERRORS[-ERROR_LEN:]
dimage = rp.vertically_concatenated_images(
dimage,
rp.labeled_image(
rp.cv_line_graph(
ERRORS,
width=dimageW,
height=rp.get_image_height(delta),
# vertical_bar_x=max_valued_index(ERRORS),
),
"Errors",font='https://github.com/Eyeline-Research/Go-with-the-Flow/raw/refs/heads/website/fonts/Futura.ttc'
),
)
rp.display_image(dimage)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment