Halcon分类器之高斯混合模型分类器

博主对Halcon自带分类器例子classify_metal_parts.hdev按自己理解重写,将示例中的MLP分类器改为GMM分类器,希望帮助刚入门同学学习理解,还给出了HDevelop代码及所用图片路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Halcon分类器示例自我理解
看了很多网上的例子,总有一种纸上得来终觉浅,绝知此事要躬行的感觉。说干就干,将Halcon自带分类器例子classify_metal_parts.hdev按照自己的理解重新写一遍,示例中的分类器是MLP(多层感知机),我将它改变为GMM(高斯混合模型)。希望可以帮助刚入门的同学学习理解,大神请绕路吧,当然也喜欢各位看官帮我找出不足之处,共同进步。谢谢!
分类效果如图:
在这里插入图片描述
下面是HDevelop代码,图片请自己寻找,是Halcon自带图片,*代码所用图片路径:C:/Users/Public/Documents/MVTec/HALCON-12.0/examples/images/rings
#====================================================#

dev_close_window ()
dev_open_window (0, 0, 640, 480, 'black', WindowHandle)
*创建分类器(高斯混合模型)(依据6个特征分三类,每个分类的类的中心)
create_class_gmm (6, 3, 2, 'spherical', 'normalization', 10, 42, GMMHandle)
*定义要分类的类别
Class:=[0,1,2]
*添加样本1
list_files ('C:/Users/yanzhenwu/Desktop/TestPic/1', ['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])
    threshold (Image, Regions, 0,100)
    connection (Regions, ConnectedRegions)
    count_obj (ConnectedRegions, Number)
    for I := 1 to Number by 1
        Features:=[]
        select_obj (ConnectedRegions, ObjectSelected, I)
        *Region紧凑度
        roundness (ObjectSelected, Distance, Sigma, Roundness, Sides)
        *Region圆度
        circularity (ObjectSelected, Circularity)
        *图像高阶矩(可表示出Region的方向和大小特征,具体不是很懂)
        moments_region_central_invar (ObjectSelected, PSI1, PSI2, PSI3, PSI4)
        *将这些特征添加到元祖中,作为一个特征向量给训练用
        Features:=real([Roundness,Circularity,PSI1, PSI2, PSI3, PSI4])
        *添加训练样本:这里的Features一定要和创建的分类器中规定的特征维度一样
        add_sample_class_gmm (GMMHandle,  Features, Class[0], 0)
    endfor
    disp_message (3600, '添加样本一第'+int(Index+1)+'张图像', 'window', 12, 12, 'black', 'true')
    stop ()
endfor

*添加样本2
list_files ('C:/Users/yanzhenwu/Desktop/TestPic/2', ['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])
    threshold (Image, Regions, 0,100)
    connection (Regions, ConnectedRegions)
    count_obj (ConnectedRegions, Number)
    for I := 1 to Number by 1
        Features:=[]
        select_obj (ConnectedRegions, ObjectSelected, I)
        roundness (ObjectSelected, Distance, Sigma, Roundness, Sides)
        circularity (ObjectSelected, Circularity)
        moments_region_central_invar (ObjectSelected, PSI1, PSI2, PSI3, PSI4)
        Features:=[Roundness,Circularity,PSI1, PSI2, PSI3, PSI4]
        add_sample_class_gmm (GMMHandle, Features, Class[1], 0)
    endfor
    disp_message (3600, '添加样本二第'+int(Index+1)+'张图像', 'window', 12, 12, 'black', 'true')
    stop ()
endfor

*添加样本3
list_files ('C:/Users/yanzhenwu/Desktop/TestPic/3', ['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])
    threshold (Image, Regions, 0,100)
    connection (Regions, ConnectedRegions)
    count_obj (ConnectedRegions, Number)
    for I := 1 to Number by 1
        Features:=[]
        select_obj (ConnectedRegions, ObjectSelected, I)
        roundness (ObjectSelected, Distance, Sigma, Roundness, Sides)
        circularity (ObjectSelected, Circularity)
        moments_region_central_invar (ObjectSelected, PSI1, PSI2, PSI3, PSI4)
        Features:=[Roundness,Circularity,PSI1, PSI2, PSI3, PSI4]
        add_sample_class_gmm (GMMHandle, Features, Class[2], 0)
    endfor
    disp_message (3600, '添加样本三第'+int(Index+1)+'张图像', 'window', 12, 12, 'black', 'true')
    stop ()
endfor
*训练
train_class_gmm (GMMHandle, 100, 0.001, 'training', 0.0001, Centers, Iter)
*这里注意:清理的是样本添加句柄,而不是分类句柄
clear_samples_class_gmm (GMMHandle)
*分类样本
list_files ('C:/Users/yanzhenwu/Desktop/TestPic/test', ['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])
    threshold (Image, Regions, 0,100)
    connection (Regions, ConnectedRegions)
    count_obj (ConnectedRegions, Number)
    for I := 1 to Number by 1
        Features:=[]
        select_obj (ConnectedRegions, ObjectSelected, I)
        area_center (ObjectSelected, Area, Row, Column)
        roundness (ObjectSelected, Distance, Sigma, Roundness, Sides)
        circularity (ObjectSelected, Circularity)
        moments_region_central_invar (ObjectSelected, PSI1, PSI2, PSI3, PSI4)
        Features:=[Roundness,Circularity,PSI1, PSI2, PSI3, PSI4]
        *这里注意,当前选的的对象的类别设置为1,ClassID则给出预先定义的Class类别中的一个,否则,给出不唯一达不到分类效果
        classify_class_gmm (GMMHandle, Features, 1, ClassID, ClassProb, Density, KSigmaProb)
        if(ClassID==Class[0])
            dev_set_color ('red')
            dev_display (ObjectSelected)
            disp_message (3600, '圆环', 'window', Row, Column, 'black', 'false')
        elseif(ClassID==Class[1])
            dev_set_color ('blue')
            dev_display (ObjectSelected)
            disp_message (3600, '六边形', 'window', Row, Column, 'black', 'false')
        else
            dev_set_color ('yellow')
            dev_display (ObjectSelected)
            disp_message (3600, '齿轮', 'window', Row, Column, 'black', 'false')
        endif
    endfor
    disp_message (3600, '用高斯混合分类器分类图像', 'window', 5, 5, 'black', 'true')
    stop ()
endfor
*清理分类句柄
clear_class_gmm (GMMHandle)
<think>嗯,用户想知道如何在Halcon中使用GMM进行异常值检测。首先,我需要回忆一下Halcon中GMM的相关函数和使用流程。根据之前提供的引用资料,Halcon的GMM主要用于分类任务,比如例程中的橘子和柠檬分类。但异常检测可能需要不同的方法,因为通常异常检测是无监督的,而分类是有监督的。不过,或许可以利用GMM的概率模型来判断样本是否为异常。 首先,用户需要了解GMM在Halcon中的基本操作步骤。根据引用[4],使用GMM的过程包括创建模型、添加样本、训练模型和保存模型。正常分类的话需要训练多个类别,但异常检测可能只需要训练正常样本的分布,然后计算新样本的概率,低于某个阈值则视为异常。 接下来,我需要查看是否有相关的函数支持这种应用。例如,是否有函数可以获取样本的概率值。根据引用[5],分类时可能使用概率最大的类别,所以可能有函数返回每个样本的概率值。比如classify_class_gmm可能返回概率,但需要确认参数设置。 然后,用户需要设置一个阈值来判断异常。这可能需要通过实验确定,比如在训练集上计算正常样本的概率分布,找到合适的阈值。如果测试样本的概率低于该阈值,则视为异常。 另外,引用[3]提到GMM的参数是通过EM算法优化的,可能需要足够的数据来训练模型。异常检测需要确保正常样本的数据足够覆盖其分布,否则模型可能不准确。 可能的问题:Halcon的GMM分类器是否支持单类别的训练,即只训练正常样本,然后检测异常。根据引用[4],add_sample_class_gmm需要指定类ID,所以可能需要至少两个类别。但或许可以将异常视为另一个类别,不过这可能不符合标准的异常检测流程。 可能的解决方案:即使Halcon的GMM主要用于多分类,可以将所有训练数据视为正常类(类别1),然后创建另一个虚拟类别,但可能无法有效训练。或者,使用单类别GMM,但需要确认Halcon是否支持。如果不行,可能需要调整方法,例如计算样本的对数似然,并与训练数据的平均似然比较,设定阈值。 另外,引用[5]的例程中分类是基于不同类之间的明显区别,异常检测可能需要更细致的概率判断。可能需要调整GMM的参数,如组件数量,来更好地拟合正常数据的分布。 总结步骤可能包括:创建GMM模型,添加正常样本数据,训练模型,对新样本计算其属于正常类的概率,设定阈值判断异常。需要具体查看Halcon的函数是否支持获取概率值,以及如何设置单类别训练。</think>在Halcon中实现基于GMM的异常值检测,需结合分类器训练与概率阈值判断。以下是具体步骤和代码示例: --- ### **步骤1:创建GMM分类器** 使用`create_class_gmm`定义高斯混合模型参数: - `NumDim`:特征向量的维度(如颜色、纹理等) - `NumClasses`:异常检测通常设为**1类**(仅正常样本) - `NumCenters`:高斯分量的数量(需根据数据复杂度调整) ```python create_class_gmm(NumDim, 1, NumCenters, 'full', 'none', 0, 42, GMMHandle) ``` --- ### **步骤2:添加训练样本** 通过`add_sample_class_gmm`加载**正常样本**特征向量: ```python * 假设Features是正常样本的特征向量数组 for i := 0 to |Features| - 1 by 1 add_sample_class_gmm(GMMHandle, Features[i], 0, 0) // 类别ID固定为0(正常类) endfor ``` --- ### **步骤3:训练GMM模型** 调用`train_class_gmm`优化参数,最大化正常样本的似然概率: ```python train_class_gmm(GMMHandle, 0.001, 'training', 0.0001, 100, ClassIDs, Error) ``` --- ### **步骤4:计算测试样本概率** 使用`get_sample_class_gmm`获取测试样本的对数似然值: ```python get_sample_class_gmm(GMMHandle, TestFeature, 0, _, LogLikelihood) ``` - `LogLikelihood`值**越低**,样本偏离正常分布的可能性越大[^3] --- ### **步骤5:设定异常阈值** 通过统计正常样本的似然分布确定阈值: ```python * 计算正常样本的平均对数似然 get_sample_class_gmm(GMMHandle, TrainingFeatures, 0, _, TrainingLogLike) mean_loglike := mean(TrainingLogLike) threshold := mean_loglike - 3 * dev(TrainingLogLike) // 3σ原则 ``` --- ### **步骤6:异常判断** 比较测试样本的似然值与阈值: ```python if (LogLikelihood < threshold) * 判定为异常 endif ``` --- ### **完整代码示例** ```python * 创建GMM模型(单类别) create_class_gmm(3, 1, 5, 'full', 'none', 0, 42, GMMHandle) * 加载正常样本特征 read_image(NormalImage, 'normal.png') extract_features(NormalImage, Features) // 自定义特征提取函数 * 添加训练数据 for i := 0 to |Features| - 1 by 1 add_sample_class_gmm(GMMHandle, Features[i], 0, 0) endfor * 训练模型 train_class_gmm(GMMHandle, 0.001, 'training', 0.0001, 100, ClassIDs, Error) * 测试样本评估 read_image(TestImage, 'test.png') extract_features(TestImage, TestFeature) get_sample_class_gmm(GMMHandle, TestFeature, 0, _, LogLikelihood) * 异常判定 if (LogLikelihood < threshold) dev_display(TestImage) stop() endif ``` --- ### **关键优化点** 1. **特征选择**:需提取与异常相关的特征(如纹理、形状参数)[^5] 2. **分量数调整**:通过交叉验证选择最佳`NumCenters`,避免过拟合 3. **在线更新**:使用`write_class_gmm`保存模型,`read_class_gmm`加载以持续学习新样本[^2] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值