opencv鼠标选定感兴趣区域进行目标检测

本文章主要对感兴趣区域ROI的操作(车辆检测)说明
车辆追踪效果
在图像处理的领域,我们常常需要去设置自己感兴趣的区域(ROI,region of interest),来专注或者简化工作过程。也就是从图像中选择的一个图像区域,这个区域是图像分析所关注的重点。我们圈定这个区域,以便进行下一步的处理.而且,使用ROI指定想读入的目标,可以减少处理时间,增加精度,给图像处理带来不小的便利。
首先我们看下任意形状图形的绘制选择:

    #include "cv.h"  
    #include "highgui.h"  
    #include <stdio.h>  
    #include <stdlib.h>  

    IplImage* inpaint_mask = 0;  
    IplImage* img0 = 0, *img = 0, *inpainted = 0;  
    CvPoint prev_pt = {-1,-1};  

    void on_mouse( int event, int x, int y, int flags, void* zhang)  
    {  
      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);  
      else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) )  
      {//手一直在绘画  
        CvPoint pt = cvPoint(x,y);  
        if( prev_pt.x < 0 )  
        prev_pt = pt;  
        cvLine( inpaint_mask, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );  
        cvLine( img, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );  
        prev_pt = pt;  
        cvShowImage( "image", img );  
      }  
    }  

    int main( int argc, char** argv )  
    {  
       char* filename = argc >= 2 ? argv[1] : (char*)"fruits.jpg";  
       if( (img0 = cvLoadImage(filename,-1)) == 0 )  
         return 0;  
       printf( "Hot keys: \n"  
       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 );     
    }  

利用OpenCV库进行编程实现对感兴趣区域ROI的操作

例如:将小图标复制到大图像的指定位置中

使用到的函数:矩形的表示:Rect类—-》Rect(x,y,width,heigh)

对Rect类的解释:Rect类的成员变量有x、y、width、height,分别在左上角点的坐标和矩形的宽和高。
这篇文章讲述了鼠标选定一个感兴趣区域后,实现对目标的运动检测并计数的功能。
1.首先,暂停视频或者在视频流的第一帧中,画出感兴趣区域。
2. 然后扣出感兴趣区域
3.使用运动目标检测(在这里我以背景差分为例子)

    #include<opencv2/core/core.hpp>  
    #include<opencv2/highgui/highgui.hpp>  
    #include<opencv2/imgproc/imgproc.hpp>  
    using namespace cv;  
    #include<iostream>  
    #include<vector>  
    using namespace std;  
    /*----定义鼠标事件--画矩形区域:作用当两个车灯----*/  
    //第一步:全局变量  
    bool drawing_box = false;  
    bool gotBox =  false;  
    Rect box;  
    Point downPoint;  
    /* 
    void mouseRectHandler(int event, int x, int y, int flags, void *param) 
    { 
        switch (event) 
        { 
        case CV_EVENT_MOUSEMOVE: 
            if (drawing_box) 
            { 
                box.width = x - box.x; 
                box.height = y - box.y; 
            } 
            break; 
        case CV_EVENT_LBUTTONDOWN: 
            drawing_box = true; 
            box = Rect(x, y, 0, 0); 
            break; 
        case CV_EVENT_LBUTTONUP: 
            drawing_box = false; 
            gotBox = true; 
            if (box.width < 0) 
            { 
                box.x += box.width; 
                box.width *= -1; 
            } 
            if( box.height < 0 ) 
            { 
                box.y += box.height; 
                box.height *= -1; 
            } 
            break; 
        default: 
            break; 
        } 
    } 
    */  

    void mouseRectHandler(int event, int x, int y, int flags, void *param)  
    {  
        switch (event)  
        {  
        case CV_EVENT_MOUSEMOVE:  
            if (drawing_box)  
            {  
                //鼠标的移动到downPoint的右下角  
                if( x >=downPoint.x && y >= downPoint.y)  
                {  
                    box.x = downPoint.x;  
                    box.y = downPoint.y;  
                    box.width = x - downPoint.x;  
                    box.height =  y -  downPoint.y;  
                }  
                //鼠标的移动到downPoint的右上角  
                if( x >= downPoint.x && y <= downPoint.y)  
                {  
                    box.x =  downPoint.x;  
                    box.y = y;  
                    box.width = x - downPoint.x;  
                    box.height = downPoint.y - y;  
                }  
                //鼠标的移动到downPoint的左上角  
                if( x <= downPoint.x && y <= downPoint.y)  
                {  
                    box.x = x;  
                    box.y = y;  
                    box.width = downPoint.x - x;  
                    box.height = downPoint.y - y;  
                }  
                //鼠标的移动到downPoint的左下角  
                if( x <= downPoint.x && y >= downPoint.y)  
                {  
                    box.x = x;  
                    box.y = downPoint.y;  
                    box.width = downPoint.x -x;  
                    box.height = y - downPoint.y;  
                }  
            }  
            break;  

        case CV_EVENT_LBUTTONDOWN:  
            //按下鼠标,代表可以可以开始画矩形  
            drawing_box = true;  
            //记录起点  
            downPoint = Point(x,y);  
            break;  

        case CV_EVENT_LBUTTONUP:  

            //松开鼠标,代表结束画矩形  
            drawing_box = false;  
            gotBox = true;  
            break;  
        default:  
            break;  
        }  
    }  

   // int main(int argc,char*argv[])    
 int main()   
  {     
    Mat diff_thresh;
    VideoCapture video("1.avi");
         //读取视频    
        // VideoCapture video(argv[1]);    
          Mat imageROI, imageROI_BW;   
         //判断视频是否打开    
         if( !video.isOpened())    
             return 0;    
        bool flag;
         //视频中的第一帧    
         Mat firstFrame;    
          flag=false;   
         Mat frame;    
         Mat imageROIdf,imageROIpro,imageROIdf_BW;
         //读取视频的第一帧    
         video>>frame;    

         //复制到firstFrame中    
         frame.copyTo(firstFrame);    

         //register     
         namedWindow("video",1);    
         setMouseCallback("video",mouseRectHandler,NULL);    

         //画感兴趣区域   
         while(!gotBox)    
         {    
             firstFrame.copyTo(frame);    
             rectangle(frame,box,Scalar(255,0,0),2);//画出感兴趣区域  
             imshow("video",frame);    
             if(waitKey(50) == 'q')//---------很重要    
                 break;    
         }    
         //remove callback    
         setMouseCallback("video",NULL,NULL);    
          Mat frame0,result;   
         //视频继续    
         for(;;)    
         {    
             //读取视频   
             video>>frame;  
              //判断是否有当前帧  
              if(!frame.data)  
                  break;  
              //画出感兴趣区域  
              rectangle(frame,box,Scalar(255,255,0),2);  
              imshow("video",frame);  
        imageROI = frame(Rect(box.x, box.y, box.width, box.height));
        cvtColor(imageROI,frame0,CV_RGB2GRAY);//灰度化 
        medianBlur(frame0, frame0, 3);//中值滤波
        if (false == flag)
        {
            imageROIpro = imageROI.clone();
            flag = true;
        }
        else
        {
            absdiff(imageROI, imageROIpro, imageROIdf);//帧间差分法
            imageROIpro = imageROI.clone();
            threshold(imageROIdf, imageROIdf_BW, 30, 255, 0);
             imshow("imageROIdf_BW", imageROIdf_BW);
    diff_thresh=imageROIdf_BW;
    cv::cvtColor(diff_thresh, diff_thresh, CV_RGB2GRAY);
    vector<vector<Point> > contours;  
    findContours(diff_thresh, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);  
//CvSeq * contour = 0; 
//  Mat contour;    
//int Num=cvFindContours( diff_thresh, storage, &contour, sizeof(CvContour), mode, CV_CHAIN_APPROX_SIMPLE); 

    // std::cout<<"The number of Contours is:"<<Num<<std::endl; 
    drawContours(imageROI, contours, -1, Scalar(0, 0, 255), 2);//在result上绘制轮廓  
    //7.查找正外接矩形  
     imshow("imageROI", imageROI);
    vector<Rect> boundRect(contours.size());  
    for (int i = 0; i < contours.size(); i++)  
    {  
        boundRect[i] = boundingRect(contours[i]);  
        rectangle(imageROI, boundRect[i], Scalar(0, 255, 0), 2);//在result上绘制正外接矩形  
    }   int x,y;
    x=contours.size();
    y=box.y;
    CvPoint point1 = cvPoint(x, y); 
    //cout<<x;
    if (contours.size()>1)
    std::cout<<"small xuejie: "<<contours.size()<<std::endl;       
    //std::cout << "Contours: " << coutours.size() << std::endl; 
//  putText(imageROI,"tracking",(100,100),FONT_HERSHEY_PLAIN,2.0,(255,255,255),2,1);

//cout<<contours.size();        
//4.腐蚀  

/*  gray=imageROIdf_BW;
    std::vector<std::vector<cv::Point> > contours;  
    cv::findContours(gray,   
        contours, // a vector of contours   
        CV_RETR_EXTERNAL, // retrieve the external contours  
        CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours  

    // Print contours' length  
    std::cout << "Contours: " << contours.size() << std::endl;  
    std::vector<std::vector<cv::Point> >::const_iterator itContours= contours.begin();  
    for ( ; itContours!=contours.end(); ++itContours)   
    {  

        std::cout << "Size: " << itContours->size() << std::endl;  
    }  

    // draw black contours on white image  
    cv::Mat result(gray.size(),CV_8U,cv::Scalar(255));  
    cv::drawContours(result,contours,  
        -1, // draw all contours  
        cv::Scalar(0), // in black  
        1); // with a thickness of 2  

    cv::namedWindow("Contours");  
    cv::imshow("Contours",result); 
            //if (imageROIdf_BW.data != NULL)
            //{
            //  cout << "youyidongwuti" << endl;
            //}
 */         }

 imshow("imageROI", imageROI);
              if(waitKey(33) == 'q')    
                  break;    
         }    
         return 0;    
     }    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiao__run

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值