Qt&OpenCV练习(五)

使用配置在Qt5环境下的OpenCV4实现窗口绘制颜色随机的矩形

本文所涉程序为毛星云/冷雪飞等编著的《OpenCV3编程入门》中所写例程,仅为记录本人学习中所碰到的问题与对程序的理解。
先在.pro文件中声明如下变量

INCLUDEPATH +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\include

LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingCVw\bin\libopencv_core411.dll
LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingw\bin\libopencv_highgui411.dll
LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingw\bin\libopencv_imgproc411.dll
LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingw\bin\libopencv_calib3d411.dll
LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingw\bin\libopencv_imgcodecs411.dll
LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingw\bin\libopencv_videoio411.dll
LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingw\bin\libopencv_video411.dll
//以上放在.pro文件原有代码的最后就好,前面的路径根据自己安装位置不同而改变

所涉程序如下

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

#define WINDOW_NAME "[程序窗口]"
//全局函数声明部分
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawRectangle( cv::Mat& img, cv::Rect box );
void ShowHelpText();
//全局变量声明部分
Rect g_rectangle;
bool g_bDrawingBox = false;
RNG g_rng(12345);//随机数产生器

int main( int argc, char** argv)
{

    g_rectangle = Rect(-1,-1,0,0);//这四个参数的分别代表矩形的左上X,Y坐标和宽度,高度
    Mat srcImage(600, 800,CV_8UC3), tempImage;//参考[link]( http://blog.csdn.net/maweifei/article/details/51221259).
    //CV_(S|U|F)C
    //其中,(1) bit_depth---比特数---代表8bite\16bite\32bite\64bite
    //eg:8表示你所创建的储存图片的Mat对象中,每个像素点在内存空间所占的空间大小8bite。
    //(2) S|U|F
    //S: signed int,即有符号整型;
    //U: unsigned int,即无符号整型;
    //F: float,单精度浮点型。
    //(3) C:所存储的图片的通道数。
    //eg 1---grayImg灰度图像---是---单通道图像
    //2---RGB彩色图像---是---3通道图像
    //3---带Alpha通道的RGB彩色图像---是---4通道图像
    srcImage.copyTo(tempImage);//image.copyTo(imageROI),作用是把image的内容粘贴到imageROI
    g_rectangle = Rect(-1,-1,0,0);
    srcImage = Scalar::all(0);//scalar所有元素设置为0,此时为全黑
    //设置鼠标操作回调函数
    namedWindow( WINDOW_NAME );
    //void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0)
    //winname:窗口的名字
    //onMouse:鼠标响应函数,回调函数。指定窗口里每次鼠标时间发生的时候,被调用的函数指针。 这个函数的原型应该为void on_Mouse(int event, int x, int y, int flags, void* param);
    //userdate:传给回调函数的参数
    setMouseCallback( WINDOW_NAME,on_MouseHandle,(void*)&srcImage);
    //程序主循环,当绘制的标识符为真时,进行绘制
    while(1)
    {
        srcImage.copyTo(tempImage);//复制源图到临时变量
        if( g_bDrawingBox ) DrawRectangle( tempImage, g_rectangle );//当绘制的标识符为真时,则进行绘制
        imshow( WINDOW_NAME, tempImage );
        if( waitKey( 10 )  == 27 ) break;//waitkey:图像刷新率。27:esc的Ascii码。按下esc键,程序退出
    }
    return 0;
}


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

    Mat& image = *(cv::Mat*) param;//Mat, copy传递,不会改变外部变量的Mat。
                                   //Mat &, reference传递,函数内部修改将会改变外部。
                                   //const Mat, copy传递,在函数内,不会被修改,也不会影响到外部的变量。
                                   //const Mat &, reference传递,确保在函数内外,都不会被修改。
    switch( event)//鼠标事件们
    {
    case EVENT_MOUSEMOVE:
    {
        if( g_bDrawingBox )//如果是否进行绘制的标识符为真,则记录下长和宽到RECT型变量中
        {
            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的处理
        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 )
{
    rectangle(img,box.tl(),box.br(),Scalar(g_rng.uniform(0,255),g_rng.uniform(0,255), g_rng.uniform(0,255)));//随机颜色。tl:top&left。br:bottom&right。
}

在这里插入图片描述

参数:
event并不是一个简单的我们自定义的int形式的变量名,而是CV_EVENT_变量之一,一般为setMouseCallBack传过来固定数据,常用的几个数据为:EVENT_MOUSEMOVE(鼠标移动)
EVENT_LBUTTONDOWN (左键按下)
EVENT_RBUTTONDOWN (右键按下)
EVENT_LBUTTONUP (左键弹起)
EVENT_RUTTONUP (右键弹起)
x为鼠标当前所在位置的x坐标。
y为鼠标当前所在位子的y坐标
flags为标志位
用来接收setMouseCallback传递过来的用户数据,为空指针类型。
例如:`void on_MouseHandle(int event, int x, int y, int flags, void
param){
Mat& image = (cv::Mat)param;//强行转为mat指针,然后读取其中的内容(因为传递过来的参数为空指针类型,不能直接使用)
switch (event){//event根据鼠标不同的操作传递不同的值过来。然后根据这些值进行不同的操作
case EVENT_MOUSEMOVE://如果鼠标动了
{………….}break;
case EVENT_MOUSEMOVE:
{………….}break;

case EVENT_LBUTTONDOWN :
{………….}break;

case EVENT_RBUTTONDOWN :
{………….}break;

case EVENT_LBUTTONUP :
{………….}break;

case EVENT_RUTTONUP :
{………….}break;

DrawRectangle(Pen, Rectangle)
功能:绘制由 Rectangle 结构指定的矩形。

参数:

第一个参数Pen,它确定线条的颜色、宽度和样式。

第二个参数Rectangle,表示要绘制的矩形的 Rectangle 结构。

Qt&OpenCV练习(五)_第1张图片
程序运行结果

你可能感兴趣的:(opencv,qt5)