前言
EMGU官方文档中有几种机器学习的案例,但是由于EMGU算法跟随OpenCV算法在升级,官方文档中SVM (Support Vector Machine) in CSharp描述的EM算法中多个方法已经重写(弃用),使用较高版本的EMGU并不能复现例程。本文参考OpenCv中的SVM算法,修改了部分源码并测试通过。
问题解决
复现过程有两个关键问题:
1、异常:‘Integer division by zero’
这个问题困扰了很久,直到发现这篇文章给出了答案Emgucv 3.* 下的SVM示例,非常简答,把例程中的分类矩阵trainClasses的数据类型由float改为int即可。但是作者还有个关键问题没弄明白,什么是支持向量,这篇文章给了很好的解释SVM通俗详解。所以Emgucv 3.* 下的SVM示例文中获取的支持向量是不正确的,如下:
// changed the GetSupportVectors()
Mat supvec = model.GetSupportVectors();
int c = supvec.Height;
for (int i = 0; i < c; i++)
{
// The way the data is received changed as well
byte[] b = supvec.GetData(i);
float[] v = new float[] {
(float)b[0], (float)b[1] };
PointF p1 = new PointF(v[0], v[1]);
img.Draw(new CircleF(p1, 4), new Bgr(128, 128, 128), 2);
}
————————————————
版权声明:本文为优快云博主「马超514」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_26996385/article/details/79418921
GetSupportVectors()方法获取的是支持向量,并不是支持向量的支撑点,而且supvec.GetData(i)获取的是一个byte数组,作者把字节数组的前两位作为点也没什么意义,所以在结果展示上并未圈出在样本点集中作为支撑的点,下图分别是不正确的支撑点和官方例程中的支撑点展示:


由此引出第二个问题
2、如何获取支持向量的点
本文通过把训练的SVM结果保存到本地,发现了xml数据中包含这些点集数据和GetSupportVectors()方法获取的支持向量。
<sv_total>3</sv_total>
<support_vectors>
<_>
-4.26625609e-02 -4.20124875e-03</_>
<_>
-2.49704085e-02 3.23080271e-02</_>
<_>
1.82409845e-02 6.01602904e-02</_>
</support_vectors>
<uncompressed_sv_total>7</uncompressed_sv_total>
<uncompressed_support_vectors>
<_>
2.13789581e+02 3.70247894e+02</_>
<_>
1.92192932e+02 2.29739059e+02</_>
<_>
2.65889404e+02 3.17239105e+02</_>
<_>
2.58218262e+02 3.95134766e+02</_>
<_>
5.11033264e+02 2.53483795e+02</_>
<_>
3.28194794e+02 2.72949036e+02</_>
<_>
1.15855988e+02 1.08835411e+02

本文介绍了在使用EMGU库实现SVM算法时遇到的'Integer division by zero'异常及如何正确获取支持向量的问题。通过修改源码和解析XML数据,成功获取支持向量的点集,并展示了训练样本的分类结果。
最低0.47元/天 解锁文章
603

被折叠的 条评论
为什么被折叠?



