我正在尝试开发一个设备,根据我的显示器的颜色来改变RGB灯带。为此,我计划对屏幕进行截图,并对显示器中各个像素的颜色进行归一化/取平均值。我在对图像进行归一化和取平均值时遇到了麻烦。下面是我使用的代码。
import numpy as np
import cv2
import mss
import time
def getAverageColor(frame):
(B, G, R) = 0, 0, 0
for i in frame:
for j in i:
B += j[0]
G += j[1]
R += j[2]
B /= len(frame) * len(frame[0])
G /= len(frame) * len(frame[0])
R /= len(frame) * len(frame[0])
return (B, G, R)
with mss.mss() as sct:
# Grab frames in an endless lopp until q key is pressed
time.sleep(2)
# Itterate the list of monitors, and grab one frame from each monitor (ignore index 0)
for monitor_number, mon in enumerate(sct.monitors[1:]):
monitor = {"top": mon["top"], "left": mon["left"], "width": mon["width"], "height": mon["height"], "mon": monitor_number} # Not used in the example
# Grab the data
img = np.array(sct.grab(mon)) # BGRA Image (the format BGRA, at leat in Wiqndows 10).
print(getAverageColor(img))
# Show down-scaled image for testing
# The window name is img0, img1... applying different monitors.
cv2.imshow(f'img{monitor_number}', cv2.resize(img, (img.shape[1]//4, img.shape[0]//4)))
key = cv2.waitKey(1)
if key == ord('q'):
break
cv2.destroyAllWindows()
程序运行良好,但我想问一下,是否有任何方法可以去掉openCV本身的平均颜色,因为我的方法不是很好,因为它在处理过程中非常缓慢。不是要添加这个,但代码也不是很准确。
3条答案
按热度按时间sc4hvdpw1#
在Python中,使用列表和
for
循环进行图像处理效率低、速度慢且容易出错。请尝试使用Numpy或矢量化库,如OpenCV、scikit-image、wand或PIL/Pillow。制作一个从石灰绿色到黄色的渐变图像样本,即没有蓝色,纯绿色和红色渐变,这将给我们提供简单、易于检查的方法:
现在使用Numpy获取所有三个通道的平均值:
nnt7mjpx2#
我更新了函数getAverageColor,目的是找到主色。我相信这会提供更好的颜色选择。时间是个问题,我会更新的,以防我能找到一种方法让它更快。
xxhby3vn3#
我想用一个简单的解决方案来回答这个问题。这可能不是这个问题的最佳解决方案,但它对我的用例来说足够快了。如果有人能改进我的解决方案,我将不胜感激。
这取出了所有像素的平均值,并且不像之前定义的解决方案那样,仅返回平均颜色,在90%的情况下,该平均颜色仅是棕色的阴影。