【opencv之路4】基本GUI操作

1、在opencv中用对话框读取文件

初次用对话框读取文件,参考了一些代码,关键是csFilter的构建,然后调用FileDlg,在此只能返回图像路径,不能返回图像。

OnFlileSaveAs是类C布匹瑕疵键Dlg的成员函数,而类C布匹瑕疵键Dlg是CDialogEx的派生类,不可随意修改OnFlileSaveAs的参数,

只能(1)用返回return,返回参数,此时注意函数声明时返回类型,不能用void,改为所返回的类型,试了一下,不能返回IplImage

    (2)保存

CString C布匹瑕疵检测Dlg::OnFileSaveAs()
{
	CString csBMP=_T("BMP Files(*.BMP)|*.BMP|");
	CString csJPG=_T("JPEG Files(*.JPG)|*.JPG|");
	CString csTIF=_T("TIF Files(*.TIF)|*.TIF|");
	CString csPNG=_T("PNG Files(*.PNG)|*.PNG|");
	CString csDIB=_T("DIB Files(*.DIB)|*.DIB|");
	CString csPBM=_T("PBM Files(*.PBM)|*.PBM|");
	CString csPGM=_T("PGM Files(*.PGM)|*.PGM|");
	CString csPPM=_T("PPM Files(*.PPM)|*.PPM|");
	CString csSR =_T("SR  Files(*.SR) |*.SR|");
	CString csRAS=_T("RAS Files(*.RAS)|*.RAS||");

	CString csFilter=csBMP+csJPG+csTIF+csPNG+csDIB
		+csPBM+csPGM+csPPM+csSR+csRAS;

	CString name[]={_T(""),_T("bmp"),_T("jpg"),_T("tif"),_T("png"),_T("dib"),
		_T("pbm"),_T("pgm"),_T("ppm"),_T("sr"), _T("ras"),_T("")};

	CString strFileName;
	CString strExtension;

	CFileDialog FileDlg(false,NULL,NULL,OFN_HIDEREADONLY,csFilter);
	//  文件存盘对话框
	if (FileDlg.DoModal()==IDOK ) {         //  选择了文件名
		strFileName = FileDlg.m_ofn.lpstrFile;
		if (FileDlg.m_ofn.nFileExtension == 0) {  //  无文件后缀
			strExtension = name[FileDlg.m_ofn.nFilterIndex];
			strFileName = strFileName + '.' + strExtension;
			//  加文件后缀
		}

		/*C布匹瑕疵检测Doc * pDoc = GetDocument();
		ASSERT_VALID(pDoc);
		pDoc->Save(strFileName,workImg);   //  当前画面存盘
		*/
		return strFileName;
	
	}
}


2、在opencv中用坐标绘制矩形框

问题1:cvCloneImage到底何用

如果不用cvCloneImage,用第二段代码,workImg会丢失信息

void C布匹瑕疵检测Dlg::OnBnClickedButton2()
{
	// TODO: 训练无瑕疵图像
	//IplImage* workImg=NULL, *dstImg=NULL;
	//cvCopy(workImg,dstImg);
	CString FileName=OnFileSaveAs();

	//CString  Namestr=_T("无瑕疵图像");
	IplImage *workImg=cvLoadImage(FileName);
	dstImg=cvCloneImage(workImg);
	cvNamedWindow("无瑕疵图像",CV_WINDOW_AUTOSIZE);
	cvSetMouseCallback("无瑕疵图像",on_mouse,0);
	cvShowImage("无瑕疵图像",workImg);

	cvWaitKey(1000);
}

void C布匹瑕疵检测Dlg::OnBnClickedButton2()
{
	// TODO: 训练无瑕疵图像
	CString FileName=OnFileSaveAs();

	//CString  Namestr=_T("无瑕疵图像");
	IplImage *workImg=cvLoadImage(FileName);

	cvNamedWindow("无瑕疵图像",CV_WINDOW_AUTOSIZE);
	
	cvSetMouseCallback("无瑕疵图像",on_mouse,0);
	cvShowImage("无瑕疵图像",workImg);

	cvWaitKey(1000);
}

绘制具体代码为:

//鼠标移动处理函数
void on_mouse(int event,int x,int y,int flags,void* priv)
{
	//设定字体格式
	CvFont font;
	double hscale=0.5;
	double vscale=0.5;
	cvInitFont(&font,CV_FONT_HERSHEY_COMPLEX,hscale,vscale,0,1,CV_AA);

	//定义三组坐标,fir_point,cur_point;lat_point,必须设为静态,不然每次都变动
	static CvPoint fir_point={0,0};
	static CvPoint cur_point={0,0};
	static CvPoint lat_point={0,0};

	//定义两个数组存放图像
	IplImage* temp;
	char Dispstring[10];

	//编辑鼠标事件处理函数
	if ((event == CV_EVENT_MOUSEMOVE) && !(flags & CV_EVENT_LBUTTONDOWN)) 
	{
		//未按下时移动,动态显示鼠标所在位置坐标
		temp=cvCloneImage(dstImg);
		cur_point=cvPoint(x,y);
		sprintf(Dispstring,"(%d,%d)",x,y);
        cvPutText(temp,Dispstring,cur_point,&font,cvScalar(0,255,0));
		cvShowImage("无瑕疵图像",temp);
	}
	if (event==CV_EVENT_LBUTTONDOWN)
	{
		//按下鼠标左键 瞬间
		temp=cvCloneImage(dstImg);
		fir_point=cvPoint(x,y);
		
		sprintf(Dispstring,"(%d,%d)",x,y);
		cvCircle(temp,fir_point,3,cvScalar(0,255,0));//显示矩形第一个点
		cvPutText(temp,Dispstring,cur_point,&font,cvScalar(0,255,0));
		cvShowImage("无瑕疵图像",temp);
	}

	else if ((event==CV_EVENT_MOUSEMOVE)&&(flags & CV_EVENT_LBUTTONDOWN))
	{
		//鼠标左键按下移动,动态显示鼠标所在位置坐标
		temp=cvCloneImage(dstImg);
		cur_point=cvPoint(x,y);

		sprintf(Dispstring,"(%d,%d)",x,y);
		cvCircle(temp,fir_point,3,cvScalar(0,255,0));//显示矩形第一个点
		cvPutText(temp,Dispstring,fir_point,&font,cvScalar(0,255,0));
		cvRectangle(temp,fir_point,cur_point,cvScalar(0,255,0)); //画矩形框
		cvPutText(temp,Dispstring,cur_point,&font,cvScalar(0,255,0)); //显示当前点坐标
		cvShowImage("无瑕疵图像",temp);

	}
	else if (event==CV_EVENT_LBUTTONUP)
	{
		//鼠标左键松开 瞬间
		temp=cvCloneImage(dstImg);
		lat_point=cvPoint(x,y);

		sprintf(Dispstring,"(%d,%d)",x,y);
		cvCircle(dstImg,fir_point,3,cvScalar(0,255,0));//显示矩形第一个点
		cvPutText(dstImg,Dispstring,fir_point,&font,cvScalar(0,255,0));
		cvCircle(dstImg,lat_point,3,cvScalar(0,255,0));//显示矩形第一个点
		cvPutText(dstImg,Dispstring,lat_point,&font,cvScalar(0,255,0));

		cvRectangle(dstImg,fir_point,lat_point,cvScalar(0,255,0)); //画矩形框
		cvShowImage("无瑕疵图像",dstImg);

		//剪切图像
		int width=abs(fir_point.x-lat_point.x);
		int height=abs(fir_point.y-lat_point.y);
		CvRect Rect;

		if (width==0 || height==0)
		{
			return;
		}

	    IplImage *dst=cvCreateImage(cvSize(width,height),temp->depth,temp->nChannels);
	
		if(fir_point.x<lat_point.x && fir_point.y<lat_point.y)  
		{  
			Rect=cvRect(fir_point.x,fir_point.y,width,height);  
		}  
		else if(fir_point.x>lat_point.x && fir_point.y<lat_point.y)  
		{  
			Rect=cvRect(lat_point.x,fir_point.y,width,height);  
		}  
		else if(fir_point.x>lat_point.x && fir_point.y>lat_point.y)  
		{  
			Rect=cvRect(lat_point.x,lat_point.y,width,height);  
		}  
		else if(fir_point.x<lat_point.x && fir_point.y>lat_point.y)  
		{  
			Rect=cvRect(fir_point.x,lat_point.y,width,height);  
		}  

		cvSetImageROI(temp,Rect);  
		cvCopy(temp,dst);  
		cvResetImageROI(temp);  
		//cvDestroyWindow("dst");  
		cvNamedWindow("dst",1);  
		cvShowImage("dst",dst);  
		cvSaveImage("dst.jpg",dst);  
	}

}
顺便说一下 cvCopy与cvCloneImage的区别

/* Copies source array to destination array */
CVAPI(void)  cvCopy( const CvArr* src, CvArr* dst,
                     const CvArr* mask CV_DEFAULT(NULL) );

/* Creates a copy of IPL image (widthStep may differ) */
CVAPI(IplImage*) cvCloneImage( const IplImage* image );

如果设定了ROI等参数的时候,cvCopy只是复制被设定的区域,复制到一个和所设定参数相吻合的新的IplImage中
而cvCloneImage则是将整个IplImage结构复制到新的IplImage中,其中的ROI等参数也会一同复制。新的IplImage将会和原来的一模一样。

cvCopy的原型是:
void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL );
在使用这个函数之前,你必须用cvCreateImage()一类的函数先开一段内存,然后传递给dst。cvCopy会把src中的数据复制到dst的内存中。

cvCloneImage的原型是:
IplImage* cvCloneImage( const IplImage* image );
在使用函数之前,不用开辟内存。该函数会自己开一段内存,然后复制好image里面的数据,然后把这段内存中的数据返回给你。

clone是把所有的都复制过来,也就是说不论你是否设置Roi,Coi等影响copy的参数,clone都会原封不动的克隆过来。
copy就不一样,只会复制ROI区域等。用clone复制之后,源图像在内存中消失后,复制的图像也变了,而用copy复制,源图像消失后,复制的图像不变



问题2:有未经处理的异常: Microsoft C++ 异常: 内存位置 0x001ae9ec 处的 cv::Exception



3、项目所在文件夹移动

.sln项目移动后,执行时会出现问题如下:


是因为项目自动记忆了所在路径,解决方案如下:

(1)修改.sln路径,方法是用记事本打开.sln文件修改高亮部分,如我的就把"布匹瑕疵检测\布匹瑕疵检测.vcxproj"改为

“F:\代码资料\VS2010\布匹瑕疵检测\布匹瑕疵检测布匹瑕疵检测.vcxproj”

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "布匹瑕疵检测", "布匹瑕疵检测\布匹瑕疵检测.vcxproj", "{95D0A435-9AA5-49F9-90CD-BC5828D85004}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{95D0A435-9AA5-49F9-90CD-BC5828D85004}.Debug|Win32.ActiveCfg = Debug|Win32
{95D0A435-9AA5-49F9-90CD-BC5828D85004}.Debug|Win32.Build.0 = Debug|Win32
{95D0A435-9AA5-49F9-90CD-BC5828D85004}.Release|Win32.ActiveCfg = Release|Win32
{95D0A435-9AA5-49F9-90CD-BC5828D85004}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

(2)删除.sln文件从新生成,会自动配置路径
(3)设置动态路径

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值