生成好的Batch.exe拷贝到darknet的x64文件夹下,地址栏输入cmd,即打开cmd.exe并进入x64所在路径:
输入命令:
Batch.exe F:\1234\img
F:\1234\img为测试图片所在路径
1.修改基于对话框的MFC程序,使其可以接受参数,而且启动时隐藏对话框。
修改initinstance()方法:
CBatchDlg dlg;
m_pMainWnd = &dlg;
//randognmei
CString acceptCmd = theApp.m_lpCmdLine;
//AfxMessageBox(acceptCmd);//185
//acceptCmd=L"F:/1234/190418181243_00002";
CLog::GetInstance()->WriteLog(acceptCmd);
int pos=acceptCmd.Find(L"-data");
if (pos>0)
{
acceptCmd=acceptCmd.Left(pos-3);
acceptCmd=acceptCmd.Right(acceptCmd.GetLength()-1);
//AfxMessageBox(acceptCmd);//185
}
string path=StringAbout::toString(acceptCmd);
pos=path.rfind("/");
if (pos==path.length())
{
path=path.substr(0,pos);
acceptCmd=StringAbout::toCString(path);
}
dlg.ImplDarknetOrder(acceptCmd);
//INT_PTR nResponse = dlg.DoModal();
//if (nResponse == IDOK)
//{
// // TODO: Place code here to handle when the dialog is
// // dismissed with OK
//}
//else if (nResponse == IDCANCEL)
//{
// // TODO: Place code here to handle when the dialog is
// // dismissed with Cancel
//}
2.获得给定路径中所有图片的路径并调用darknet命令预测
void CBatchDlg::ImplDarknetOrder(CString path)
{
m_savePath=path;
MyCountFile m_CountFile;
vector<string> mvfiles,mvfiles1;
CString findstr=L".jpg";
CLog::GetInstance()->WriteLog(path);
m_CountFile.GetAndPrintFileNames(StringAbout::toString(path),m_vPaths,StringAbout::toString(findstr));
CString totalmy;
totalmy.Format(L"路径个数:%d",m_vPaths.size());
CLog::GetInstance()->WriteLog(totalmy);
ImplTestCmd();
}
3.ImplTestCmd()函数实现
void CBatchDlg::ImplTestCmd()
{
//获取阈值
GetThreshold();
//获得图像列表
GetImgList();
std::wstring cmdmy=L"darknet classifier test data/METAL/metal.data data/METAL/darknet19_448.cfg backup/_darknet19_448_final.weights";
CLog::GetInstance()->WriteLog(L"ExeCmd(cmdmy)");
ExeCmdBigRes(cmdmy,false);
CLog::GetInstance()->WriteLog(L"ExeCmd(cmdmy)111");
//输出结果
OutputResult();
}
3.1获得阈值
void CBatchDlg::GetThreshold()
{
CMyDirectory m_directory;
CString curPath=m_directory.GetCurrentPath();
ifstream file;
file.open("threshold.txt", ios::in);
if (!file)
{
CLog::GetInstance()->WriteLog(L"打开MyCmd.exe阈值文档threshold.txt失败");
return ;
}
double mm_threshold;
file>>mm_threshold;
file.close();
m_dthreshold=mm_threshold;
CLog::GetInstance()->WriteLog(_T("当前阈值m_dthreshold:%lf"),m_dthreshold);
}
3.2获得图像列表
void BatchDlg::GetImgList()
{
CMyDirectory m_directory;
CString curPath=m_directory.GetCurrentPath();
int comPos=curPath.Find(L"common");
CString dirPath;
if (comPos>0)
{
curPath=curPath.Left(comPos);
dirPath=curPath+L"test.list";
}else{
dirPath=/*curPath+*/L"test.list";
}
CLog::GetInstance()->WriteLog(_T("m_vPaths.size():%d"),m_vPaths.size());
//
CLog::GetInstance()->WriteLog(L"test.list保存路径:");
CLog::GetInstance()->WriteLog(dirPath);
char* resList=StringAbout::toCharX(dirPath);
ofstream ofnPath(resList);
for (int i=0;i<m_vPaths.size()+2;i++)
{
CString strJpg;
if (i<m_vPaths.size())
{
strJpg.Format(L"/s%03d.jpg",i+1);
}else{
strJpg.Format(L"/s001.jpg");
}
string ithPath=StringAbout::toString(m_savePath+strJpg);
ofnPath <<ithPath<< endl;
}
ofnPath.close();
}
3.3通过管道执行cmd指令并解析结果
void CBatchDlg::ExeCmdBigRes(std::wstring pszCmd,bool isOutCmd)
{
// 创建匿名管道
SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
HANDLE hRead, hWrite;
CLog::GetInstance()->WriteLog(L"if (!CreatePipe(&hRead, &hWrite, &sa, 0))");
if (!CreatePipe(&hRead, &hWrite, &sa, 0))
{
CLog::GetInstance()->WriteLog(L"!CreatePipe(&hRead, &hWrite, &sa, 0))");
return ;
}
// 设置命令行进程启动信息(以隐藏方式启动命令并定位其输出到hWrite
STARTUPINFO si = {sizeof(STARTUPINFO)};
GetStartupInfo(&si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdError = hWrite;
si.hStdOutput = hWrite;
// 启动命令行
PROCESS_INFORMATION pi;
CLog::GetInstance()->WriteLog(L"if (!CreateProcess(NULL, (LPWSTR)pszCmd.c_str(), NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))");
if (!CreateProcess(NULL, (LPWSTR)pszCmd.c_str(), NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
{
CLog::GetInstance()->WriteLog(L"Cannot create process");
return ;
}
CloseHandle(hWrite);
DWORD dwRead = 0;
std:;string mm_str;
vector<std::string> m_vstrRes;
CLog::GetInstance()->WriteLog(L"while (ReadFile(hRead, buff, 2048, &dwRead, NULL))");
char* distAll=StringAbout::toCharX(m_savePath+L"/cmdOutput.txt");
ofstream ofn(distAll);
list<string> strBuffer;
int i=0;
while (true)
{
i++;
char buffer[4098];
bool isEnd=ReadFile(hRead, buffer, 4096, &dwRead, NULL);
if (!isEnd)
{
break;
}
std::string strTemp = buffer;
int cont = dwRead;
if (cont<4096)
{
strTemp = strTemp.substr(0, cont);
}
int pos = strTemp.find("烫");
strTemp=strTemp.substr(0,pos);
int posa,posb,posc;
posa=strTemp.find("Loaded");
posb=strTemp.find("seconds");
posc=strTemp.find("total");
//过滤掉统计信息,只保留每张图的预测信息
if (posa==-1&&posb==-1&&posc==-1)
{
ofn<<strTemp;
CLog::GetInstance()->WriteLog(StringAbout::toCString(strTemp));
strBuffer.push_back(std::move(strTemp));
}
}
ofn.close();
CloseHandle(hRead);
CLog::GetInstance()->WriteLog(m_savePath+L"/cmdOutput.txt");
CLog::GetInstance()->WriteLog(_T("MyParseStringList(strBuffer)"));
MyParseStringList(strBuffer);
CLog::GetInstance()->WriteLog(L"CloseHandle(hRead)");
}
MyParseStringList()解析字符串
void CBatchDlg::MyParseStringList(list<string> strBuffer)
{
while (!strBuffer.empty())
{
strTm += strBuffer.front();
strBuffer.pop_front();
int pos1=strTm.find(".jpg");
CLog::GetInstance()->WriteLog(_T("MyParseStringList,int pos1=m_str.find(.jpg):pos1:%d"),pos1);
//换行符站2个字符
while(pos1>0)
{
int tmPos=strTm.find("\n");
if (tmPos<0)
{
break;
}
StatRes mStatRes;
mStatRes.m_time=50;
strTm=strTm.substr(pos1-5,strTm.length()-pos1+5);
pos1=strTm.find("\n");
int pos2=strTm.find("s");
string m_label;
m_label=strTm.substr(pos2+1,pos1-pos2-1);
CLog::GetInstance()->WriteLog(StringAbout::toCString(m_label));
strTm = strTm.substr(pos1+1, strTm.length() - pos1-1);
pos1=m_label.find(".jpg");
string strNum=m_label.substr(0,pos1);
mStatRes.m_imgNum=_ttoi(StringAbout::toCString(strNum));
CLog::GetInstance()->WriteLog(_T("MyParseStringList,编号,概率1和2,mStatRes.m_imgNum:%d"),mStatRes.m_imgNum);
int m_class;
double m_probNormal,m_probabnor;
m_probNormal=0.0;
m_probabnor=0.0;
m_label=m_label.substr(pos1+4,m_label.length()-pos1-4);
pos1=m_label.rfind(".");
if (pos1>0)
{
string normalProb=m_label.substr(1,pos1-1-2);
CLog::GetInstance()->WriteLog(StringAbout::toCString(normalProb));
m_probNormal=_ttof(StringAbout::toCString(normalProb));
if (m_probNormal>m_dthreshold)
{
m_class=0;//正常
}
else
{
m_label=m_label.substr(pos1-1,m_label.length()-pos1);
CLog::GetInstance()->WriteLog(StringAbout::toCString(m_label));
m_probabnor=_ttof(StringAbout::toCString(m_label));
m_class=1;//异常
}
}
else
{
CLog::GetInstance()->WriteLog(L"没有找到.,概率字符可能错了,m_class=1");
CLog::GetInstance()->WriteLog(StringAbout::toCString(m_label));
m_class=1;
}
if (m_class==0)
{
mStatRes.m_prob=m_probNormal;
}
else
{
mStatRes.m_prob=m_probabnor;
}
mStatRes.m_class=m_class;
m_vStatRes.push_back(mStatRes);
pos1=strTm.find(".jpg");
CLog::GetInstance()->WriteLog(_T("MyParseStringList,pos1=m_str.find(.jpg)pos:%d"),pos1);
}
}
}
3.4输出结果
void CBatchDlg::OutputResult()
{
CLog::GetInstance()->WriteLog(_T("m_vStatRes.size:%d"),m_vStatRes.size());
if (m_vStatRes.size()>0)
{
//保存vector中的结果到图片路径prePath中,清空vector,然后执行
CLog::GetInstance()->WriteLog(m_savePath+L"/simple.txt");
char* fileList=StringAbout::toCharX(m_savePath+L"/simple.txt");
//char* fileList="simple.txt";
ofstream ofn(fileList);
for (int i=0;i<m_vStatRes.size();i++)
{
ofn <<m_vStatRes[i].m_class/*<< endl*/;
}
ofn.close();
CLog::GetInstance()->WriteLog(m_savePath+L"/res.txt");
char* resList=StringAbout::toCharX(m_savePath+L"/res.txt");
//char* resList="res.txt";
ofstream ofnRes(resList);
for (int i=0;i<m_vStatRes.size();i++)
{
ofnRes <<m_vStatRes[i].m_class<<","<<m_vStatRes[i].m_prob<<","<<m_vStatRes[i].m_time<<","<<m_vStatRes[i].m_imgNum<< endl;
}
ofnRes.close();
m_vStatRes.clear();
}
}
涉及的变量定义
private:
CString m_path;
int m_num;
vector<StatRes> m_vStatRes;
vector<string> m_vPaths ;
CString m_savePath;
string strTm;
double m_dthreshold;