C++下OpenCV学习笔记
----HighGUI图形用户界面函数
文章目录
头文件&命名空间:
#include<opencv2/opencv.hpp>
using namespace cv;
一.图像输入:imread()
- 原型
Mat imread(const string& filename,int flags = IMREAD_COLOR); |
第一个参数,const string&类型的filename,表示需要载入的图片路径名
支持:(1)Windows位图:*.bmp, *.dib (2)JPEG文件:*.jpeg, *.jpg, *.jpe
(3)JPEG2000文件:*.jp2 (4)PNG文件:*.png
(5)便携文件格式:*.pbm,*.pgm,*.ppm (6)Sun rasters光栅文件:*.sr,*.ras
(7)TIFF文件:*.tiff,*.tif
第二个参数,int类型的flags,表示载入的标识,默认为1
常用标识符:(1)CV_LOAD_IMAGE_GRAYSCALE,等价取值0,将图像转为灰度再返回
(2)CV_LOAD_IMAGE_COLOR,等价取值1,将图像转为彩色再返回
(3)CV_LOAD_IMAGE_ANYDEPTH,等价取值2,若载入的图像深度为12位/32位,就返回对应深度的图像,否则返回8位图像再返回
即flags>0返回3通道的彩色图像;flags=0返回灰度图像;flags<0返回包含Alpha通道的加载图像
- 代码实现
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat srcImage = imread("C:\\Users\\441\\Desktop\\ZL\\夏目\\1.jpg");
imshow("原图",srcImage);
waitKey(0);
return 0;
}
- 运行结果
二.图像显示:imshow()
- 原型
void imshow(const string& winname, InputArray mat); |
第一个参数:const string&类型的winname,表示需要显示的窗口标识名称
第二个参数:InputArray类型的mat,表示需要显示的图像
- 代码实现&运行结果
同imread()函数。 - attention:
imshow之后必须有waitKey函数,否则显示窗内将一闪而过,不会驻留屏幕。
waitKey(0); 不关闭窗口
waitKey(5000); 等待5秒后关闭
三.创建窗口:namedWindow()
- 原型
void namedWindow(const string& winname, int flags=WINDOW_AUTOSIZE ); |
第一个参数:const string&型的name,表示被用作窗口的标识符的窗口名称。
第二个参数:int类型的flags,表示窗口的标识。
常用标识符:(1)WINDOW_NORMAL,表示用户可以改变窗口大小。【OpenCV2中为CV_WINDOW_NORMAL】
(2)WINDOW_AUTOSIZE,表示窗口会自动调整大小以适应图像,用户不可以改变窗口大小。【OpenCV2中为CV_WINDOW_AUTOSIZE】
(3)WINDOW_OPENGL,表示窗口创建时会支持OpenGL。【OpenCV2中为CV_WINDOW_OPENGL】
(4)WINDOW_FULLSCREEN,表示全屏显示图片。
(5)WINDOW_FREERATIO,表示调整图像尺寸以充满窗口。
(6)WINDOW_KEEPRATIO,表示保持图像比例。
(7)WINDOW_GUI_EXPANDED,表示创建的窗口允许添加工具栏和状态栏。
(8)WINDOW_GUI_NORMAL,表示创建没有状态栏和工具栏的窗口。
- 代码实现
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
namedWindow("图1",WINDOW_NORMAL);
waitKey(0);
return 0;
}
- 运行结果
- attention:
调用destroyWindow()或者destroyAllWindows()函数来关闭窗口。
destroyWindow();
destroyAllWindows();
四.输出图像到文件:imwrite()
- 原型
bool imwrite(const string& filename, InputArray img, const vector& params = vector() ); |
第一个参数:const string&类型的filename,表示需要写入的文件名。【记得带上后缀】
第二个参数:InputArray类型的img,一般填一个Mat类型的图像数据。
第三个参数:const vector&类型的params,默认值vector()。表示为特定格式保存的参数编码。【一般不需要填写】
填写:
(1)JPEG/JPG格式的图片:参数表示从0到100的图片质量(IMWRITE_JPEG_QUALITY),默认值95.
(2)PNG格式的图片:参数表示压缩级别(IMWRITE_PNG_COMPRESSION)从0到9,较高的值意味着更小的尺寸和更长的压缩时间,默认值3
(3)PPM,PGM,BGM格式的图片,参数表示一个二进制格式标志(IMWRITE_PXM_BINARY),取值为0或1,默认值1
(1)JPEG/JPG
vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
compression_params.push_back(95);
(2)PNG
vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(3);
(3)PPM,PGM,BGM
vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_PXM_BINARY);
compression_params.push_back(1);
- 代码实现
该代码实现的是将jpg图片转换为png图片。
#include <opencv2/opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;
int main()
{
Mat src1 = imread("C:\\Users\\441\\Desktop\\ZL\\Natsume\\1.jpg");
imshow("jpg图像",src1);
waitKey(0);
vector<int>compression_params;
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(3);
imwrite("1.png", src1, compression_params);
imshow("png图像", src1);
waitKey(0);
}
- 运行结果
1> 首先打开jpg图像(原图)
2>关闭后生成png图像
3>打开工程目录,可以看到生成的png图像:1.png
- attention
使用imwrite函数时,要注意图片路径中最好不要出现中文,否则可能出错。
五.图像融合:addWeighted()
---->addWeighted函数详解
- 原型
void addWeighted(InputArray src1,double alpha,InputArray src2,double beta,double gamma,OutputArray dst,int dytpe=-1); |
第一个参数,InputArray类型的src1,表示需要加权的第一个数组,填一个Mat。
第二个参数,double类型的alpha,表示第一个数组的权重。
第三个参数,InputArray类型的src2,表示需要加权的第二个数组,需要和第一个数组拥有同样的尺寸和通道数。
第四个参数,double类型的beta,表示第二个数组的权重。
第五个参数,double类型的gamma,一个加到权重总和上的标量值
第六个参数,OutputArray类型的dst,输出的数组,拥有同样的尺寸和通道数。
第七个参数,int类型的dtype,输出阵列的可选深度,默认值-1。
尺寸:长x宽(分辨率)
通道:灰度(1通道),RGB555或RGB565(2通道),RGB(3通道),RGBA(4通道)
- 代码实现
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat src1 = imread("C:\\Users\\441\\Desktop\\ZL\\夏目\\1.jpg");
Mat src2 = imread("C:\\Users\\441\\Desktop\\ZL\\夏目\\2.jpg");
Mat dst;
addWeighted(src1, 0.7, src2, 0.3, 3, dst);
imshow("图1", src1);
imshow("图2", src2);
imshow("mixed", dst);
waitKey(0);
return 0;
}
- 运行结果
![](https://img-blog.csdnimg.cn/2021012317115651.png)
- attention:
第二个参数和第四个参数还有第五个参数,越大,图片越白。
六.创建滑动条:createTrackbar()
- 原型
int createTrackbar(const string& trackbarname, const string& winname,int* value, int count,TrackbarCallback onChange = 0,void* userdata = 0); |
第一个参数:const string&类型的trackbarname,表示轨迹条的名字。
第二个参数:const string&类型的winname,表示这个轨迹条会依附到哪个窗口上,即对应namedWindow()创建窗口时填的某一个窗口名。
第三个参数:int* 类型的value,一个指向整型的指针,表示滑块的位置。并且在创建时,滑块的初始位置就是该变量当前的值。
第四个参数:int类型的count,表示滑块可以达到的最大位置的值。【滑块最小的位置的值始终为0】。
第五个参数:TrackbarCallback类型的onChange,默认值0。这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。并且这个函数的原型必须为void XXXX(int,void*);其中第一个参数是轨迹条的位置,第二个参数是用户数据(看下面的第六个参数)。如果回调是NULL指针,表示没有回调函数的调用,仅第三个参数value有变化。【即滑动滑动条引起的图片变化】
第六个参数,void*类型的userdata,默认值0。这个参数是用户传给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value实参是全局变量的话,完全可以不去管这个userdata参数。
- 代码实现
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int num = 0;
int numMax = 10;
void onChange(int num, void* userdata)
{
cout << "num的值为" << num << endl;
}
int main()
{
namedWindow("窗口", WINDOW_NORMAL);
createTrackbar("值", "窗口", &num, numMax, onChange, &num);
onChange(num, &num);
waitKey(0);
return 0;
}
(1)该代码实现的是移动滑动条实现输出滑动条对应的值。
(2)其中onChange为回调函数,若要用滑动条实现其他功能,如图像二值化,则在此更改代码。
(3)在这个程序中,createTrackbar函数的第三参数num设置为全局变量,所以他的第六参数可以不用管,也是num。
- 运行结果
七.获取当前轨迹条的位置:getTrackbarPos()
- 原型
int getTrackbarPos(const string& trackbarname, const string& winname); |
第一个参数:const string& trackbarname,表示轨迹条的名字。
第二个参数:const string& winname,表示轨迹条依托窗口的名称。
- 代码实现
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int num = 0;
int numMax = 10;
int i;
void onChange(int num, void* userdata)
{
i = getTrackbarPos("值", "窗口");
cout << "num的值为" << i << endl;
}
int main()
{
namedWindow("窗口", WINDOW_NORMAL);
createTrackbar("值", "窗口", &num, numMax, onChange, &num);
onChange(num, &num);
waitKey(0);
return 0;
}
- 运行结果
八.鼠标操作:SetMouseCallback()
- 原型
void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0); |
第一个参数:const string&类型的winname,表示窗口的名字。
第二个参数:MouseCallback类型的onMouse,表示指定窗口里每次鼠标时间发生的时候,被调用的函数指针。
函数原型为:void on_Mouse(int event, int x, int y, int flags, void* param);
(1)event是 CV_EVENT_*变量之一
(2,3)x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系)
(4)flags是CV_EVENT_FLAG的组合
1>CV_EVENT_FLAG_LBUTTON 左键拖拽
2>CV_EVENT_FLAG_RBUTTON 右键拖拽
3>CV_EVENT_FLAG_MBUTTON 中键拖拽
4>CV_EVENT_FLAG_CTRLKEY Ctrl按下不放
5>CV_EVENT_FLAG_SHIFTKEY shift按下不放
5>CV_EVENT_FLAG_ALTKEY alt按下不放
(5)param是用户定义的传递到setMouseCallback函数调用的参数:
1>CV_EVENT_MOUSEMOVE 移动,
2>CV_EVENT_LBUTTONDOWN 左键按下,
3>CV_EVENT_RBUTTONDOWN 右键按下,
4>CV_EVENT_MBUTTONDOWN 中键按下,
5>CV_EVENT_LBUTTONUP 左键放开,
6>CV_EVENT_RBUTTONUP 右键放开,
7>CV_EVENT_MBUTTONUP 中键放开,
8>CV_EVENT_LBUTTONDBLCLK 左键双击,
9>CV_EVENT_RBUTTONDBLCLK 右键双击,
10>CV_EVENT_MBUTTONDBLCLK 中键双击,
11>CV_EVENT_MOUSEWHEEL 鼠标向前(+)或向后(-)滑动,
12>CV_EVENT_MOUSEHWHEEL 鼠标向右(+)或向左(-)滑动,
第三个参数:void*类型的userdata,默认值0,表示用户定义的传递到回调函数的参数。
- 代码实现
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int c = 0;
void on_Mouse(int event, int x, int y, int flags, void* param)
{
c++;
cout << "第 " << c << " 次鼠标事件" << endl;
if (event == CV_EVENT_MOUSEMOVE)
cout << "鼠标移动" << endl;
else if (event == CV_EVENT_LBUTTONDOWN)
cout << "鼠标左键按下" << endl;
else if (event == CV_EVENT_MBUTTONDOWN)
cout << "鼠标中键按下" << endl;
else if (event == CV_EVENT_RBUTTONDOWN)
cout << "鼠标右键按下" << endl;
else if (event == CV_EVENT_LBUTTONUP)
cout << "鼠标左键放开" << endl;
else if (event == CV_EVENT_MBUTTONUP)
cout << "鼠标中键放开" << endl;
else if (event == CV_EVENT_RBUTTONUP)
cout << "鼠标右键放开" << endl;
else if (event == CV_EVENT_LBUTTONDBLCLK)
cout << "鼠标左键双击" << endl;
else if (event == CV_EVENT_MBUTTONDBLCLK)
cout << "鼠标中键双击" << endl;
else if (event == CV_EVENT_RBUTTONDBLCLK)
cout << "鼠标右键双击" << endl;
else if (event == CV_EVENT_MOUSEWHEEL)
cout << " 鼠标向前(+)或向后(-)滑动" << endl;
else if (event == CV_EVENT_MOUSEHWHEEL)
cout << "鼠标向右(+)或向左(-)滑动" << endl;
}
int main()
{
namedWindow("测试窗口");
setMouseCallback("测试窗口",on_Mouse);
waitKey(0);
return 0;
}
- 运行结果