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