1.C++调用cmd指令
c++调用cmd指令的方式用两种:
第一种方式:system命令弹黑窗方式,
system("darknet classifier predict data/METAL/metal.data data/METAL/darknet19_448.cfg backup/_darknet19_448_final.weights data/METAL/abnor/190324141318_00002/s001_abnor.jpg");
第二种方式:
通过管道的方式调用cmd命令,管道调用可以隐藏黑窗,而且还可以获得cmd窗口的输出。
std::string CRRDlg::ExeCmd(std::wstring pszCmd)
{
// 创建匿名管道
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 "Cannot create process";
}
// 立即关闭hWrite
CloseHandle(hWrite);
// 读取命令行返回值
std::string strRetTmp;
char buff[2048] = {0};
DWORD dwRead = 0;
strRetTmp = buff;
std:;string mm_str;
CLog::GetInstance()->WriteLog(L"while (ReadFile(hRead, buff, 2048, &dwRead, NULL))");
while (ReadFile(hRead, buff, 2048, &dwRead, NULL))
{
mm_str=buff;
CLog::GetInstance()->WriteLog(StringAbout::toCString(mm_str));
strRetTmp += buff;
memset(buff,0,sizeof(buff)/sizeof(char));
}
CLog::GetInstance()->WriteLog(L"CloseHandle(hRead);");
CloseHandle(hRead);
return strRetTmp;
}
2.通过管道方式调用darknet的predict命令预测一张图片并解析预测类别和概率
void CRRDlg::ImplCmd(string order)
{
double m_allStart,m_begin,m_end,m_allend,cost,m_cost;
std::wstring cmdmy=L"darknet classifier predict data/METAL/metal.data data/METAL/darknet19_448.cfg backup/_darknet19_448_final.weights "+String2WString(order);
CLog::GetInstance()->WriteLog(StringAbout::toCString(order));
m_begin=GetTickCount();
Sleep(1000);
m_allend=GetTickCount();
m_cost=m_allend-m_begin;
CLog::GetInstance()->WriteLog(L"ExeCmd(cmdmy)");
std::string m_str=ExeCmd(cmdmy);
CLog::GetInstance()->WriteLog(L"ExeCmd(cmdmy)111");
m_end=GetTickCount();
cost=m_end-m_allend;
int pos1=m_str.find("seconds.");
//换行符站2个字符
m_str=m_str.substr(pos1+10,m_str.length()-pos1-10);
pos1=m_str.find(":");
string m_label;
m_label=m_str.substr(0,pos1);
m_str=m_str.substr(pos1+2,m_str.length()-pos1-2);
pos1=m_str.find("compute_capability");
m_str=m_str.substr(0,pos1-1);
double m_prob=_ttof(StringAbout::toCString(m_str));
CLog::GetInstance()->WriteLog(StringAbout::toCString(m_label));
int m_class;
if (m_label.compare("abnor")==0)
{
m_class=1;//异常
}else if (m_label.compare("normal")==0)
{
m_class=0;//正常
}else{
m_class=-1;//预测有问题
}
StatRes mStatRes;
mStatRes.m_class=m_class;
mStatRes.m_prob=m_prob;
mStatRes.m_time=cost;
m_vStatRes.push_back(mStatRes);
}
predict命令可以预测一张图片的类别,参数order为预测图片的路径。
3.运用predict指令预测一个指定路径下所有图片,并将解析结果保存该路径下到sample.txt和res.txt文件中
void CRRDlg::ImplDarknetOrder(CString path)
{
MyCountFile m_CountFile;
vector<string> mvfiles,mvPaths,mvfiles1;
CString findstr=L".jpg";
CLog::GetInstance()->WriteLog(path);
m_CountFile.GetAndPrintFileNames(StringAbout::toString(path),mvPaths,StringAbout::toString(findstr));
CString totalmy;
totalmy.Format(L"MyCmd路径个数:%d",mvPaths.size());
CLog::GetInstance()->WriteLog(totalmy);
string prePath,curPath;
prePath="";
for (int i=0;i<mvPaths.size();i++)
{
totalmy.Format(L"%d",i+1);
int m_pos=mvPaths[i].rfind("\\");
curPath=mvPaths[i].substr(0,m_pos+1);
if (curPath.compare(prePath)!=0&&i!=0)
{
//保存vector中的结果到图片路径prePath中,清空vector,然后执行
char* fileList=StringAbout::toCharX(StringAbout::toCString(prePath+"simple.txt"));
ofstream ofn(fileList);
for (int i=0;i<m_vStatRes.size();i++)
{
ofn <<m_vStatRes[i].m_class/*<< endl*/;
}
ofn.close();
char* resList=StringAbout::toCharX(StringAbout::toCString(prePath+"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<< endl;
}
ofnRes.close();
m_vStatRes.clear();
}
string order=mvPaths[i];
ImplCmd(order);
prePath=curPath;
}
if (m_vStatRes.size()>0)
{
//保存vector中的结果到图片路径prePath中,清空vector,然后执行
char* fileList=StringAbout::toCharX(StringAbout::toCString(prePath+"simple.txt"));
ofstream ofn(fileList);
for (int i=0;i<m_vStatRes.size();i++)
{
ofn <<m_vStatRes[i].m_class/*<< endl*/;
}
ofn.close();
char* resList=StringAbout::toCharX(StringAbout::toCString(prePath+"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<< endl;
}
ofnRes.close();
m_vStatRes.clear();
}
CLog::GetInstance()->WriteLog(L"RR.exe执行完毕");
//int a=0;
}
参数path是一批图片存放的文件夹路径,也是传给RR.exe程序的参数。
新建的基于对话框MFC程序,改为可传命令且不显示对话框方式
CRRDlg dlg;
m_pMainWnd = &dlg;
//randognmei
CString acceptCmd = theApp.m_lpCmdLine;
AfxMessageBox(acceptCmd);//185
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
}
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
//}
这样就可以在darknet的x64文件夹下,输入如下指令后,预测一批图像:
RR.exe 图片路径
图片路径可以是绝对路径也可以是相对路径
该程序支持*.jpg文件格式