《OpenCV3编程入门》学习笔记三:HighGUI图形用户界面

Posted NodYoung

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《OpenCV3编程入门》学习笔记三:HighGUI图形用户界面相关的知识,希望对你有一定的参考价值。

一:内容介绍

本节主要介绍OpenCV的HighGUI模块,并分享几个例子:
1. 用imwrite函数生成png透明图
2. 综合示例程序:图像的载入、显示与输出
3. 为程序界面添加滑动条
4. 鼠标操作

二:学习笔记

  1. 使用OpenCV首先要学会使用它的图形界面,此章节介绍了OpenCV的一些HighGUI使用方法,并不涉及什么理论部分。关于HighGUI大家可参考官网HighGUI模块 http://docs.opencv.org/3.1.0/d7/dfc/group__highgui.html ,这里也只是讲了其中一部分。
  2. 下面代码中用到了ROI(region of interest),注意它的构造方式。ROI重新设定了局部坐标,且并没有分配新的内存。
  3. 下文代码中用到了saturate_cast 模板函数,为防止数据不合理的数据转换,类似于C++中的static_cast等强制类型转换。可参见:http://blog.csdn.net/mvtechnology/article/details/8139272
  4. 本节函数清单
    这里写图片描述

三:相关源码及解析

1. 用imwrite函数生成png透明图

源码:

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

int main()
{
    Mat mat(480, 640, CV_8UC4);  //创建带alpha通道的Mat
    for (int i = 0; i < mat.rows; i++) {
        for (int j = 0; j < mat.cols; j++) {
            Vec4b& rgba = mat.at<Vec4b>(i, j);
            rgba[0] = UCHAR_MAX;
            rgba[1] = saturate_cast<uchar>((float(mat.cols-j))/((float)mat.cols)*UCHAR_MAX);
            //为什么上面的函数会用到saturate_cast呢,因为无论是加是减,乘除,都会超出一个像素灰度值的范围(0~255)所以,所以当运算完之后,结果为负,则转为0,结果超出255,则为255
            rgba[2] = saturate_cast<uchar>((float(mat.rows - i)) / ((float)mat.rows)*UCHAR_MAX);
            rgba[3] = saturate_cast<uchar>(0.5*(rgba[1]+rgba[2]));
//          rgba[3] = 0;
        }
    }

    vector<int> compression_params = { IMWRITE_PNG_COMPRESSION, 9 };
    try {
        imwrite("透明Alpha值图.png", mat, compression_params);
        imshow("【生成的png图】", mat);
        cout << "PNG图像保存完毕,可在工程目录下看到" << endl;
    }
    catch (runtime_error& ex) {
        cout << "图像生成发生错误:" << ex.what() << endl;
    }

    waitKey(0);
    return 0;
}

素材:

效果图:
透明Alpha值图.png
这里写图片描述
提示:

2. 综合示例程序:图像的载入、显示与输出

源码:

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

int main()
{
    Mat girl = imread("poster_girl.jpg");
    imshow("【动漫画】", girl);

    Mat dota = imread("poster_dota.jpg");
    Mat logo = imread("poster_dota_logo.jpg");
    imshow("【原图】", dota);
    imshow("【logo图】", logo);

    Mat imageROI;
    imageROI = dota(Rect(800, 350, logo.cols, logo.rows));
    addWeighted(imageROI, 0.5, logo, 0.3, 0, imageROI);
    imshow("【原图+logo图】", dota);
    imwrite("poster_dota_logo_overlay.jpg", dota);

    waitKey(0);
    return 0;
}

素材:
poster_girl.jpg
这里写图片描述
poster_dota.jpg
这里写图片描述
poster_dota_logo.jpg
这里写图片描述
效果图:
poster_dota_logo_overlay.jpg
这里写图片描述
提示:
此程序中用到了ROI,ROI是重新设定局部坐标

3. 为程序界面添加滑动条

源码:

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

#define WINDOW_NAME "【线性混合示例】"
const int g_nMaxAlphaValue = 100; //Alpha最大值
int g_nAlphaValueSlider=70;  //滑动条对应的变量,初始值70
double g_dAlphaValue;
double g_dBetaValue;
Mat g_srcImage1;
Mat g_srcImage2;
Mat g_dstImage;

void on_Tracker(int, void*);

int main()
{
    g_srcImage1 = imread("poster_spring_1.jpg");
    g_srcImage2 = imread("poster_spring_2.jpg");

    namedWindow(WINDOW_NAME);  //此处一定要先创建窗体,否则Trackbar无法显示

    String TrackbarName("透明值");
    createTrackbar(TrackbarName, WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Tracker);
    on_Tracker(g_nAlphaValueSlider, 0);

    waitKey(0);
    return 0;
}

void on_Tracker(int, void*)
{
    g_dAlphaValue = (double)g_nAlphaValueSlider / g_nMaxAlphaValue;
    g_dBetaValue = 1.0 - g_dAlphaValue;
    addWeighted(g_srcImage1, g_dAlphaValue, g_srcImage2, g_dBetaValue, 0, g_dstImage);
    imshow(WINDOW_NAME, g_dstImage);
}

素材:
poster_spring_1.jpg
poster_spring_1.jpg
poster_spring_2.jpg
这里写图片描述
效果图:
这里写图片描述
提示:

4. 鼠标操作

源码:

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

#define WINDOW_NAME "【程序窗口】"
void on_MouseHandle(int event, int x, int y, int flags, void* param);
Rect g_rectangle=Rect(-1, -1, 0, 0);
bool g_bDrawingBox = false;  //是否进行绘制
RNG g_rng; //生成随机函数的类

int main()
{
    Mat srcImage(600, 800, CV_8UC3, Scalar::all(0)), tempImage;
    srcImage.copyTo(tempImage);
    namedWindow(WINDOW_NAME);
    setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);

    while (1){
        srcImage.copyTo(tempImage);
        if (g_bDrawingBox)
            rectangle(tempImage, g_rectangle.tl(), g_rectangle.br(), Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));
        imshow(WINDOW_NAME, tempImage);
        if (waitKey(10) == 27) //按下ESC键
            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:
        {
            if (g_bDrawingBox)
            {
                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;
            }
            rectangle(image, g_rectangle.tl(), g_rectangle.br(), Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));
        }
        break;
    }
}

素材:

效果图:
这里写图片描述
提示:

以上是关于《OpenCV3编程入门》学习笔记三:HighGUI图形用户界面的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV3编程入门--读书笔记

OpenCV3编程入门-读书笔记3-滤波

图像识别——《OpenCV3编程入门-毛星云》第一部分 快速上手OpenCV

OpenCV3编程入门读书笔记2-core组件

图像识别——《OpenCV3编程入门-毛星云》第三部分 掌握imgproc组件

《OpenCV3编程入门》毛星云高清PDF无水印+源代码学习