使用HALCON进行图像分类——图像分类(系统讲解,附模板例程精讲)

更新时间:2023-05-25 16:09:40 阅读: 评论:0

使⽤HALCON进⾏图像分类——图像分类(系统讲解,附模板例程精讲)
利⽤HALCON对图像进⾏分类
1.基础知识
1.1分类器的作⽤与使⽤范围
2012高考语文试卷及答案
分类器的作⽤是将⽬标对象指定为已给的多个类别中的⼀个。例如⼀张图中包含了⼏种形状不同的物体,我们可以通过分别对每⼀种形状对应样本的区域的某些特征值,并告诉它每⼀类形状的这些样本属于哪种类别来进⾏训练,完成训练后,再输⼊待判断物体的形状区域的相应特征值,这时分类器便可以根据之前的训练成果,来对输⼊区域进⾏判断,并给出判断的结果。
这⾥,我对区域进⾏了加粗,是因为需要⼤家知道,分类器所需要的输⼊是区域的特征值,⽽不是单纯的原始图像,⽆论是进⾏训练,还是进⾏识别,它的输⼊始终都是区域的特征值。因此,进⾏分类器操作之前,对原始图像进⾏⼀些预处理以及图像分割来得到我们需要输⼊的⽬标区域是必须的。具体如何分割,则需要具体场景具体分析。
1.2分类器的种类
Halcon提供了多种分类器,⽐较重要的分类器有
(1)基于神经⽹络,特别是多层感知器的MLP分类器
(2)基于⽀持向量机的SVM分类器
(3)基于⾼斯混合模型的GMM分类器
(4)基于k近邻的k-NN分类器
1.3 分类器特点
(1) MLP分类器
MLP分类器分类速度快,但训练速度慢,对内存的要求低,⽀持多维特征空间,特别适合需要快速分类并且⽀持离线训练的场景,但不⽀持缺陷检测。
(2)SVM分类器
分类检测的速度快,当向量维度低时速度最快,但⽐MLP分类器慢,尽量训练速度⽐MLP分类器快得多。其对内存的占⽤取决于样本的数量,如果有⼤量的样本,如字符库这样的样本需要训练,分类器将变得⾮常庞⼤。
(3) GMM分类器
训练速度和检测速度都很快,特别是类别较少时速度特别快,⽀持异常检测,但不适⽤于⾼维度特征检测。
(4)k-NN分类器
训练速度⾮常快,分类速度⽐MLP分类器慢,适合缺陷检测和多维度特征分类,但对内存的需求较⾼。
多数情况下,上⾯四种分类器都是可以胜任需求的。
1.4 图像分类的⼀般流程
(1)准备样本图⽚
(2)对样本图⽚进⾏处理(如⼆值化、图像分割等),提取出⽬标区域
(3)分析⽬标特征,选取可以⽤来将不同类别区分开来的⼏种特征值作为特征向量以训练分类器
(2)创建分类器
(3)训练分类器
(4)检测待测⽬标对象,分类器根据训练得到的类别的边界条件判断检测对象属于哪个分类
(5)清除分类器,释放内存
总的来说,针对不同的分类任务,需要选择⼀组合适的特征和合适的分类器,以及合适的训练样本。
2.特征的分类
2.1 MLP分类器的关键算⼦
(1)创建分类器——create_class_mlp算⼦
create_class_mlp( : : NumInput, NumHidden, NumOutput, OutputFunction, Preprocessing, NumComponents, RandSeed : MLPHandle)
该算⼦除了MLPHandle是输出参数以外,其余都是输⼊参数,介绍如下:
NumInput:⽤于训练和分类的特征空间的维度数。默认是20,也可以更⼤甚⾄500。
NumHidden:表⽰神经⽹络中隐藏层的单元数量。改值会明显地影响分类结果,需要谨慎设置。其取值范围与NumInput及NumOutput 相似。其值越⼩,超平⾯就越简单,有时能够得到更好的效果;如果取值过⼤,反⽽会有过拟合的可能,⽐如可能将噪声点⽤于训练分类器的边界,这时如果待测对象不包括这些⾮关键的点,则可能分类失败。
NumOutput:表⽰输出的分类数量,⽐如对两种物体进⾏分类,即为2,对三种物体分类即为3。
OutputFunction:表⽰神经⽹络的输出单元使⽤的函数,可选的有softmax、logistic、linear。绝⼤多数情况下,输出函数都可以使⽤softmax。logistic⽤于处理多个逻辑独⽴的属性的分类问题,⾮常少见。linear⽤于最⼩⼆乘法,⽽不是⽤于分类,可以忽略。Preprocessing:该参数表⽰在训练与分类前对特征向量进⾏预处理。预处理可以加快训练或者分类的速度,有时也有助于提升分类的准确度。其可选⽅法有四种。选择none时不进⾏任何预处理,⼤多数情况下,选择normalization,表⽰将特征向量归⼀化为0⾄1的数。这种处理既不会改变特征向量的长度,⼜能有效提升速度,因此是预处理的⾸选。如果特征向量是⾼度相关的,可以选择
principal_components
NumComponents:在Preprocessing选择canonical_variates或者principal_components时使⽤。因为这两种预处理⽅法可能会减少特征空间的维度,NumComponents就表⽰减少后的特征向量的维度。
RandSeed:⽤于初始化MLP中的权重值,该值表⽰随机数种⼦数,存储在RandSeed中。
MLPHandle:唯⼀的输出参数。这是分类器的句柄,⽤于后续对分类器进⾏各种操作,如调⽤、修改、删除等。
(2)将单个样本添加到MLP分类器中——add_sample_class_mlp算⼦
add_sample_class_mlp( : : MLPHandle, Features, Target : )
MLPHandle:表⽰分类器的句柄
Feaures:表⽰输⼊样本的特征向量。该向量类似于⼀个数组,其中的每⼀个值表⽰⼀种特征,其维度数应当与create_class_mlp中的NumInput的值相同。
Target:设置类别的标识号。它可以设置的值的个数与create_class_mlp中的NumOutput的值相同。⽐如有三种类型的物体需要进⾏图像分类,那么Target对应每种形状时就可以分别设置为0、1、2。当然也可以设置为其他数字。Target表⽰类别的标识ID,每⼀个Traget 即代表是⼀种类别。
(3)进⾏样本的训练——train_class_mlp算⼦
train_class_mlp( : : MLPHandle, MaxIterations, WeightTolerance, ErrorTolerance : Error, ErrorLog)
MaxIterations:表⽰优化算法的最⼤迭代次数,默认为200。多数情况下,算法会在迭代了MaxIterations次后结束。100~200的次数⼀般都是⾜够的。
WeightTolerance:表⽰优化算法的两次迭代之间的权重差异阈值。如果权重⼩于该值,优化算法将终⽌。⼀般默认为1,且⽆需改变。ErrorTolerance:表⽰优化算法的两次迭代之间的误差均值的阈值。均值⼩于该值,算法也会终⽌。⼀般默认为0.01,且⽆需改变。Error:表⽰MLP在最佳权重下的训练数据的平均误差。
ErrorLog:该参数将MLP的训练数据的平均误差作为迭代次数返回。它⽤于判断是否应该使⽤不同的RandSeed对同样的样本进⾏⼆次训练。合适的情况下,ErrorLog应当是在开始时急剧下降,后越来越平稳。如果是从头到尾其值都⾛势陡峭,则通常应重新设置参数重新训练。
(4)评估⼀个算⼦属于某个类别的概率——evaluate_class_mlp算⼦
evaluate_class_mlp( : : MLPHandle, Features : Result)
Features:表⽰输⼊的待评估的特征向量。这⾥的特征向量的维度与结构应当与add_sample_class_mlp中的训练样本的特征向量相同。Result:表⽰由MLP评估后输出的结果。
(5)使⽤训练好的分类器进⾏分类——classify_class_mlp算⼦
classify_class_mlp( : : MLPHandle, Features, Num : Class, Confidence)
完成创建与训练后的分类器便可以对未知对象进⾏分类了。
Features:输⼊的待评估的特征向量。
Num:想要寻找的最佳分类的数量。如设置为1则只返回概率最⼤的那个类别,设置为2则将概率前两名的两个类别都返回。
class:输出所寻找的类别ID,若Num为1,则返回⼀个ID,Num为2则返回两个,每个值都为add_sample_class_mlp中Target设置的值之⼀,即代表每个类别的ID。
(6)释放分类器——clear_class_mlp算⼦
clear_class_mlp (MLPHandle)
根据分类器的句柄,将完成分类任务后不需要在使⽤的分类器清除释放。同时释放MLP分类器所占⽤的内存资源。
相亲聊天
2.2 HALCON相关⽰例程序精解
这⾥使⽤的是HALCON的⼀个相关例程,是⼀个⾮常标准的图像分类模板,笔者在注释中对本例程进⾏了详细的讲解,⽅便初学者学习。
另外,笔者对例程进⾏了稍微的改动。主要是原始例程编写了⼏个本地函数(即⾃定义函数,它使⽤已存在算⼦对多个步骤进⾏了封装,对于简化代码与提⾼代码模块化有很⼤作⽤),虽然合理但是不⽅便初学者查阅理解,因此在下述代码中笔者⽤原始算⼦替换了原来的本地函数,本地函数被注释。这样⽅便每⼀个步骤的精确讲解,也⽅便⼤家对程序进⾏改动移植⽽不出错。
本地函数包括gment,add_samples,get_features,classify,笔者已注释,读者可⾃⾏删除。
dev_update_off ()
dev_clo_window ()soq
dev_open_window (0, 0, 640, 480, 'black', WindowHandle)
t_display_font (WindowHandle, 16, 'mono', 'true', 'fal')
dev_t_colored (6)
dev_t_draw ('margin')
dev_t_line_width (3)
*
*⼀、创建mlp分类器。
*⽤于训练和分类的特征向量维度数为6,神经⽹络中隐藏层为5,共需要对3种类别进⾏分类,其他参数参考⽂章2.1 MLP分类器的关键算⼦
create_class_mlp (6, 5, 3, 'softmax', 'normalization', 3, 42, MLPHandle)
*
*⼆、添加样本到分类器
*循环读取每⼀个图⽚⽂件,对每⼀个图⽚进⾏⼆值化图像分割,获取每个区域的特征向量与各⾃所对应的类别作为样本添加⼊分类器
FileNames := ['nuts_01','nuts_02','nuts_03','washers_01','washers_02','washers_03','retainers_01','retainers_02','retainers_03']
*这⾥按照图⽚顺序将每张图⽚的类别ID(即add_sample_class_mlp中的Target)存放在数组Class当中,⽅便在循环中⾃动根据图⽚顺序选择相应的类别ID Class := [0,0,0,1,1,1,2,2,2]
*对于每⼀张图⽚,将进⾏以下操作
for J := 0 to |FileNames| - 1 by 1
read_image (Image, 'rings/' + FileNames[J])
dev_display (Image)
dev_t_colored (6)
*gment (Image, Objects)
*⼆值化分割图像,提取图像中较暗的部分("dark"),即零件部分,'max_parability'表⽰在直⽅图中对最⼤的可分性进⾏分割,
*UdThreshold是算法⾃动计算出⽤于图像分割的阈值,作为输出参数返回
binary_threshold (Image, Objects, 'max_parability', 'dark', UdThreshold)
*合并像素相连部分成为⼀个个区域
connection (Objects, ConnectedRegions)
*填充每个区域(零件)中的孔或和缝等,形成新的实⼼区域。
fill_up (ConnectedRegions, Objects)
dev_display (Objects)
*设置字体颜⾊,显⽰当前循环位置,⽅便观察
dev_t_color ('black')
disp_message (WindowHandle, 'Add Sample ' + J + ', Class Index ' + Class[J], 'window', 10, 10, 'black', 'true')
*    add_samples (Objects, MLPHandle, Class[J])
*计算区域的个数,也就是⼀张图像中零件的个数。
count_obj (Objects, Number)
*对于⼀张图⽚中的每⼀个处理后的实⼼区域(零件),将进⾏以下操作
for k := 1 to Number by 1
best wishes*选择第k个区域(零件),计算该区域的相关特征参数,作为特征向量准备输⼊给分类器
lect_obj (Objects, Region, k)
* get_features (Region, Features)
lect_obj (Region, SingleRegion, 1)
lect_obj (Region, SingleRegion, 1)
*与圆的相似度Circularity,roundness则由区域的轮廓与区域中⼼之间的平均距离(Distance)及与平均距离的偏差(Sigma)组合公式⽽来。 circularity (SingleRegion, Circularity)
roundness (SingleRegion, Distance, Sigma, Roundness, Sides)
*这个算⼦⽤于计算区域⼏何特性,输出4个代表区域⼏何特性的参数。
moments_region_central_invar (SingleRegion, PSI1, PSI2, PSI3, PSI4)
*前⾯通过三个算⼦得到了Circularity,roundness, PSI1, PSI2, PSI3, PSI4共6个参数,使⽤这六个特征参数组合成特征向量Features
Features := [Circularity,Roundness,PSI1,PSI2,PSI3,PSI4]
*将得到的特征向量作为样本添加进分类器,并指明对应的类别ID,即Class[J]
gxwadd_sample_class_mlp (MLPHandle, Features, Class[J])
endfor
*⼀张图⽚中多个区域处理的循环结束
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endfor
* 多张图⽚的处理的循环结束
* 三.利⽤添加好的样本特征向量组,训练分类器
dev_clear_window ()
dev_t_color ('black')
disp_message (WindowHandle, '', 'window', 10, 10, 'black', 'true')
*开始训练分类器
train_class_mlp (MLPHandle, 200, 1, 0.01, Error, ErrorLog)
*训练完成后,清除分类器中的样本数据,释放占⽤内存资源
clear_samples_class_mlp (MLPHandle)
*出现⽂字提⽰训练完成
disp_message (WindowHandle, ' completed', 'window', 10, 10, 'black', 'true')conflicts
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* 四.实现分类器分类功能
*dev_t_draw ('fill')
*对于每⼀张图⽚,进⾏⽬标区域的获取与每⼀个区域特征向量的获取,输⼊给分类器进⾏类别的判断西安新东方英语
for J := 1 to 4 by 1
read_image (Image, 'rings/mixed_' + J$'02d')
dev_display (Image)
dev_t_color ('black')
dev_t_draw ('margin')
disp_message (WindowHandle, 'Classifiy Image' + J, 'window', 10, 10, 'black', 'true')
*gment (Image, Objects)
*对每张图⽚进⾏区域分割,得到每个零件的区域并进⾏填充,具体步骤含义参考创建mlp分类器时的相同代码
binary_threshold (Image, Objects, 'max_parability', 'dark', UdThreshold)
connection (Objects, ConnectedRegions)
fill_up (ConnectedRegions, Objects)
*classify (Objects, MLPHandle, Class)
*完成对每个区域(也就是每⼀个零件)的提取后,分别计算每个区域的特征向量并输⼊给分类器进⾏分类,分类结果存储在Class数组当中    count_obj (Objects, Number)
Class := []
for k := 1 to Number by 1
*下⾯计算特征向量步骤与创建mlp分类器部分相应代码相同,⾃⾏向前查阅。
lect_obj (Objects, Region, k)
*get_features (Region, Features)
lect_obj (Region, SingleRegion, 1)
circularity (SingleRegion, Circularity)
roundness (SingleRegion, Distance, Sigma, Roundness, Sides)
moments_region_central_invar (SingleRegion, PSI1, PSI2, PSI3, PSI4)
英语时态hq是什么意思Features := [Circularity,Roundness,PSI1,PSI2,PSI3,PSI4]
*得到特征向量Features输⼊分类器,进⾏分类,返回⼀个最可能的结果Class,并给出置信度Confidence
classify_class_mlp (MLPHandle, Features, 1, Class, Confidence)
*该语法含义是将每次循环中class的值添加⼊Class当中,相当于很多语⾔中的数组的.push()⽅法,以此将分类结果class存储在数组Class *当中,如Class为0,则对应第⼀类,Class为2,则对应第三类。
Class := [Class,Class]
endfor
*结束对⼀张图⽚中所有区域(零件)的分类
stop()
*下⾯是针对每张图⽚分类完成后的结果,进⾏可视化显⽰
disp_obj_class (Objects, Class)
count_obj (Objects, Number)
*采⽤三种不同颜⾊放在数组中,根据类别ID(0,1,2),来选择数组中的颜⾊
高中辅导
Colors := ['yellow','magenta','green']
for l := 1 to Number by 1
lect_obj (Objects, Region, l)
dev_t_color (Colors[Class[l - 1]])
dev_display (Region)
endfor
if (J < 4)
* 判断四张图⽚未处理完时,每⼀张处理完成后,暂停进⾏提⽰,再⼿动进⼊下⼀张的处理
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endif
endfor
*四张图⽚全部处理完成
stop ()
*
*5.清除分类器,释放分类器所占⽤的内存
clear_class_mlp (MLPHandle)
其他分类器的操作步骤也可以参考MLP分类器的操作步骤,希望读者结合HALCON的相关⾃带例程,⾃⾏发现相通之处。
3.光学字符识别
3.1 ⼀般步骤
(1)字符的训练
①读取样本图像,并对样本中的已知字符进⾏区域分割,分割的单位是单个字符的包围区域这时可以使⽤draw_rectangle1等算⼦选择出单个字符的区域
②将分割出的区域和对应的字符名称存储在训练⽂件中。可以使⽤append_ocr_class_mlp算⼦,将字符区域存在指定的以“.trf”结尾的训练⽂件中。
③检查训练⽂件中的对应关系,即图像与字符的名称⼀⼀对应。
④训练分类器。创建分类器后开始训练。
⑤保存分类器
⑥清除分类器
(2)字符检测
①读取分类器⽂件。
②对待检测的字符进⾏区域分割,提取出独⽴的字符区域。
③使⽤分类器进⾏分类。
④清除分类器
Halcon根⽬录下的ocr⽂件夹中内置了许多针对数字、字母和喷码等类字符的分类器。针对多种标准的、⾮中⽂的字符,可以直接调⽤这些训练好的分类器⽂件⽽⽆需⾃⼰进⾏训练。⼿写体或者中⽂字符则需要⾃⼰进⾏离线训练。
3.2 HALCON相关⽰例程序
这⾥仅放置Halcon实例程序源代码,具体步骤参考之前的mlp分类器分类程序讲解。分类步骤及思想都是想通的。
(1)字符的训练

本文发布于:2023-05-25 16:09:40,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/78/772951.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:分类器   分类   训练   区域   特征向量   图像   样本   类别
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图