1,基于HSV分量的颜色识别。
1.1,HSV概述。
HSV(Hue, Saturation, Value)是一种广泛应用于图像处理的颜色模型,其通过色相、饱和度和明度三个维度描述颜色特性,相比RGB模型更符合人类对颜色的直观感知。以下是HSV在图像处理中的核心要点:
一、HSV模型的构成
-
色相(Hue)
- 表示颜色类型,以角度度量,范围通常为 0°~360°(如OpenCV中缩放到 0~179)。
- 红色对应0°(或180°),绿色120°,蓝色240°,补色间隔180°。
-
饱和度(Saturation)
- 表示颜色纯度,范围 0%~100%(或 0~255),值越高颜色越鲜艳,0%时为灰度。
-
明度(Value)
- 表示颜色亮度,范围 0%~100%(或 0~255),0%为纯黑,100%为最亮颜色。
二、HSV在图像处理中的优势
-
颜色分离特性
- H、S、V分量独立,便于单独调整颜色属性。例如:通过H通道提取特定颜色(如红色物体),或通过S通道增强/减弱色彩鲜艳度。
-
直观的色彩调整
- 用户可通过调整饱和度(S)控制颜色鲜艳程度,或通过明度(V)模拟光照变化,无需直接操作RGB三通道。
-
适应复杂场景
- 在目标检测、图像分割等任务中,HSV可有效分离亮度与颜色信息,减少光照变化对算法的影响。
三、RGB与HSV的转换
-
转换逻辑
- RGB→HSV:基于RGB分量的最大值(V)、色相角(H)和饱和度(S)计算。例如:当R为最大值时,H = 60°×((G-B)/(max-min)),并修正为0~360°范围。
- HSV→RGB:根据H所在的色相区间(每60°为一个区间),分段计算RGB分量。
-
应用示例
- 在OpenCV中,常用
cv2.cvtColor()
函数实现RGB与HSV的转换,需注意数值范围调整(如H在OpenCV中为0~179)。
- 在OpenCV中,常用
四、典型应用场景
-
颜色检测与分割
- 通过设定H的阈值范围(如绿色H∈[35°,85°]),结合S和V过滤背景,实现植物叶片或交通标志的检测。
-
图像增强
- 提升低饱和度图像的色彩表现:增大S值使颜色更鲜艳,或调整V值改善过曝/欠曝区域。
-
渐变效果生成
- 在HSV空间中,通过线性插值H值可生成平滑的渐变色(如彩虹效果),优于RGB空间的直接混合。
五、注意事项
- 数值范围差异:不同编程库对HSV的取值范围定义可能不同(如H在理论模型为0~360°,而OpenCV中为0~179),需按实际工具调整参数。
- 颜色域限制:HSV仅覆盖CIE色度图的子集,某些高纯度颜色无法完全表示。
六、HSV效果。
使用绘图工具,可查看HSV效果。
1.2,应用实例。
参考案例:Halcon实例库->应用范围->颜色检测->color_fuses.hdev
dev_close_window ()
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
dev_set_line_width (2)
dev_update_window ('off')
fusesColor:=['orange','red','blue','yellow','green']
*根据网上查询的各颜色对应HSV的H(色调)值
* HueRanges := [10,30,0,10,125,162,30,64,96,128]
hueRange:=[11,25,0,11,127,149,34,81,83,126]
fusesType:=[10,15,20,25,5]
for Index := 0 to 4 by 1
read_image (Image, 'color/color_fuses_'+Index$'02')
dev_display (Image)
decompose3 (Image, ImageR, ImageG, ImageB)
trans_from_rgb (ImageR, ImageG, ImageB, ImageH, ImageS, ImageV, 'hsv')
*从饱和度分量S进行阈值分割获取数量
threshold (ImageS, Regions, 86, 255)
connection (Regions, Connection)
opening_rectangle1 (Connection, RegionOpening, 5, 5)
fill_up ( RegionOpening, RegionFillUp)
select_shape (RegionFillUp, SelectedRegions, 'area', 'and', 1045.87, 20000)
*计算fuses总量
count_obj (SelectedRegions, fusesTotal)
shape_trans (SelectedRegions, RegionTrans1, 'convex')
union1 (RegionTrans1, RegionUnion)
*根据不同颜色对应的H值(色调值)不同进行区分
reduce_domain (ImageH, RegionUnion, ImageReduced)
for i := 0 to |fusesColor|-1 by 1
threshold (ImageReduced, Region, hueRange[i*2],hueRange[i*2+1])
connection (Region, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions1, 'area', 'and', 4000, 99999)
shape_trans (SelectedRegions1, RegionTrans, 'convex')
*计算中心位置,并计算出数量
area_center (RegionTrans, Area, Row, Column)
*进行颜色规格标注
for k := 0 to |Row|-1 by 1
dev_set_color (fusesColor[i])
gen_contour_region_xld (RegionTrans, Contours, 'border')
dev_display (Contours)
set_display_font (WindowHandle, 12, 'mono', 'true', 'false')
str:= fusesColor[i]+' '+fusesType[i]$'02'+'A'
get_string_extents (WindowHandle, str, Ascent, Descent, Width, Height)
* set_tposition (WindowHandle, Row[k]- Height/2, Column[k]-Width/2)
* write_string (WindowHandle,str)
disp_message (WindowHandle, str, 'image', round(Row[k]- Height/2),round( Column[k]-Width/2), fusesColor[i], 'false')
endfor
dev_set_color (fusesColor[i])
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
set_tposition (WindowHandle, 30*i, 20)
write_string (WindowHandle, fusesColor[i]$'-6'+':'+|Row|$'02'+' PCS')
endfor
*总数
dev_set_colored (12)
set_tposition (WindowHandle, 30*i, 20)
write_string (WindowHandle, 'Total '+':'+fusesTotal$'02'+' PCS')
stop ()
endfor
2,基于训练分类器的颜色识别。
参考:Halcon实例库->应用范围->颜色检测->color_pieces.hdev
*使用颜色分类器训练查找
dev_close_window ()
read_image (Image, 'color/color_pieces_00')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_set_draw ('margin')
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
Regions := ['yellow','pink','blue','background']
Highlight := ['goldenrod','magenta','cyan']
*框选需要进行查找的颜色,这里是3个目标色加上1个背景色
gen_empty_obj (classis)
for Index := 0 to 3 by 1
dev_display (Image)
dev_display (classis)
disp_message (WindowHandle, '框选目标色(注意框选区切勿混有其他颜色):'+Regions[Index], 'window', 12, 12, 'black', 'false')
draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
concat_obj (classis, Rectangle, classis)
endfor
*创建颜色分类器
*参数:NumOutput:需要查找的颜色的数量,
*这里需要查找['yellow','pink','blue','background']四种颜色,所以这里设置为4
create_class_mlp (3, 10, 4, 'softmax', 'normalization', 10, 42, MLPHandle)
*进行训练
add_samples_image_class_mlp (Image, classis, MLPHandle)
train_class_mlp (MLPHandle, 200, 1, 0.01, Error, ErrorLog)
*进行颜色查找
for i := 0 to 3 by 1
read_image (Image, 'color/color_pieces_'+i$'02')
dev_display (Image)
classify_image_class_mlp (Image, ClassRegions, MLPHandle, 0.5)
*查找的结果为:每一种颜色为一个区域,区域顺序与创建分类器时的颜色区域一致
count_obj (ClassRegions, Number)
*遍历颜色区域
for k := 1 to Number-1 by 1
copy_obj (ClassRegions, ObjectsSelected, k, 1)
*一个颜色区域可能分解为多个区域(即一个颜色区域可能包含多个该颜色的目标)
erosion_circle (ObjectsSelected, RegionErosion, 1.5)
connection (RegionErosion, ConnectedRegions)
dilation_circle (ConnectedRegions, RegionDilation, 1.5)
select_shape (RegionDilation, SelectedRegions, 'area', 'and', 1000, 99999)
*颜色区域拆解出来的区域,通过这些区域计算每种颜色的数量
count_obj (SelectedRegions, Number1)
if(k<|Highlight|+1)
dev_set_color (Highlight[k-1])
endif
dev_display (SelectedRegions)
dev_set_color ('black')
set_tposition (WindowHandle, 20+(k-1)*30, 20)
write_string (WindowHandle, Regions[k-1]$'-10'+':'+Number1)
endfor
stop ()
endfor
clear_class_mlp (MLPHandle)