OpenCV 结合 SURF 和神经网络

Posted

技术标签:

【中文标题】OpenCV 结合 SURF 和神经网络【英文标题】:OpenCV Combining SURF with Neural Network 【发布时间】:2013-01-01 05:24:41 【问题描述】:

我想从静态图像中识别车辆(汽车、自行车等)。 我正在考虑使用 SURF 来获得有用的 keypointsdescriptors,然后训练 MLP(多层感知器)神经网络。 但是我不知道神经网络的输入和输出是什么,以便我可以识别车辆位于图像的哪个部分(可能是围绕它绘制的矩形)。 我知道 SURF 可以返回图像中有用的关键点及其描述符(我已经这样做了)。关键点有角度,每个关键点对应一个64或128长的Vector作为Descriptor。 我不知道这些关键点究竟是什么以及如何将它们用作神经网络的输入。

我将 OpenCV 与 Python 一起使用。

我不熟悉使用 SURF 和其他特征提取方法。任何与此相关的帮助都会非常好。

【问题讨论】:

【参考方案1】:

我的建议是观察 BOW 而不是神经网络。请参阅此处使用带有词袋模型的 SURF 进行对象分类的示例 (first part,second part)。为了提高分类性能,您可以尝试用 SVM 替换朴素贝叶斯分类器。 另外,作者提供了很好的source code example。我认为这是一个很好的起点。

【讨论】:

我检查了您指定的 BOW 技术。这似乎很有希望,但是我一直在寻找一种可以从磁盘保存和加载的学习过程(学习继续),就像神经网络一样。我已经设法使用 surf 提取特征描述符,但是数据是多维的('N' 个关键点 vs 128 个特征向量)我的新问题是如何将多维数据输入到神经网络中?【参考方案2】:

如果您使用冲浪功能,这意味着浮动偏移向量 [128] 或 [64] 取决于您的冲浪配置,您将按如下方式设置神经网络

-使用模型创建数据库:

-bikes
-cars
-autobus
-truck

-为每种类型的物体拍摄不同的照片,例如 10 张不同的汽车模型照片、10 张不同的自行车模型照片、10 张不同的卡车模型照片……等等,每个物体类别的每张照片都提取其冲浪特征向量。

-像这样,每种类型的对象将代表神经网络中的一类对象;

-car   ;object class 1 =binary representaation in 4 bits= 0 0 0 1
-bikes ;obejct class 2 =binary representaation in 4 bits= 0 0 1 0 
-truck ;obejct class 3 =binary representaation in 4 bits= 0 0 1 1
-ball  ;obejct class 4 =binary representaation in 4 bits= 0 1 0 0

-二进制表示中的每一位将对应网络输出层中的一个神经元,代表一类待识别对象

现在神经网络的配置将根据特征向量的大小和你想用这种方式识别的对象类型的数量;

输入层中的神经元数量;64 或 128,取决于您配置和使用的 surf 特征向量的大小

神经网络中输出层的神经元数量将是您在本例中要识别的对象类别的数量 4

每个神经元需要的激活函数是 sigmoid 或 tanh 函数 (http://www.learnartificialneuralnetworks.com/),因为 surf 特征由浮点数表示,如果您使用怪异特征或其他二进制局部特征描述符(Brisk、ORB、BRief)然后你将对每个神经元使用二进制激活函数,如阶跃函数 o sigm 函数

用于训练网络的算法是反向传播

在继续之前,您需要设置和准备数据集以训练神经网络

例子

-all feature vector extracted from picture belong a car will be label or asociated to class 1               
-all feature vector extracted from picture belong a bike will be label or asociated to class 2
-all feature vector extracted from picture belong a truk will be label or asociated to class 3
-all feature vector extracted from picture belong a ball will be label or asociated to class 4

在这个例子中,输出层有 4 个神经元,输入层有 128 个 0r 64 个神经元。

-神经网络在识别模式下的输出将是这4个神经元中具有最高值的神经元。

在开始训练阶段之前,它必须在 [0,1] 区间内对数据集中的所有特征使用归一化,因为神经网络的输出是输入向量属于 1 的概率数据集中的对象类。

训练网络的数据集必须按如下方式拆分:

-70% off the data used to train
-15% off the data used to validate the network arquitecture (number of neurons in the hidden layyer)
-15% off the data used to test the final network

在训练神经网络时,停止标准是识别率,当识别率接近85-90%时

为什么使用神经网络而不是 svm 机器,svm 机器工作得很好,但它不能在像这样的线性分类问题或当你有很多不同的对象类或对象类型时做出最好的分离类图,这种缺乏在识别阶段结果中很重要

我建议您阅读一些有关神经网络理论的内容,以了解它们的工作原理

http://link.springer.com/chapter/10.1007%2F11578079_10

opencv 有机器学习类到神经网络 mlp 模块

希望对你有帮助

【讨论】:

感谢您向我解释如何使用神经网络进行对象识别。但是,在我的场景中,可能必须处理彼此靠近的类似对象(例如,彼此相邻的两辆出租车)。我需要能够单独识别它们。神经网络有什么办法可以帮助我解决这个问题吗?我觉得使用你提到的技术可以让我识别车辆但不能单独分开它们(就像在两辆出租车周围画一个矩形)【参考方案3】:

分离检测到的对象的一种简单方法是运行轮廓检测器 在像that这样的输入图像中。

之后,您可以使用来自每个关键点的 x,y 坐标与神经网络识别的每个特征向量相关联,并检查这些关键点中有多少在每个对象的每个轮廓旁边,

同时它让您设置一个阈值来验证正确的汽车检测,例如,如果您有 2 辆出租车;2 个轮廓属于每辆车,然后检查每个轮廓中有多少个关键点;

轮廓属于出租车 1,里面有 20 个关键点 轮廓属于出租车1,里面有5个关键点

您可以将出租车 1 或汽车 1 视为识别的对象

当您识别出验证对象及其轮廓时,您可以计算关闭对象的边界框

另一种方法是对每个训练图像提取其属于每个对象的轮廓,计算其边界框,像纯图像一样使用它来提取特征并使其成为训练集的所有图片

【讨论】:

以上是关于OpenCV 结合 SURF 和神经网络的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV Sift/Surf/Orb:drawMatch 功能无法正常工作

OpenCV:从用户定义的关键点中提取 SURF 特征

NVIDIA GPU / CUDA 中使用 OpenCV 深度神经网络模块

OpenCV中的SURF(Speeded-Up Robust Features 加速鲁棒特征)

OpenCV - 使用 SURF 描述符和 BruteForceMatcher 进行对象匹配

尽管设置了标志 DOPENCV_ENABLE_NONFREE=ON,但运行 opencv 获得专利的 SIFT 和 SURF 的问题