《OpenCV3编程入门》学习笔记3 HighGUI图形用户界面初步

本文详细介绍OpenCV的HighGUI模块,包括图像的载入、显示、混合与输出,滑动条的创建与使用,以及鼠标操作的实现。通过具体示例展示了如何利用这些功能进行图像处理和用户交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第3章 HighGUI图形用户界面初步

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

1.OpenCV命名空间2种访问方法
(1)代码开头加:usingnamespace cv;
(2)每个类或函数前加:cv::

2.Mat类
(1)Mat类用于保存图像及其他矩阵数据,默认尺寸0
(2)定义Mat对象: cv::Mat pic(320,640,cv::Scalar(100));

3.图像载入:imread()函数

函数原型:Mat imread(const string& filename, intflags=1);

(1)const string& filename : 载入图片路径名,Windows系统下,OpenCV的imread函数支持类型:
在这里插入图片描述
(2)int flags:载入标识,制定加载图像的颜色类型:
· 取值0,CV_LOAD_IMAGE_GRAYSCALE,始终将图像转换成灰度再返回
· 取值1,CV_LOAD_IMAGE_COLOR,总是转换图像到彩色再返回
· 取值2,CV_LOAD_IMAGE_ANYDEPTH,载入图像深度为16位或32位,就返回对应深度图像,否则转换为8位图像再返回
通常:
·flags>0返回一个3通道彩色图像
·flags=0返回灰度图像
·flags<0返回包含Alpha通道的加载图像

4.图像显示:imshow()函数

函数原型:void imshow(const string& winname,InputArray mat);

(1)const string&类型的winname,填需要显示的窗口标识名称
(2)InputArray类型的mat,填需要显示的图像
(3)imshow默认窗口(CV_WINDOW_AUTOSIZE)显示图像原始大小,否则缩放以适合窗口,缩放取决于图像深度:
·8位无符号类型图像,显示原始大小
·16位无符号或32位整型,像素值除以256,即[0,255*256]->[0,255]
·32位浮点数,像素值乘以255,即[0,1]->[0,255]

5.nameWindow()函数

函数原型:void nameWindow(const string& winname,int flas=EINDOW_AUTOSIZE);

(1)参数说明:1)窗口名2)窗口标识(WINDOW_NORMAL:可改变窗口大小;WINDOW_AUTOSIZE:窗口自动调整大小;WINDOW_OPENGL:窗口创建时支持OpenGL)
(2)作用:创建窗口

6. imwrite函数

函数原型:bool imwrite(const string& fliename,InputArray img,const vector& params=vector());

(1)参数说明:
文件名;
Mat类型的图像数据;
特定格式保存的参数编码(默认vector()):JPEG格式图片,参数表示0-100的图片质量(默认值95);PNG格式图片,参数表示0-9压缩级别(默认值3);PPM\PGM\PB,格式图片,参数表示0或1二进制格式标志(默认值1)
(2)作用:输出到文件
(3)示例:在OpenCV中生成一副png图片,并写到当前目录下

#include<opencv2/opencv.hpp>
#include<vector>

using namespace cv;
using namespace std;

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(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;
}

7.图像载入、混合、显示、输出到文件综合示例

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>

using namespace cv;

int main()
{
	//1.图像的载入和显示
	Mat girl = imread("girl.jpg");
	namedWindow("[1]动漫图");    //创建一个名为“【1】动漫图”的窗口
	imshow("[1]动漫图", girl);

	//2.初级图像混合
	Mat image = imread("cat.jpg");
	Mat logo = imread("dog.jpg");

	namedWindow("[2]原画图");
	imshow("[2]原画图", image);

	namedWindow("[3]logo图");
	imshow("[3]logo图", logo);

	Mat imageROI;//定义一个Mat类型,用于存放,图像的ROI
	imageROI = image(Rect(800, 300, logo.cols, logo.rows));//方法一
	//imageROI = image(Range(350, 350 + logo.rows), Range(800, 800 + logo.cols));//方法二
	addWeighted(imageROI, 0.5, logo, 0.3, 0.0, imageROI);//将logo加到原图上

	namedWindow("[4]原画+logo图");
	imshow("[4]原画+logo图", image);

	//3.图像输出
	//imwrite("由imwrite生成的图片", image);

	waitKey(0);

	return 0;
}

3.2 滑动条的创建和使用

3.2.1 创建滑动条:createTrackbar()函数

函数原型:int createTrackbar(conststring& trackbarname,conststring& winname,int* value,int count,TrackbarCallback onChange=0,void* userdata=0);

(1)参数说明:轨迹条名字 ,依附窗口名 , 滑块初始位置 ,滑块可以到达的最大位置, 指向回调函数指针(每当滑块改变时函数都会回调), 用户传给回调函数的数据
(2)函数作用:创建一个具有特定名称和范围的轨迹条
(3)示例:用轨迹条控制两幅图像的Alpha混合

#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_dAlphValue;
double g_dBetaValue;
//声明存储图像的变量
Mat g_srcImage1;
Mat g_srcImage2;
Mat g_dstImage;
//响应滑动条的回调函数,第一个参数是轨迹条位置,第二个参数是用户数据
void on_Teackbar(int, void*)
{
	//求出当前alpha值相对于最大值的比例
	g_dAlphValue = (double)g_nAlphaValueSlider / g_nMaxAlphaValue;
	//则beta值为1减去alpha值
	g_dBetaValue = (1.0 - g_dAlphValue);
	//根据alpha和beta值进行线性混合
	addWeighted(g_srcImage1, g_dAlphValue, g_srcImage2, g_dBetaValue, 0.0, g_dstImage);
	//显示效果图
	imshow(WINDOW_NAME, g_dstImage);
}
int main()
{
	//加载图像(两图像尺寸需要相同)
	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_s(TrackbarName, "透明值 %d", g_nMaxAlphaValue);
	createTrackbar(TrackbarName, WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue,on_Teackbar);
	//结果在回调函数中显示
	on_Teackbar(g_nAlphaValueSlider, 0);
	//按任意键退出
	waitKey(0);

	return 0;
}

3.2.2 getTrackbarPos()函数

函数原型:int getTrackbarPos(conststring& trackbarname,conststring& winname);

(1)参数说明: 轨迹条名字 , 窗口名
(2)作用:获取当前轨迹条位置

3.3 鼠标操作

SetMouseCallback()函数:void setMouseCallback(conststring& winname,MouseCallback onMouse,void* userdata=0)

(1)参数说明:窗口名字,指定窗口里每次鼠标事件发生的时候被调用的函数指针,用户定义的传递到回调函数的参数(默认0)
(2)作用:为指定的窗口设置鼠标消息回调函数
(3)示例:

#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()
{
	//[1]准备参数
	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);

	//[2]设置鼠标操作回调函数
	namedWindow(WINDOW_NAME);
	cvSetMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);

	//[3]程序主循环,当进行绘制的标识符为真时,进行绘制
	while (1)
	{
		srcImage.copyTo(tempImage);//复制原图到临时变量
		if (g_bDrawingBox) DrawRectangle(tempImage, g_rectangle);//当进行绘制的标识符为真,则进行绘制
		imshow(WINDOW_NAME, tempImage);
		if (waitKey(10) == 27) break;//按下ESC键,程序退出
	}
	return 0;
}

void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
	Mat& image = *(cv::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;
	}
}
//自定义的矩形绘制函数
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)));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值