`
/* Includes ------------------------------------------------------------------*/
#include
#include
#include
#include
#include
#include “dtector.h”
#include “ui_dtector.h”
#include “subwinconfig/subwinconfig.h”
#include
#include
#include
#include
#include “dtector.h”
#include"opencv2/opencv.hpp"
#include
#include
#include
#include
#include
#include
#include
//https://blog.csdn.net/maweifei/article/details/60152242
QString trainImage = “/train-images.idx3-ubyte”;
QString trainLabel = “/train-labels.idx1-ubyte”;
QString testImage = “/t10k-images.idx3-ubyte”;
QString testLabel = “/t10k-labels.idx1-ubyte”;
int testLblsNum;
int imgVectorLen ;
#define OPENCV3 1
//#define SVM_HOG 1
//#define SVM_NORMAL 1
#define SVM_DILATE 1
/** ****************************************************************************
@remarks dtector::dtector(QWidget *parent) :
CBaseSubWin(parent),
ui(new Ui::dtector)
@brief 构造函数
@param [IN ] parent 父窗口指针
@return NONE
@attention
********************************************************************************/
dtector::dtector(QWidget *parent) :
CBaseSubWin(parent),
ui(new Ui::dtector)
{
ui->setupUi(this);
isDrawing = false;
//image = QImage(180,180, QImage::Format_RGB32);
image= QImage(200,200,QImage::Format_RGB32);
backColor = qRgb(0, 0, 0);
image.fill(backColor);
btnGroupSvm = new QButtonGroup(this);
btnGroupSvm->addButton(ui->norRadio,1);
btnGroupSvm->addButton(ui->theRadio,2);
connect(ui->norRadio, SIGNAL(clicked()), this, SLOT(onRadioClick()));
connect(ui->theRadio, SIGNAL(clicked()), this, SLOT(onRadioClick()));
ui->norRadio->setChecked(true);
}
/** ****************************************************************************
}
/** ****************************************************************************
/** ****************************************************************************
@remarks void dtector::SetLabelTxt
@brief 设置LABEL字符
@param
@return
@attention
********************************************************************************/
void dtector::SetLabelTxt(QLabel *pLabel,
double Value,
bool IsTrue,
char Format,
uint32_t Perc)
{
QString SetStrn = QString::number(Value, Format, Perc);
pLabel->setText(SetStrn);
if(IsTrue)
{
pLabel->setStyleSheet(“background-color:white;”);
}else
{
pLabel->setStyleSheet(“background-color:red;”);
}
}
void dtector::SetLabelTxtColor(QLabel *pLabel,
double Value,
char IsTrue,
char Format,
uint32_t Perc)
{
QString SetStrn = QString::number(Value, Format, Perc);
pLabel->setText(SetStrn);
if(IsTrue==1)
{
pLabel->setStyleSheet(“background-color:white;”);
}else if(IsTrue == 3)
{
pLabel->setStyleSheet(“background-color:green;”);
}
else
{
pLabel->setStyleSheet(“background-color:red;”);
}
}
/** ****************************************************************************
@remarks void dtector::SetLabelTxt
@brief 设置LABEL字符
@param
@return
@attention
********************************************************************************/
void dtector::SetLabelTxt(QLabel *pLabel,
bool IsTrue)
{
if(IsTrue)
{
pLabel->setText(“正常”);
pLabel->setStyleSheet(“background-color:green;”);
}
else
{
pLabel->setText(“故障”);
pLabel->setStyleSheet(“background-color:red;”);
}
}
void dtector::paintEvent(QPaintEvent *)
{//可理解为是一个绘图终端函数,在本程序中只通过update()触发,调用结束后
//这也是一个状态函数,只要没关闭mainwindow,一直待机等待update()触发
QPainter painter(this);//QPainter是绘图操作,父亲是paintwidget类而paintwidget的父亲又是mainwindow
//既关闭mainwindow就关闭paintwidget就关闭了painter
painter.drawImage(0,0, image);//把图画在image上
}
void dtector::mousePressEvent(QMouseEvent *event){
if (event->button() == Qt::LeftButton){//-------------------------鼠标按下且为左键
lastPoint = event->pos();//----------------------------------设置起点为鼠标按下的点
endPoint = event->pos();//-----------------------------------设置终点为鼠标按下的点
isDrawing = true;//------------------------------------------开始绘图了
}
}
void dtector::mouseMoveEvent(QMouseEvent *event){ //重点理解部分
if (event->buttons() & Qt::LeftButton){//-------------------------鼠标按下左键并移动
endPoint = event->pos();//-----------------------------------鼠标每移动一次都刷新终点
paint(image); //--------------理解清楚这个函数--------仔细看看void paint (QImage &theImage)函数
//---------------------------------------最后会通过update()函数调用void paintEvent(QPaintEvent *)重绘函数
//---------------------------------------再仔细看看void paintEvent(QPaintEvent *)重绘函数会把图画在image画布上
//---------------------------------------我觉得理解了这个就理解得差不多了
}
}
void dtector::mouseReleaseEvent(QMouseEvent *event){
isDrawing = false;//--------------------------------------------绘图完毕
paint(image);//--------------------------------------------------把最后一点画在image画布上,可参考上面注释
}
void dtector::paint(QImage &theImage){//------------------(画图函数)调用这个函数就是调用重绘函数,把图画在image上
QPainter p(&theImage); //------------------------------------把图画在theImage(theImage是painterDevice类型参数,由于是引用,其实就是画在image上)
QPen apen;
apen.setWidth(10);//------------------------------------------画笔线条宽度设置为5
apen.setColor(Qt::white);
p.setPen(apen);//--------------------------------------------设置画笔线条宽度,也可以不设置,既把这两句注释掉,线条默认宽度为1
p.drawLine(lastPoint, endPoint);//----------------------------画线,由于鼠标移动事件会调用此函数,因此lastPoint和endPoint相距近似为0
//---------------------------因此可近似看成画点,点连起来就是画笔的痕迹了
lastPoint = endPoint;//--------------------------------------把终点复制给起点
update();//--------------------------------------------------刷新
}
Mat dtector::ReadMnistImage(QString pathName){
int magicNumber = 0;
int imageNumber = 0;
int rows = 0;
int cols = 0;
Mat dataMat;
ifstream file(pathName.toStdString(), ios::binary);
if (file.is_open() == true){
qDebug()<(i, j) = value;
}
}
}else{
qDebug()<<" open failed "<
}
Mat dtector::ReadMnistLabel(QString pathName){
int magicNumber;
int labelNumber;
Mat labelMat;
ifstream file(pathName.toStdString(), ios::binary);
if (file.is_open() == true){
qDebug()<(i, 0) = (unsigned int)temp;
}
}else{
qDebug()<
}
int dtector::CvtToLittleEndian(int i){
unsigned char c1, c2, c3, c4;
c1 =i & 255;
c2 = (i >> 8) & 255;
c3 = (i >> 16) & 255;
c4 = (i >> 24) & 255;
return ((int)c1 << 24) + ((int)c2 << 16) + ((int)c3 << 8) + c4;
}
#if 0
void dtector::test()
{
//creat SVM classfier
Ptr svm = SVM::create();
//load train file
svm = SVM::load(“SVM_HOG.xml”);
if (!svm)
{
// ui.loadXmllabel->setText("load file faile...");
}
Mat test;
test = imread("Win32/Debug/demo.png");
//imshow("image", test);
// ui.loadImagelabel->setText(“succcess”);
//winsize(64,128),blocksize(16,16),blockstep(8,8),cellsize(8,8),bins9
//检测窗口(64,128),块尺寸(16,16),块步长(8,8),cell尺寸(8,8),直方图bin个数9
HOGDescriptor hog(Size(128, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9);
vector descriptors;//HOG描述子向量
hog.compute(test, descriptors, Size(8, 8));//计算HOG描述子,检测窗口移动步长(8,8)
int r = svm->predict(descriptors); //对所有行进行预测
// ui.testResultlabel->setText("The number is " + QString::number® + “.”);
//ui.TestButton->setText(“success”);
}
void dtector::clearPaint()
{
image = QImage(128, 128, QImage::Format_RGB32);
backColor = qRgb(0, 0, 0);
image.fill(backColor);
// ui.loadXmllabel->setText(“Waitting…”);
// ui.loadImagelabel->setText(“Waitting…”);
// ui.testResultlabel->setText(“Waitting…”);
update();
}
#endif
void dtector::on_starttrain_clicked()
{
double consumeTime = 0;
std::clock_t startTime = 0;
std::clock_t endTime = 0;
cv::Mat trainData;
cv::Mat trainDataLabels;
QString runPath = QCoreApplication::applicationDirPath();
//【1】读入训练样本
trainData = ReadMnistImage( runPath+trainImage);
trainDataLabels = ReadMnistLabel(runPath+trainLabel);
//【2】设置支持向量机的参数,SVM中的参数有很多,但是与C_SVC有关的就只有gamma和C,所以只要设置好这两个就可以了
// 其实,很多资料将gamma设置为0.01,这样训练的收敛速度就会快很多
#if OPECV2 #if OPENCV3 #if EPS // Ptr tData = TrainData::create(trainData, ROW_SAMPLE, trainDataLabels); } void dtector::on_pushButton_2_clicked() //blog.csdn.net/wblgers1234/article/details/73477860 } // cvtColor(testIma,color_mat,CV_BGR5552GRAY); // cv::imshow(“my”,testIma); #if 0 // test.convertTo(show_mat, CV_32FC1); // CvMat* SVMtrainMat=cvCreateMat(1,descriptors.size(),CV_32FC1); // for(vector::iterator iter=descriptors.begin();iter!=descriptors.end();iter++) } void dtector::on_clearscreen_clicked() void dtector::on_pushButton_clicked() #elif SVM_HOG #endif
CvSVMParams params;
params.svm_type = SVM::C_SVC;
params.kernel_type = SVM::RBF;
params.degree = 10.0;
params.gamma = 0.01;
params.coef0 = 1.0;
params.C = 10.0;
params.nu = 0.5;
params.p = 0.1;
params.term_crit = cv::TermCriteria(CV_TERMCRIT_EPS,1000,FLT_EPSILON);
//【3】训练SVM
std::cout<<"[NOTICE]Starting training process!"<
CvSVM svm;
svm.train(trainData,trainDataLabels,cv::Mat(),cv::Mat(),params);
endTime = std::clock();
consumeTime = (endTime - startTime);
qDebug()<<"[NOTICE]Finished training process…consumeTime = "<
#endif
qDebug()<<“current path :”<Ptr
svm->setTermCriteria(cv::TermCriteria(CV_TERMCRIT_EPS, 200, FLT_EPSILON));//
#endif
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 200, FLT_EPSILON));
//训练开始trainData.convertTo(trainData,CV_32FC1);
trainDataLabels.convertTo(trainDataLabels, CV_32SC1);
qDebug()<<"[NOTICE]Starting training process!";
this->ui->statu1->setText("训练需要二、三十分钟");
startTime = std::clock();
svm->train(trainData, ROW_SAMPLE, trainDataLabels);
// svm->train(tData);
endTime = std::clock();
consumeTime = (endTime - startTime);
qDebug()<<"[NOTICE]Finished training process…consumeTime = “<
svm->save(xmlPath.toStdString());
//https://blog.csdn.net/LIT_Elric/article/details/79202469
#endif
{
double consumeTime = 0;
std::clock_t startTime = 0;
std::clock_t endTime = 0;cv::Mat testDataimage;
cv::Mat testDataLabels;
QString runPath = QCoreApplication::applicationDirPath();
//【1】读入训练样本
testDataimage = ReadMnistImage( runPath+testImage);
testDataLabels = ReadMnistLabel(runPath+testLabel);
testDataimage.convertTo(testDataimage,CV_32FC1);
testDataLabels.convertTo(testDataLabels, CV_32SC1);
qDebug()<<"[NOTICE]Starting predict process!";
this->ui->statu1->setText("预测需要二、三分钟");
//载入训练好的SVM模型
QString xmlPath = runPath +"/SVM_DATA.xml";
Ptr
}
//https://blog.csdn.net/Almost_Miao/article/details/79132319
void dtector::onRadioClick()
{checkedId = btnGroupSvm->checkedId();
void dtector::on_pushButton_4_clicked()
{QString path = QString("%1/demot.bmp").arg(QApplication::applicationDirPath());
QString xmlPath = QString("%1/SVM_DATA.xml").arg(QApplication::applicationDirPath());
Ptr
cv::resize(gray,imgReadScal,imgReadScal.size());
imgReadScal.convertTo(show_mat, CV_32FC1);
// cvtColor(show_mat,show_mat,CV_RGB2GRAY);
// testIma.convertTo(testIma,CV_32FC1);show_mat = show_mat / 255;
Mat predict_mat = Mat::zeros(1, 28*28, CV_32FC1);
memcpy(predict_mat.data, show_mat.data, 28*28 * sizeof(float));
imshow("test", testIma);
float predict_label = svm->predict(predict_mat);
Mat predict_mat = Mat::zeros(1, 2828, CV_32FC1);
memcpy(predict_mat.data, testIma.data , 2828 * sizeof(float));
float predict_label = svm->predict(predict_mat);
//真实的样本标签
#endif
qDebug() << “预测结果为:”<
this->ui->result->setText(b);
// this->ui->statu1->setText(“预测准确率为:”+b);
//blog.csdn.net/wblgers1234/article/details/73477860
}else if(checkedId == 2){Mat test;
test = imread(path.toStdString(),0);
Mat show_mat = Mat::zeros(28, 28, CV_8UC3);
//检测窗口(28,28),块尺寸(14,14),块步长(7,7),cell尺寸(7,7),直方图bin个数9
HOGDescriptor hog(Size(28, 28), Size(14, 14), Size(7, 7), Size(7, 7), 9);vector
Mat predict_mat = Mat::zeros(1, 28*28, CV_32FC1); memcpy(predict_mat.data,descriptors.data(),28*28* sizeof(float));
predict_mat=predict_mat/255;
// {
// // mats(SVMtrainMat,0,n,*iter);
// predict_mat.data ++ = *iter;
// n++;
// }
imshow(“HOG”, predict_mat);
float predict_label = svm->predict(predict_mat); //对所有行进行预测qDebug() << "预测结果为:"<
{
image = QImage(200, 200, QImage::Format_RGB32);
backColor = qRgb(0, 0, 0);
image.fill(backColor);
// ui.loadXmllabel->setText(“Waitting…”);
// ui.loadImagelabel->setText(“Waitting…”);
// ui.testResultlabel->setText(“Waitting…”);
update();
}
{
QString path = QString("%1/demot.bmp").arg(QApplication::applicationDirPath());
#ifdef SVM_NORMAL
QImage newimg3 = image.scaled(28,28,Qt::KeepAspectRatio);newimg3.save(path);
QImage newimg3 = image.scaled(28,28,Qt::KeepAspectRatio);
newimg3.allGray();
newimg3.save(path);
#endif
#if SVM_DILATE
QImage newimg3 = image.scaled(28,28,Qt::KeepAspectRatio);newimg3.save(path);
this->ui->statu1->setText(“图片保存成功”);
}