caffe-3.1--(本机PC上一个完整独立的测试程序)--MFC前台+调用Caffe后台

来源:互联网 发布:加拿大医学院申请知乎 编辑:程序博客网 时间:2024/05/17 01:32

原因:因为界面和caffe不是一个程序,需要整合。

目标:在MFC前台显示一张图片,当点击“开始测试”时,得到识别率并显示在界面上

需要传入图片路径,将图片路径写入*.bat里,运行*.bat,找到输出的识别率,显示在MFC界面上。


controledit初始化

// TODO:  在此添加额外的初始化代码CEdit* pBox1;pBox1 = (CEdit*)GetDlgItem(IDC_EDIT1);CString CStrRecordData = CString("F:\\caffe-master170309\\examples\\cifar10\\194357.png");pBox1->SetWindowText(CStrRecordData);


按钮的事件响应函数,基本功能已实现,但没有显示图片

void CMFCCaffe1Dlg::OnBnClickedButton1(){// TODO: 在此添加控件通知处理程序代码// 1. 输入图片路径,送入str变量 // http://www.cnblogs.com/visionfeng/p/5611214.htmlCEdit* pBox1;pBox1 = (CEdit*)GetDlgItem(IDC_EDIT1);CString strpicPath;pBox1->GetWindowText(strpicPath);pBox1->SetWindowText(strpicPath);// fstream清空文件char* strRecordTxtPath = "F:\\caffe-master170309\\examples\\cifar10\\cmdOutputRecord.txt";std::fstream f1(strRecordTxtPath, std::fstream::out | std::ios_base::trunc);f1.close();// 2. 将str写入*.bat文件std::fstream f;std::string strBatPath = "F:\\caffe-master170309\\Build\\x64\\Debug\\calssfication.bat";f.open(strBatPath, std::ios::out);if (f){std::string str1 = "F:\\caffe-master170309\\Build\\x64\\Debug\\classification.exe";std::string str2 = "F:\\caffe-master170309\\examples\\cifar10\\cifar10_quick.prototxt";std::string str3 = "F:\\caffe-master170309\\examples\\cifar10\\cifar10_quick_iter_400.caffemodel.h5";std::string str4 = "F:\\caffe-master170309\\examples\\cifar10\\mean.binaryproto";std::string str5 = "F:\\caffe-master170309\\examples\\cifar10\\synset_words.txt";std::string str6 = strpicPath + " >" + strRecordTxtPath;// 不pause的话,cmd一闪而过即可//std::string str6 = strpicPath + " >" + strRecordTxtPath + "\n\npause";  // 在EDIT1输入"F:\caffe-master170309\examples\cifar10\194357.png";std::string strall = str1 + " " + str2 + " " + str3 + " " + str4 + " " + str5 + " " + str6; f << strall;// f << "F:\\caffe-master170309\\Build\\x64\\Debug\\classification.exe F:\\caffe-master170309\\examples\\cifar10\\cifar10_quick.prototxt F:\\caffe-master170309\\examples\\cifar10\\cifar10_quick_iter_400.caffemodel.h5 F:\\caffe-master170309\\examples\\cifar10\\mean.binaryproto F:\\caffe-master170309\\examples\\cifar10\\synset_words.txt F:\\caffe-master170309\\examples\\cifar10\\194357.png \n\npause";f.close();}// 3. MFC中调用"F:\\caffe-master170309\\Build\\x64\\Debug\\calssfication.bat"程序  system(strBatPath.c_str());        // http://blog.csdn.net/u011867581/article/details/44161787// 4. 找到Caffe测试(识别)的结果(已保存到F:\\caffe-master170309\\examples\\cifar10\\cmdOutputRecord.txt里),并输出到Edit2上std::fstream fRecord;fRecord.open(strRecordTxtPath, std::ios::in);if (fRecord){//std::istreambuf_iterator<char> beg(fRecord), end; // https://wenku.baidu.com/view/9f387877172ded630a1cb699.html//std::string recordData(beg, end);std::string recordData;std::string line;while (getline(fRecord, line))  // http://blog.csdn.net/guowenyan001/article/details/11231927{std::string s1 = line;std::string s2 = std::string("\r\n\n");std::string s3 = s1 + s2;char *cs3 = const_cast<char*>(s3.c_str());recordData += std::string(cs3);}CEdit* pBox3;pBox3 = (CEdit*)GetDlgItem(IDC_EDIT3);CString CStrRecordData = CString(recordData.c_str());pBox3->SetWindowText(CStrRecordData);fRecord.close();}


最终的效果:(根据输入的png路径,打开png并转换存储为bmp图片,通过picControl空间动态加载bmp图片),效果如下:

工程下载:链接:http://pan.baidu.com/s/1miI4J5u 密码:mh96


void CMFCCaffe1Dlg::OnBnClickedButton1(){// TODO: 在此添加控件通知处理程序代码// 0. 输入图片路径,送入str变量 // http://www.cnblogs.com/visionfeng/p/5611214.htmlCEdit* pBox1;pBox1 = (CEdit*)GetDlgItem(IDC_EDIT1);CString strPicPath;pBox1->GetWindowText(strPicPath);pBox1->SetWindowText(strPicPath);// 1. 动态加载bmp图片CImage img;//img.Load(_T("F:\\caffe-master170309\\examples\\cifar10\\194357.png")); // http://blog.csdn.net/akof1314/article/details/5167279//img.Save(_T("F:\\caffe-master170309\\examples\\cifar10\\194357.bmp")); // http://bbs.csdn.net/topics/380029681 最底下img.Load(strPicPath);   // http://blog.csdn.net/akof1314/article/details/5167279strPicPath.Replace(CString("png"), CString("bmp"));   // "F:\\caffe-master170309\\examples\\cifar10\\194357.png"变为"F:\\caffe-master170309\\examples\\cifar10\\194357.bmp"img.Save(strPicPath);       // http://bbs.csdn.net/topics/380029681 最底下/*CBitmap bitmap;// CBitmap对象,用于加载位图   // http://www.jizhuomi.com/software/193.htmlHBITMAP hBmp;// 保存CBitmap加载的位图的句柄bitmap.LoadBitmap(IDB_BITMAP1);// 将位图IDB_BITMAP1加载到bitmaphBmp = (HBITMAP)bitmap.GetSafeHandle();// 获取bitmap加载位图的句柄m_jzmPicture.SetBitmap(hBmp);// 设置图片控件m_jzmPicture的位图图片为IDB_BITMAP1*/CString  m_strfile;CRect r;GetClientRect(&r);// 格式char*转为LPCWSTR  // http://blog.csdn.net/zhouxuguang236/article/details/8761497char* szStr = "F:\\caffe-master170309\\examples\\cifar10\\194357.bmp";CString str = CString(szStr);USES_CONVERSION;LPCWSTR wszClassName = A2CW(W2A(str));str.ReleaseBuffer();HBITMAP  hbitmap = (HBITMAP)LoadImage(AfxGetInstanceHandle(),wszClassName,IMAGE_BITMAP,r.Width() / 2,r.Height() / 2,LR_LOADFROMFILE);m_jzmPicture.SetBitmap(hbitmap);// 设置图片控件m_jzmPicture的位图图片为IDB_BITMAP1  // 2. 将str写入*.bat文件// fstream清空文件char* strRecordTxtPath = "F:\\caffe-master170309\\examples\\cifar10\\cmdOutputRecord.txt";std::fstream f1(strRecordTxtPath, std::fstream::out | std::ios_base::trunc);f1.close();std::fstream f;std::string strBatPath = "F:\\caffe-master170309\\Build\\x64\\Debug\\calssfication.bat";f.open(strBatPath, std::ios::out);if (f){std::string str1 = "F:\\caffe-master170309\\Build\\x64\\Debug\\classification.exe";std::string str2 = "F:\\caffe-master170309\\examples\\cifar10\\cifar10_quick.prototxt";std::string str3 = "F:\\caffe-master170309\\examples\\cifar10\\cifar10_quick_iter_400.caffemodel.h5";std::string str4 = "F:\\caffe-master170309\\examples\\cifar10\\mean.binaryproto";std::string str5 = "F:\\caffe-master170309\\examples\\cifar10\\synset_words.txt";std::string str6 = strPicPath + " >" + strRecordTxtPath;// 不pause的话,cmd一闪而过即可//std::string str6 = strPicPath + " >" + strRecordTxtPath + "\n\npause";  // 在EDIT1输入"F:\caffe-master170309\examples\cifar10\194357.png";std::string strall = str1 + " " + str2 + " " + str3 + " " + str4 + " " + str5 + " " + str6; f << strall;// f << "F:\\caffe-master170309\\Build\\x64\\Debug\\classification.exe F:\\caffe-master170309\\examples\\cifar10\\cifar10_quick.prototxt F:\\caffe-master170309\\examples\\cifar10\\cifar10_quick_iter_400.caffemodel.h5 F:\\caffe-master170309\\examples\\cifar10\\mean.binaryproto F:\\caffe-master170309\\examples\\cifar10\\synset_words.txt F:\\caffe-master170309\\examples\\cifar10\\194357.png \n\npause";f.close();}// 3. MFC中调用"F:\\caffe-master170309\\Build\\x64\\Debug\\calssfication.bat"程序  system(strBatPath.c_str());        // http://blog.csdn.net/u011867581/article/details/44161787// 4. 找到Caffe测试(识别)的结果(已保存到F:\\caffe-master170309\\examples\\cifar10\\cmdOutputRecord.txt里),并输出到Edit2上std::fstream fRecord;fRecord.open(strRecordTxtPath, std::ios::in);if (fRecord){//std::istreambuf_iterator<char> beg(fRecord), end; // https://wenku.baidu.com/view/9f387877172ded630a1cb699.html//std::string recordData(beg, end);std::string recordData;std::string line;while (getline(fRecord, line))  // http://blog.csdn.net/guowenyan001/article/details/11231927{std::string s1 = line;std::string s2 = std::string("\r\n\n");std::string s3 = s1 + s2;char *cs3 = const_cast<char*>(s3.c_str());recordData += std::string(cs3);}CEdit* pBox3;pBox3 = (CEdit*)GetDlgItem(IDC_EDIT3);CString CStrRecordData = CString(recordData.c_str());pBox3->SetWindowText(CStrRecordData);fRecord.close();}




参考:MFC中Edit Control值的获取与赋值  设置controledit初始化

vc调用*.bat文件12  VC中如何调用其他的可执行程序

cmd输出到txt

MFC通过PicControl控件加载bmp图像1  2


第二步:“MFC+Caffe的程序"改为批处理

效果如下:(控制台界面会一闪一闪,只有最后一张图的识别结果能显示在界面上)

主要是因为:速度慢,因为把jpg转为bmp才画出来的。




改进点:

1. 加时间戳

2. 存两个txt,一个是完整的classfication.bat运行的结果从cmd重定向到txt输出的结果,另一个是上述结果的解析(包含两列:一列是图片路径;另一列是该图片的识别结果)

代码如下:

if (strTmp == ".png"){// 1. 将str写入*.bat文件,并将*.bat文件运行结果从cmd从定向到txt输出std::fstream f_classficationbat;std::string strBatPath = "F:\\caffe-master170309\\Build\\x64\\Debug\\calssfication.bat";f_classficationbat.open(strBatPath, std::ios::out);if (f_classficationbat){std::string str1 = "F:\\caffe-master170309\\Build\\x64\\Debug\\classification.exe";std::string str2 = "F:\\caffe-master170309\\examples\\cifar10\\cifar10_quick.prototxt";std::string str3 = "F:\\caffe-master170309\\examples\\cifar10\\cifar10_quick_iter_400.caffemodel.h5";std::string str4 = "F:\\caffe-master170309\\examples\\cifar10\\mean.binaryproto";std::string str5 = "F:\\caffe-master170309\\examples\\cifar10\\synset_words.txt";std::string str6 = pathStr_EachFileInFolders + " >>" + strRecognizeResultRecordFromCmdTxt;// 不pause的话,cmd一闪而过即可, "<<"为将cmd追加输出至txt//std::string str6 = pathStr_OnePic + " >" + f_RecognizeResultRecordFromCmdTxt + "\n\npause";  // 在EDIT1输入"F:\caffe-master170309\examples\cifar10\194357.png";std::string strall = str1 + " " + str2 + " " + str3 + " " + str4 + " " + str5 + " " + str6;f_classficationbat << strall << std::endl << std::endl;// f << "F:\\caffe-master170309\\Build\\x64\\Debug\\classification.exe F:\\caffe-master170309\\examples\\cifar10\\cifar10_quick.prototxt F:\\caffe-master170309\\examples\\cifar10\\cifar10_quick_iter_400.caffemodel.h5 F:\\caffe-master170309\\examples\\cifar10\\mean.binaryproto F:\\caffe-master170309\\examples\\cifar10\\synset_words.txt F:\\caffe-master170309\\examples\\cifar10\\194357.png \n\npause";f_classficationbat.close();}// 2. MFC中调用"F:\\caffe-master170309\\Build\\x64\\Debug\\calssfication.bat"程序system(strBatPath.c_str());        // http://blog.csdn.net/u011867581/article/details/44161787// 3. 将结果整理,解析到另一个txt(AnalysisOfRecognitionfromCmdTxt.txt)里,并显示在界面上std::fstream f_AnalysisOfRecognitionFromCmdTxt;char* strAnalysisOfRecognitionFromCmdTxt = "F:\\caffe-master170309\\examples\\cifar10\\AnalysisOfRecognitionfromCmdTxt.txt";// 识别结果的解析txtf_AnalysisOfRecognitionFromCmdTxt.open(strAnalysisOfRecognitionFromCmdTxt, std::ios::out);if (f_AnalysisOfRecognitionFromCmdTxt){std::fstream f_RecognizeResultRecordFromCmdTxt_2;char* strAnalysisOfRecognitionFromCmdTxt = "F:\\caffe-master170309\\examples\\cifar10\\RecognizeResultRecordFromCmd.txt";// 第二次打开,未解析的RecognizeResultRecordFromCmd.txt文件f_RecognizeResultRecordFromCmdTxt_2.open(strAnalysisOfRecognitionFromCmdTxt, std::ios::in);// 读取已经写好的RecognizeResultRecordFromCmd.txt文件,并解析然后写入另一个AnalysisOfRecognitionfromCmdTxt.txt文件if (f_RecognizeResultRecordFromCmdTxt_2){std::string OnePicPath;// 单张图片的路径std::string RecognizeAnsOfOnePic;// 该图片的识别结果std::string rubbishTmp;// 解析:就是将多余的信息去掉getline(f_RecognizeResultRecordFromCmdTxt_2, OnePicPath);// 第一行getline(f_RecognizeResultRecordFromCmdTxt_2, RecognizeAnsOfOnePic);// 第二行while (!f_RecognizeResultRecordFromCmdTxt_2.eof()){for (int i = 0; i < 4; ++i)getline(f_RecognizeResultRecordFromCmdTxt_2, rubbishTmp);// 解析时:中间多余的3行就不要了getline(f_RecognizeResultRecordFromCmdTxt_2, OnePicPath);// 读取单张图片的路径 的那一行getline(f_RecognizeResultRecordFromCmdTxt_2, RecognizeAnsOfOnePic);// 读取该单张图片对应的识别结果 的那一行f_AnalysisOfRecognitionFromCmdTxt << OnePicPath << "   " << RecognizeAnsOfOnePic << std::endl;// 两列:图片路径+识别结果}}


未解析的效果如下:


解析的效果如下:



3. 将上述的解析后的txt输出在界面上

但是不是显示一张图片出一张结果,而是所有图片播放&处理完了之后,才在界面上显示结果。

放在运行第二部:*.bat之后,但无效,如下图:

// 2. MFC中调用"F:\\caffe-master170309\\Build\\x64\\Debug\\calssfication.bat"程序system(strBatPath.c_str());        // http://blog.csdn.net/u011867581/article/details/44161787  // 如果嫌system黑窗口一闪,将system("...")替换为WinExec("cmd /c ...",SW_HIDE);// WinExec("""F:\\caffe-master170309\\Build\\x64\\Debug\\calssfication.bat", SW_HIDE);/*// 3. 读取并解析Caffe测试(识别)的结果(已保存到F:\\caffe-master170309\\examples\\cifar10\\RecognizeResultRecordFromCmdTxt.txt里),并输出到界面Edit2上// 在这里无效,显示的太快看不见的原因吧std::fstream f_RecognizeResultRecordFromCmdTxt;f_RecognizeResultRecordFromCmdTxt.open(strRecognizeResultRecordFromCmdTxt, std::ios::in);if (f_RecognizeResultRecordFromCmdTxt){std::string OnePicPath;// 单张图片的路径std::string RecognizeAnsOfOnePic;// 该图片的识别结果std::string rubbishTmp;// 解析:就是将多余的信息去掉getline(f_RecognizeResultRecordFromCmdTxt, OnePicPath);// 第一行: 读取单张图片的路径getline(f_RecognizeResultRecordFromCmdTxt, RecognizeAnsOfOnePic);// 第二行: 读取该单张图片对应的识别结果for (int i = 0; i < 4; ++i)// 跳过4行getline(f_RecognizeResultRecordFromCmdTxt, rubbishTmp);// 解析时:中间多余的4行就不要了std::string RecgnitionAns = OnePicPath + "   " + RecognizeAnsOfOnePic;// 两列:图片路径+识别结果CEdit* pBox3;pBox3 = (CEdit*)GetDlgItem(IDC_EDIT3);CString CStrRecordData = CString(RecgnitionAns.c_str());pBox3->SetWindowText(CStrRecordData);f_RecognizeResultRecordFromCmdTxt.close();}







// 4. 找到并读取Caffe测试(识别)的结果(已保存到F:\\caffe-master170309\\examples\\cifar10\\AnalysisOfRecognitionfromCmdTxt.txt里),并输出到界面Edit2上// 因为f_AnalysisOfRecognitionFromCmdTxt文件已经走到末尾了,在读也读不出东西了,必须把偏移量指向开头。我这里是关了再重新打开,然后从头读取std::fstream fRecord;fRecord.open(strAnalysisOfRecognitionFromCmdTxt, std::ios::in);if (fRecord){std::string recordData;std::string line;while (getline(fRecord, line))  // http://blog.csdn.net/guowenyan001/article/details/11231927{std::string s1 = line;std::string s2 = std::string("\r\n\n");std::string s3 = s1 + s2;char *cs3 = const_cast<char*>(s3.c_str());recordData += std::string(cs3);}CEdit* pBox3;pBox3 = (CEdit*)GetDlgItem(IDC_EDIT3);CString CStrRecordData = CString(recordData.c_str());pBox3->SetWindowText(CStrRecordData);}




4. 加一个进度条

需要提前遍历一遍,统计文件夹内有多少个png文件totalCnt,然后第二次遍历时,每当有一个png时,cnt++,算出百分比cnt / totalCnt,百分比就是进度条的值。

如下:

// 3. 进度条++pngFilecnt;CProgressCtrl *myProCtrl2 = (CProgressCtrl *)GetDlgItem(IDC_PROGRESS1);myProCtrl2->SetRange(0, 100);double pos = 100 * (pngFilecnt / totalPngFileCnt);// 因为进度条SetPos函数参数是int,而int/int = int, 故需要将范围设置为(0,100)而不是(0,1)myProCtrl2->SetPos(pos);


最终效果如下图:



程序在这:链接:http://pan.baidu.com/s/1kUS03bx 密码:ozrh

20170323,cmd窗口不出现不闪烁的程序:链接: http://pan.baidu.com/s/1i54ynA1

20170324程序,界面上的图片和标签不一同显示。


参考:我的MFC笔记

参考:后台运行bat程序

0 0
原创粉丝点击