RoboMaster_SWPU铁人战队视觉组工作笔记(二)在opencv3以上中遇到的SVM坑

本文详述了从OpenCV2.4.9升级到3.0.0后,SVM几何体分类中遇到的问题及解决方案,包括参数设置、数据格式、内核选择等关键点,分享了实战代码与模型加载技巧。

一、前言

  之前做视觉工程的时候,用的是opencv2.4.9,成功用上了SVM做几何体分类,但自从opencv3对SVM的调用方法大改后,套用之前的工程就遇到了很多问题,为了给以后的人正确的指引,也为了给自己提个醒,便有了写下这篇博文的心。正文开始之前,不妨听我絮叨一下。
  铁人战队自RM第一次比赛之初创立已有5年历史,最近学校批准我们可以参加RM2020赛季机甲大师赛,大家兴奋不已。之前哭着喊着要参加RM,终于有机会参赛了,但真正落到自己头上的时候,还是有诸多问题,队员资质、比赛资金、老师支持、队伍人心、规则大改都是问题,我才意识到长路漫漫,其修远兮。这一年对我们来说是机会也是难题,难在队伍招新不达标,人员配置有很大问题,好在规则大改,意味着所有队伍都没有经验,我们更能成为一匹黑马,大杀四方。未来还有更多的年轻人来到铁人战队,有望学以成才,活出不一样的人生,甚至看着今天我们铁人战队的荣耀,为自己是铁人战队的一员而感到骄傲、自豪。我们有着责任,有着义务,排除一切艰难险阻,为了心中的白月光,热血奋斗到2020赛季结束。总之,一起加油吧,青年工程师们。

二、在opencv3.0.0中遇到的SVM坑

1、设置SVM类型,内核类型,迭代终止条件时,参数设置按网上某篇教程有错,下面的代码里面是正确的设置方法。
2、使用trainAuto时,参数不能直接给(训练数据,类型,标签),要以TrainData类对象的形式给定。
3、标签的类型必须是CV_32S,不能是CV_32F。
4、标签不能是负数,即不能给负样本设置标签为-1。
5、训练数据最好不要用push_back的形式给定,会错行,而用range方式给定,则不会错行,我用debug看过二者矩阵大小的区别,用push_back会多个30多行,另外这样拿去作为创建TrainData的参数会报错。
6、内核类型选用RBF(径向基核)还没有LINEAR(线性内核)好用,同样的训练数据,选用RBF会出现很多误判,大坑啊,谁说的用RBF能处理大部分情况的,打死。

下面是我测试过的opencv3.0.0 SVM识别装甲板数字的工程代码,仅作为参考用。

#include "./SVM_TrainAuto/svm_trainauto.h"

using namespace std;
using namespace cv;

int main()
{
    // initial SVM
   Ptr<ml::SVM> _svmClassifier = ml::SVM::create();
   _svmClassifier->setType(ml::SVM::C_SVC);   //SVM类型(允许用异常值惩罚因子C进行不完全分类)
   _svmClassifier->setKernel(ml::SVM::LINEAR);  //SVM的内核类型,一般情况下使用径向基核可以很好处理大部分情况
   _svmClassifier->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 10000, 1e-6)); //指定迭代终止的条件

   RM::MySVM mySVM;
   printf("\t\t\t\t开始获取训练集数据\n");
   mySVM.getTrainData();
   printf("\t\t\t\t成功获取训练集数据\n");
   printf("\t\t\t\tSVM训练样本开始\n");
   //SVM的训练函数是ROW_SAMPLE类型的,也就是说,送入SVM训练的特征需要reshape成一个行向量,所有训练数据全部保存在一个Mat中,一个训练样本就是Mat中的一行
   Ptr<ml::TrainData> tData = ml::TrainData::create(mySVM._trainData, ml::ROW_SAMPLE, mySVM._trainClasses);
   _svmClassifier->trainAuto(tData);//自动训练并优化参数
   _svmClassifier->save("svm.xml");
   printf("\t\t\t\tSVM训练样本结束\n");

   Mat srcImg = imread(ARMOR_IMAGE_PATH,IMREAD_COLOR);
   Mat grayImg,imageNewSize;
   cvtColor(srcImg,grayImg,COLOR_BGR2GRAY);
   resize(grayImg, imageNewSize, Size(mySVM._sampleData.width,mySVM._sampleData.height)); //统一摄像头画面里面采集到的轮廓图像的尺寸
   grayImg.release();					   //把image的矩阵信息释放(清除)
   grayImg = imageNewSize.reshape(0, 1);   //图像深度不变,把图片矩阵转为一行储存
   grayImg.convertTo(grayImg, CV_32FC1);
   int response = (int)_svmClassifier->predict(grayImg);

   switch (response)
   {
       case RM::Hero:
          putText(srcImg,mySVM._sampleData.str,Point(srcImg.size().width/2,srcImg.size().height/2),
                  FONT_HERSHEY_SIMPLEX,0.5,Scalar(0, 0, 255));
          break;

       default : break;
   }
   imshow("【效果图】",srcImg);
   waitKey(0);

   return 0;
}

SVM模型训练好后,opencv3.0.0加载模型用如下语句:

Ptr<ml::SVM> _svmClassifier = ml::SVM::load<ml::SVM>("svm.xml");

-------------------------------------------------------更新-----------------------------------------------------------
opencv3.4.6加载模型用如下语句:

Ptr<ml::SVM> _svmClassifier = ml::StatModel::load<ml::SVM>("svm.xml");

opencv3.4.6不支持图像显示窗格名有中文格式

如支持    imshow("_roiImg",_roiImg);
不支持    imshow("【原始图像】",_roiImg);

识别到的效果图如下:
在这里插入图片描述

本期作者:Young
csdn昵称:Mr.羊
RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具 RoboMaster智能数据集标注工具
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值