分享

C 版OpenCV里的机器学习

 黄爸爸好 2021-05-26
图片
如果你在使用C ++安装OpenCV时遇到任何麻烦,下面这个视频,展示了如何轻松安装它。
  • https:///IzaXRux_FAY

使用openCV的Knn

定义
在人工智能中,更确切地说在机器学习中,k最近邻方法是一种有监督的学习方法。
在这个框架中,我们有一个由N个“输入-输出”对组成的训练数据库。
为了估计与新输入x 相关联的输出,k最近邻方法包括根据要定义的距离(以相同的方式)考虑k个训练样本,其输入最接近新输入x。
由于此算法基于距离,因此归一化可以提高其准确性。
方法
因此,要使用KNN方法进行分类,我们必须首先声明训练样本,或者可以说输入数据。
图片
在声明了0和1矩阵之后,我们必须使用函数“RNG”将它们填充为随机值。
图片
现在我们需要将两个类连接起来,以便进行学习。
训练
要进行训练,你必须首先使用以下代码行创建模型:
图片
现在,我们将进行遍历整个图像的循环(我们选择的平面为500x500像素,以绘制不同类别的区域,当然也将点放置在它们的位置),然后学习模型的输出对于第一类将为0,对于第二类将为1。
通过查找(或者可以说通过计算距离),我们用定义该像素属于此类的颜色填充图像的每个像素,这样就可以使边框可视化。
因此,要进行训练,你必须首先使用以下代码行创建模型:
图片
因此,你可以看到我们具有find_nearest函数,该函数计算入口点与其他点之间的距离以查找邻居,然后该函数为第一个类返回0或为第二个返回1。
最后,我们使用了条件块if,为每个类赋予特定的颜色。
因此,通过执行这些步骤,我们进行了学习,找到了两个类,并且我们当然划定了边界,如图:
图片
现在,如果我们想展示用于学习的样本,我们只需要把每个要点放在适当的位置即可,这样我们就可以了解学习是否做得很好。
图片
这是样本表示后的输出图像:
图片
可以看出,这两个类的界限是明确的,有一些点没有很好地分类,但总的来说,学习效果不错。
测试
对于测试,我们声明了一个200个元素的矩阵来进行测试,并且在计算了这些样本的最近邻居之后,我们放了一个小循环来计算两类的分类良好的样本和分类不良的样本。
这是测试样本的表示:

图片

评估
现在,我们必须通过查看分类良好和分类较差的样本来评估我们的模型。
为了理解我们将要做什么,我将举一个小例子。
在我们的例子中,我们有两个类,第一个包含绿色点,另一个包含红色点。
为了进行评估,我们必须放置一类好的和一类不好的,因此,在这里我将举一个例子:
对于绿点,我们将说它们代表未生病的人(好的类),红点代表生病的人(坏的类)。
  • 如果有病的人被归类为有病的人(带有红点),那么在这里我们说他是一个真阴性(正确分类为真,生病为阴性)。
  • 如果将一个有病的人归类为没有生病的人,那么在这里我们说这是一个假阴性(错误分类为假,生病为阴性)。
  • 如果没有生病的人被归类为没有生病的人(带有绿色),那么在这里我们说这是一个真阳性(对于分类良好的人来说是真,对于没有病的人来说是阳性)。
  • 如果未生病的人被归类为生病的人,那么在这里我们说这是假阳性。
因此,从这个原理开始,我们对结果进行评估,以便我们可以计算精度
图片
TP:真阳性
TN:真阴性
FP:假阳性
FN:假阴性
因此,由于我们知道16个绿色的错误分类点和9个红色的错误分类点,并且知道每个类别的总点数是200,因此我们可以轻松地填充表格。
图片
现在,使用这些值,我们可以计算出准确度
准确度
图片
召回
图片
特异性
图片
每个类的错误
第1类:
图片
第2类:
图片
总误差
图片

具有OpenCV的SVM

定义
支持向量机或大边缘分离器是一组有监督的学习技术,旨在解决判别和回归问题。支持向量机是线性分类器的推广。
支持向量机可用于解决判别问题,即确定样本属于哪一类,或回归问题,即预测变量的数值。解决这两个问题需要构造一个函数h,该函数与输入向量x匹配输出 y: y=h(x)
在我们的例子中,我们将对包含随机点的两个类进行分类,就像我们对KNN方法所做的那样。
方法
在这种方法中,我们将执行与KNN中几乎相同的操作,但是在这里我们必须做不同的部分。
第一个训练将始终使用具有正态分布函数的两类100个随机元素进行训练,然后我们必须生成200个元素的其他测试样本,然后进行预测。
因为如果我们始终使用训练样本,那么我们将无法研究生成的模型的性能。
因此,要进行学习,我们还必须为两个类创建两个矩阵,然后将它们连接起来并将其放入SVM模型的输入中。(与我们之前所做的相同)。
要进行学习,我们必须执行以下行:

图片

但是在此之前,我们必须通过执行以下操作来初始化模型参数:(我们使用了RBF核心)

图片

如果我们很好地注意到,当我们启动学习时,我们添加了类的向量,因为我们说这是监督学习,这意味着我们必须将类的名称提供给模型。
边界显示
训练后,我们需要像在KNN中所做的那样对数据进行表示,这样我们就可以看到边界,也可以看到模型是否根据我们拥有的训练数据很好地选择了边界。
图片
我们注意到边界确实使这两个类之间有所不同,有些点很难分类,但基本上,学习做得很好。
测试
现在,我们需要通过声明其他测试样本来测试模型,并使用预测函数直接在模型中运行它们,以预测每个点属于哪个类。
为此,我们为两个类声明了另外两个矩阵,每个矩阵包含200个测试项目。
最后,只需通过执行以下行来传递级联矩阵(该矩阵包含两个类的数据)就可以了:
图片
这是测试结果:
图片
评估
图片
因此,由于我们知道16个绿色的错误分类点和9个红色的错误分类点,并且知道每个类别的总点数是200,因此我们可以轻松地填充表格。
图片
准确度
图片
召回率
图片
特异性
图片
每个类的错误
第1类:
图片
第2类:
图片
总误差
图片
结论
总而言之,我们可以看到,获得的评估值非常令人满意。因为误差非常小,所以精度很高,这意味着该模型学习得很好,如果我们在此配置下使用SVM模型,那么它将在这种类型的应用程序中很好地工作。

词袋

介绍
在我们了解了如何将支持向量机用于一个基本案例之后,我们将尝试在图像上应用支持向量机模型来进行分类。
为此,我们有一个4个类的数据库,每个类都有隔离的图像。
但这里的问题是,一个图像包含几个特征,因此如果我们想使用图像,那么它将是一个具有大量值的输入矩阵,这将使学习过程非常缓慢,甚至无法确定它们是否是正确的特征。
这就是为什么我们需要找到一种方法,帮助我们从图像中提取必要的信息,我们将学习这些信息。因为如果我们不这样做,那么输入向量将是整个图像。
所以这里的想法是从图像中找到只包含图像重要信息的描述符,所以这里或者我们将使用BOW(bag of words)和SURF的方法。
SURF方法用于提取图像的兴趣点,它可以是轮廓、圆……因为如果我们只提取图像的兴趣点,那么输入向量将很大程度上非常小,并且只包含必要的内容,这样学习将非常快。
创建字典
在进行学习之前,我们说过必须先找到兴趣点,然后将它们放在单个矩阵中,所以此矩阵称为字典,然后从该字典中对兴趣点最多的图像进行分类分组。
为了提取点,我们将使用可完成此工作的openCV函数。我们决定为每个类拍摄10张图像进行训练,因此即使字典也必须包含10张图像的信息,因此这是我们用来提取兴趣点的代码行:
图片
因此,这些代码行将提取这些点并将其放入描述符中,最后,我们将此描述符放入保存的字典中,并在学习部分中使用它。
训练
提取兴趣点并填充字典后,我们需要找到包含我们所有学习图像之间共有兴趣点的图。
我们将使用以下代码行来进行学习,并使用此图:
图片
对于模型的参数,我们使用与点相同的参数,也使用RBF内核。
因此,在训练完成之后,我们必须保存模型,以便稍后在测试部分中使用它。
测试
现在我们必须使用openCV的预测功能来测试模型,但是在执行此操作之前,我们必须知道对于测试来说是一样的,我们不会将整个图像都放入模型的输入中,而是相反,我们必须在此处应用相同的SURF算法来提取该图像的兴趣点,并获得将要在预测输入中获得的此描述符。
因此,对于测试,我选择了每个类别的15张图像,以便我们可以简单地构建混淆矩阵。
在将我解释的方法应用于所有测试图像后,我得到了以下混淆矩阵:
图片
该矩阵表示:
  • 在有关手风琴对象的15张测试图像中,有5张分类错误的图像和10张分类正确的图像。
  • 对于“飞机”:分类良好的11张图像,分类不良的4张
  • 对于“锚”:5张图像分类良好,10张图像分类不良。
  • 对于“蚂蚁”:8张分类良好的图像和7张分类不良的图像。
我们注意到,对于“手风琴”,“飞机”和“蚂蚁”,该模型比“锚”模型更为敏感,因为它看起来很像飞机,因此飞机和锚点的兴趣点非常接近这意味着很难在测试级别上区分这两个对象
评估
为了进行评估,我们将计算每个类的误差和全局误差。尽管如此,我们可以注意到该模型的性能较差。
图片
在计算了局部误差之后,我们可以看到它并不是真正有效,这是由于以下几个因素造成的:
  • 数据的类型非常接近,这使得4个类的关注点的提取变得非常接近。
  • 训练数据,我们每班仅使用10张图像,而有必要放置更多图像,以便该模型在许多图像上学习更多。
  • 而且在测试级别上,我们仅对15张图像进行了测试,也许如果我们增加测试数据,则误差会有所降低。
结论
将SVM与SURF一起使用是一种很好的方法,因为它避免了学习图像的所有像素,并且使模型更加准确,并包含了对图像进行分类所必需的功能。
但在这种情况下,仅仅有一个好的模型是不够的,这就给出了一个好的分类——也许描述符的选择做得不好。这是我们在没有神经网络的情况下制定机器学习算法时将会遇到的问题之一,这意味着我们必须自己选择特征(我说自己是因为我们必须放置外部算法来提取特征) ,但使用神经网络,所有这些工作将自动完成,并且特征的提取将在学习过程中由网络完成。
不幸的是,由于缺乏数据,我们无法对案件进行神经网络处理。因为我认为即使在这种情况下的神经网络也无法提供更准确的结果。
你可以在此链接中找到代码
https://github.com/amine0110/opencv-for-machine-learning-using-cpp

☆ END ☆

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多