HighGUI图形用户界面
1.图像的载入、显示和输出到文件
1.1 图像的载入:imread()函数
Mat imread(const string &filename,int flags=1)
- 第一个参数:图片路径
- 第二个参数:载入标识,指定一个加载图像的颜色类型。可以看到它自带的默认值为1
1.2 图像的显示:imshow()函数
void imshow(const string& winname InputArray mat)
- 第一个参数:填需要显示的窗口标识名称
- 第二个参数:填需要显示的图像
1.3 创建窗口:namedWindow()函数
void namedWindow(const string &winname, int flags=WINDOW_AUTOSIZE)
- 第一个参数:窗口名称
- 第二个参数:窗口的标识,可以设置以下几个值
WINDOW_NORMAL:用户可以改变窗口大小
WINDOW_AUTOSIZE:窗口大小会自动调整使用图片的大小,用户不能手动改变窗口的大小
WINDOW_OPENGL:窗口创建的时候会支持OPENGL
1.4 输入图像到文件:imwrite()函数
bool imwrite(const string& filename, InputArray img, const vector<int>& params=vector<int>() )
- 第一个参数: 填写要写入的文件名,带上后缀,如123.jpg
- 第二个参数:一般填一个Mat类型的图像数据
- 第三个参数:表示为特定格式保存的参数编码
1.5综合案例代码
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main() {
//---------------------1.图像的载入和显示---------------------
Mat girl = imread("../../image/girl.jpg"); //载入图像到Mat
namedWindow("【1】动漫图", WINDOW_NORMAL); //创建一个名为 [1]动漫图 的窗口
imshow("【1】动漫图", girl); //显示名为“【1】动漫图”的窗口
//-----------------------2.初级图像混合------------------------
Mat dota= imread("../../image/dota.jpg");
Mat logo = imread("../../image/logo.jpg");
//载入后显示
namedWindow("【2】dota",WINDOW_NORMAL);
imshow("【2】dota", dota);
namedWindow("【3】logo", WINDOW_NORMAL);
imshow("【3】logo", logo);
//定义一个Mat类型,用于存放图像的ROI
Mat imageROI;
//方法一
imageROI = dota(Rect(800, 350, logo.cols, logo.rows));
//方法二
dota(Range(350, 350 + logo.rows), Range(800, 800 + logo.cols));
//将image2加到image1上
addWeighted(imageROI, 0.5, logo, 0.3, 0., imageROI);
//显示结果
namedWindow("【4】dota+logo", WINDOW_NORMAL);
imshow("【4】dota+logo", dota);
//-------------------------------3.图像的输出----------------------------
//将一个Mat图像输出到图像文件
imwrite("由imrite生成的图片.jpg", dota);
waitKey(0);
return 0;
}
2. 滑动条的创建和使用
2.1 创建滑动条:createTrackbar()函数
int createTrackbar(const string& trackbarname , const string& winname , int* value , int count, TrackbarCallback onChange=0 , void* userdata=0);
- 第一个参数:轨迹条的名字
- 第二个参数:窗口的名字
- 第三个参数:一个指向整形的指针,表示滑块的位置。在创建时,滑块的初始位置就是该变量当前的值。
- 第四个参数:表示滑块可以达到的最大值。滑块最小位置的值始终为0;
2.2 滑动条案例
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
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);
}
int main() {
//加载图像
g_srcImage1 = imread("../../image/1.tif");
g_srcImage2 = imread("../../image/2.tif");
if (!g_srcImage1.data) {
cout << "读取第一幅图片失败" << endl;
return -1;
}
if (!g_srcImage2.data) {
cout << "读取第二幅图片失败" << endl;
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);
return 0;
}
2.3 获取当前轨迹条的位置:getTrackbarPos()函数
该函数是配合createTrackbar使用的函数,它用于获取当前轨迹条的位置。
int getTrackbarpos(const string& trackbarname,const string& winname);
- 第一个参数:表示轨迹条的名字
- 第二个参数:表示轨迹条的父窗口的名称
3.鼠标操作
OpenCV中的鼠标操作和滑动条的消息映射方式很类似,都是通过一个中介函数配合一个回调函数来实现的。
void setMousecCallback(const string &winname,MouseCallback onMouse,void* userdata=0)
- 第一个参数:窗口的名称
- 第二个参数:指定窗口里每次鼠标时间发生的时候,被调用的函数指针。
3.1 鼠标操作案例
#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() {
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;
}
void on_MouseHandle(int event, int x, int y, int flag, 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.x += 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)));//设置随机颜色
}