您的位置:首页 > 运维架构

on_mouse OpenCV 获得矩形区域

2014-05-17 10:59 381 查看
选取矩形区域



保存矩形区域



哈哈,忍不住感叹opencv功能的强大,这要裸编出来得多不容易啊,呵呵。

下面把代码大概贴一下

用控制台函数和MFC均可,这里是MFC的情况

//view.cpp里面

将鼠标函数声明为全局函数,不然编译时cvSetMouseCallback("image",on_mouse,0)函数会报错:

'cvSetMouseCallback' : cannot convert parameter 2 from 'void (int,int,int,int,void *)' to 'void (__cdecl *)(int,int,int,int,void *)'

void on_mouse(int event,int x,int y,int flags,void *zhang);

IplImage* inpaint_mask=0;

IplImage* img0=0 ,*img=0, *inpainted=0,*selimg=0;;

CvPoint prev_pt={-1,-1} ;

CvPoint pt_beg={-1,-1},pt_end = {-1,-1};

CvPoint pt1={-1,-1},pt2={-1,-1};

CvRect rect;

鼠标事件函数

void on_mouse(int event,int x,int y,int flags,void *)

{

if (!img)

return;

if (event==CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) )

{

prev_pt=cvPoint(-1,-1);

}

else if (event==CV_EVENT_LBUTTONDOWN )

{

prev_pt=cvPoint(x,y);

pt_beg = cvPoint(x,y);//点下鼠标左键时得到起始位置

}

else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) )

{

cvZero( inpaint_mask );

cvCopy( img0, img );//拖动时随时更新恢复至原图像,然后只重绘当前拖动位置

CvPoint pt = cvPoint(x,y);

pt1.x=pt.x;

pt1.y=prev_pt.y;

pt2.x=prev_pt.x;

pt2.y=pt.y;//得到其他两个定点的位置,然后绘制矩形

cvLine( inpaint_mask, prev_pt, pt1, cvScalarAll(255),2, 8, 0 );

cvLine( inpaint_mask, prev_pt, pt2, cvScalarAll(255), 2, 8, 0 );

cvLine( inpaint_mask, pt1, pt, cvScalarAll(255), 2, 8, 0 );

cvLine( inpaint_mask, pt2, pt, cvScalarAll(255), 2,8, 0 );

cvLine( img, prev_pt, pt1, cvScalarAll(255), 2, 8, 0 );

cvLine( img, prev_pt, pt2, cvScalarAll(255), 2, 8, 0 );

cvLine( img, pt1, pt, cvScalarAll(255), 2, 8, 0 );

cvLine( img, pt2, pt, cvScalarAll(255), 2, 8, 0 );

pt_end = pt;//得到当前矩形结束位置

cvShowImage( "image", img );

}

}

主函数

void COpcv1View::OnDrawLine()

{

// TODO: Add your command handler code here

CString str;

CFileDialog filedlg(TRUE);

if(filedlg.DoModal()!=IDOK)

return;

str=filedlg.GetPathName();

if( (img0 = cvLoadImage(str,-1)) == 0 ) //打开文件

return ;

cvNamedWindow( "image", 1 );

img = cvCloneImage( img0 );

inpainted = cvCloneImage( img0 );

inpaint_mask = cvCreateImage( cvGetSize(img), 8, 1 );

cvZero( inpaint_mask );

cvZero( inpainted );

cvShowImage( "image", img );

cvShowImage( "watershed transform", inpainted );

cvSetMouseCallback("image",on_mouse,0);

for(;;)

{

int c = cvWaitKey(0);

if( (char)c == 27 )

break;

if( (char)c == 'r' )

{

cvZero( inpaint_mask );

cvCopy( img0, img );

cvShowImage( "image", img );

}

if( (char)c == 'i' || (char)c == '\n' )

{

cvNamedWindow( "inpainted image", 1 );

cvInpaint( img, inpaint_mask, inpainted, 3, CV_INPAINT_TELEA );

cvShowImage( "inpainted image", inpainted );

}

if ((char)c == 'c')

{

rect.x = min(pt_beg.x,pt_end.x);//这样得到的才准确,不能直接pt_beg.x,因为可以从右下角拉动

rect.y = min(pt_beg.y,pt_end.y);

rect.height = abs(pt_end.y - pt_beg.y);

rect.width = abs(pt_end.x - pt_beg.x);

cvSetImageROI( img0, rect );//选取目标区域,这个函数好,同学帮助告知的

CvSize size;

size.width=rect.width;

size.height=rect.height;

selimg=cvCreateImage(size,IPL_DEPTH_8U,3);//新建一个图像,这里的3个通道实际上应该判断一下是灰度图还是彩图。

cvCopy(img0,selimg,NULL);//复制感兴趣区域

cvNamedWindow( "select image", 1 );

cvShowImage("select image",selimg);

cvSaveImage("selimg.bmp",selimg);//保存

break;

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: