opencv学习(3)鼠标的操作和copyTo等函数的学习

先贴一段毛星云大神的一段代码。


#include <opencv2/opencv.hpp>
using namespace cv;

// 描述:定义一些辅助宏 
#define WINDOW_NAME "【程序窗口】" //为窗口标题定义的宏 

// 描述:全局函数的声明

void on_MouseHandle(int event, int x, int y, int flags, void* param);
// 鼠标函数的第一个参数是说明鼠标的事件;flags是CV_EVENT_FLAG的组合; 
//x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系);param 用户定义的传递到回调函数的参数

void DrawRectangle( cv::Mat& img, cv::Rect box ); //用于矩形框的绘制

// 描述:全局变量的声明
Rect g_rectangle;
bool g_bDrawingBox = false;//是否进行绘制
RNG g_rng(12345); //定义一个随机函数对象;

//------【main( )函数】---

int main( int argc, char** argv ) 
{
    //【1】准备参数
    g_rectangle = Rect(-1,-1,0,0);//初始化g_rectangle;
    Mat srcImage(600, 800,CV_8UC3), tempImage;//定义并初始化矩阵(图像)srcImage,长宽分别为600*800;CV_8UC3表示存储类型,3表示通道数;
    srcImage.copyTo(tempImage);   //将srcImage复制给临时图像tempImage;
    srcImage = Scalar::all(255);

    //【2】设置鼠标操作回调函数
    namedWindow( WINDOW_NAME );
    setMouseCallback(WINDOW_NAME,on_MouseHandle,(void*)&srcImage);

    //【3】程序主循环,当进行绘制的标识符为真时,进行绘制
    while(1)
    {
        srcImage.copyTo(tempImage);//拷贝源图到临时变量
        if( g_bDrawingBox )
            DrawRectangle( tempImage, g_rectangle );//当进行绘制的标识符为真,则进行绘制
        imshow( WINDOW_NAME, tempImage );
        if( waitKey( 10 ) == 27 ) break;//按下ESC键,程序退出
    }
    return 0;
}

void on_MouseHandle(int event, int x, int y, int flags, void* param)
{

    Mat& image = *(cv::Mat*) param;
    switch( event)
    {
        //鼠标移动消息
    case EVENT_MOUSEMOVE: 
        {
            if( g_bDrawingBox )//如果是否进行绘制的标识符为真,则记录下长和宽到RECT型变量中
            {
                //鼠标移动的过程中鼠标的坐标(x,y)是在不断的改变的;
                g_rectangle.width = x-g_rectangle.x;
                g_rectangle.height = y-g_rectangle.y;
            }
        }
        break;

        //左键按下消息
    case EVENT_LBUTTONDOWN: 
        {
            g_bDrawingBox = true;
            g_rectangle =Rect( x, y, 0, 0 );//记录起始点
        }
        break;

        //左键抬起消息
    case EVENT_LBUTTONUP: 
        {
            g_bDrawingBox = false;//置标识符为false
            //对宽和高小于0的处理
            //如果鼠标是向左移动,则将最后生成的矩形的左上角的点作为新的g_rectangle.x和g_rectangle.y;
            if( g_rectangle.width < 0 )
            {
                g_rectangle.x += g_rectangle.width;
                g_rectangle.width *= -1;
            }

            if( g_rectangle.height < 0 ) 
            {
                g_rectangle.y += g_rectangle.height;
                g_rectangle.height *= -1;
            }
            //调用函数进行绘制
            DrawRectangle( image, g_rectangle );
        }
        break;

    }
}

void DrawRectangle( cv::Mat& img, cv::Rect box )
{
    cv::rectangle(img,box.tl(),box.br(),cv::Scalar(g_rng.uniform(0, 255), g_rng.uniform(0,255), g_rng.uniform(0,255)));//随机颜色
}

//-----------------------------------【DrawRectangle( )函数】----------------------------
void DrawRectangle( cv::Mat& img, cv::Rect box )
{
    cv::rectangle(img,box.tl(),box.br(),cv::Scalar(g_rng.uniform(0, 255), g_rng.uniform(0,255), g_rng.uniform(0,255)));//随机颜色
}

每段代码后面我都做了一个简短的参数说明。这里主要总结几小点:

1.void on_MouseHandle(int event, int x, int y, int flags, void* param);

// 鼠标函数的第一个参数是说明鼠标的事件;flags是CV_EVENT_FLAG的组合;
x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系);
flags是EVENT_FLAG的组合;
param 用户定义的传递到回调函数(SetMouseCallback)的参数;

2. RNG g_rng(12345); RNG( )函数的作用为初始化随机数状态的生成器;

3. srcImage.copyTo(tempImage)
将src复制到dst矩阵中;相当于Mat dst=src.clone( ) ;

  1. 常用的几种显式创建Mat对象的几种方法:

【1】使用Mat( )构造函数

Mat M(2,2,CV_8UC3,Scalar(0,0,255));

参数:
1)行数和列数;
2)存储元素的数据类型以及每个矩阵点的通道数;CV_8UC3表示使用8位的unsigned char型,每个元素由三个元素组成三通道。
3)Scalar是个short型的向量,能够用指定的定制化的值来初始化矩阵,还可以用于表示颜色。

【2】在C/C++中通过构造函数进行初始化

int sz[3]={2,2,2};
Mat L(3,sz,CV_8UC,Scalar::all(0));

参数:
L()函数中的第一个参数3表示维数;
sz表示指针数组,它包含了每个维度的尺寸;
同样,CV_8UC3表示使用8位的unsigned char型,每个元素由三个元素组成三通道。
Scalar是个short型的向量,能够用指定的定制化的值来初始化矩阵,还可以用于表示颜色。

【3】利用Create( )函数进行Mat类的初始化操作;

5、opencv中的格式化输出方法;
(1)opencv默认风格
cout<<”r (opencv默认风格) =”<< r<<”;”<< endl<< endl;

(2)python分隔风格
cout<<”r (python 风格) =“<< format(r,Formatter::FMT_PYTHON)<< “;”<< endl<< endl;

(3)逗号分隔风格
cout<<”r (逗号 风格) =“<< format(r,Formatter::FMT_CSV)<<”;”<< endl<< endl;

Numpy分隔分隔和C语言风格都是同理 ,相应的换成Formatter::FMT_NUMPY和Formatter::FMT_C就可以了;

你可能感兴趣的:(opencv学习(3)鼠标的操作和copyTo等函数的学习)