我是靠谱客的博主 活力长颈鹿,最近开发中收集的这篇文章主要介绍用opencv和Qt做的Svm工具,用来生成模型和测试模型说明:程序:软件的界面:,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

svm分类软件

  • 说明:
  • 程序:
  • 软件的界面:

说明:

由于公司的需要,采集到的数据能够根据数据的特性,对数据的结构进行分类,自己为了方便和测试,写了一个工具,程序并不是通用的学习机器,自己给的数据是csv格式的数据,csv的第一位数据是标志。还有256位的数据是真实的数据。程序提供给大家进行学习和参考

程序:

mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QFileDialog>
#include <QString>
#include <QDir>
#include <QDataStream>
#include <QCoreApplication>
#include <QApplication>
#include <QMessageBox>
#include <QDebug>
#include <QTimer>
#include <QTime>
#include <vector>
#include <algorithm>


#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
//#pragma comment(lib,"opencv_ml3411d.lib")

using namespace cv::ml;
using namespace cv;

//设置程序的延迟
void delay(int time)
{
    QTime t;
    t.start();
    while(t.elapsed()<time)
        QCoreApplication::processEvents();
}

//判断选择的文件夹是否是存在的
bool isDirExist(QString fullPath)
{
    QDir dir(fullPath);
    if(dir.exists())
    {
      return true;
    }
    return false;
}

bool isFileExist(QString fullName)
{
    QFile file(fullName);
    if(file.exists())
    {
        return true;
    }
    return false;
}

//设置按键全使用性
void MainWindow::setAllBtnEnabled(bool useEnable)
{
    ui->btn_csv->setEnabled(useEnable);
    ui->btn_open->setEnabled(useEnable);
    ui->btn_save->setEnabled(useEnable);
    ui->btn_start->setEnabled(useEnable);
    ui->btn_start_fo->setEnabled(useEnable);
    ui->btn_load_turn->setEnabled(useEnable);
    ui->btn_open_folder->setEnabled(useEnable);
    ui->btn_save_model->setEnabled(useEnable);
}

//读取bin文件并对应输出csv文件
bool bin2Csv(QString aFileName,QString savePath)
{
    //读写文件
    QFile   aFile(aFileName);
    if (!aFile.exists()) //文件不存在
       return false;
    if (!aFile.open(QIODevice::ReadOnly))
       return false;
    QDataStream  aStream(&aFile); //用文本流读取文件
    SaveHeader fft_header;//{ 0x11223344, 1, model.m_sample_count, model.m_fft_count };

    aStream.readRawData((char*)&fft_header,sizeof(SaveHeader));

    std::vector<std::vector<int>> data;
    std::vector<int> ve;
    while(!aStream.atEnd())
    {
        int tmp;
        aStream.readRawData((char*)&tmp,sizeof(tmp));
        ve.push_back(tmp);
        if(ve.size()>256)
        {
            data.push_back(ve);
            ve.clear();
        }
    }
    aFile.close();
    QFile  outFile(savePath);
    outFile.open(QIODevice::WriteOnly);
    QTextStream  outStream(&outFile);
    for(unsigned int i=0;i<data.size();i++)
    {
        QString line;
        line=QString::number(data[i][0]);
        for(int j=1;j<data.at(i).size();j++)
        {
            line=line+","+QString::number(data[i][j]);
        }
//        for(auto elem:data.at(i))
//        {
//            line=line+","+QString::number(elem);
//        }
        line+="n";
        outStream<<line;
        //outFile.write(line.toStdString().c_str());
    }

    outFile.close();
    return true;
}

//读取bin文件输出到一个文件中
//bool bin2OneCsv(QString aFileName)

//读取bin文件
void MainWindow::readBin2Mat(QString aFileName)
{
    //读写文件
    QFile   aFile(aFileName);
    if (!aFile.exists()) //文件不存在
       return ;
    if (!aFile.open(QIODevice::ReadOnly))
       return;
    QDataStream  aStream(&aFile); //用文本流读取文件
    SaveHeader fft_header;//{ 0x11223344, 1, model.m_sample_count, model.m_fft_count };

    aStream.readRawData((char*)&fft_header,sizeof(SaveHeader));
    //dataMat=new Mat(fft_header.sample_count,256,CV_32FC1);

    fft_header.sample_count=2;
    dataMat=new cv::Mat_<float>(fft_header.sample_count,256);
    labelMat=new cv::Mat_<int>(fft_header.sample_count, 1);
    //labelMat=new Mat(256,1,CV_32SC1);
    //Mat dataMat(fft_header.sample_count,256,CV_32FC1);
    qDebug()<<fft_header.sample_count;
    qDebug()<<fft_header.fft_count;
    for(int i=0;i<fft_header.sample_count;i++)
    {
        if(i==0)
        {
            labelMat->at<int>(i,0)=1;
        }
        else
        {
            labelMat->at<int>(i,0)=0;
        }
        //labelMat->at<int>(i,0)=0;
        int distance;
        aStream.readRawData((char*)&distance,sizeof(distance));
        for(int j=0;j<256;j++)
        {
            int tmp;
            aStream.readRawData((char*)&tmp,sizeof(int));
            float temp=(float)tmp;
            dataMat->at<float>(i, j) = temp;
        }
        int a=0;
    }
     aFile.close();//关闭文件
}

//读取csv数据(参数:cvs文件,Mat数据容器,标签容器)
bool MainWindow::readCvs2Mat(QString aFileName)
{
    QFile   aFile(aFileName);
      if (!aFile.exists()) //文件不存在
         return false;
      if (!aFile.open(QIODevice::ReadOnly | QIODevice::Text))
         return false;
      QTextStream  aStream(&aFile); //用文本流读取文件
      aStream.setAutoDetectUnicode(true); //自动检测Unicode
      QStringList strlist;
      float temp=0.0;
      int row=0;
      while (!aStream.atEnd())
      {
         row++;
         QString line;
         line=aStream.readLine();//读取文件的一行文本
         //qDebug()<<line;
         strlist.push_back(std::move(line));
      }
      aFile.close();//关闭文件
      dataMat=new cv::Mat_<float>(row,256);
      labelMat=new cv::Mat_<int>(row, 1);
      for(int i=0;i<strlist.size();i++)
      {
          QStringList split = strlist.at(i).split(",");
          //qDebug()<<split.size();

          std::vector<int>ve_data;
          if(split.at(0).toInt()>0)
          {
              labelMat->at<int>(i,0)=1;
          }
          else
          {
              labelMat->at<int>(i,0)=0;
          }
          for(int j=1;j<split.size();j++)
          {
              int a=split.at(j).toInt();
              ve_data.push_back(a);
          }
          std::vector<int>::iterator biggest =std::max_element(ve_data.begin(),ve_data.end());
          int max=*biggest;
          for(int j=0;j<ve_data.size();j++)
          {
              //qDebug()<<ve_data[j];
              temp=((float)ve_data[j])/max;
              qDebug()<<temp;
              dataMat->at<float>(i,j)=temp;
          }
      }
      return  true;
}

bool MainWindow::readAlarmCvs2Mat(QString aFileName,int threshold)
{
    QFile   aFile(aFileName);
      if (!aFile.exists()) //文件不存在
         return false;
      if (!aFile.open(QIODevice::ReadOnly | QIODevice::Text))
         return false;
      QTextStream  aStream(&aFile); //用文本流读取文件
      aStream.setAutoDetectUnicode(true); //自动检测Unicode
      QStringList strlist;
      float temp=0.0;
      while (!aStream.atEnd())
      {
         QString line;
         line=aStream.readLine();//读取文件的一行文本
         QStringList split = line.split(",");
         if(split.at(0).toInt()==threshold)
         {
             //qDebug()<<line;
             strlist.push_back(std::move(line));
         }
//         if(threshold==0&&split.at(0).toInt()>5125&&split.at(0).toInt()<5135)
//         {
//             strlist.push_back(std::move(line));
//         }
         else if(threshold==0&&split.at(0).toInt()>0)
         {
             strlist.push_back(std::move(line));
         }
      }
      aFile.close();//关闭文件
      for(int i=0;i<strlist.size();i++)
      {
          QStringList split = strlist.at(i).split(",");
          //qDebug()<<split.size();
//          if(threshold!=split.at(0).toInt())
//          {
//              continue;
//          }

          labelMat->at<int>(dataMatCount(),0)=1;
          //qDebug()<<dataMatCount();
          for(int j=1;j<split.size();j++)
          {
              temp=split.at(j).toFloat();
              //qDebug()<<temp;
              dataMat->at<float>(dataMatCount(),j-1)=temp;
          }
          m_alarmCount++;
          qDebug()<<m_alarmCount;
          if(m_alarmCount>=m_dataCount)
          {//数据达到1000,可以结束读取数据了
              return true;
          }
      }
      return  false;
}

bool MainWindow::readUnAlarmCvs2Mat(QString aFileName)
{
    QFile   aFile(aFileName);
      if (!aFile.exists()) //文件不存在
         return false;
      if (!aFile.open(QIODevice::ReadOnly | QIODevice::Text))
         return false;
      QTextStream  aStream(&aFile); //用文本流读取文件
      aStream.setAutoDetectUnicode(true); //自动检测Unicode
      QStringList strlist;
      float temp=0.0;
      int row=0;
      while (!aStream.atEnd())
      {
         row++;
         QString line;
         line=aStream.readLine();//读取文件的一行文本
         QStringList split = line.split(",");
         if(split.at(0).toInt())
         {
             //qDebug()<<line;
             strlist.push_back(std::move(line));
         }
      }
      aFile.close();//关闭文件

      for(int i=0;i<strlist.size();i++)
      {
          QStringList split = strlist.at(i).split(",");
          //qDebug()<<split.size();
          labelMat->at<int>(dataMatCount(),0)=0;
          for(int j=1;j<split.size();j++)
          {
              temp=split.at(j).toFloat();
              dataMat->at<float>(dataMatCount(),j-1)=temp;
          }
          m_unAlarmCount++;
          //判断数据量
          if(m_unAlarmCount>=m_dataCount)
          {//数据量达到,返回false
              return true;
          }
      }
      return  false;
}

bool MainWindow::matData2Csv(QString saveCsvPath)
{
    QFile  outFile(saveCsvPath);
    outFile.open(QIODevice::WriteOnly);
    QTextStream  outStream(&outFile);
    for(int i=0;i<dataMat->rows;i++)
    {
        QString lines;
        //int temp=(int)dataMat->at<float>(i,0);
        //lines=QString::number(temp);
//        if(i<DATAMIN)
//        {
//            lines+="1";
//        }
//        else
//        {
//            lines+="0";
//        }
        int a=labelMat->at<int>(i,0);
        lines=lines+QString::number(a);
        for(int j=0;j<dataMat->cols;j++)
        {
            float tmp;
            tmp=(float)dataMat->at<float>(i,j);
            lines=lines+","+QString::number(double(tmp),'f',6);//QString::number(tmp);
        }
        lines +="n";
        outStream<<lines;
    }
    outFile.close();
    return true;
}

//测试模型
bool MainWindow::testModel(QString aFileName)
{
    QFile   aFile(aFileName);
      if (!aFile.exists()) //文件不存在
         return false;
      if (!aFile.open(QIODevice::ReadOnly | QIODevice::Text))
         return false;
      QTextStream  aStream(&aFile); //用文本流读取文件
      aStream.setAutoDetectUnicode(true); //自动检测Unicode
      QStringList strlist;
      float temp=0.0;
      int row=0;
      while (!aStream.atEnd())
      {
         row++;
         QString line;
         line=aStream.readLine();//读取文件的一行文本
         QStringList split = line.split(",");

         //cv::Mat testData(1,256,CV_32F);
         cv::Mat_<float> testData(1,256);
         //qDebug()<<split.size();
         std::vector<int>ve_data;
         for(int j=1;j<split.size();j++)
         {
             int a=split.at(j).toInt();
             ve_data.push_back(a);
         }
         std::vector<int>::iterator biggest =std::max_element(ve_data.begin(),ve_data.end());
         int max=*biggest;
         for(int j=0;j<ve_data.size();j++)
         {
             qDebug()<<ve_data[j];
             temp=((float)ve_data[j])/max;
             qDebug()<<temp;
             testData.at<float>(0,j)=temp;
         }

         float r=svm->predict(testData);
         //qDebug()<<r;
         int re=(int)r;
         if(re==1)
         {
             //qDebug()<<row<<re<<"报警点";
             QString str=QString("%1t报警点").arg(row);
             ui->text_box->append(str);
         }
         else if(re==0)
         {
             //QString str=QString("%1t非报警点").arg(row);
             //ui->text_box->append(str);
             //qDebug()<<row<<re<<"非报警点";
         }

      }
      aFile.close();//关闭文件
}

//输出对应cvs
void MainWindow::outCvsMacth(QString binPath)
{
    //获取文件夹下的所有的文件
    QDir dir(binPath);
//        QStringList binList;
//        QStringList nameFilters;
//        nameFilters << "*.bin";
//        binList=dir.entryList(nameFilters, QDir::Files|QDir::Readable, QDir::Name);

    //存储到同目录csv
    dir.cdUp();
    QString cvsPath=dir.path()+"\"+"csv";
    if(!isDirExist(cvsPath))
    {
        dir.mkdir("csv");
    }
    dir.setPath(binPath);
    QFileInfoList fileList=dir.entryInfoList(QStringList() << "*.bin");
    dir.setPath(cvsPath);
    QFileInfoList fileList1=dir.entryInfoList(QStringList() << "*.csv");
    qDebug()<<"对应要转化的文件数:"<<fileList.size();
    //判断文件是否在csv文件中已经存在
    bool flag;
    for(auto elem:fileList)
    {
        flag=false;
        for(auto elem1:fileList1)
        {
            if(elem.baseName()==elem1.baseName())
            {
                flag=true;
                break;
            }
        }
        if(!flag)
        {
            //QString savestr=binPath+"/"+elem.baseName()+".csv";
            QString savestr=cvsPath+"\"+elem.baseName()+".csv";
            bin2Csv(elem.filePath(),savestr);
            qDebug()<<elem.baseName();
        }
    }
}

//输出一个cvs
bool MainWindow::outCvsSingle(QString binPath)
{
    QDir dir(binPath);
    dir.cdUp();
    QString cvsPath=dir.path()+"\"+"csv";
    if(!isDirExist(cvsPath))
    {
        dir.mkdir("csv");
    }
    dir.setPath(binPath);
    QFileInfoList fileList=dir.entryInfoList(QStringList() << "*.bin");
    //判断文件是否存在
    QString savePath=cvsPath+"\"+"all.csv";
    if(isFileExist(savePath)) return false;
    QStringList strList;

    qDebug()<<"一个要转化的文件数:"<<strList.size();
    for(auto elem:fileList)
    {
        //读写文件
        QFile   aFile(elem.filePath());
        if (!aFile.exists()) //文件不存在
           return false;
        if (!aFile.open(QIODevice::ReadOnly))
           return false;
        QDataStream  aStream(&aFile); //用文本流读取文件
        SaveHeader fft_header;//{ 0x11223344, 1, model.m_sample_count, model.m_fft_count };

        aStream.readRawData((char*)&fft_header,sizeof(SaveHeader));
        std::vector<std::vector<int>> data;
        std::vector<int> ve;
        while(!aStream.atEnd())
        {
            int tmp;
            aStream.readRawData((char*)&tmp,sizeof(tmp));
            ve.push_back(tmp);
            if(ve.size()>256)
            {
                data.push_back(ve);
                ve.clear();
            }
        }
        aFile.close();

        QFile  outFile(savePath);
        outFile.open(QIODevice::WriteOnly|QIODevice::Append);
        QTextStream  outStream(&outFile);
        for(unsigned int i=0;i<data.size();i++)
        {
            QString line;
            line=QString::number(data[i][0]);
            for(int j=1;j<data.at(i).size();j++)
            {
                line=line+","+QString::number(data[i][j]);
            }
            line+="n";
            outStream<<line;
        }

        outFile.close();
    }
}

//输出需要的数据
bool MainWindow::outCvsNeed(QString binPath,int from,int to)
{
    QDir dir(binPath);
    dir.cdUp();
    QString cvsPath=dir.path()+"\"+"csv";
    if(!isDirExist(cvsPath))
    {
        dir.mkdir("csv");
    }
    dir.setPath(binPath);
    QFileInfoList fileList=dir.entryInfoList(QStringList() << "*.bin");
    //判断文件是否存在
    QString savePath=cvsPath+"\"+"allNeed.csv";
    //if(isFileExist(savePath)) return false;
    QStringList strList;

    for(auto elem:fileList)
    {
        //读写文件
        QFile   aFile(elem.filePath());
        if (!aFile.exists()) //文件不存在
           return false;
        if (!aFile.open(QIODevice::ReadOnly))
           return false;
        QDataStream  aStream(&aFile); //用文本流读取文件
        SaveHeader fft_header;//{ 0x11223344, 1, model.m_sample_count, model.m_fft_count };

        aStream.readRawData((char*)&fft_header,sizeof(SaveHeader));
        std::vector<std::vector<int>> data;
        std::vector<int> ve;
        int temp[256]{0};
        int ncount=0;
        bool isNeed=false;
        while(!aStream.atEnd())
        {
            int tmp;
            aStream.readRawData((char*)&tmp,sizeof(tmp));
            if(ncount==0)
            {
                if(tmp>=from&&tmp<=to)
                {
                    isNeed=true;
                }
            }
            if(isNeed)
            {
                ve.push_back(tmp);
                if(ve.size()>256)
                {
                    data.push_back(ve);
                    ve.clear();
                }
            }
            ncount++;
            if(ncount>256)
            {
                ncount=0;
                isNeed=false;
            }
        }
        aFile.close();

        qDebug()<<"一个要转化的文件数:"<<data.size();
        QFile  outFile(savePath);
        outFile.open(QIODevice::Append);
        QTextStream  outStream(&outFile);
        for(unsigned int i=0;i<data.size();i++)
        {
            QString line;
            line=QString::number(data[i][0]);
            for(int j=1;j<data.at(i).size();j++)
            {
                line=line+","+QString::number(data[i][j]);
            }
            line+="n";
            outStream<<line;
        }

        outFile.close();
    }
}

//csv数据文件的处理
bool MainWindow::findCvs2Need(QString csvPath,int from,int to)
{
    QDir dir(csvPath);
    dir.cdUp();
    QString savePath=dir.path()+"\"+"csv";
    if(!isDirExist(savePath))
    {
        dir.mkdir("csv");
    }
    dir.setPath(csvPath);
    QString saveCsvPath=savePath+"\allCsvNeed.csv";
    //遍历文件夹内文件
    QFileInfoList fileList=dir.entryInfoList(QStringList() << "*.csv");
    //QStringList fileList=dir.entryList(QStringList() << "*.csv");
    for(auto file:fileList)
    {

    QFile   aFile(file.filePath());
      if (!aFile.exists()) //文件不存在
         return false;
      if (!aFile.open(QIODevice::ReadOnly | QIODevice::Text))
         return false;
      QTextStream  aStream(&aFile); //用文本流读取文件
      aStream.setAutoDetectUnicode(true); //自动检测Unicode
      QStringList strlist;
      while (!aStream.atEnd())
      {
         QString lines;
         lines=aStream.readLine();//读取文件的一行文本
         QStringList list=lines.split(",");
         if(list[0].toInt()>=from&&list[0].toInt()<=to)
         {
              strlist.push_back(std::move(lines));
         }
      }
      aFile.close();//关闭文件

      QFile  outFile(saveCsvPath);
      outFile.open(QIODevice::Append);
      QTextStream  outStream(&outFile);
      for(int i=0;i<strlist.size();i++)
      {
          strlist[i]+="n";
          outStream<<strlist[i];
      }
      outFile.close();
    }
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->btn_save_model->setEnabled(false);
    setWindowTitle("SVN-机器学习模型");
    QString str=QString("请选择需要学习的文件");
    ui->text_box->append(str);
    //设置edit显示的内容最大数
    ui->text_box->document()->setMaximumBlockCount(500);
    //ui->text_box->deleteLater();
    //ui->btn_save_model->setEnabled(false);

    svm->setType(cv::ml::SVM::C_SVC);
    svm->setKernel(cv::ml::SVM::LINEAR);
    svm->setC(0.01);

    //2000组数据,报警1000,环境1000
    dataMat=new cv::Mat_<float>(MATCOUNT,256);
    labelMat=new cv::Mat_<int>(MATCOUNT, 1);
    //选择要bin转化为csv的文件夹
    connect(ui->btn_csv,&QPushButton::clicked,this,[&](){
        QString binPath;
        QString curPath=QCoreApplication::applicationDirPath();
        binPath=QFileDialog::getExistingDirectory(this,"选择有bin文件的文件夹",curPath);
        ui->edit_csv_path->setText(binPath);
        QString str=QString("【选择的转化文件夹】:%1").arg(binPath);
        ui->text_box->append(str);
        qDebug()<<binPath;
    });

    //bin转csv(存储到csv)
    connect(ui->btn_load_turn,&QPushButton::clicked,this,[&](){
        QString binPath=ui->edit_csv_path->text();
        if(!isDirExist(binPath)||binPath=="")
        {
            QMessageBox::critical(this, "错误", "选择的处理的文件夹不存在");
            return ;
        }


        setAllBtnEnabled(false);
        ui->text_box->append("【转化中】");
        delay(1000);

        int type=ui->combo_bin_type->currentIndex();
        switch(type)
        {
            case 0:
                outCvsMacth(binPath);
                break;
            case 1:
                outCvsSingle(binPath);
                break;
            case 2:
                bool fromOk;
                bool toOk;
                int from=ui->edit_from->text().toInt(&fromOk);
                int to=ui->edit_to->text().toInt(&toOk);
                if(fromOk&&toOk)
                outCvsNeed(binPath,from,to);
                else
                QMessageBox::critical(this, "错误", "范围错误");
                break;
        }

        ui->text_box->append("【转化完成】");
        setAllBtnEnabled(true);
    });

    //选择csv要处理的文件夹
    connect(ui->btn_csv_3,&QPushButton::clicked,this,[&](){
        QString path;
        QString curPath=QCoreApplication::applicationDirPath();
        path=QFileDialog::getExistingDirectory(this,"选择有cvs文件的文件夹",curPath);
        ui->edit_csv_path_3->setText(path);
        QString str=QString("【选择的csv文件夹】:%1").arg(path);
        ui->text_box->append(str);
    });

    //处理csv文件
    connect(ui->btn_screen,&QPushButton::clicked,this,[&](){
        QString path=ui->edit_csv_path_3->text();
        if(!isDirExist(path)) return;
        bool fromOk;
        bool toOk;
        int from=ui->edit_csv_from->text().toInt(&fromOk);
        int to=ui->edit_csv_to->text().toInt(&toOk);
        if(fromOk&&toOk)
        {
            findCvs2Need(path,from,to);
        }
        else
        QMessageBox::critical(this, "错误", "范围错误");
    });

    //选择要训练的csv文件
    connect(ui->btn_open,&QPushButton::clicked,this,[&](){
        //打开文件选框
        QString curPath=QDir::currentPath();
        QString dlgTitle=QString("选择一个文件");
        QString filter=QString("文本文件(*.bin *.csv);;文本文件2(*.jpg *.gif);;所有文件(*.*)");
        QString aFileName=QFileDialog::getOpenFileName(this,
                            dlgTitle, curPath, filter);
        if (!aFileName.isEmpty())
        {
            m_openPath=aFileName;
            ui->edit_open_path->setText(aFileName);
            QString str=QString("【指定的文件】:%1").arg(aFileName);
            ui->text_box->append(str);
        }

        //读取数据
        readCvs2Mat(m_openPath);

    });

    //选择csv文件进行训练
    connect(ui->btn_start,&QPushButton::clicked,this,[&](){
        QString cvsPath=ui->edit_open_path->text();
        if(!isFileExist(cvsPath))
        {
            QString dlgTitle="错误";
            QString strInfo="指定的文件错误";
            QMessageBox::critical(this, dlgTitle, strInfo);
            return ;
        }
        //ui->btn_save_model->setEnabled(false);
        ui->btn_start->setEnabled(false);
        ui->text_box->append("【训练开始】");

        readCvs2Mat(cvsPath);
        auto result=svm->trainAuto(*dataMat,cv::ml::ROW_SAMPLE,*labelMat);
        //auto result=svm->train(*dataMat, cv::ml::ROW_SAMPLE,*labelMat);
        //auto result=svm->train(sampleMat,cv::ml::ROW_SAMPLE,labelMat);

        if(result)
        {
            ui->text_box->append("【训练完成】");
        }
        else
        {
            ui->text_box->append("【训练失败】");
        }
        ui->btn_save_model->setEnabled(true);
        ui->btn_start->setEnabled(true);
    });

    //选择模型保存的路径
    connect(ui->btn_save,&QPushButton::clicked,this,[=](){
        QString curPath=QCoreApplication::applicationDirPath();
           QString dlgTitle="保存文件";
           QString filter="xml文件(*.xml);;所有文件(*.*)";
           QString aFileName=QFileDialog::getSaveFileName(this,dlgTitle,curPath,filter);
           if (!aFileName.isEmpty())
           {
               m_savePath=aFileName;
               ui->edit_save_path->setText(aFileName);
               QString str=QString("【保存文件】:%1").arg(aFileName);
               ui->text_box->append(str);
           }
    });

    //保存模型
    connect(ui->btn_save_model,&QPushButton::clicked,this,[=](){
        QString savePath=ui->edit_save_path->text();
        //if(!isFileExist(savePath))
        if(savePath=="")
        {
            QString dlgTitle="错误";
            QString strInfo="保存模型的路径错误";
            QMessageBox::critical(this, dlgTitle, strInfo);
            return ;
        }
        //svm->cv::ml::SVM::save("C:\Users\ae\Desktop\SvnDvs\test.xml");
        //保存模型的csv文件
        if(ui->checkBox->isChecked())
        {
            QStringList list=savePath.split(".");
            QString path=list[0]+".csv";
            matData2Csv(path);
        }
        svm->cv::ml::SVM::save(savePath.toStdString());
        //测试模型
        QString str="C:\Users\ae\Desktop\model\modelCvs\testModel.csv";
        testModel(str);
        ui->text_box->append("【模型已存】");
    });

    //打开csv文件夹
    connect(ui->btn_open_folder,&QPushButton::clicked,this,[&](){
        QString csvPath;
        QString curPath=QCoreApplication::applicationDirPath();
        csvPath=QFileDialog::getExistingDirectory(this,"选择有cvs文件的文件夹",curPath);
        ui->edit_open_path_2->setText(csvPath);
        QString text=QString("【使用csv文件夹】:%1").arg(csvPath);
        ui->text_box->append(text);
        qDebug()<<csvPath;
    });

    //选择文件夹训练
    connect(ui->btn_start_fo,&QPushButton::clicked,this,[&](){
        ui->text_box->append("【训练开始】");
        QString dirPath=ui->edit_open_path_2->text();
        //初始化
        m_alarmCount=0;
        m_unAlarmCount=0;
        setAllBtnEnabled(false);
        //ui->btn_start_fo->setDisabled(true);
        ui->text_box->append("【训练中】");
        delay(1000);

        //计算给的数据量
        m_dataCount=ui->spinBox_2->value();
        dataMat=new cv::Mat_<float>(m_dataCount,256);
        labelMat=new cv::Mat_<int>(m_dataCount,1);

        QStringList dirPaths;
        QDir splDir(dirPath);        
        //获取子目录的名字
        QFileInfoList names = splDir.entryInfoList(QDir::Dirs| QDir::NoDotAndDotDot);
        for(auto elem:names)
        {
            bool a;
            elem.baseName().toInt(&a);
            if(a)
            {
                m_threshold=elem.baseName().toInt();
                qDebug()<<elem.baseName();
                qDebug()<<elem.filePath();
                if(m_alarmCount>=m_dataCount) continue;
                //遍历文件夹内文件
                QDir dir(elem.filePath());
                QFileInfoList fileList=dir.entryInfoList(QStringList() << "*.csv");
                //QStringList fileList=dir.entryList(QStringList() << "*.csv");
                for(auto file:fileList)
                {
                    qDebug()<<file.filePath();
                    bool datafull=readAlarmCvs2Mat(file.filePath(),m_threshold);
                    if(datafull)
                    {
                        break;
                    }
                }
            }
            else if(elem.baseName()=="环境")
            {
                qDebug()<<elem.baseName();
                if(m_unAlarmCount>=m_dataCount) continue;
                //遍历文件夹内文件
                QDir dir(elem.filePath());
                QFileInfoList fileList=dir.entryInfoList(QStringList() << "*.csv");
                //QStringList fileList=dir.entryList(QStringList() << "*.csv");
                for(auto file:fileList)
                {
                    qDebug()<<file.filePath();
                    bool datafull=readUnAlarmCvs2Mat(file.filePath());
                    if(datafull)
                    {
                        break;
                    }
                }
            }
            else if(elem.baseName()=="csv")
            {

                if(m_alarmCount>=m_dataCount) continue;
                //遍历文件夹内文件
                QDir dir(elem.filePath());
                QFileInfoList fileList=dir.entryInfoList(QStringList() << "*.csv");
                //QStringList fileList=dir.entryList(QStringList() << "*.csv");
                for(auto file:fileList)
                {
                    qDebug()<<file.filePath();
                    bool datafull=readAlarmCvs2Mat(file.filePath(),0);
                    if(datafull)
                    {
                        break;
                    }
                }
            }
        }

        if(dataMatCount()==DATAMIN*2)
        {
            qDebug()<<dataMatCount();
            //训练
            svm->trainAuto(*dataMat, cv::ml::ROW_SAMPLE,*labelMat);
            //svm->train(*dataMat, cv::ml::ROW_SAMPLE,*labelMat);
            //测试模型
            QString str="C:\Users\ae\Desktop\svm的算法模型\FFT\test\test.csv";
            testModel(str);
        }
        else
        {
            qDebug()<<dataMatCount();
            qDebug()<<"数据量不够"<<endl;
            setAllBtnEnabled(true);
            ui->btn_save_model->setEnabled(false);
            return;
        }
        ui->text_box->append("【训练结束】");
        setAllBtnEnabled(true);


        //加载模型
        //svm->load("C:\Users\ae\Desktop\test\svmtest.xml");
        //svm=Algorithm::load<SVM>("C:\Users\ae\Desktop\test\test.xml");

        return;


        return;
        QFileInfoList fileInfoListInSplDir = splDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
        for(auto elem:fileInfoListInSplDir)
        {
            //获取子目录下的文件
            int a;
            a=elem.absoluteFilePath().toUInt();
            if(a)
            {
            splDir.setPath(elem.absoluteFilePath());
            QFileInfoList fileList=splDir.entryInfoList(QStringList() << "*.csv");
            //读取csv的内容
            for(auto elem1:fileList)
            {

            }
           }
        }

        for(auto elem:fileInfoListInSplDir)
        {
            dirPaths<<elem.absoluteFilePath();
            qDebug()<<elem.path();
        }
        for(auto elem:dirPaths)
        {
            qDebug()<<elem;
        }
    });


    //加载模型的按键
    connect(ui->btn_load_model,&QPushButton::clicked,this,[&](){
        //打开文件选框
        QString curPath=QDir::currentPath();
        QString dlgTitle=QString("选择一个csv文件");
        QString filter=QString("文本文件(*.xml);;文本文件2(*.jpg *.gif);;所有文件(*.*)");
        QString aFileName=QFileDialog::getOpenFileName(this,dlgTitle, curPath, filter);
        ui->edit_load_model_path->setText(aFileName);
    });

    //加载测试数据按键
    connect(ui->btn_load_test_data,&QPushButton::clicked,this,[&](){
        //打开文件选框
        QString curPath=QDir::currentPath();
        QString dlgTitle=QString("选择一个csv文件");
        QString filter=QString("文本文件(*.bin *.csv);;文本文件2(*.jpg *.gif);;所有文件(*.*)");
        QString aFileName=QFileDialog::getOpenFileName(this,dlgTitle, curPath, filter);
        ui->edit_load_test_data_path->setText(aFileName);
    });

    connect(ui->btn_test_model,&QPushButton::clicked,this,[&](){
        QString loadModel=ui->edit_load_model_path->text();
        QString testData=ui->edit_load_test_data_path->text();
        if(testData=="")
        {
            testData="C:\Users\ae\Desktop\model\modelCvs\testModel.csv";//默认路径
        }
        else
        {
            if(!isFileExist(testData)) return;
        }
        if(loadModel=="")
        {
            //loadModel="";//默认路径
            if(!svm.empty())
            {
                testModel(loadModel);
            }
        }
        else
        {
            if(isFileExist(loadModel))
            {
                svm=Algorithm::load<SVM>(loadModel.toStdString());
                if(!svm.empty())
                {
                    testModel(testData);
                }
            }
            else
            {
                ui->text_box->append("指定的模型为空或者无效");
            }
        }
    });
}


MainWindow::~MainWindow()
{
    delete ui;
}
//tab_1切换文件输出模式
void MainWindow::on_combo_bin_type_currentIndexChanged(int index)
{
    //判断当前的选择
    if(index==2)
    {
        ui->edit_from->show();
        ui->edit_to->show();
    }
    else
    {
        ui->edit_from->hide();
        ui->edit_to->hide();
    }
}


软件的界面:

在这里插入图片描述

最后

以上就是活力长颈鹿为你收集整理的用opencv和Qt做的Svm工具,用来生成模型和测试模型说明:程序:软件的界面:的全部内容,希望文章能够帮你解决用opencv和Qt做的Svm工具,用来生成模型和测试模型说明:程序:软件的界面:所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部