【OpenCV】OpenCV基础教程(11)—— HighGUI图形用户界面

11. HighGUI图形用户界面

11.1 滑动条的创建和使用

11.1,1 创建滑动条:createTrackbar()函数

createTrackbar 函数用于创建一个可以调整数值的滑动条:

int cv::createTrackbar(const cv::String &trackbarname, const cv::String &winname, int *value, int count, cv::TrackbarCallback onChange = (cv::TrackbarCallback)0, void *userdata = (void *)0)

trackbarname:轨迹条的名字,用来代表我们创建的轨迹条。

winname:窗口的名字,表示这个轨迹条会依附到哪个窗口上,即对应 namedWindow 创建窗口时填的某一个窗口名。

value:一个指向整型的指针,表示滑块的位置。在创建时,滑块的初始位置就是该变量当前的值。

count:滑块可以达到的最大位置的值。滑块最小位置的值始终为0。

onChange:这是一个指向回调函数的指针,有默认值0。每次滑块位置改变时,这个函数都会进行回调。并且这个函数的原型必须为void XXXX(int, void);,其中第一个参数是轨迹条的位置,第二个参数是用户数据(看下面的第六个参数)。如果回调是NULL指针,则表示没有回调函数的调用,仅第三个参数value有变化。

userdata:这个参数是用户传给回调函数的数据,用来处理轨迹条事件,有默认值0。如果使用的第三个参数value实参是全局变量的话,完全可以不去管这个userdata参数。


使用方法如下(混合两张输入图片):

//为窗口标题定义的宏
#define WINDOW_NAME "【线性混合示例】"

//Alpha值的最大值
const int Max_AlphaValue = 100;
//滑动条对应的变量
int Slider_AlphaValue;
//定义Alpha和Beta的值
double AplhaValue;
double BetaValue;
//声明存储图像的变量
Mat srcImage1;
Mat srcImage2;
Mat dstImage;

//响应滑动条的回调函数
void on_Trackbar(int, void*)
{
    //求出当前Alpha值相对于最大值的比例
    AplhaValue = (double) Slider_AlphaValue / Max_AlphaValue;
    //Beta = 1 - Alpha
    BetaValue = (1.0 - AplhaValue);
    //根据Alpha和Beta进行线性混合
    addWeighted(srcImage1, AplhaValue, srcImage2, BetaValue, 0.0, dstImage);
    //显示效果图
    imshow(WINDOW_NAME, dstImage);
}

int main()  
{  
    //加载图像(两图像的尺寸需相同)
    srcImage1 = imread("../1.jpg");
    srcImage2 = imread("../2.jpg");
    //设置滑动条初值为70
    Slider_AlphaValue = 70;
    //创建窗体
    namedWindow(WINDOW_NAME, 1);
    //在创建的窗体中创建一个滑动条控件
    char TrackbarName[50];
    sprintf(TrackbarName, "透明值 %d", Max_AlphaValue);
    createTrackbar(TrackbarName, WINDOW_NAME, &Slider_AlphaValue, Max_AlphaValue, on_Trackbar);
    //结果在回调函数中显示
    on_Trackbar(Slider_AlphaValue, 0);
    waitKey(0);
    destroyAllWindows();
} 

11.1.2 获取当前轨迹条的位置:getTrackbarPos()函数

getTrackbarPos函数用于获取当前轨迹条的位置并返回:

int cv::getTrackbarPos(const cv::String &trackbarname, const cv::String &winname)

trackbarname:表示轨迹条的名字

winname:表示轨迹条的父窗口的名字

11.2 鼠标操作

OpenCV中的鼠标操作和滑动条的消息映射方式很类似,都是通过一个中介函数配合一个回调函数来实现的。创建和指定滑动条回调函数的函数为createTrackbar,而指定鼠标操作消息回调函数的函数为setMouseCallback

void cv::setMouseCallback(const cv::String &winname, cv::MouseCallback onMouse, void *userdata = (void *)0)

winname:窗口的名字

onMouse:指定窗口里每次鼠标时间发生的时候,被调用的函数指针。

userdata:用户定义的传递到回调函数的参数,有默认值0。


使用方法如下(利用鼠标绘制矩形):

//为窗口标题定义的宏
#define WINDOW_NAME "【程序窗口】"

//全局函数的声明
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawRectangle(Mat& img, Rect box);

//全局变量的声明
Rect rect = Rect(-1, -1, 0, 0);
bool flag_DrawingBox = false;   //是否进行绘制
RNG rand_num(12345);   //产生随机数


int main()  
{
    //准备参数
    Mat srcImage(600, 800, CV_8UC3);
    Mat tempImage;
    srcImage.copyTo(tempImage);
    srcImage = Scalar::all(0);
    //设置鼠标操作回调函数
    namedWindow(WINDOW_NAME);
    setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);
    //程序主循环,当进行绘制的标识符为真时,进行绘制
    while(1)
    {
        //复制源图到临时变量
        srcImage.copyTo(tempImage); 
        //当进行绘制的标识符为真,则进行绘制
        if(flag_DrawingBox)
        {
            DrawRectangle(tempImage, rect);
        }
        imshow(WINDOW_NAME, tempImage);
        //按下ESC键,程序退出
        if(waitKey(10)==27)
        {
            break;
        }
    }
    return 0;
} 

//鼠标回调函数,根据不同的鼠标事件进行不同的操作
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
    Mat& image = *(Mat*) param;
    switch(event)
    {
        //鼠标移动消息
        case EVENT_MOUSEMOVE:
            {
                //如果是否进行绘制的标识符为真,则记录下长和宽到RECT型变量中
                if(flag_DrawingBox)
                {
                    rect.width = x - rect.x;
                    rect.height = y - rect.y;
                }
            }
            break;
        //左键按下消息
        case EVENT_LBUTTONDOWN:
            {
                flag_DrawingBox = true;
                rect = Rect(x, y, 0, 0); //记录起始点
            }
            break;
        //左键抬起消息
        case EVENT_LBUTTONUP:
            {
                flag_DrawingBox = false;  //置标识符为false
                //对宽小于0的处理
                if(rect.width < 0)
                {
                    rect.x += rect.width;
                    rect.width *= -1;
                }
                //对高小于0的处理
                if(rect.height < 0)
                {
                    rect.y += rect.height;
                    rect.height *= -1;
                }
                //调用函数进行绘制
                DrawRectangle(image, rect);
            }
            break;
    }
}

//自定义的矩形绘制函数
void DrawRectangle(Mat& img, Rect box)
{
    //随机颜色绘制矩形框
    rectangle(img, box.tl(), box.br(), Scalar(rand_num.uniform(0,255), rand_num.uniform(0,255), rand_num.uniform(0,255)));
}

你可能感兴趣的:(OpenCV,opencv,c++,图像处理)