目录
HighGUI图形用户界面初步上手
一:图像的载入
//用于载入图像
Mat imread(const string& filename, int flags=1);
//第一个参数:载入的图片路径名
//第二个参数:标识,默认为1。‘1’ 代表载入彩色图像;‘0’代表载入灰色图像;‘2|4’代表载入无损图像。
//例子
Mat image1=imread("1.jpg",1);//载入彩色图像
Mat image1=imread("1.jpg",0);//载入灰度图
Mat image1=imread("1.jpg",2|4);//载入无损图像
二:图像的显示
//用于显示图像
void imshow(const string& winname, InputArray mat);
//第一个参数:需要显示的窗口名称
//第二个参数:需要显示的图像 mat对象
//例子
imshow("原图",image);
三:写入图像
//输出图像到文件
bool imwrite(const string& filename,InputArray img,const vector<int>& params=vector<int>());
//第一个参数:写入的图像名
//第二个参数:mat对象
//第三个参数:const vector<int>&类型的params,表示特定格式保存的参数编码。默认为vector<int>
//例子
imwrite("111.png",image,compression_params);
第三个参数中数据与保存的图片格式有关
- 对于JPEG格式的图片,表示从0到100的图片质量(CV_IMWRITE_JPEG_QUALITY),默认值95
- 对于PNG格式的图片,这个参数表示压缩级别(CV_IMWRITE_PAN_COMPRESSION)从0到9,较高的值意味着更小的尺寸和更长的压缩时间,默认为3
- 对于PPM,PGM,PBM格式的图片,这个参数表示一个二进制格式表示(CV_IMWRITE_PXM_BINARY)取0或1,默认1
(opencv2中有CV_前缀)
生成一副png图片并保存,完整代码如下:
#include <opencv2/opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;
void creatAlphMat(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 - j)) / ((float)mat.rows)*UCHAR_MAX);
rgba[3] = saturate_cast<uchar>(0.5*(rgba[1] + rgba[2]));
}
}
}
int main(){
Mat mat(480, 640, CV_8UC4);
creatAlphMat(mat);
vector<int>compression_params;
//compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION); //opencv2中
//opencv3中
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可以在工程目录下查看生成的图片");
waitKey(0);
}
catch (runtime_error& ex){
fprintf(stderr, "发生错误:%s\n", ex.what());
return 1;
}
return 0;
}
运行结果:
四:滑动条的使用
createTrackbar()创建滑动条函数
//创建滑动条
int createTrackbar(const string& trackbarname,const string& winname,int* value,int count,TrackbarCallback onChange=0,void* userdate=0);
//第一个参数:滑动条的名称
//第二个参数:依附的窗口名称
//第三个参数:一个指向整型的指针,表示滑块的位置。表示此变量的初始值
//第四个参数:表示滑块的最大值
//第五个参数:滑动条的回调函数的指针,这个函数须自己定义,形式为void xxx(int,void*);轨迹条位置和用户数据;默认0,表示没有回调函数。
//第六个参数:void*类型的userdata,默认0,这个参数是用户传给回调函数的数据,用来处理轨迹条时间。若第三个参数是全局变量,则不需要这个参数。
//例子
createTrackbar("对比度:","效果图窗口",&g_nContrastValue,300,on_change);//g_nContrastValue为全局的整型变量,on_change为回调函数函数名。
创建窗口函数: nameWindow()
//创建窗口
void nameWindow(const string& winname,int flags=WINDOW_AUTOSIZE);
//第一个参数:窗口名称
//第二个参数:窗口的标识,WINDOW_NORMAL:用户可改变窗口大小;WINDOW_AUTOSIZE:窗口大小自动调整;WINDOW_OPENGL:窗口支持opengl。参数默认WINDOW_AUTOSIZE
//例子
nameWindow("原图");
opencv2中加"CV_"前缀
创建滑动条例子,完整代码如下:
#include <opencv2/opencv.hpp>
#include <vector>
using namespace cv;
#define WINDOW_NAME "线性混合示例"
//定义全局变量
const int maxalphavalue = 100; //透明度alpha最大值
int alphavalueslider; //滑动条对应的变量
double alphavalue;//image1所占比重
double betavalue;//mage1所占比重
Mat image1;
Mat image2;
Mat image3;//输出
//相应滑动条的回调函数
void on_Trackbar(int, void*){
alphavalue = (double)alphavalueslider / maxalphavalue;//计算image1所占比重
betavalue = (1.0 - alphavalue);//计算image1所占比重
//线性混合操作
//输出image3=image1*alphavalue+image2*betevalue+0.0
addWeighted(image1, alphavalue, image2, betavalue, 0.0, image3);
imshow(WINDOW_NAME, image3);
}
int main(int agrc, char** argv){
image1 = imread("1.png");//加载图片,俩图片尺寸须一致
image2 = imread("2.jpg");
if (!image1.data){
printf("读取第一幅图片错误\n");
return -1;
}
if (!image2.data){
printf("读取第二幅图片错误\n");
return -1;
}
alphavalueslider = 70;//初始值
namedWindow(WINDOW_NAME, 1);//创建窗口
//窗体中输出滑动条控件名
char trackbarname[50];
sprintf(trackbarname, "透明度 %d", maxalphavalue);
//创建滑动条
createTrackbar(trackbarname, WINDOW_NAME, &alphavalueslider, maxalphavalue, on_Trackbar);
//结果在回调函数中显示
on_Trackbar(alphavalueslider, 0);
waitKey(0);
return 0;
}
运行结果:
五:鼠标操作
setMouseCallback()函数,为指定窗口设置鼠标回调函数
//为指定窗口设置鼠标回调函数
void setMouseCallback(const string& winname,MouseCallback onMouse,Void* userdata=0)
//第一个参数:窗口名称
//第二个参数:鼠标回调函数指针,回调函数为void Foo(int event,int x,int y,int flags,void* param),event是“EVENT_”作为前缀的int类型数据,x,y是图形坐标系中的坐标,
//第三个参数,用户定义的传递到回调函数的参数,默认值0
用鼠标进行画矩形,完整代码如下:
注意:定义全局变量是最好都加上前缀“g_”
#include <opencv2/opencv.hpp>
using namespace cv;
//全局函数的声明
void on_mousehandle(int event, int x, int y, int flags, void* params);
void drawrectangle(Mat& img, Rect box);
void showhelptext();
//声明全局变量
Rect g_rectangle; //全局变量最好加前缀“g_”
bool bdrawingbox = false; //是否进行绘制
RNG rng(12345);
int main(int agrc,char** agrv){
g_rectangle = Rect(-1, -1, 0, 0);
Mat image1(600, 800, CV_8UC3), image2;
image1.copyTo(image2);
g_rectangle = Rect(-1, -1, 0, 0);
image1 = Scalar::all(0);
namedWindow("程序窗口");
setMouseCallback("程序窗口", on_mousehandle, (void*)&image1);
while (1){
image1.copyTo(image2);
if (bdrawingbox)drawrectangle(image2, g_rectangle);
imshow("程序窗口", image2);
if (waitKey(10) == 27)break;//按下esc 退出
}
return 0;
}
void on_mousehandle(int event, int x, int y, int flags, void* param){
Mat& image = *(Mat*)param;
switch (event){
case EVENT_MOUSEMOVE://移动鼠标消息
{
if (bdrawingbox){
g_rectangle.width = x - g_rectangle.x;
g_rectangle.height = y - g_rectangle.y;
}
}break;
case EVENT_LBUTTONDOWN://左键按下消息
{
bdrawingbox = true;
g_rectangle = Rect(x, y, 0, 0);
}break;
case EVENT_LBUTTONUP://左键抬起消息
{
bdrawingbox = false;
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(Mat& img, Rect box){
rectangle(img, box.tl(), box.br(), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)));
}
运行结果: