玖叶教程网

前端编程开发入门

如何使用OpenCV可视化的截取感兴趣区域

OpenCV是一个著名的计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

程序的大致效果就是:显示一张较大的图像,鼠标在图像上移动的时候会实时的显示一个"十"字的交叉线,然后在图像上点两个点得到的矩形框就是感兴趣区域。

一、介绍一下OpenCV中如何设置鼠标事件的回调函数

1)设置鼠标回调函数

 void   SetMouseCallback(const string & winname,MouseCallback onMouse,void* userdata=0)

参数说明:

winname: 窗口的名字

onMouse: 鼠标事件发生的时候,调用的函数的函数指针

userdata: 在鼠标事件发生的时候,传给调用函数的参数

2)对第二个参数MouseCallback onMouse的详细说明:

它表示鼠标事件发生的时候,被调用的函数的函数指针,其函数原型为:

void my_mouse(int event, int x, int y, int flags, void* param);
  • event是鼠标事件类型,OpenCV中定义的常见事件有(枚举类型变量):
CV_EVENT_MOUSEMOVE      =0,
CV_EVENT_LBUTTONDOWN    =1,
CV_EVENT_RBUTTONDOWN    =2,
CV_EVENT_MBUTTONDOWN    =3,
CV_EVENT_LBUTTONUP      =4,
CV_EVENT_RBUTTONUP      =5,
CV_EVENT_MBUTTONUP      =6,
CV_EVENT_LBUTTONDBLCLK  =7,
CV_EVENT_RBUTTONDBLCLK  =8,
CV_EVENT_MBUTTONDBLCLK  =9,
CV_EVENT_MOUSEWHEEL     =10,
CV_EVENT_MOUSEHWHEEL    =11
  • x, y表示鼠标在图像坐标系中的位置
  • flags是CV_EVENT_FLAG的组合,用来表示鼠标拖拽的事件,其状态有:
EVENT_FLAG_LBUTTON 								//左键拖拽
EVENT_FLAG_RBUTTON 							 //右键拖拽
EVENT_FLAG_MBUTTON 						  //中键拖拽
EVENT_FLAG_CTRLKEY 							 //按住Ctrl不放
EVENT_FLAG_SHIFTKEY 					   //按住Shift不放
EVENT_FLAG_ALTKEY                  //按住Alt不放
  • params用来接收函数被调用时,用户传给它的数据(注意是一个void*类型)

二、上代码

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

#define WIN_NAME        "Pano"
#define PANO_IMAGE_PATH "/home/llf/Pictures/cat.jpg"
#define ROI_SAVE_PATH   "/home/llf/Pictures/res_roi.jpg"

Mat pano, pano_raw, pano_dst;
vector<Point> two_points;

/*
 * 鼠标事件回调
*/
void my_mouse_call_back(int event, int x, int y, int flags, void* param) {
    switch (event)
    {
    case CV_EVENT_MOUSEMOVE:
        pano = pano_raw.clone();
        line(pano, Point(x, 0), Point(x, pano.rows), Scalar(0, 255, 0), 5);
        line(pano, Point(0, y), Point(pano.cols, y), Scalar(0, 255, 0), 5);
        break;
    case CV_EVENT_LBUTTONDOWN:
        if(two_points.size() < 2)
        {
            Point p(x, y);
            two_points.push_back(p);
            line(pano_raw, Point(x, 0), Point(x, pano_raw.rows), Scalar(0, 255, 0), 10);
            line(pano_raw, Point(0, y), Point(pano_raw.cols, y), Scalar(0, 255, 0), 10);
        }
        break;
    case CV_EVENT_RBUTTONDOWN:
    {
        Mat roi = pano_dst(Rect(two_points[0], two_points[1]));
        namedWindow("roi", WINDOW_NORMAL);
        imshow("roi", roi);
        waitKey(0);
        imwrite(ROI_SAVE_PATH, roi);
        destroyWindow("roi");
    }
        break;
    default:
        break;
    }
}

int main(int argc, char **argv) {
    pano = imread(PANO_IMAGE_PATH, IMREAD_COLOR);
    pano_dst = (pano_raw = pano.clone()).clone(); 

    namedWindow(WIN_NAME, WINDOW_NORMAL);
    setMouseCallback(WIN_NAME, my_mouse_call_back, NULL);

    int key = -1;
    while(27 != key) {
        imshow(WIN_NAME, pano);
        key = waitKey(20);
    }

    return 0;
}

效果:鼠标挪到哪里,十字架的中心就挪到哪里



如果对我的推|文有兴趣,欢迎转|载分|享。也可以推|荐给朋友关|注哦。只推干货,宁缺毋滥。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言