2021-06-02

工件匹配MFC框架搭建

创建基于对话框的MFC项目:
对话框界面:
在这里插入图片描述
打开文件
按钮ID是button1负责选择要匹配的图,并显示在下方的picture control控件中。主要代码(直接双击按钮就可以在里面写代码):

void CMFCApplicationDlg::OnBnClickedButton1()
 {
	// TODO: 在此添加控件通知处理程序代码
	//读入待检测图像
	CFileDialog dlg(
		TRUE, _T("*.bmp"), NULL,
		OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
		_T(" All Files (*.*) |*.*||"), NULL
	);// 选项图片的约定
	dlg.m_ofn.lpstrTitle = _T("OpenImage");    // 打开文件对话框的标题名
	if (dlg.DoModal() != IDOK)                   // 判断是否获得图片
		return;
	mPath1 = dlg.GetPathName(); // 获取图片路径
	char* mmPath;
	mmPath = str2char(mPath1);
	IplImage* ipl = cvLoadImage(mmPath, 1);    // 读取彩色图片、缓存到一个局部变量ipl 中
	if (!ipl)                                   // 判断是否成功载入图片
		return;
	if (TheImage)                               // 对上一幅显示的图片数据清零
		cvZero(TheImage);
	ShowImage(ipl, IDC_STATIC1);            // 调用显示图片函数   
	cvReleaseImage(&ipl);
}

导入模板图
按钮ID是button2负责选择模板图,并显示在下方的picture control控件中。主要代码:

void CMFCApplicationDlg::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码
	CFileDialog dlg(
		TRUE, _T("*.bmp"), NULL,
		OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
		_T(" All Files (*.*) |*.*||"), NULL
	);                                       // 选项图片的约定
	dlg.m_ofn.lpstrTitle = _T("OpenImage");    // 打开文件对话框的标题名
	if (dlg.DoModal() != IDOK)                   // 判断是否获得图片
		return;
	mPath2 = dlg.GetPathName(); // 获取模板图片路径
	char* mmPath;
	mmPath = str2char(mPath2);
	IplImage* ipl = cvLoadImage(mmPath, 1);    // 读取彩色图片、缓存到一个局部变量ipl 中
	if (!ipl)                                   // 判断是否成功载入图片
		return;
	if (TheImage)                               // 对上一幅显示的图片数据清零
		cvZero(TheImage);
	ShowImage(ipl, IDC_STATIC2);            // 调用显示图片函数   
	cvReleaseImage(&ipl);
}

注册模板
按钮ID是button3负责提取模板图特征,特征提取完后在下方编辑框中显示注册成功。主要代码:

void CMFCApplicationDlg::OnBnClickedButton3()
{
	// TODO: 在此添加控件通知处理程序代码
	//注册模板按钮
	imageFilename = CString2string(mPath1);
	templateFilename = CString2string(mPath2);
	rec_num = 3;
	imagemodel = imread(imageFilename);

	template_image = imread(templateFilename);
	tempWidth = template_image.cols;
	tempHeight = template_image.rows;
	getFeatures(template_image, m_features);
	for (int i = 0; i < m_features[0].FeaturePoint.size(); i++)
	{
		template_image.at<Vec3b>(m_features[0].FeaturePoint[i].y, m_features[0].FeaturePoint[i].x)[0] = 0;
		template_image.at<Vec3b>(m_features[0].FeaturePoint[i].y, m_features[0].FeaturePoint[i].x)[1] = 0;
		template_image.at<Vec3b>(m_features[0].FeaturePoint[i].y, m_features[0].FeaturePoint[i].x)[2] = 255;//R通道
	}
	CString show ;
	char show1[20] = "注册成功!";
	show = show1;
    //show.Format(_T("%S"),show);
	SetDlgItemText(IDC_EDIT5, show);
}

这里要注意要想将“注册成功!”中文成功显示,不能用以前的show.Format(_T("%S"),show);该函数是将CString类型转换为字符型显示,但是在VS2019会显示出乱码。直接先定义字符数组然后show=show1解决了乱码问题。
开始匹配
按钮ID是button4负责进行模板匹配,匹配完成后将匹配图显示出来,并显示匹配时间,匹配信息等。主要代码:

void CMFCApplicationDlg::OnBnClickedButton4()
{
	UpdateData(true);
	// TODO: 在此添加控件通知处理程序代码
	//开始匹配按钮
	Mat Max_grad = Mat::zeros(imagemodel.rows, imagemodel.cols, CV_32F);
	Mat Max_alpha = Mat::zeros(imagemodel.rows, imagemodel.cols, CV_32F);
	double start = static_cast<double>(getTickCount());

	Match(imagemodel, m_features, Max_grad, Max_alpha);
	double time1 = (double)getTickCount();
	vector<Roi> Rois;
	getRois(rec_num, Max_grad, Max_alpha, Rois);
	Mat dst1 = imagemodel.clone();
	Mat	dst2;
	for (int i = 0; i < Rois.size(); i++)
	{
		draw_recs(dst1, dst1, Rois[i].Max_loc, Rois[i].Max_alpha, tempWidth, tempHeight);
		putText(dst1, std::to_string(Rois[i].Max_alpha), Rois[i].Max_loc, cv::FONT_HERSHEY_SIMPLEX, 0.45, CV_RGB(0, 255, 0), 1.8);
		//cout << "粗匹角度" << Rois[i].Max_alpha << "粗匹坐标" << Rois[i].Max_loc << endl;
	}

	int angle_loc, row_loc, col_loc;
	local_match(imagemodel, Rois, m_features, angle_loc, row_loc, col_loc);
	double time2 = (double)getTickCount();
	Point fin_loc = Point(col_loc, row_loc);
	draw_rec(imagemodel, template_image, dst2, fin_loc, angle_loc);
	putText(dst2, std::to_string(angle_loc), fin_loc, cv::FONT_HERSHEY_SIMPLEX, 0.45, CV_RGB(0, 255, 0), 1.8);

	Rect roi(col_loc, row_loc, tempWidth, tempHeight);
	rectangle(imagemodel, roi, Scalar(0, 0, 255), 2);

	imwrite(imageFilename, dst2);//不改变原图,只显示检测图
	mPath3 = string2CString(imageFilename);
	char* mmPath;
	mmPath = str2char(mPath3);
	IplImage* img0 = cvLoadImage(mmPath, 1);
	
	ShowImage(img0, IDC_STATIC3);            // 调用显示图片函数   
	cvReleaseImage(&img0);
	float time0 = (time2 - start) / getTickFrequency();

//	//显示数据
	CString times, angle, xlabel, ylabel;
	times.Format(_T("%.6f"), time0);
	angle.Format(_T("%d"), angle_loc);
	xlabel.Format(_T("%d"), fin_loc.x);
	ylabel.Format(_T("%d"), fin_loc.y);

	SetDlgItemText(IDC_EDIT1, times);
	SetDlgItemText(IDC_EDIT4, angle);
	SetDlgItemText(IDC_EDIT2, xlabel);
	SetDlgItemText(IDC_EDIT3, ylabel);
	
}

匹配按钮中那些匹配函数,画框函数,显示图片函数等在dlg.cpp文件中直接定义
void CMFCApplicationDlg::local_match
注意所有函数要继承CDlg对话框类,MFCApplication是项目名称
声明在dig.h头文件声明

tips:
1、加入CvvImage用于显示图片,具体可以看该博文:
https://blog.csdn.net/wgf5845201314/article/details/78186178
2、改控件的ID后会出现ID 未定义标识符,此时关闭软件重启即可;
3、opencv版本过高,GetCvSize会出错,CvSize size = cvGetSize(img);该句会中断,改成

CvSize size;
size.width = img->width;
size.height = img->height;

之后再完善!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值