最近完成了一个使用SVM进行图像识别的项目,总结一下整个过程的一些思考和经验。
关于特征的提取,肯定是差别越大效果越好,一般基于边缘和颜色进行一些设计,排除掉背景无关的干扰,让提取到的特征差距明显,这样通过SVM训练出来的模型可以准确分割。
不同特征如何连接呢?直接把不同的特征接在一起,训练出一个SVM模型的效果肯定是不好的,无关的特征相互干扰,导致原本可以区分开不同物体的差距被抵消了。这也是为什么要避免背景干扰,能准确定位框出肯定效果更好。定位是另外一个大的模块了,需要根据已经有的信息进行组合,提高稳定性。比较有效的做法是,一种特征训练一个模型,不同模型得到的结果再进行加权得到最后的得分。
送入SVM训练的样本,只有在边界附近的才是影响模型的,所以不需要特别多的训练数据,需要不同类的有代表性的数据,能训练出合理分割的边界。训练出模型后采集测试图,获取分类错误的数据,再送入训练,调整模型。
提高识别速度的问题,提取的特征越简单,识别速度就越快。如何简化特征呢?比如边缘,一般梯度在128的灰度值内,可以将大于128的统一为128。小于128的按4倍、8倍量化缩小,减少特征长度,损失一些精度换取更小的模型和更快的识别速度。还有就是编译优化,有时候苦苦思索算法上如何优化,其实忘记了编译上的优化,直接加速好几倍,省去了牺牲算法精度的问题。
对于解决一个大的识别问题,可以思考如何拆分成更小识别问题,用一个模型来完成这种拆分,拆分后小的分类可以提取出更有区分度的特征,再用新的模型来区分小分类里的识别问题。比如大的识别问题可以用颜色来拆分成小的类别,只要颜色差异足够大,训练的模型基本上能够100%分类准确,再从按颜色分类后的小类别里设计有区分度的特征,再去训练新的模型。层层拆分,针对性地设计特征,比想用组合起来的复杂特征训练一个模型,直接一步解决问题要有效许多。
在识别之前,先解决定位问题,定位不准确,靠识别是很难纠回去的,只要定位准确就能识别,那就应该把重点放在如何优化定位的问题上。定位问题,梯度、灰度、区域,垂直平行,连通域,多种组合提高稳定性。