import numpy as np
import queue
import threading
+import random
class VideoCapture:
- def __init__(self, device_id):
+ def __init__(self, device_id, backend):
- self.camera = cv.VideoCapture(device_id + cv.CAP_GSTREAMER)
+ self.camera = cv.VideoCapture(device_id, backend)
self.camera.set(cv.CAP_PROP_FRAME_WIDTH, 1920.0)
self.camera.set(cv.CAP_PROP_FRAME_HEIGHT, 1080.0)
display_size: tuple,
device_id: int = 0,
debug: bool = True,
- dummy: bool = False
+ dummy: bool = False,
+ use_files: bool = False
):
self.window_size = window_size
self.show_debug = debug
self.dummy = dummy
- self.camera = VideoCapture(device_id)
+ self.camera = VideoCapture(device_id, cv.CAP_V4L)
self.camera.set(cv.CAP_PROP_BUFFERSIZE, 38)
self.camera.set(cv.CAP_PROP_FRAME_WIDTH, 1920.0)
if self.show_debug == True:
cv.namedWindow("debug", cv.WINDOW_NORMAL)
- def capture_raw(
- self
- ) -> np.ndarray:
-
- _, capture = self.camera.read()
-
- return capture
-
def calibrate(
self
):
) -> None:
if self.dummy == True:
- return
+ pass #return
vingette_compression = 50
self.lookup_vingette = np.zeros((
- 255 // vingette_compression + 1, # potentially +1
- self.window_height // vingette_compression + 1,
- self.window_size // vingette_compression + 1
+ 255 // vingette_compression + 1,
+ self.display_size[0] // vingette_compression + 1,
+ self.display_size[1] // vingette_compression + 1
), dtype=np.uint8)
for v in range(0, 255, vingette_compression):
pixel = cv.cvtColor(pixel, cv.COLOR_HSV2BGR)
self.display(pixel)
- capture = self.capture()
+ #capture = self.capture()
+ #capture = cv.cvtColor(capture, cv.COLOR_BGR2HSV)
- capture = cv.cvtColor(capture, cv.COLOR_BGR2HSV)
+ # apply vingette overlay
+ capture = cv.resize(pixel, self.display_size, interpolation=cv.INTER_NEAREST_EXACT)
- for y in range(0, self.window_height, vingette_compression):
- for x in range(0, self.window_size, vingette_compression):
+ rows = len(capture)
+ columns = len(capture[0])
+ for y, row in enumerate(capture):
+ for x, pixel in enumerate(row):
+ y -= rows // 2
+ x -= columns // 2
+ math_pixel = pixel.astype(np.int16)
+ if x > y:
+ math_pixel += round(y * 0.0043)
+ else:
+ math_pixel += round(x * 0.0043)
+
+ pixel = np.clip(math_pixel, 0, 255).astype(np.uint8)
+
+
+ for y in range(0, self.display_size[0], vingette_compression):
+ for x in range(0, self.display_size[1], vingette_compression):
self.lookup_vingette[v // vingette_compression, y // vingette_compression, x // vingette_compression] = capture[y, x, 2] - v
color_compression = 90
pixel = cv.cvtColor(pixel, cv.COLOR_HSV2BGR)
self.display(pixel)
- capture = self.capture()
+ #capture = self.capture()
+ #capture = cv.cvtColor(capture, cv.COLOR_BGR2HSV)
- capture = cv.cvtColor(capture, cv.COLOR_BGR2HSV)
+ # apply the color ovelay
+ pixel = np.sin(pixel / (127.5 / np.pi)) * 2
+ pixel = np.clip(pixel, 0, 255)
+ capture = cv.resize(pixel, self.display_size, interpolation=cv.INTER_NEAREST_EXACT)
- color = capture[self.window_height // 2, self.window_size // 2]
+ cx = self.display_size[1] // 2
+ cy = self.display_size[0] // 2
+ sample_diameter = 5
+ color = np.average(capture[cy - sample_diameter:cy + sample_diameter, cx - sample_diameter:cx + sample_diameter], axis=(0,1))
- self.lookup_color[h // color_compression, s // color_compression, v // color_compression] = color - [h, s, v]
+ self.lookup_color[h // color_compression, s // color_compression, v // color_compression, 0:2] = color - [h, s, v]
np.save("lookup_vingette", self.lookup_vingette)
np.save("lookup_color", self.lookup_color)
+ def apply_lookup(
+ self,
+ image: np.ndarray
+ ) -> np.ndarray:
+ # must be given an array in the HSV color space
+
+ # apply the vingentte and color lookup table
+ for y, row in enumerate(image):
+ for x, pixel in enumerate(row):
+ pixel[2] += self.lookup_vingette[pixel[2] // self.lookup_compression][y // self.lookup_compression][x // self.lookup_compression]
+ pixel = self.lookup_color[pixel[0] // self.lookup_compression][pixel[1] // self.lookup_compression][pixel[2] // self.lookup_compression]
+
+ return image
+
+ def lookup_debug(
+ self,
+ tests: int
+ ) -> np.ndarray:
+
+ error_array = None
+
+ # begin loop over the desired sample size
+ for i in range(tests):
+ pixel = [[[random.randint(0,255), random.randint(0,255), random.randint(0,255)]]]
+
+ # apply the color ovelay
+ pixel = np.sin(pixel / (127.5 / np.pi)) * 2
+ pixel = np.clip(pixel, 0, 255)
+
+ capture = cv.resize(pixel, self.display_size, interpolation=cv.INTER_NEAREST_EXACT)
+ rows = len(capture)
+ columns = len(capture[0])
+ for y, row in enumerate(capture):
+ for x, pixel in enumerate(y):
+ y -= rows
+ x -= columns
+ distance = np.sqrt((x ^ 2) + (y ^ 2)) * 0.02
+ pixel += distance
+ capture = np.clip(capture, 0, 255)
+
+ returned = self.apply_lookup(capture)
+ self.display(returned)
+
+ if error_array is None:
+ error_array = error
+ error_array = (error_array + error) / 2
+
+ error_array = cv.cvtColor(error_array, cv.COLOR_BGR2HSV)
+ cv.imwrite("error_array.png", error_array)
+
def display(
self,
image: np.ndarray