From 7f5828931ff5f8934e65ce9d9ee405ce1962e104 Mon Sep 17 00:00:00 2001 From: will Date: Sun, 18 Aug 2024 17:34:42 +0100 Subject: [PATCH] Fixed camera buffer issue and started on lookup Moved to V4L backend on the VideoCapture - seemed to fix it --- __pycache__/camera.cpython-311.pyc | Bin 11731 -> 15376 bytes camera.py | 116 +++++++++++++++++++++++------ loop.py | 16 ++-- 3 files changed, 102 insertions(+), 30 deletions(-) diff --git a/__pycache__/camera.cpython-311.pyc b/__pycache__/camera.cpython-311.pyc index f24b8e54ef6d950def15e2d6db6ea1c5d8abaa9a..b6d39f2e52b91aa93ef7a8327c0ed19c507f91ee 100644 GIT binary patch delta 7174 zcmb_BZE#apcJD(^PhU@8mMq(VKQIPl48(w!K-hpGd<6nA#z4FziqMm78Cw=l&%}15 z>ap>*Ce^kgmz{`)oqF3OOEzRnC)t_KY}47aP0PRNrEg|EZ|aWoBh%)eXu{5P+U@q7 zCtH?m$aJQC@;mR|dp_=Y=bdxzx!3>nz1)QJr-ERk;M%zUZwD5dZaC}cOE)&PSwu>t zN6h`^8z<}6@C3;T$i2%@)cbIku71l6vw(TFE_HAZuE!j7XDCTMfBoYQiC!BY#7$A3tR?5`g+rbt`4ly5 zU23POVdE{Zf0un1W`4gsdzuwZDK=y;)3W4~wY6lc+es44CYzu$k*ksku;d<-+-A~E z$>_*{ZWW_fW07bmChGj9aO83{F6wqE8WuzH5I&N~(M*oAXB#chN?r$`P+z*eH(j&V zJG)i)PR+ej*)Y9@m>3;96i&$FQgj=#MI|5koLkuLM?N~N)0dJgG@F~7rFwWu_=;2RDz;=)ZYE!t z1F?~4GGal;rQ_tPb>@pOpIhXr6srZr>d3e~Krf>C zRp>)>fIPH6xf5sA`9s~$htBOfDWU5b?xEM<(DP?bKOZ{ScjU<7Grh^dOe6slND_6j>~A24@qr4S%V zq3~g=%WR@|llGebq%V_=zMC6*fCIe!3_PS>06Kd)v18Ghm69{}k$>?8%_B&0jtKq> zw2ch-Uw7?8YAzwg;&RXfp8Pw1twX0nIv*(o3Tdhh(!Jz(ZIk&d^7fN>?NjuL4}Vts z8@g3DOHqiX_^C)aI{*zD2jl4Lc6cSy?F#TTxH6Nb$>}u#^6z!^n?(-et8}I4DM($S zX$rdV;gQj}L{mLQ*3`E`9@}A2@+zlq$jvh;b4c=2#4EWiNE5%m6iR@k)2Sv)- z-sRr~1>Y|#nKsGmh-z)vmgeMj%M2+~rLk6IVzb9v$Zx;Jx7|&-pc;G z+CeHmOr>R0bhS`0)uA;1Exh2KOIMlq#l;a|-jKGYOkiWHXc=HDNSP@J4^X1)zbU2^ z0YGa+0vOVG4zL)S*|zL6IXe5PXiM8Me74$C_T_jH*>CAN225a+KxT!LS7pVrH)8CF zAbX_|Ae8#kj%qXDtdF33CM`UQ4pQB+lRra&z-<_tB-7?+9Vy}eFBVZK}vN~krn=rL0;v56+To7y-XSxzj98fbkGt(8W!ZV zyDGIo^p-C0H&@DS_!mB5@CQuFxj2GPV`P9?_D0cl*IkuaV^rFc@}%Iqq?kc=(N)Wf zD2yA<2iVe+S#&>0BtKvVOz5!StWUsw1n!GfYSxvM1V{6r`x`6o%dLWIdE5)*KH_Oy zm#H~*RyqOnU;Pe%bOZq=p&$)ahdh~xzDMf4OjgOB;rLY{;&EX`fsB=Kx`5m2;#>S!4 zHAO~Z31bGGO~&FnlZfej_$sgrMxjE6R?rKp?^lf*GI11WlEz+1!Xi92GCmql>NFIz zFrw2Fx@|Np4}}u3iRg�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 diff --git a/camera.py b/camera.py index 9c660ef..62efb3f 100644 --- a/camera.py +++ b/camera.py @@ -2,11 +2,12 @@ import cv2 as cv 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) @@ -42,7 +43,8 @@ class camera(): 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 @@ -52,7 +54,7 @@ class camera(): 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) @@ -70,14 +72,6 @@ class camera(): 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 ): @@ -122,14 +116,14 @@ class camera(): ) -> 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): @@ -137,12 +131,29 @@ class camera(): 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 @@ -161,17 +172,74 @@ class camera(): 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 diff --git a/loop.py b/loop.py index b61302d..227c078 100644 --- a/loop.py +++ b/loop.py @@ -38,15 +38,19 @@ camera = camera( window_size, window_height, (1840, 1000), - device_id=2, - debug=True, - dummy=False + device_id = 0, + debug = True, + dummy = False, + use_files = False ) + camera.calibrate() -#camera.get_lookup() -#print(camera.lookup_vingette) -#print(camera.lookup_color) +# camera.get_lookup() +# print(camera.lookup_vingette) +# print(camera.lookup_color) +# lookup_debug(100) +# quit() transform = fft(window_size, hop_size) -- 2.39.2