我的项目是开发一个能够识别特定对象的软件,比如苹果或硬币等。我想使用Kinect。我的问题是:我是否需要使用像Haar分类器这样的机器学习算法来识别对象,还是Kinect本身就可以做到这一点?
回答:
Kinect本身无法识别对象。它会提供一个密集的深度图。然后,您可以结合一些简单的特征(在您的案例中,可能使用颜色特征或梯度特征就足够了)来使用深度特征。这些特征您可以输入到一个分类器中(例如SVM或随机森林)来训练系统。您可以使用训练好的模型来测试新的样本。
关于Haar特征,我认为它们可以完成任务,但您需要一个足够大的特征数据库。一切都取决于您想要检测什么。在苹果和硬币的情况下,仅颜色就足够了。
参考这篇论文,以了解如何使用Kinect摄像头进行人体姿态识别。您只需关注他们的深度特征和分类器。不要直接应用他们的方法。您的问题更简单。
编辑:简单的梯度方向直方图
梯度方向可以为您提供关于对象形状的粗略信息(这不是一种特定的形状特征,更好的形状特征是存在的,但这种方法计算速度极快)。
代码片段:
%calculate gradient[dx,dy] = gradient(double(img));A = (atan(dy./(dx+eps))*180)/pi; %eps added to avoid division by zero.
A将包含每个像素的方向。根据深度值分割您的原始图像。对于具有相似深度值的区域,计算颜色直方图。提取该区域对应的像素方向,称之为A_r
。计算一个9个区间的直方图(您可以有更多的区间。九个区间意味着每个区间包含180/9=20度
)。连接颜色特征和梯度直方图。对足够多的叶子执行此操作。然后,您可以将这些数据输入到分类器中进行训练。
编辑:这是对下方评论的回复。
关于opencv_traincascade中的MaxDepth
参数
文档中说,“弱树的最大深度。一个不错的选择是1,即树桩的情况”。当您执行二元分类时,它采取以下形式:
if yourFeatureValue>=learntThresh class=1;else class=0;end
上述类型对单个特征值(标量)进行阈值处理的分类器称为决策树桩。只有一个分割点将正类和负类分开(因此maxDepth
为1)。例如,它将在以下场景中工作。假设您有一个一维特征:
f=[1 2 3 4 -1 -2 -3 -4]
前四个是类1,其余是类0。决策树桩通过将阈值设置为零,可以在这个数据上获得100%的准确率。现在,假设有一个复杂的特征空间,例如:
f=[1 2 3 4 5 6 7 8 9 10 11 12];
前四个和最后四个是类1,其余是类0。在这里,您无法通过决策树桩获得100%的分类。您需要两个阈值/分割点。因此,您可以构建一个深度值为2的树。您将有2^(2-1)=2个阈值。对于深度=3,您得到4个阈值,对于深度=4,您得到8个阈值,依此类推。在这里,我假设一个单节点树的高度为1。
您可能会觉得层数越多,准确率就越高,但这会带来过拟合的问题(以及计算、内存存储等)。因此,您必须为深度设置一个合适的值。我通常将其设置为3。