C++编写小软件RR.exe通过predict命令调用已经训练好的darknet模型

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文件格式

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

haimianjie2012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值