You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用OpenCV Python实时提取视频中未知范围的主导色

实时提取视频主导色并可视化的解决方案

核心思路

不用固定颜色检测或手动设置HSV范围,改用K-Means聚类算法自动从视频帧的像素中分组出占比最高的颜色。聚类能根据当前帧的像素分布自动识别主导色,完全适配未知颜色范围的视频。

原代码的问题

  • 循环内重复创建VideoCapture实例,会导致资源浪费且无法正常读取帧
  • 冗余读取本地图片taxi.jpeg,对视频处理无意义
  • 仅计算单通道(B通道)的直方图,无法获取多通道的整体主导色
  • 直接用cv.imshow显示plt对象是错误用法,两者渲染逻辑不兼容

完整实现代码

import cv2 as cv
import numpy as np
from sklearn.cluster import KMeans
from collections import Counter

# 设置参数:要提取的主导色数量
TOP_COLORS = 3  # 可改为6或其他数字

def get_dominant_colors(frame, num_colors):
    # 将BGR转RGB,并扁平化像素数据
    rgb_frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
    pixels = rgb_frame.reshape(-1, 3)
    
    # K-Means聚类
    kmeans = KMeans(n_clusters=num_colors)
    labels = kmeans.fit_predict(pixels)
    
    # 计算每个颜色的占比
    color_counts = Counter(labels)
    total_pixels = len(pixels)
    color_info = []
    for label, count in color_counts.items():
        color = kmeans.cluster_centers_[label].astype(int)
        percentage = (count / total_pixels) * 100
        color_info.append((color, percentage))
    
    # 按占比从高到低排序
    color_info.sort(key=lambda x: x[1], reverse=True)
    return color_info

def plot_color_blocks(color_info):
    # 创建颜色块画布
    block_width = 100
    block_height = 300
    canvas = np.zeros((block_height, len(color_info)*block_width, 3), dtype=np.uint8)
    
    for i, (color, percentage) in enumerate(color_info):
        start_x = i * block_width
        canvas[:, start_x:start_x+block_width] = color[::-1]  # RGB转回BGR给OpenCV显示
        # 添加占比文字
        cv.putText(canvas, f"{percentage:.1f}%", 
                   (start_x + 10, block_height//2), 
                   cv.FONT_HERSHEY_SIMPLEX, 0.6, (255,255,255), 2)
    return canvas

# 初始化视频捕获:0为摄像头,替换为视频路径则读取本地视频
vid = cv.VideoCapture(0)

while True:
    ret, frame = vid.read()
    if not ret:
        break  # 视频结束或读取失败
    
    # 获取主导色
    dominant_colors = get_dominant_colors(frame, TOP_COLORS)
    
    # 生成颜色块显示图
    color_canvas = plot_color_blocks(dominant_colors)
    
    # 显示原视频和颜色块
    cv.imshow("Original Video", frame)
    cv.imshow("Dominant Colors", color_canvas)
    
    # 按q退出
    if cv.waitKey(1) & 0xFF == ord('q'):
        break

# 释放资源
vid.release()
cv.destroyAllWindows()

代码说明

  • get_dominant_colors函数:负责将帧像素扁平化,用K-Means聚类得到指定数量的主导色,并计算每个颜色的占比
  • plot_color_blocks函数:生成包含颜色块和占比文字的画布,方便和视频同步显示
  • 支持切换摄像头/本地视频:把cv.VideoCapture(0)的参数换成视频文件路径即可
  • 可调整TOP_COLORS变量来提取前N种主导色

注意事项

  • 需要提前安装依赖:pip install opencv-python scikit-learn numpy
  • 若实时性要求高,可适当降低视频分辨率(比如用cv.resize缩小帧),减少K-Means的计算量

内容的提问来源于stack exchange,提问作者plus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 11:46:08