使用OpenCV和Python提取视频帧指定区域主色实现魔方扫描的问题求解
核心错误点
- 通道顺序不匹配
OpenCV读取的视频帧默认是BGR通道顺序,而PIL的Image.fromarray方法按RGB顺序解析图像,未做转换直接传入会导致红蓝通道完全颠倒,识别红色面时R通道数值不会偏高,反而B通道数值更高。 - 引导框像素干扰
绘制的蓝色引导框宽度为2像素,当前裁剪的ROI区域包含框的边缘,蓝色像素混入主色统计,进一步干扰识别结果。 - ROI裁剪逻辑冗余
通过坐标相加计算ROI结束位置的方式容易出错,建议直接使用预先定义的矩形上下边坐标裁剪。
修复方案
1. 补充通道转换逻辑
修改get_dominant_color函数,首先将传入的BGR图像转为RGB格式:
def get_dominant_color(pil_img, palette_size=6): # 转换OpenCV的BGR格式为PIL所需的RGB格式 img = cv2.cvtColor(pil_img.copy(), cv2.COLOR_BGR2RGB) image = Image.fromarray(img) # 后续逻辑保持不变 paletted = image.convert('P', palette=Image.ADAPTIVE, colors=palette_size) palette = paletted.getpalette() color_counts = sorted(paletted.getcolors(), reverse=True) palette_index = color_counts[0][1] dominant_color = palette[palette_index*3:palette_index*3+3] # 若需要返回BGR格式与OpenCV逻辑对齐,可返回dominant_color[::-1] return dominant_color
2. 修正ROI裁剪规则
裁剪时向内缩进2像素,避开蓝色引导框像素,以第一个方格为例:
# 原裁剪逻辑 # rect1_img = frame[r1_1[1]: r1_1[1] + r1_1[0],r1_1[0]:r1_1[0] + r1_1[1]] # 修正后 rect1_img = frame[r1_1[1]+2 : r1_1[3]-2, r1_1[0]+2 : r1_1[2]-2]
其余8个方格的裁剪逻辑均按此规则修改即可。
可选优化
裁剪ROI后添加高斯模糊去除噪点,提升主色提取稳定性:
rect1_img = cv2.GaussianBlur(rect1_img, (3,3), 0)
内容的提问来源于stack exchange,提问作者Pratik Hadawale
相关产品推荐
相关产品推荐

