如何用OpenCV快速准确获取屏幕截图的平均颜色?
优化屏幕平均颜色计算(适配RGB灯带)
你的嵌套循环遍历像素的方式效率极低,Python层面的循环在处理高分辨率屏幕时会非常慢,而且手动计算容易出现精度偏差。OpenCV和Numpy提供了原生的优化方法,能大幅提升速度并保证精度:
方法1:使用OpenCV内置的cv2.mean()
cv2.mean()是专门用于计算图像各通道均值的函数,底层由C++实现,速度远快于Python循环。它会直接返回每个通道的平均值,对于你的BGRA格式截图,只需要取前三个通道(B、G、R)即可。
方法2:使用Numpy向量化操作
Numpy的向量化计算同样基于底层优化,通过mean()方法指定轴参数,可以一次性计算所有像素的通道均值,代码简洁且高效。
修改后的完整代码
以下是替换了平均颜色计算逻辑的代码,这里用cv2.mean()为例:
import numpy as np import cv2 import mss import time def getAverageColor(frame): # 计算BGRA四个通道的均值,取前三个B、G、R通道 mean_vals = cv2.mean(frame) return (mean_vals[0], mean_vals[1], mean_vals[2]) with mss.mss() as sct: time.sleep(2) # 遍历所有显示器(跳过索引0的虚拟主显示器) for monitor_number, mon in enumerate(sct.monitors[1:]): # 抓取屏幕画面,转为BGRA格式的numpy数组 img = np.array(sct.grab(mon)) # 获取平均颜色 print(getAverageColor(img)) # 显示缩小后的测试画面 cv2.imshow(f'img{monitor_number}', cv2.resize(img, (img.shape[1]//4, img.shape[0]//4))) # 按q退出 if cv2.waitKey(1) == ord('q'): break cv2.destroyAllWindows()
如果想用Numpy的方式,只需要把getAverageColor改成:
def getAverageColor(frame): # 沿(0,1)轴计算均值,即对所有行和列的像素求平均 b_mean, g_mean, r_mean, a_mean = frame.mean(axis=(0,1)) return (b_mean, g_mean, r_mean)
额外优化建议
如果追求更快的速度,可以先对截图进行降采样(比如缩小到100x100的小图)再计算均值,这样既不会明显影响颜色准确性,又能进一步减少计算量,特别适合高分辨率屏幕的实时处理:
# 在抓取图像后添加降采样 small_img = cv2.resize(img, (100, 100), interpolation=cv2.INTER_AREA) print(getAverageColor(small_img))
内容的提问来源于stack exchange,提问作者code-wolf-byte
相关产品推荐
相关产品推荐

