python-telemetrix-ambilight/ambilight_mulitprocessing.py

128 lines
4.1 KiB
Python
Raw Permalink Normal View History

2022-04-01 10:39:15 +00:00
import multiprocessing
2022-03-30 04:10:28 +00:00
from tkinter import TOP
import pyautogui
import scipy.cluster as cluster
import sys
import numpy as np
from time import sleep, time
import numpy
import signal
import atexit
from time import perf_counter as timestamp
from telemetrix_rpi_pico import telemetrix_rpi_pico
from multiprocessing import Pool
import PIL.ImageGrab
2022-03-30 13:15:41 +00:00
from PIL import Image
import colorsys
2022-03-31 05:29:41 +00:00
from scipy.stats import mode
2022-03-30 13:15:41 +00:00
import win32gui, win32ui, win32con
2022-03-30 17:43:46 +00:00
2022-03-31 05:29:41 +00:00
BOARDER_SIZE = 300
2022-03-30 17:43:46 +00:00
TOP_LEDS = 19
RIGHT_LEDS = 11
BUTTOM_LEDS = 19
LEFT_LEDS = 11
MIN_TIME = 0.05
2022-03-31 05:29:41 +00:00
METHOD = 'MEDIAN' #MEAN/MEDIAN/MODE/CLUSTER_MEAN, WARNING: CLUSTER_MEAN might burn down your house.
2022-03-30 17:43:46 +00:00
SATURATION_BOOST_FACTOR = 2
NUM_CLUSTERS = 3
2022-04-01 10:39:15 +00:00
KMEAN_QUALITY = 50
NUM_THREADS = 8
2022-03-30 17:43:46 +00:00
if __name__ == '__main__':
board = telemetrix_rpi_pico.TelemetrixRpiPico()
2022-03-31 05:29:41 +00:00
def sigint_handler(signal=None, frame=None):
if __name__ == '__main__':
print ('KeyboardInterrupt is caught')
board.neopixel_clear()
sleep(0.75)
board.shutdown()
exit()
2022-03-30 04:10:28 +00:00
class size:
width = None
height = None
2022-03-30 13:15:41 +00:00
def get_screenshot():
return PIL.ImageGrab.grab()
2022-03-30 17:43:46 +00:00
2022-03-30 04:10:28 +00:00
def find_dorminant_color(im):
2022-03-31 05:29:41 +00:00
color = numpy.reshape(numpy.asarray(im),(-1,3))
if METHOD == 'MODE':
color = mode(color,axis=0).mode[0]
elif METHOD == 'MEDIAN':
color = np.median(color,axis=0)
elif METHOD == 'MEAN':
color = np.mean(color,axis=0)
elif METHOD == 'CLUSTER_MEAN':
2022-03-30 17:43:46 +00:00
im = im.resize((KMEAN_QUALITY, KMEAN_QUALITY))
2022-03-30 04:10:28 +00:00
ar = np.asarray(im)
shape = ar.shape
ar = ar.reshape(np.product(shape[:2]), shape[2]).astype(float)
codes, dist = cluster.vq.kmeans(ar, NUM_CLUSTERS)
vecs, dist = cluster.vq.vq(ar, codes)
counts, bins = np.histogram(vecs, len(codes))
index_max = np.argmax(counts)
2022-03-31 05:29:41 +00:00
color = codes[index_max]
h,s,v = colorsys.rgb_to_hsv(r=color[0]/255,g=color[1]/255,b=color[2]/255)
s = min(1,s*SATURATION_BOOST_FACTOR)
r,g,b = colorsys.hsv_to_rgb(h=h,s=s,v=v)
return [r*255,g*255,b*255]
2022-03-30 04:10:28 +00:00
if __name__ == '__main__':
2022-03-30 13:15:41 +00:00
size = size()
size.width=pyautogui.size().width
size.height=pyautogui.size().height
2022-03-30 04:10:28 +00:00
signal.signal(signal.SIGINT, sigint_handler)
atexit.register(sigint_handler)
2022-03-30 13:15:41 +00:00
2022-03-30 04:10:28 +00:00
NUM_LEDS = TOP_LEDS+RIGHT_LEDS+BUTTOM_LEDS+LEFT_LEDS
board.set_pin_mode_neopixel(pin_number=2,num_pixels=NUM_LEDS)
board.neopixel_clear(auto_show=True)
board.neopixel_show()
screenshot = pyautogui.screenshot()
2022-03-30 17:43:46 +00:00
pool = Pool(NUM_THREADS)
2022-03-30 13:15:41 +00:00
2022-03-30 04:10:28 +00:00
while True:
try:
2022-03-30 13:15:41 +00:00
screenshot = get_screenshot()
2022-03-30 04:10:28 +00:00
lastTime = timestamp()
chunk = []
top = screenshot.crop(box=[0,0,size.width,BOARDER_SIZE])
left = screenshot.crop(box=[0,0,BOARDER_SIZE,size.height])
buttom = screenshot.crop(box=[0,size.height-BOARDER_SIZE,size.width,size.height])
right = screenshot.crop(box=[size.width-BOARDER_SIZE,0,size.width,size.height])
for i in range(0,TOP_LEDS):
segment = top.crop(box=[i*size.width/TOP_LEDS,0,(i+1)*size.width/TOP_LEDS,BOARDER_SIZE])
2022-03-30 04:44:23 +00:00
chunk.append(segment)
for i in range(0,RIGHT_LEDS):
segment = right.crop(box=[0,i*size.height/RIGHT_LEDS,BOARDER_SIZE,(i+1)*size.height/RIGHT_LEDS])
chunk.append(segment)
2022-03-30 04:10:28 +00:00
2022-03-30 04:44:23 +00:00
for i in reversed(range(0,BUTTOM_LEDS)):
segment = buttom.crop(box=[i*size.width/BUTTOM_LEDS,0,(i+1)*size.width/BUTTOM_LEDS,BOARDER_SIZE])
chunk.append(segment)
for i in reversed(range(0,LEFT_LEDS)):
2022-03-30 04:10:28 +00:00
segment = left.crop(box=[0,i*size.height/LEFT_LEDS,BOARDER_SIZE,(i+1)*size.height/LEFT_LEDS])
2022-03-30 04:44:23 +00:00
chunk.append(segment)
2022-03-30 04:10:28 +00:00
colors = pool.map(find_dorminant_color,chunk)
for i in range(0,len(colors)):
board.neo_pixel_set_value(i,r=int(colors[i][0]),g=int(colors[i][1]),b=int(colors[i][2]))
board.neopixel_show()
2022-03-30 13:15:41 +00:00
while timestamp()-lastTime < MIN_TIME:
sleep(0.001)
print("loop time : "+str(timestamp()-lastTime))
2022-03-30 04:10:28 +00:00
except Exception as e:
2022-03-31 05:29:41 +00:00
print(e)
2022-03-30 04:10:28 +00:00
print("Retrying")