1. 图像样本

首先来看一下图像样本,这是铜片:

基于HSV空间下颜色识别的简单图像分类-萤火
基于HSV空间下颜色识别的简单图像分类-萤火

这是铝片:

基于HSV空间下颜色识别的简单图像分类-萤火
基于HSV空间下颜色识别的简单图像分类-萤火

2. 分析及思路

可以看出,不光在红光还是白光下,铜片都呈现橙黄色,而铝片在白光下呈现白色,在红光下呈现红色。因此可以通过将图像转换到HSV空间,然后提取出橙色和黄色区域,计算该区域面积,如果大于设定阈值,就是铜片,否则为铝片。

3. HSV

色调(H),饱和度(S),明度(V)。 常用于选取颜色或图像编辑。

基于HSV空间下颜色识别的简单图像分类-萤火

一般对颜色空间的图像进行有效处理都是在HSV空间进行的,然后对于基本色中对应的HSV分量需要给定一个严格的范围,下面是通过实验计算的模糊范围:

  • H:0 – 180
  • S:0 – 255
  • V:0 – 255
基于HSV空间下颜色识别的简单图像分类-萤火
此处将部分红色归为紫色范围

4. 代码实现

此处为了方便演示,使用了halcon

dev_get_window (WindowHandle)
set_display_font (WindowHandle, 22, 'mono', 'true', 'false')
threshold := 100000

* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('Image', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
    read_image (Image, ImageFiles[Index])
    * Image Acquisition 01: Do something
    
    decompose3 (Image, R, G, B)
    trans_from_rgb (R, G, B, H, S, V, 'hsv')
    
    *筛选橙色和黄色
    *将H空间拉伸至[0,180]
    scale_image_range (H, H, [0,0], [255,180])
    *H筛选
    threshold (H, Region1, 11, 34)
    reduce_domain (Image, Region1, ImageReduced1)
    *S筛选
    threshold (S, Region1, 43, 255)
    reduce_domain (ImageReduced1, Region1, ImageReduced2)
    *V筛选
    threshold (V, Region1, 46, 255)
    reduce_domain (ImageReduced2, Region1, ImageReduced3)
    area_center (ImageReduced3, Area, Row, Column)
    
    if (Area > threshold)
        dev_set_color ('orange')
        Polarity := '铜'
    else
        dev_set_color ('white')
        Polarity := '铝'
    endif
    
    dev_display (Image)
    
    write_string (WindowHandle, Polarity)
    stop ()
endfor

5. 效果

下面展示一下在各图中提取出来的橙黄色区域:

基于HSV空间下颜色识别的简单图像分类-萤火
基于HSV空间下颜色识别的简单图像分类-萤火
基于HSV空间下颜色识别的简单图像分类-萤火
基于HSV空间下颜色识别的简单图像分类-萤火

可以看到铜片的橙黄色区域面积很大,铝片的很小,只需要加一个简单的面积阈值判断即可实现分类。