OpenCV选取矩形区

转自http://hapkui.blog.sohu.com/74264444.html

选取矩形区域

2009年10月27日 - 寒山月影 - 寒 山 月 影

保存矩形区域

2009年10月27日 - 寒山月影 - 寒 山 月 影

哈哈,忍不住感叹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;

   }

    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值