on_mouse OpenCV 获得矩形区域

选取矩形区域

保存矩形区域

哈哈,忍不住感叹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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值