OpenCV3学习笔记:第三章 HighGUI图形用户界面初步

目录

第三章、HighGUI图像用户界面初步

3.1、图像的载入、显示、输出到文件

3.1.1、opencv的命名空间

3.1.2、Mat类解析

3.1.4、图像的载入:imread()函数

3.1.5、图像的显示:imshow()函数

3.1.7、创建窗口:namedWindow()函数

3.1.8、输入图像到文件:imwrite()函数

3.1.9、综合实例程序:图像载入显示与输出

3.2、滑动条的创建和使用

3.2.1、创建滑动条

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

3.3、鼠标操作:SetMouseCallback


第三章、HighGUI图像用户界面初步

  • 3.1、图像的载入、显示、输出到文件

    • 3.1.1、opencv的命名空间

      • #include <opencv2/core/core.hpp>
      • #include <opencv2/highgui/highgui.hpp>
      • using namespace cv
    • 3.1.2、Mat类解析

      • Mat类时用于保存图像以及其他矩阵数据的数据结构,默认情况下为0,也可以指定其初始尺寸,比如Mat pic(320,640,Scalar(100))
    • 3.1.4、图像的载入:imread()函数

      • Mat imread(const string& filename, intflags=1)
      • 第一个参数,const &string 类型的filename,填我们需要载入的图片路径名。
      • 第二个参数,int类型的flags为载入标识,指定一个加载图像的颜色类型。默认是1,三通道。
    • 3.1.5、图像的显示:imshow()函数

      • void imshow(const string& winname,InputArray mat);第一个参数填需要显示的窗口表示名称,第二个参数是需要显示的图像
    • 3.1.7、创建窗口:namedWindow()函数

      • void nameWindouw(const string& winname,int flags=WINDOW_AUTOSIZE);第一个参数填写被用作窗口的标识符的窗口名称;第二个参数窗口的标识,可以填:
    • 3.1.8、输入图像到文件:imwrite()函数

      • bool imwrite(const string& filename,InputArray img,const vector<int>& params=vectior<int>())
      • 第一个参数,填需要写入的文件名。第二个参数填一个Mat类型的图像数据。第三个参数一般不写,
    • #include<opencv2/opencv.hpp>
      #include<vector>
      using namespace std;
      using namespace cv;
      
      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.cols - 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(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;
      }
      

      3.1.9、综合实例程序:图像载入显示与输出

      • #include<opencv2/core/core.hpp>
        #include<opencv2/highgui/highgui.hpp>
        
        using namespace cv;
        
        int main()
        {
        	//1、图像的载入和显示
        	Mat dog = imread("D:/photo/3.png");
        	namedWindow("【1】狗图",CV_WINDOW_NORMAL);//创建一个窗口
        	imshow("【1】狗图", dog);//显示上边创建的窗口
        
        
        	//2、初级图像混合
        	//载入图片
        	Mat image = imread("D:/photo/6.png");
        	Mat logo = imread("D:/photo/2.png");
        
        	//载入后先显示
        	namedWindow("【2】原画图", CV_WINDOW_NORMAL);
        	imshow("【2】原画图", image);
        
        	namedWindow("【3】logo图", CV_WINDOW_NORMAL);
        	imshow("【3】logo图", logo);
        
        	//定义一个Mat类型,用于存放图像的ROI
        	Mat imageROI;
        	//方法一
        	
        	imageROI = image(Rect(1300, 400, 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图", CV_WINDOW_NORMAL);
        	imshow("【4】原画加logo图", imageROI);
        
        	//3、图像的输出
        	//描述:将一个mat图像输出到图像文件
        	//输出一张jpg图片到工程目录下
        	imwrite("由imwrite生成的图片.jpg", image);
        	waitKey();
        	return 0;
        }

  • 3.2、滑动条的创建和使用

    • 3.2.1、创建滑动条

      • int createTrackbar(coonststring& trackbarname, conststrings& winname,int* value, int count, TrackbarCallback onChange=0,void* userdata=0)
        • 第一个参数:轨迹条的名字,用来表示创建的轨迹条
        • 第二个参数:窗口的名字,表示轨迹条会依附在哪个窗口上
        • 第三个参数:一个指向整形的指针,表示滑块的位置。在创建时,滑块的初始位置就是该变量当前的值。
        • 第四个参数:表示滑块可以达到的最大位置的值,滑块最小位置的值始终为0
        • 第五个参数:默认是0.这是 一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。这个函数的原型必须是(int,void);第一个参数时轨迹条的位置,第二个参数时用户数据。如果回调是NULL指针,表示没有回调函数的调用,仅第三个参数有变化
        • 第六个参数:默认值0、是用户传给回调函数的数据,用来处理轨迹条事件,如果第三个参数是全局变量,则不用管这个参数
      • createTrackbar函数为我们创建了一个具有特定名称和范围的轨迹条(Trackbar,或者说是滑块范围控制工具),指定一个和轨迹条位置同步的变量,并且要指定回调函数(第五个参数),在轨迹条位置改变时来调用这个回调函数,并且创建的轨迹条显示在指定的(第二个参数)代表的窗口上
      • 回调函数是一个通过函数指针调用的函数。如果我们把函数的指针作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就称其为回调函数。回调函数不由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用,用于该事件或条件进行响应。
      • #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, g_srcImage2, 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);
        
        }
        //----------------------------【mian()函数】------------------------
        //      描述:控制台应用程序的入口函数
        //----------------------------------------------------------------
        int main(int argc, char* argv)
        {
        	//加载图像(两图像的尺寸大小得相同)
        	g_srcImage1 = imread("D:/photo/7.png");
        	g_srcImage2 = imread("D:/photo/8.png");
        
        	if (!g_srcImage1.data) { printf("读取第一幅图片错误,请确定目录下是否有图片!\n"); return -1; }
        	if (!g_srcImage2.data) { printf("读取第二幅图片错误,请确定目录下是否有图片!\n"); return -1; }
        	
        	//设置滑动条初值为70
        	g_nAlphaValueSlider = 70;
        
        	//创建窗体
        	namedWindow(WINDOW_NAME,0);
        
        	//在创建的窗体中创建一个滑动条控件
        	char TrackbarName[50];
        	sprintf_s(TrackbarName, "透明值 %d", g_nMaxAlphaValue);
        
        	createTrackbar(TrackbarName, WINDOW_NAME, &g_nAlphaValueSlider,
        		g_nMaxAlphaValue, on_Trackbar);
        
        	//结果在回调函数中显示
        	on_Trackbar(g_nAlphaValueSlider, 0);
        
        	//按任意键退出
        	waitKey(0);
        
        	return 0;
        	
        	
        }

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

      • int getTrackbarPos(const string& trackbarname, const string& winname)
      • 第一个参数:轨迹条的名字
      • 第二个参数:轨迹条的父窗口的名字
  • 3.3、鼠标操作:SetMouseCallback

    • void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata=0)
      • 第一个参数,窗口的名字
      • 第二个参数,指定窗口里每次鼠标事件发生的时候,被调用的函数指针,
      • 第三个参数,用户定义的传递到回调函数的参数,默认值0
      • #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(Mat& img, 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);
        	Mat srcImage(600, 800, CV_8UC3), tempImage;
        	srcImage.copyTo(tempImage);
        	g_rectangle = Rect(-1, -1, 0, 0);
        	srcImage = Scalar::all(0);
        
        	//设置鼠标操作回调 函数
        	namedWindow(WINDOW_NAME,0);
        	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;//按下esc退出
        	}
        	return 0;
        }
        
        //-------------【on_MouseHandle()函数】---------------
        //   鼠标回调函数,根据不同的鼠标事件进行不同的操作
        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)//如果是否进行绘制的标识符为真,则记录长和宽到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;
        	}
        }
        
        //--------------【DrawRectangle()函数】-------------
        // 自定义的矩形绘制函数
        
        void DrawRectangle(Mat& img, Rect box)
        {
        	rectangle(img, box.tl(), box.br(), Scalar(g_rng.uniform(0, 255),
        		g_rng.uniform(0, 255), g_rng.uniform(0, 255)));//随机颜色
        }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值