Delete old code
This commit is contained in:
parent
959f31d585
commit
b5ffcec41a
|
@ -1 +0,0 @@
|
|||
{"0": [0, 0, 0], "1": [0, 0, 85], "2": [0, 0, 170], "3": [0, 0, 255], "4": [0, 85, 0], "5": [0, 85, 85], "6": [0, 85, 170], "7": [0, 85, 255], "8": [0, 170, 0], "9": [0, 170, 85], "10": [0, 170, 170], "11": [0, 170, 255], "12": [0, 255, 0], "13": [0, 255, 85], "14": [0, 255, 170], "15": [0, 255, 255], "16": [85, 0, 0], "17": [85, 0, 85], "18": [85, 0, 170], "19": [85, 0, 255], "20": [85, 85, 0], "21": [85, 85, 85], "22": [85, 85, 170], "23": [85, 85, 255], "24": [85, 170, 0], "25": [85, 170, 85], "26": [85, 170, 170], "27": [85, 170, 255], "28": [85, 255, 0], "29": [85, 255, 85], "30": [85, 255, 170], "31": [85, 255, 255], "32": [170, 0, 0], "33": [170, 0, 85], "34": [170, 0, 170], "35": [170, 0, 255], "36": [170, 85, 0], "37": [170, 85, 85], "38": [170, 85, 170], "39": [170, 85, 255], "40": [170, 170, 0], "41": [170, 170, 85], "42": [170, 170, 170], "43": [170, 170, 255], "44": [170, 255, 0], "45": [170, 255, 85], "46": [170, 255, 170], "47": [170, 255, 255], "48": [255, 0, 0], "49": [255, 0, 85], "50": [255, 0, 170], "51": [255, 0, 255], "52": [255, 85, 0], "53": [255, 85, 85], "54": [255, 85, 170], "55": [255, 85, 255], "56": [255, 170, 0], "57": [255, 170, 85], "58": [255, 170, 170], "59": [255, 170, 255], "60": [255, 255, 0], "61": [255, 255, 85], "62": [255, 255, 170], "63": [255, 255, 255]}
|
|
@ -1 +0,0 @@
|
|||
{"corner_colors": {"0": [["#000000", "#000000", "#000000", "#000000"], ["#000000", "#ff0000", "#ff0000", "#000000"], ["#000000", "#ff0000", "#ff0000", "#000000"], ["#000000", "#000000", "#000000", "#000000"]], "1": [["#000000", "#000000", "#000000", "#000000"], ["#000000", "#00ff00", "#00ff00", "#000000"], ["#000000", "#00ff00", "#00ff00", "#000000"], ["#000000", "#000000", "#000000", "#000000"]], "2": [["#000000", "#000000", "#000000", "#000000"], ["#000000", "#0000ff", "#0000ff", "#000000"], ["#000000", "#0000ff", "#0000ff", "#000000"], ["#000000", "#000000", "#000000", "#000000"]], "3": [["#000000", "#000000", "#000000", "#000000"], ["#000000", "#ffffff", "#ffffff", "#000000"], ["#000000", "#ffffff", "#ffffff", "#000000"], ["#000000", "#000000", "#000000", "#000000"]]}, "corner_width": 4, "corner_height": 4}
|
|
@ -1,9 +0,0 @@
|
|||
import itertools
|
||||
import json
|
||||
|
||||
|
||||
color_vals = [0, 85, 170, 255] # giving all color channels the same equally-spaced values
|
||||
color_combs = {i: comb for i, comb in enumerate(itertools.product(color_vals, repeat=3))}
|
||||
|
||||
with open("colors_64_v0.json", "w") as f:
|
||||
json.dump(color_combs, f)
|
|
@ -1,36 +0,0 @@
|
|||
import json
|
||||
|
||||
import sys # hacky way to import utils for now
|
||||
sys.path.append("..")
|
||||
from utils import rgb_to_hex
|
||||
|
||||
|
||||
corner_shape = [ # giving all 4 corners have the same shape
|
||||
[0, 0, 0, 0],
|
||||
[0, 1, 1, 0],
|
||||
[0, 1, 1, 0],
|
||||
[0, 0, 0, 0],
|
||||
]
|
||||
|
||||
center_color = [0, 0, 0]
|
||||
corner_colors = { # assuming each corner will only have two colors (center_color and a corner-specific color)
|
||||
0: [255, 0, 0],
|
||||
1: [0, 255, 0],
|
||||
2: [0, 0, 255],
|
||||
3: [255, 255, 255,]
|
||||
}
|
||||
|
||||
center_color = rgb_to_hex(center_color)
|
||||
corner_colors = {key: rgb_to_hex(val) for key, val in corner_colors.items()}
|
||||
|
||||
corner_colored_shapes = {
|
||||
corner_ind: [[corner_color if cell else center_color for cell in row] for row in corner_shape]
|
||||
for corner_ind, corner_color in corner_colors.items()
|
||||
}
|
||||
|
||||
with open("corners_hollow4x4_v0.json", "w") as f:
|
||||
json.dump({
|
||||
"corner_colors": corner_colored_shapes,
|
||||
"corner_width": len(corner_shape[0]),
|
||||
"corner_height": len(corner_shape),
|
||||
}, f)
|
|
@ -1,167 +0,0 @@
|
|||
import argparse
|
||||
import json
|
||||
import math
|
||||
import time
|
||||
import tkinter as tk
|
||||
|
||||
import numpy as np
|
||||
import pygame
|
||||
|
||||
from utils import rgb_to_hex
|
||||
|
||||
|
||||
def parse_args():
|
||||
return {
|
||||
"cell_size": 8, # in pixels
|
||||
"num_cells_w": 100, # TODO: w/h or r/c?
|
||||
"num_cells_h": 100,
|
||||
"colors_path": "configs/colors_64_v0.json",
|
||||
"corners_path": "configs/corners_hollow4x4_v0.json",
|
||||
"frame_delay": 1000 // 20, # time b/w frames, in millis
|
||||
}
|
||||
|
||||
|
||||
def seq_to_frames(bin_seq: np.ndarray, args: dict) -> np.ndarray: # TODO: Namespace
|
||||
"""
|
||||
Converts a binary sequence to an array of frames.
|
||||
TODO: doc, expecting size of exactly one frame in the future?
|
||||
|
||||
np.packbits seems relevant but limited to 8 bits
|
||||
|
||||
Args:
|
||||
bin_seq: a 1D array of binary values.
|
||||
args: config parameters
|
||||
|
||||
Returns:
|
||||
array of shape (num_frames, args["num_cells_h"], args["num_cells_w"]), where each element is
|
||||
a hex string for the color of that cell
|
||||
"""
|
||||
bin_seq = bin_seq.copy() # so that we don't mutate bin_seq
|
||||
|
||||
with open(args["colors_path"], "r") as f:
|
||||
colors = json.load(f)
|
||||
|
||||
with open(args["corners_path"], "r") as f:
|
||||
corners = json.load(f)
|
||||
|
||||
assert len(corners["corner_colors"]) == 4, "Hardcoded for 4 corners"
|
||||
corner_width = corners["corner_width"]
|
||||
corner_height = corners["corner_height"]
|
||||
|
||||
num_colors = len(colors)
|
||||
bits_per_cell = int(math.log2(num_colors))
|
||||
assert 2**bits_per_cell == num_colors, "Assumed the number of colors is a power of 2."
|
||||
|
||||
# bits_per_frame = bits_per_cell * args["num_cells_w"] * args["num_cells_h"]
|
||||
# num_frames = int(math.ceil(len(bin_seq) / bits_per_frame))
|
||||
# bin_seq.resize(bits_per_frame * num_frames)
|
||||
# # frames_bits = bin_seq.reshape(num_frames, args["num_cells_h"], args["num_cells_w"], bits_per_cell)
|
||||
#
|
||||
# pows = 2 ** np.arange(bits_per_cell)
|
||||
# frames_vals = (frames_bits * pows).sum(axis=-1) # low to high bit order
|
||||
|
||||
cells_per_frame = args["num_cells_w"] * args["num_cells_h"] - 4 * corner_width * corner_height
|
||||
bits_per_frame = bits_per_cell * cells_per_frame
|
||||
num_frames = int(math.ceil(len(bin_seq) / bits_per_frame))
|
||||
bin_seq.resize(bits_per_frame * num_frames)
|
||||
frames_bits = bin_seq.reshape(num_frames, cells_per_frame, bits_per_cell)
|
||||
pows = 2 ** np.arange(bits_per_cell)
|
||||
frames_vals = (frames_bits * pows).sum(axis=-1) # low to high bit order
|
||||
|
||||
# Efficiently map frame_vals to the corresponding hex colors (https://stackoverflow.com/a/55950051)
|
||||
color_mapping_arr = np.empty(num_colors, dtype="<U7")
|
||||
for i in range(num_colors):
|
||||
color_mapping_arr[i] = rgb_to_hex(colors[str(i)]) # JSON keys stored as str
|
||||
|
||||
frames_colors = color_mapping_arr[frames_vals]
|
||||
|
||||
num_top_cells = (args["num_cells_w"] - 2 * corner_width) * corner_height # TODO: explain
|
||||
top_cells = frames_colors[:, :num_top_cells].reshape(num_frames, corner_height, -1)
|
||||
center_cells = frames_colors[:, num_top_cells:-num_top_cells].reshape(num_frames, -1, args["num_cells_w"])
|
||||
bottom_cells = frames_colors[:, -num_top_cells:].reshape(num_frames, corner_height, -1)
|
||||
|
||||
corners_numpy_dict = {key: np.broadcast_to(val, (num_frames, corner_height, corner_width))
|
||||
for key, val in corners["corner_colors"].items()}
|
||||
top_rows = np.concatenate([corners_numpy_dict["0"], top_cells, corners_numpy_dict["1"]], axis=2)
|
||||
bottom_rows = np.concatenate([corners_numpy_dict["2"], bottom_cells, corners_numpy_dict["3"]], axis=2)
|
||||
|
||||
return np.concatenate([top_rows, center_cells, bottom_rows], axis=1)
|
||||
|
||||
|
||||
class AnimatedFrames:
|
||||
def __init__(self, frames: np.ndarray, args: dict):
|
||||
self.frames = frames
|
||||
self.args = args
|
||||
|
||||
|
||||
def display_frame(self):
|
||||
func_start_time = time.time_ns()
|
||||
for inds_tuple, color_hex in np.ndenumerate(self.frames[self.frame_ind % len(self.frames)]):
|
||||
self.canvas.itemconfigure(self.inds_to_id[inds_tuple], fill=color_hex)
|
||||
|
||||
self.canvas.itemconfigure(self._debug_text_id, text=self.frame_ind)
|
||||
self.frame_ind += 1
|
||||
|
||||
adjusted_delay = round((self.start_time + self.args["frame_delay"] * int(1e6)
|
||||
* self.frame_ind - func_start_time) / 1e6)
|
||||
assert adjusted_delay > 1, adjusted_delay # o/w we lagged too far behind, assuming 1 ms for this instruction
|
||||
self.canvas.after(adjusted_delay, self.display_frame) # TODO: check delay is exact
|
||||
# TODO: set self time and just sleep until then
|
||||
|
||||
def animate(self):
|
||||
epilepsy_warning_id = self.canvas.create_text(self.width_pixels / 2, self.height_pixels / 2,
|
||||
text="Warning: Epilepsy")
|
||||
|
||||
def delete_and_animate():
|
||||
self.canvas.delete(epilepsy_warning_id)
|
||||
self.start_time = time.time_ns()
|
||||
self.display_frame()
|
||||
|
||||
self.canvas.after(5000, delete_and_animate)
|
||||
# self.display_frame()
|
||||
self.root.mainloop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
|
||||
rand_bin_seq = np.random.randint(2, size=1000000)
|
||||
frames = seq_to_frames(rand_bin_seq, args)
|
||||
|
||||
width_pixels = args["cell_size"] * args["num_cells_w"]
|
||||
height_pixels = args["cell_size"] * args["num_cells_h"]
|
||||
|
||||
pygame.init()
|
||||
clock = pygame.time.Clock()
|
||||
screen = pygame.display.set_mode((width_pixels, height_pixels))
|
||||
font = pygame.font.SysFont(None, 25)
|
||||
pygame.event.get()
|
||||
|
||||
text = font.render("<Epilepsy Warning>", True, "white")
|
||||
text_rect = text.get_rect(center=(width_pixels / 2, height_pixels / 2))
|
||||
screen.blit(text, text_rect)
|
||||
pygame.display.update()
|
||||
clock.tick(0.2)
|
||||
frame_ind = 0
|
||||
running = True
|
||||
while running:
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
running = False
|
||||
|
||||
for (i, j), color_hex in np.ndenumerate(frames[frame_ind % len(frames)]):
|
||||
rect = pygame.Rect(i * args["cell_size"], j * args["cell_size"], args["cell_size"], args["cell_size"])
|
||||
pygame.draw.rect(screen, color_hex, rect)
|
||||
|
||||
text = font.render(str(frame_ind), True, "black")
|
||||
text_rect = text.get_rect(center=((args["num_cells_w"] - 2) * args["cell_size"], (args["num_cells_h"] - 2) * args["cell_size"]))
|
||||
screen.blit(text, text_rect)
|
||||
frame_ind += 1
|
||||
pygame.display.update()
|
||||
# clock.tick(15)
|
||||
clock.tick_busy_loop(10) # https://gamedev.stackexchange.com/a/102831
|
||||
if frame_ind % 30 == 0:
|
||||
print(f"{clock.get_fps()=}")
|
||||
|
||||
# https://stackoverflow.com/questions/28405222/syncing-image-display-with-screen-refresh-rate?
|
||||
pygame.quit()
|
|
@ -1,151 +0,0 @@
|
|||
import argparse
|
||||
import json
|
||||
import math
|
||||
import time
|
||||
import tkinter as tk
|
||||
|
||||
import numpy as np
|
||||
|
||||
from utils import rgb_to_hex
|
||||
|
||||
|
||||
def parse_args():
|
||||
return {
|
||||
"cell_size": 8, # in pixels
|
||||
"num_cells_w": 100, # TODO: w/h or r/c?
|
||||
"num_cells_h": 100,
|
||||
"colors_path": "configs/colors_64_v0.json",
|
||||
"corners_path": "configs/corners_hollow4x4_v0.json",
|
||||
"frame_delay": 1000 // 15, # time b/w frames, in millis
|
||||
}
|
||||
|
||||
|
||||
def seq_to_frames(bin_seq: np.ndarray, args: dict) -> np.ndarray: # TODO: Namespace
|
||||
"""
|
||||
Converts a binary sequence to an array of frames.
|
||||
TODO: doc, expecting size of exactly one frame in the future?
|
||||
|
||||
np.packbits seems relevant but limited to 8 bits
|
||||
|
||||
Args:
|
||||
bin_seq: a 1D array of binary values.
|
||||
args: config parameters
|
||||
|
||||
Returns:
|
||||
array of shape (num_frames, args["num_cells_h"], args["num_cells_w"]), where each element is
|
||||
a hex string for the color of that cell
|
||||
"""
|
||||
bin_seq = bin_seq.copy() # so that we don't mutate bin_seq
|
||||
|
||||
with open(args["colors_path"], "r") as f:
|
||||
colors = json.load(f)
|
||||
|
||||
with open(args["corners_path"], "r") as f:
|
||||
corners = json.load(f)
|
||||
|
||||
assert len(corners["corner_colors"]) == 4, "Hardcoded for 4 corners"
|
||||
corner_width = corners["corner_width"]
|
||||
corner_height = corners["corner_height"]
|
||||
|
||||
num_colors = len(colors)
|
||||
bits_per_cell = int(math.log2(num_colors))
|
||||
assert 2**bits_per_cell == num_colors, "Assumed the number of colors is a power of 2."
|
||||
|
||||
# bits_per_frame = bits_per_cell * args["num_cells_w"] * args["num_cells_h"]
|
||||
# num_frames = int(math.ceil(len(bin_seq) / bits_per_frame))
|
||||
# bin_seq.resize(bits_per_frame * num_frames)
|
||||
# # frames_bits = bin_seq.reshape(num_frames, args["num_cells_h"], args["num_cells_w"], bits_per_cell)
|
||||
#
|
||||
# pows = 2 ** np.arange(bits_per_cell)
|
||||
# frames_vals = (frames_bits * pows).sum(axis=-1) # low to high bit order
|
||||
|
||||
cells_per_frame = args["num_cells_w"] * args["num_cells_h"] - 4 * corner_width * corner_height
|
||||
bits_per_frame = bits_per_cell * cells_per_frame
|
||||
num_frames = int(math.ceil(len(bin_seq) / bits_per_frame))
|
||||
bin_seq.resize(bits_per_frame * num_frames)
|
||||
frames_bits = bin_seq.reshape(num_frames, cells_per_frame, bits_per_cell)
|
||||
pows = 2 ** np.arange(bits_per_cell)
|
||||
frames_vals = (frames_bits * pows).sum(axis=-1) # low to high bit order
|
||||
|
||||
# Efficiently map frame_vals to the corresponding hex colors (https://stackoverflow.com/a/55950051)
|
||||
color_mapping_arr = np.empty(num_colors, dtype="<U7")
|
||||
for i in range(num_colors):
|
||||
color_mapping_arr[i] = rgb_to_hex(colors[str(i)]) # JSON keys stored as str
|
||||
|
||||
frames_colors = color_mapping_arr[frames_vals]
|
||||
|
||||
num_top_cells = (args["num_cells_w"] - 2 * corner_width) * corner_height # TODO: explain
|
||||
top_cells = frames_colors[:, :num_top_cells].reshape(num_frames, corner_height, -1)
|
||||
center_cells = frames_colors[:, num_top_cells:-num_top_cells].reshape(num_frames, -1, args["num_cells_w"])
|
||||
bottom_cells = frames_colors[:, -num_top_cells:].reshape(num_frames, corner_height, -1)
|
||||
|
||||
corners_numpy_dict = {key: np.broadcast_to(val, (num_frames, corner_height, corner_width))
|
||||
for key, val in corners["corner_colors"].items()}
|
||||
top_rows = np.concatenate([corners_numpy_dict["0"], top_cells, corners_numpy_dict["1"]], axis=2)
|
||||
bottom_rows = np.concatenate([corners_numpy_dict["2"], bottom_cells, corners_numpy_dict["3"]], axis=2)
|
||||
|
||||
return np.concatenate([top_rows, center_cells, bottom_rows], axis=1)
|
||||
|
||||
|
||||
class AnimatedFrames:
|
||||
def __init__(self, frames: np.ndarray, args: dict):
|
||||
self.frames = frames
|
||||
self.args = args
|
||||
self.width_pixels = args["cell_size"] * args["num_cells_w"]
|
||||
self.height_pixels = args["cell_size"] * args["num_cells_h"]
|
||||
|
||||
self.root = tk.Tk()
|
||||
self.root.columnconfigure(0, weight=1)
|
||||
self.root.rowconfigure(0, weight=1)
|
||||
self.canvas = tk.Canvas(self.root, width=self.width_pixels, height=self.height_pixels,
|
||||
borderwidth=0, highlightthickness=0) # https://stackoverflow.com/a/63220348
|
||||
self.canvas.grid(column=0, row=0)
|
||||
|
||||
# We will create each cell (rectangle) now, and then update their colors in different frames
|
||||
self.inds_to_id = dict() # map from (row_ind, col_ind) to the id of the rectangle at that cell position
|
||||
for i in range(args["num_cells_h"]):
|
||||
for j in range(args["num_cells_w"]):
|
||||
self.inds_to_id[(i, j)] = self.canvas.create_rectangle(
|
||||
i * args["cell_size"], j * args["cell_size"], (i + 1) * args["cell_size"],
|
||||
(j + 1) * args["cell_size"], width=0
|
||||
)
|
||||
|
||||
self.frame_ind = 0 # the index in `self.frames` of the next frame to display
|
||||
self.start_time = None
|
||||
self._debug_text_id = self.canvas.create_text((args["num_cells_w"] - 2) * args["cell_size"], (args["num_cells_h"] - 2) * args["cell_size"])
|
||||
|
||||
def display_frame(self):
|
||||
func_start_time = time.time_ns()
|
||||
for inds_tuple, color_hex in np.ndenumerate(self.frames[self.frame_ind % len(self.frames)]):
|
||||
self.canvas.itemconfigure(self.inds_to_id[inds_tuple], fill=color_hex)
|
||||
|
||||
self.canvas.itemconfigure(self._debug_text_id, text=self.frame_ind)
|
||||
self.frame_ind += 1
|
||||
|
||||
adjusted_delay = round((self.start_time + self.args["frame_delay"] * int(1e6)
|
||||
* self.frame_ind - func_start_time) / 1e6)
|
||||
assert adjusted_delay > 1, adjusted_delay # o/w we lagged too far behind, assuming 1 ms for this instruction
|
||||
self.canvas.after(adjusted_delay, self.display_frame) # TODO: check delay is exact
|
||||
# TODO: set self time and just sleep until then
|
||||
|
||||
def animate(self):
|
||||
epilepsy_warning_id = self.canvas.create_text(self.width_pixels / 2, self.height_pixels / 2,
|
||||
text="Warning: Epilepsy")
|
||||
|
||||
def delete_and_animate():
|
||||
self.canvas.delete(epilepsy_warning_id)
|
||||
self.start_time = time.time_ns()
|
||||
self.display_frame()
|
||||
|
||||
self.canvas.after(5000, delete_and_animate)
|
||||
# self.display_frame()
|
||||
self.root.mainloop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
|
||||
rand_bin_seq = np.random.randint(2, size=1000000)
|
||||
frames = seq_to_frames(rand_bin_seq, args)
|
||||
|
||||
AnimatedFrames(frames, args).animate()
|
Loading…
Reference in a new issue