颜色识别是计算机视觉领域最基础也最实用的技术之一。我在工业质检、医疗影像、智能家居等多个项目中都深度应用过这项技术。简单来说,它能让机器像人眼一样感知并分析颜色信息,但比人眼更精确、更稳定。
这项技术的核心价值在于将模拟世界的颜色信息转化为数字世界可处理的数据。比如在自动化产线上,我们可以通过颜色识别快速检测产品外观是否合格;在医疗领域,可以通过分析皮肤或组织颜色辅助诊断;在智能家居中,可以根据环境颜色自动调节灯光氛围。
RGB是最直观的颜色表示方式,但实际项目中我很少直接使用。HSV/HSL颜色空间更适合颜色识别,因为它将亮度(Value/Lightness)与色相(Hue)、饱和度(Saturation)分离。在OpenCV中,转换代码很简单:
python复制hsv_image = cv2.cvtColor(rgb_image, cv2.COLOR_BGR2HSV)
我通常会先做这个转换,因为:
设定颜色范围是核心难点。新手常犯的错误是直接使用网上找到的HSV范围值,这往往不准。我的经验方法是:
python复制# 示例:检测红色物体
lower_red = np.array([0, 100, 100])
upper_red = np.array([10, 255, 255])
mask = cv2.inRange(hsv_image, lower_red, upper_red)
注意:OpenCV中H范围是0-180(不是0-360),S和V是0-255
在工厂环境中,光照条件变化是最大挑战。我的标准预处理流程:
python复制# 白平衡校正
def white_balance(img):
result = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
avg_a = np.average(result[:, :, 1])
avg_b = np.average(result[:, :, 2])
result[:, :, 1] = result[:, :, 1] - ((avg_a - 128) * (result[:, :, 0] / 255.0) * 1.1)
result[:, :, 2] = result[:, :, 2] - ((avg_b - 128) * (result[:, :, 0] / 255.0) * 1.1)
return cv2.cvtColor(result, cv2.COLOR_LAB2BGR)
当需要同时检测多种颜色时,我的策略是:
python复制# 多颜色检测示例
colors = {
"red": ([0, 100, 100], [10, 255, 255]),
"blue": ([110, 100, 100], [130, 255, 255]),
"green": ([50, 100, 100], [70, 255, 255])
}
for color_name, (lower, upper) in colors.items():
mask = cv2.inRange(hsv_img, np.array(lower), np.array(upper))
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
if cv2.contourArea(cnt) > 500: # 过滤小噪点
x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
cv2.putText(img, color_name, (x,y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0,255,0), 2)
在嵌入式设备上运行时,我常用的优化手段:
python复制# ROI设置示例
roi = frame[100:400, 200:500] # 只处理特定区域
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
经过多个项目验证,这些方法最有效:
python复制cv2.namedWindow('trackbars')
cv2.createTrackbar('H_min', 'trackbars', 0, 179, nothing)
# 类似创建S_min, V_min, H_max等trackbar
python复制hist_h = cv2.calcHist([hsv_img], [0], None, [180], [0, 180])
plt.plot(hist_h)
当需要匹配特定色卡时(如Pantone色),我会使用Delta E算法计算色差:
python复制import numpy as np
from colormath.color_objects import LabColor
from colormath.color_diff import delta_e_cie2000
color1 = LabColor(lab_l=50, lab_a=20, lab_b=30)
color2 = LabColor(lab_l=60, lab_a=20, lab_b=30)
delta_e = delta_e_cie2000(color1, color2)
传统方法在复杂场景下可能失效,这时可以:
python复制model = Sequential([
Conv2D(32, (3,3), activation='relu', input_shape=(64,64,3)),
MaxPooling2D(2,2),
Flatten(),
Dense(128, activation='relu'),
Dense(num_classes, activation='softmax')
])
在实际项目中,我发现结合传统方法和深度学习效果最好 - 先用颜色阈值快速筛选,再用神经网络精细分类。
经过多个项目的验证,这些硬件组合最稳定:
关键点:相机的帧率要和传送带速度匹配,避免运动模糊。我通常使用以下公式计算:
所需帧率 = 传送带速度(mm/s) / 检测精度(mm)
在最近的一个药品包装检测项目中,我遇到了颜色渐变区域的识别难题。传统阈值方法在色相渐变处会产生断裂。最终的解决方案是:
python复制blurred = cv2.GaussianBlur(hsv_img, (15,15), 0)
closed = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((20,20),np.uint8))
另一个教训是关于色差评估的:人眼对蓝色区域的亮度变化更敏感,但对红色区域的色相变化更敏感。因此在不同颜色区间,需要设置不同的容差阈值。