《OpenCV3编程入门》学习 第三章 HighGUI图形用户界面初步

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

1.1 OpenCV的命名空间

OpenCV中的C++类和函数都是定义在命名空间 cv 之内的,在访问时可以:

  • 在代码开头加上 using namespace cv; (推荐这种方法)
  • 每一次在使用OpenCV相关类和函数时,前面加上 cv:: ,例如:cv::imread()。

1.2 Mat类简析

OpenCV中Mat用于保存图像以及其他矩阵数据的数据结构。
例如:

Mat img=imread("1.jpg")

这里就是将图片中的信息读取保存在名为img的Mat变量里面。

1.3 图像的载入:imread( )函数

imread( )函数原始定义:

Mat imread( const String& filename, int flags = IMREAD_COLOR );

格式:imread(参数1,参数2)

  • 参数1:const String&类型的filename,指载入图片的路径名。
    例如:Mat img = imread("D:/practice/opencv3/imge/2.jpg");
    在Windows系统下,OpenCV的imread( )函数支持的图像类型:
    在这里插入图片描述
  • 参数2:int类型的flags,为载入标识,它指定加载图像的颜色类型。该参数常常忽略,其默认为1(IMREAD_COLOR ),表示加载三通道的彩色图像。
    其他的有:
    在这里插入图片描述
    对应的解释:
    在这里插入图片描述
    注意:当以彩色模式载入图像时,解码后的图像会以BGR的通道顺序进行存储,即蓝、绿、红的顺序。

1.4 图像的显示:imshow( )函数

imshow( )函数用于在指定窗口显示一副图像,函数的原始定义为:

void imshow(const String& winname, InputArray mat);

格式:imshow(参数1,参数2);

  • 参数1:const String&类型的winname,填需要显示的窗口名称。
  • 参数2:InputArray 类型的mat,填需要显示的图像。
    例如:imshow("原始图片", img);

1.5 创建窗口:namedWindow( )函数

namedWindow( )函数,用于创建一个窗口。一般用于在显示窗口之前就需要用到窗口名这种情况,否则直接用imshow( )就好。
原始定义:

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

格式:namedWindow(参数1,参数2);
例如:namedWindow("WIN1", WINDOW_NORMAL);

  • 参数1:const String&类型的name,填写窗口的名称;
  • 参数2:int类型的flags,窗口的标识,有以下选择:
    在这里插入图片描述
    可以调用 destroyWindow( )或者destroyAllWindow( )函数来关闭窗口。

1.6 输出图像到文件:imwrite( )函数

imwrite( )函数用于将图像输出到文件中去,原始定义为:

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

格式:imwrite(参数1,参数2,参数3);
例如:imwrite("D:/imge/test123.jpg", img);

  • 参数1:const String& 类型的filename,填写需要写入的文件名字,注意要加后缀,例如”img.jpg"。
  • 参数2:InputArray 类型的img,一般填一个Mat类型的图像数据。
  • 参数3:const vector&类型的params,表示特定格式保存的参数编码。默认值为vector( ),一般情况不需要填写。

综合示例:图像的载入、显示与输出

目标:读入两张图片,并且将这两张图片进行混合,最后将其保存输出。
示例代码:

#include<opencv2/opencv.hpp>

using namespace cv;

int main()
{
	//-------------------- 图像的载入和显示 ---------------
	Mat img = imread("D:/practice/opencv3/imge/2.jpg");//载入原始图片
	namedWindow("【原始图像】");//创建原始图片窗口
	imshow("【原始图像】", img);//显示原始图片
	

	//-------------------- 初级图像混合 ------------------
	Mat cat = imread("D:/practice/opencv3/imge/mao.jpg");//载入猫咪的图片
	namedWindow("【猫咪的图片】");
	imshow("【猫咪的图片】", cat);

	//定义一个Mat类型,用于存放图像的ROI
	Mat imgeROI;
	
	imgeROI = cat(Rect(10, 50, img.cols, img.rows));
	
	//将原图加到猫咪上(因为这里原图尺寸比猫咪小很多)
	addWeighted(imgeROI, 0.5, img, 0.6, 0., imgeROI);
	//显示结果
	namedWindow("【混合后】");
	imshow("【混合后】", cat);

	//--------------------- 图像的输出 ----------------
	imwrite("D:/practice/opencv3/imge/混合图片.jpg",cat);
	waitKey(0);
	system("pasue");
}

运行结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 滑动条的创建和使用

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

createTrackbar( )函数用于创建一个调整数值的滑动条,该滑动条依附在指定的窗口上。该函数常常和一个回调函数配合起来使用。
原始定义:

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

格式:createTrackbar(参数1,参数2,参数3,参数4,参数5,参数6);

  • 参数1:const String&类型的trackbarname,我们创建的滑动条的名字
  • 参数2:const String&类型的winname,滑动条所依附窗口的名字,即对应nameWindow( )函数创建窗口时填入的窗口名字。
  • 参数3:int*类型的value,一个指向整型的指针,表示滑动条上滑块的位置。在创建时,滑块的初始位置就是该变量当前的值。
  • 参数4:int类型的count,表示滑块可以达到的最大位置的值。滑块的最小位置的值始终是0。
  • 参数5:TrackbarCallback类型的onChange ,它有默认值为0。具体介绍如下:
  • 在这里插入图片描述

参数6:void*类型的userdata,也有默认值0。具体介绍如下:
在这里插入图片描述
示例:利用滑动条来控制两个图像的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_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);
}



//-------------------------- mian()函数 ————————————
//                  描述:控制台应用程序的入口函数,我们的程序从这里开始i执行
//-------------------------------------------------------------------------
int main(int argc,char** argv)
{
	//加载图像(两图像的尺寸需要相同)
	g_srcImage1 = imread("D:/practice/opencv3/imge/1.jpg");
	g_srcImage2 = imread("D:/practice/opencv3/imge/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_Trackbar);
	//结果在回调函数中显示
	on_Trackbar(g_nAlphaValueSlider, 0);
	//按任意键退出
	waitKey(0);
	system("pause"); 
	return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 获取当前滑动条的位置:getTrackbarPos( )函数

getTrackbarPos( )函数,用于获取当前滑动条的位置。原始定义:

int getTrackbarPos(const String& trackbarname, const String& winname);

格式:getTrackbarPos(参数1,参数2);

  • 参数1:const String&类型的trackbarname,表示滑动条的名字
  • 参数2:const String&类型的winname,表示滑动条父窗口的名字

3. 鼠标操作

setMouseCallback( )函数,为指定的窗口设置鼠标回调函数,原始定义如下:

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

格式:setMouseCallback(参数1,参数2,参数3);

  • 参数1:const String&类型的winname,窗口的名字

  • 参数2:MouseCallback类型的onMouse,指定窗口每次鼠标时间发生的时候,被调用的函数指针。具体介绍如下:
    在这里插入图片描述

  • 参数3:void*类型的userdata,用户定义的传递到回调函数的参数,有默认值为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(cv::Mat& img, cv::Rect box);
void showHelpText();

//--------------------- 全局变量声明部分 ---------------
Rect g_rectangle;
bool g_bDrawingBox = false;//是否进行绘制
RNG g_rng(12345); //产生随机数

//------------------- main() 主函数 -------------------
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);
	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;
	//system("pasue");
}

//--------------------------- on_MouseHandle()函数 -------------------
//描述:鼠标回调函数。根据不同的鼠标事件进行不同的操作
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;
	}
}

//------------------------ DrawRectangle()函数 ---------------
//描述:自定义的矩形绘制函数
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)));//随机颜色
}

运行结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值