基于Halcon的支持向量机(SVM)技术的特征分类
深度学习与支持向量机的分类原理相同之处:都是通过非线性矩阵变换后,用线性超平面对数据进行分类。不同之处:深度学习可以向低维和高维空间进行变换,而线性变换和非线性变换是分两步走的,支持向量机只能由低维向高维映射,其变换是通过核函数一步完成的。深度学习可以多分类,支持向量机只能二分类
支持向量机理论和神经网络理论和多层分类器理论都属于智能学习理论,它们都是通过统计学习理论建立模型,并使用这个模型检测数据,并对数据进行分类与回归处理。学习方法可分为监督式学习和无监督式学习,所谓监督式学习,是指根据已知的训练数据获得一个函数或模型,训练数据包括输入向量和预期输出。支持向量机技术属于监督式学习,它是基于统计学习理论发展起来的,在解决小样本问题和非线性问题时表现出特有的优势。传统的智能方法(如神经网络方法)求得的最优解往往是局部最优解,而支持向量机可求出全局最优解,并且可以避免陷入维数灾难。
支持向量机起源于20世纪90年代,当时它并没有被人们所重视,其跨越式发展在最近20年左右,经过人们的不断努力,支持向量机技术的理论基础越来越完善,使之趋近于﹣门专业学科。目前,支持向量机被大范围地使用于生产、生活的各个领域,并取得了可喜的成果。支持向量机的发展阶段可以大致划分为模糊支持向量机,最小二乘支持向量机,加权支持向量机,主动学习支持向量机,粗糙集支持向量机,分级聚类支持向量机,基于决策树的支持向量机。
支持向量机的应用非常广泛,其主要用于机器故障类型的分析与诊断、金融市场的未来预测、指纹的识别、信号的分类与分析、行人的检测、人脸的匹配、工业产品的分类检测、手写字体的识别以及数据挖掘与数据分析等领域,由于支持向量机的使用,人们对很多以前不能解决或者难以解决的问题有了新的启发,并可以利用支持向量机技术处理这些难题。
支持向量机的提出最早是用于解决二分类问题,即如何划分开两类问题,这两类问题可以是线性的,也可以是非线性的。如何构造一个最优分类面将两类数据完美地划分开,也就是最优分类线问题。所谓最优分类线即是可以将两类数据正确区分开,并且使区分程度最大,也就是使其经验风险最小为0。
支持向量机是根据分类间隔最大化来处理数据的,对于平面上线性可分的数据,其分类过程相对简单,可以通过构造最优分类线使两类数据尽可能大地区分开,则该分类线就是所谓的最优分类线。对于平面上线性不可分的数据,其分类问题在实际生产生活中较为常见,可以通过一个变换函数将线性不可分的数据映射到更高维的空间使其变得线性可分。在高维的空间中,分割数据的不是直线而是平面,我们称这个平面为分类面。
如图所示,黑点和白点是两类不同的数据,且两类数据是线性可分的,直线 H 就是我们需要的最优分类线,它可以最大限度地将两类数据分开,这时两类数据的分类间隔最大,错分误差最小。在直线H1和H2上面的白点和黑点就是所谓的支持向量,这两条直线之间的距离 margin 就是这两类数据的最大分类间隔。对于线性不可分的数据,将其映射高维空间仍然是求取其最大分类面使 margin 最大。
由于实际应用中需要通过支持向量机解决的问题基本上属于线性不可分问题,因此使用支持向量机解决问题的基本步骤可以归纳为:首先将数据所属空间映射到高维空间,那么对于在低维空间线性不可分的数据,通过高维空间的映射使其变得线性可分,然后在高维空间求得最优分类面,将数据线性分开。
支持向量机可以解决分类问题、预测问题和回归问题,其计算的复杂程度由支持向量的数目所决定。支持向量机算法与其他的智能分类算法不同,它不是采用降维即减少特征量等方法,而是利用核函数将原有数据映射到高维空间,这种方法虽然使维度增加但是并没有增加太多的运算量。通过维度空间的提升,可将不能线性分割的数据就变得线性可分,并且使整个问题变为全局的二次规划问题,可以求出全局最优解,避免了局部最优解。
在数字图像处理中,分类对象一般为图像或区域。针对区域的分类是指训练的样本特征为区域特征,如面积、长度、圆度、椭圆度等。针对图像的分类是指训练的样本特征为图像特征,如纹理、灰度直方图等。
支持向量机分类流程为:
- :创建SVM分类器
- :添加样本
- :训练样本
- :SVM分类器分类
案例分析:
以区分任意圆和四角星为例,圆度,外接圆半径,内接圆半径,可以确定圆度是其区分特征,内外半径比例也是特征之一,基于此两点,做一个简单的二分类项目案例
基于区域特征的 SVM 分类的相关算子
1:create _ class _ svm (:: NumFeatures , KernelType , KernelParam , Nu , NumClasses . Mode ,Preprocessing , NumComponents : SVMHandle )
功能:创建 SVM 模型。
NumFeatures : SVM 的输入变量(特征)数。
KernelType :内核类型。
KernelParam :内核函数的附加参数。
Nu : SVM 的正则化常数。
NumClasses :样本分类个数。
Mode : SVM 的模式。
Preprocessing :用于变换特征向量的预处理类型。
NumComponents :预处理参数(转换特征数)。
SVMHandle : SVM 句柄。
create _ class _ svm 算子创建一个可用于模式分类的支持向量机。分类模式的维度在 NumFeatures 中指定, NumFeatures 是 NumClasses 中的类别个数。
2: add _ sample _ class _ svm (:: SVMHandle , Features , Class :)
功能:将训练样本添加至 SVM 中。
SVMHandle : SVM 句柄。
Features :需要存储训练样本的特征向量。
Class :需要存储训练样本的类别,范围为0~ Numclassess -1.
add _ sample _ class _ svm 算子用于将训练样本添加到 SVM 句柄对应的支持向量机( SVM )中,训练样本由特征和类别给出。特征是指样本的特征向量,该向量是长度为 NumFeatures 的实数向量。在使用 train _ class _ svm 算子训练 SVM 之前,必须使用 add _ sample _ class _ svm 算子将训练样本添加到 SVM 中。
3 :train _ class _ svm (:: SVMHandle , Epsilon , TrainMode ;)
功能:训练支持向量机。
SVMHandle : SVM 句柄。
Epsilon :停止训练的参数。
TrainMode :训练模式。
训练支持向量机的目的是解决凸二次优化问题,保证训练在全局最优的有限步骤后终止。为了识别终止标志,内部优化函数的梯度值必须低于 epsilon 中设置的阈值,默认情况下, epsilon 中的阈值为0.001。若梯度值过大,则会导致训练过早终止,通常不会得到最优解决方案。在梯度值太小的情况下,优化需要更长的时间,通常不会显著改变识别率。
4: clasify_class_svm (:: SVWHiandle , Features , Num : Class )
功能:使用支持向量机对特征向量进行分类。
SVMHandle : SVM 句柄。
Features :特征向量。
Num :确定类的数目。
Class :利用支持向量机对特征向量进行分类的结果。
classify _ class _ svm 算子使用支持向量机句柄 SVMHandle 来计算特征向量的最佳分类,并在 Class 中返回结果。
1,支持向量机的标注和训练阶段
dev_close_window ()
read_image (Image1, 'E:/Halcon数据/测量程序/向量机SVM分类/图片/模型图片/1.png')
get_image_pointer1 (Image1, Pointer, Type, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
set_display_font (WindowHandle, 20, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (2)
dev_display (Image1)
*创建特征数组
FeaturesScale:=[]
FeaturesCircularty:=[]
*确定分类名称
ClassName:=['圆','四角星']
*创建SVM模型
create_class_svm (2, 'rbf', 0.02, 0.05, 2, 'one-versus-one', 'normalization', 2, SVMHandle)
* 读图
list_files ('E:/Halcon数据/测量程序/向量机SVM分类/图片/模型图片', ['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])
dev_display (Image)
threshold (Image, Region, 0, 120)
connection (Region, ConnectedRegions)
count_obj (ConnectedRegions, Number)
for Index1 := 1 to Number by 1
select_obj (ConnectedRegions, ObjectSelected, Index1)
*提取特征
region_features (ObjectSelected, 'inner_radius', Value1)
region_features (ObjectSelected, 'outer_radius', Value11)
FeaturesScale:=[FeaturesScale,Value1/Value11]
region_features (ObjectSelected, 'circularity', Value2)
FeaturesCircularty:=[FeaturesCircularty,Value2]
region_features (ObjectSelected, 'row', Row)
region_features (ObjectSelected, 'column', Column)
FeatureVector:=real([Value1/Value11,Value2])
if (Index<1)
*
add_sample_class_svm (SVMHandle, FeatureVector, 0)
disp_message (WindowHandle, '添加到支持向量机的训练数据:'+ClassName[0], 'window', Row, Column, 'black', 'true')
else
add_sample_class_svm (SVMHandle, FeatureVector, 1)
disp_message (WindowHandle, '添加到支持向量机的训练数据:'+ClassName[1], 'window', Row, Column, 'black', 'true')
endif
stop ()
endfor
endfor
stop ()
*训练SVM分类器
train_class_svm (SVMHandle, 0.001, 'default')
2,支持向量机的推断阶段
list_files ('E:/Halcon数据/测量程序/向量机SVM分类/图片/测试图片', ['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, Region1, 0, 120)
connection (Region1, ConnectedRegions1)
count_obj (ConnectedRegions1, Number1)
for Index2 := 1 to Number1 by 1
select_obj (ConnectedRegions1, ObjectSelected1, Index2)
*提取特征
region_features (ObjectSelected1, 'inner_radius', Value1)
region_features (ObjectSelected1, 'outer_radius', Value11)
FeaturesScale:=[FeaturesScale,Value1/Value11]
region_features (ObjectSelected1, 'circularity', Value2)
FeaturesCircularty:=[FeaturesCircularty,Value2]
FeatureVector:=real([Value1/Value11,Value2])
region_features (ObjectSelected1, 'row', Row1)
region_features (ObjectSelected1, 'column', Column1)
*使用SVM分类器分类
classify_class_svm (SVMHandle, FeatureVector, 1, Class)
disp_message (WindowHandle, '类型:'+ClassName[Class], \
'window', Row1, Column1, 'black', 'true')
endfor
stop ()
endfor