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

在OpenCV中如何可靠将颜色分类为红、黄或「其他」?机器人项目场景

红黄色调区分方案(暗淡色归为「其他」)

方案1:RGB分量阈值+亮度过滤(轻量直接)

针对已提取的圆圈平均RGB值,直接通过分量对比+亮度筛选分类,无需复杂颜色空间转换:

  • 亮度计算:用加权公式 Y = 0.299*R + 0.587*G + 0.114*B,先过滤掉Y < 60(可根据实际样本调整阈值)的暗淡色,直接归为「其他」
  • 红色判断:满足 R > G*1.5 且 R > B*1.5,同时亮度达标
  • 黄色判断:满足 abs(R - G) < 30 且 R > B*2 且 G > B*2,同时亮度达标
  • 其余情况归为「其他」

示例代码:

def classify_color(r, g, b):
    # 计算亮度
    brightness = 0.299 * r + 0.587 * g + 0.114 * b
    if brightness < 60:
        return "其他"
    # 判断红色
    if r > g * 1.5 and r > b * 1.5:
        return "红色"
    # 判断黄色
    if abs(r - g) < 30 and r > b * 2 and g > b * 2:
        return "黄色"
    return "其他"

方案2:校准版LAB距离匹配(解决标准值偏差问题)

之前用标准LAB值效果差,核心是实际涂色和标准色存在偏差,改用实际样本校准:

  1. 从输入图像中手动挑选10-20个明确的红色、黄色圆圈,提取它们的平均LAB值,分别计算红、黄的LAB平均值(记为lab_red_avg、lab_yellow_avg)
  2. 计算待分类颜色的LAB值与两个平均值的欧氏距离:dist_red = sqrt((L-Lr)^2 + (A-Ar)^2 + (B-Br)^2),同理dist_yellow
  3. 结合亮度过滤和距离阈值(比如红色阈值40、黄色阈值35,根据样本聚类调整)分类:
    • 亮度达标且dist_red < 阈值_red → 红色
    • 亮度达标且dist_yellow < 阈值_yellow → 黄色
    • 其余归为「其他」

示例代码:

import math
import cv2
import numpy as np

# 替换为你的实际样本校准平均值
lab_red_avg = np.array([50, 70, 20])
lab_yellow_avg = np.array([75, 10, 70])
brightness_thresh = 60
red_dist_thresh = 40
yellow_dist_thresh = 35

def classify_lab(r, g, b):
    # RGB转LAB
    rgb = np.uint8([[[r, g, b]]])
    lab = cv2.cvtColor(rgb, cv2.COLOR_RGB2LAB)[0][0]
    # 亮度过滤
    brightness = 0.299 * r + 0.587 * g + 0.114 * b
    if brightness < brightness_thresh:
        return "其他"
    # 计算距离
    dist_red = math.sqrt(sum((lab - lab_red_avg)**2))
    dist_yellow = math.sqrt(sum((lab - lab_yellow_avg)**2))
    if dist_red < red_dist_thresh and dist_red < dist_yellow:
        return "红色"
    elif dist_yellow < yellow_dist_thresh:
        return "黄色"
    return "其他"

方案3:轻量机器学习分类(稳定适配复杂色调)

如果前两种方案仍有偏差,用极小的机器学习模型适配,适合嵌入式/机器人场景:

  1. 收集标注数据:提取至少50个样本(红、黄、其他各若干)的平均RGB/LAB值,标注对应类别
  2. 用scikit-learn训练逻辑回归或SVM模型(仅3维特征,训练极快)
  3. 导出轻量模型(如joblib格式),部署到机器人端直接预测

示例训练代码:

from sklearn.linear_model import LogisticRegression
import joblib
import numpy as np

# 替换为你的实际标注数据集
# X:RGB特征数组,y:标签(0=其他,1=红色,2=黄色)
X = np.array([[200, 50, 50], [220, 200, 50], [80, 80, 80], ...])
y = np.array([1, 2, 0, ...])

# 训练并保存模型
model = LogisticRegression()
model.fit(X, y)
joblib.dump(model, "color_classifier.pkl")

# 预测函数
def classify_ml(r, g, b):
    pred = model.predict([[r, g, b]])
    return ["其他", "红色", "黄色"][pred[0]]

额外优化建议

  • 对提取的圆圈区域先做中值滤波去噪,再计算平均颜色,避免噪点干扰结果
  • 亮度阈值可根据木板实际光照动态调整,比如取图像整体平均亮度的0.3倍

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 14:47:17