OpenCV学习之旅2——HighGUI图形用户界面

1. HighGUI 简介

HighGUI模块为高层GUI图形用户界面模块,包括媒体的输入输出、视频捕捉、图像和视频的编码解码、图形交互界面接口等等。这篇博客将从几个例程直观的了解这一模块的作用。

2. 利用imwrite()生成透明png图像

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

//--------------------------------【createAlphaMat( )函数】----------
//      描述:创建带alpha通道的Mat
//------------------------------------------------------------------
void createAlphaMat(Mat &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);
            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]));
        }
    }
}

int main( )
{
    //创建带alpha通道的Mat
    Mat mat(480, 640, CV_8UC4);
    createAlphaMat(mat);

    vector<int>compression_params;
    compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
    compression_params.push_back(9);

    //显示图片
    try{
        imwrite("透明Alpha值图.png", mat, compression_params);
        imshow("生成的png图",mat);
        fprintf(stdout,"PNG图片文件的alpha数据保存完毕~\n可以在工程目录下查看由imwrite函数生成的图片\n");
        waitKey(0);
    }
    catch(runtime_error& ex) {
        fprintf(stderr,"图像转换成PNG格式发生错误:%s\n", ex.what());
        return 1;
    }

    return 0;
}

2.1 imwrite()函数

bool imwrite( const string& filename, InputArray img,const vector<int>& params=vector<int>());

第一个参数:需要写入的文件名,注意需要带上后缀名;
第二个参数:Mat类图像;
第三个参数:特定格式的参数编码。对于jpg格式,0-100表示图像质量,默认为95;对于png格式,0-9表示压缩级别,越高图像尺寸越小,默认值为3。

3. 图像的载入、显示与输出

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

int main( )
{
    //-----------------------------------【一、图像的载入和显示】-------
    //  描述:以下三行代码用于完成图像的载入和显示
    //--------------------------------------------------------------
    Mat girl=imread("girl.jpg"); //载入图像到Mat
    namedWindow("【1】动漫图"); //创建一个名为 "【1】动漫图"的窗口  
    imshow("【1】动漫图",girl);//显示名为 "【1】动漫图"的窗口  

    //-----------------------------------【二、初级图像混合】----------
    //  描述:二、初级图像混合
    //--------------------------------------------------------------
    //载入图片
    Mat image= imread("dota.jpg",199);
    Mat logo= imread("dota_logo.jpg");

    //载入后先显示
    namedWindow("【2】原画图");
    imshow("【2】原画图",image);

    namedWindow("【3】logo图");
    imshow("【3】logo图",logo);

    // 定义一个Mat类型,用于存放,图像的ROI
    Mat imageROI;
    //方法一
    imageROI= image(Rect(800,350,logo.cols,logo.rows));
    //方法二
    //imageROI= image(Range(350,350+logo.rows),Range(800,800+logo.cols));

    // 将logo加到原图上
    addWeighted(imageROI,0.5,logo,0.3,0.,imageROI);

    //显示结果
    namedWindow("【4】原画+logo图");
    imshow("【4】原画+logo图",image);

    //-----------------------------------【三、图像的输出】------------
    //  描述:将一个Mat图像输出到图像文件
    //--------------------------------------------------------------
    //输出一张jpg图片到工程目录下
    imwrite("由imwrite生成的图片.jpg",image);
    waitKey();
    return 0;
}

3.1 namedWindow()函数

void namedWindow(const string& winname, int flags = WINDOW_AUTOSIZE);

第一个参数:窗口名称;
第二个参数:窗口标识符,当为WINDOW_ NORMAL时,用户可以改变窗口大小;当为WINDOW_ AUTOSIZE时,窗口会自动调整大小;当为WINDOW_ OPENGL时,窗口支持OpenGL。

3.2 Rect()函数

//////////////////////////////// Rect ////////////////////////////////

template<typename _Tp> inline Rect_<_Tp>::Rect_() : x(0), y(0), width(0), height(0) {}
template<typename _Tp> inline Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height) : x(_x), y(_y), width(_width), height(_height) {}
template<typename _Tp> inline Rect_<_Tp>::Rect_(const Rect_<_Tp>& r) : x(r.x), y(r.y), width(r.width), height(r.height) {}
template<typename _Tp> inline Rect_<_Tp>::Rect_(const CvRect& r) : x((_Tp)r.x), y((_Tp)r.y), width((_Tp)r.width), height((_Tp)r.height) {}

四种方式获取矩形区域。

3.3 addWeighted()函数

void addWeighted(InputArray src1, double alpha, InputArray src2,double beta, double gamma, OutputArray dst, int dtype=-1);

第一个参数:输入第一个Mat类数据;
第二个参数:alpha表示第一个图片所占的权重;
第三个参数:输入第二个Mat类数据;
第四个参数:beta表示第二个图片所占的权重;
第五个参数:加到权重总和上的标量,dst=src1* alpha+src* beta+gamma;
第六个参数:输出;
第七个参数:输出阵列的可选深度。

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

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

//-----------------------------------【宏定义部分】-------------------
//  描述:定义一些辅助宏 
//------------------------------------------------------------------
#define WINDOW_NAME "【滑动条的创建&线性混合示例】"        //为窗口标题定义的宏 

//-----------------------------------【全局变量声明部分】--------------------------------------
//      描述:全局变量声明
//-----------------------------------------------------------------------------------------------
const int g_nMaxAlphaValue = 100;//Alpha值的最大值
int g_nAlphaValueSlider;//滑动条对应的变量
double g_dAlphaValue;
double g_dBetaValue;

//声明存储图像的变量
Mat g_srcImage1;
Mat g_srcImage2;
Mat g_dstImage;

//-----------------------------------【on_Trackbar( )函数】--------------------------------
//      描述:响应滑动条的回调函数
//------------------------------------------------------------------------------------------
void on_Trackbar( int, void* )
{
    //求出当前alpha值相对于最大值的比例
    g_dAlphaValue = (double) g_nAlphaValueSlider/g_nMaxAlphaValue ;
    //则beta值为1减去alpha值
    g_dBetaValue = ( 1.0 - g_dAlphaValue );

    //根据alpha和beta值进行线性混合
    addWeighted( g_srcImage1, g_dAlphaValue, g_srcImage2, g_dBetaValue, 0.0, g_dstImage);

    //显示效果图
    imshow( WINDOW_NAME, g_dstImage );
}

//--------------------------------------【main( )函数】-----------------------------------------
//      描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( int argc, char** argv )
{
    //加载图像 (两图像的尺寸需相同)
    g_srcImage1 = imread("1.jpg");
    g_srcImage2 = imread("2.jpg");

    if( !g_srcImage1.data ) { 
        printf("读取第一幅图片错误,请确定目录下是否有imread函数指定图片存在~! \n"); 
        return -1; 
    }

    if( !g_srcImage2.data ) {
        printf("读取第二幅图片错误,请确定目录下是否有imread函数指定图片存在~!\n"); 
        return -1; 
    }

    //设置滑动条初值为70
    g_nAlphaValueSlider = 70;

    //创建窗体
    namedWindow(WINDOW_NAME, 1);

    //在创建的窗体中创建一个滑动条控件
    char TrackbarName[50];
    sprintf( TrackbarName, "透明值 %d", g_nMaxAlphaValue );

    createTrackbar( TrackbarName, WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Trackbar );

    //结果在回调函数中显示
    on_Trackbar( g_nAlphaValueSlider, 0 );

    //按任意键退出
    waitKey(0);

    return 0;
}

4.1 createTrackbar()函数

int createTrackbar(const string& trackbarname, const string& winname,int* value, int count,TrackbarCallback onChange = 0,void* userdata = 0);

第一个参数:轨迹条名称;
第二个参数:窗口名称,它会对应到namedWindow()创建窗口时的窗口;
第三个参数:int* 类型的value,表示滑块的初始位置。
第四个参数:int类型的count,表示滑块可以达到的最大位置(最小位置始终为零)。
第五个参数:TrackbarCallback类型的onChange,这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。

小埋
通过这三个简单的例子说明了HighGUI的一些用处

未完待续~~~

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值