【OpenCV】HighGUI图形用户界面
【OpenCV】HighGUI图形用户界面
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
//查看OpenCV版本:宏
CV_VERSION
读取图像
imread()
cv::Mat imread(图片路径,int flags=1);
图片路径支持:
※关于flags:
//flags>0 -> 载入三通道彩色图像
cv::Mat image0=imread("1.jpg",199);
//flags=0 -> 载入灰度图
cv::Mat image0=imread("1.jpg",0);
//flags<0 -> 载入无损原图
cv::Mat image0=imread("1.jpg",-50);
显示图像
imshow()
imshow(图片路径,cv::Mat)
创建窗口
namedWindow()
显式规定窗口名称
namedWindow(窗口名称,int flag=WINDOW_AUTOSIZE)
对于flag
WINDOW_NORMAL 可改变窗口大小
WINDOW_AUTOSIZE 窗口自适应 不能改变大小
关闭窗口:释放内存
destoryWindow()
destoryAllWindow()
输出图像到文件
imwrite()
imwrite(文件名,Mat,特定格式保存编码)
小demo
#include<bits/stdc++.h>
#include<opencv4/opencv2/opencv.hpp>
using namespace std;
void createAlphaMat(cv::Mat &mat){
for(int i=0;i<mat.rows;i++){
for(int j=0;j<mat.cols;j++){
cv::Vec4b &rgba=mat.at<cv::Vec4b>(i,j);
rgba[0]=UCHAR_MAX;
rgba[1]=static_cast<uchar>((float (mat.cols-j))/((float)mat.cols)*UCHAR_MAX);
rgba[2]=static_cast<uchar>((float (mat.rows-i))/((float)mat.rows)*UCHAR_MAX);
rgba[3]=static_cast<uchar>(0.5*(rgba[1]+rgba[2]));
}
}
}
int main(){
cv::Mat mat(480,640,CV_8UC4);
createAlphaMat(mat);
vector<int> compression_params;
compression_params.push_back(cv::IMWRITE_PNG_COMPRESSION);
try{
cv::imwrite("透明Alpha值图.png",mat,compression_params);
cv::imshow("生成的PNG图",mat);
fprintf(stdout,"PNG图片文件的alpha数据保存完毕\n可以在工程目录下查看由imwrite函数生成的图片\n");
cv::waitKey(0);
}
//注意try...catch...捕获错误
catch(runtime_error &ex){
fprintf(stderr,"图像转换为PNG格式发生错误:%s\n",ex.what());
return 1;
}
return 0;
}
滑动条
//创建滑动条
createTracker(轨迹条名字,轨迹条依附的窗口,滑块初始位置[注意这个是指针 int*],滑块可达到的最大值,回调函数,用户传给回调函数的数据)
//获取滑动条位置
int getTrackbarPos(轨迹条名字,轨迹条所在窗口名字)
小demo
#include<bits/stdc++.h>
#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;
//响应滑动条的回调函数
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(int argc,char** argv){
g_srcImage1=imread("image/a.jpg");
g_srcImage2=imread("image/b.jpg");
//注意两张图片要一样大小!不然会报错
resize(g_srcImage2, g_srcImage2, g_srcImage1.size());
if(!g_srcImage1.data){
cout<<"读取第一副图片错误"<<endl;
return -1;
}
if(!g_srcImage2.data){
cout<<"读取第二副图片错误"<<endl;
return -1;
}
//设置滑动条初值
g_nAlphaValueSlider=70;
//创建窗口
namedWindow(WINDOW_NAME,1);
//创建滑动条
char TrackbarName[50];
sprintf(TrackbarName,"透明值 %d",g_nMaxAlphaValue);
//主函数
createTrackbar(TrackbarName,WINDOW_NAME,&g_nAlphaValueSlider,g_nMaxAlphaValue,on_Trackbar);
//结果在回调函数中显示
on_Trackbar(g_nAlphaValueSlider,0);
waitKey(0);
return 0;
}
鼠标操作
中介函数配合回调函数
setMouseCallback(窗口名称,回调函数,传递到回调函数参数(void* usrdata=0))
->回调函数MouseCallback:
void Foo(int EVENT,x,y(鼠标指针在图像坐标系),EVENT_FLAG,参数)
小demo
注意;
srcImage
:最终图像 Mouse回调函数中调用 用来确定已经画好图形的图像
tempImage
中间图像 用来显示按下鼠标左键时拖动的实时Rect
#include<bits/stdc++.h>
#include<opencv2/opencv.hpp>
using namespace std;
#define WINDOW_NAME "【程序窗口】"
//声明全局函数
void on_MouseHandle(int event,int x,int y,int flags,void *param);
void DrawRectangle(cv::Mat &img,cv::Rect box);
//声明全局变量
cv::Rect g_rectangle;
bool g_bDrawingBox=false;//是否进行绘制
cv::RNG g_rng(12345);//随机数生成器
int main(int argc,char** argv){
g_rectangle=cv::Rect(-1,-1,0,0);
cv::Mat srcImage(600,800,CV_8UC3),tempImage;
srcImage.copyTo(tempImage);
srcImage=cv::Scalar::all(0);
//设置鼠标操作回调函数
cv::namedWindow( WINDOW_NAME );
//只要鼠标有动作就会被回调:不需要加入循环
cv::setMouseCallback(WINDOW_NAME,on_MouseHandle,(void*)&srcImage);
//【对于绘图】
//当进行绘制的标识符为真->进行绘制
while(1){
srcImage.copyTo(tempImage);
if(g_bDrawingBox) DrawRectangle(tempImage,g_rectangle);
//这里是显示正在被拖动的矩形
cv::imshow( WINDOW_NAME , tempImage );
if(cv::waitKey(10)==27) break;//按下ESC键程序退出
}
return 0;
}
//【对于鼠标】
//鼠标回调函数
void on_MouseHandle(int event,int x,int y,int flags,void* param){
cv::Mat &image=*(cv::Mat*) param;
switch(event){
//鼠标移动
case cv::EVENT_MOUSEMOVE:
{
if(g_bDrawingBox){
g_rectangle.width=x-g_rectangle.x;
g_rectangle.height=y-g_rectangle.y;
}
}
break;
//左键按下
case cv::EVENT_LBUTTONDOWN:
{
g_bDrawingBox=true;
g_rectangle=cv::Rect(x,y,0,0);//记录起始点
}
break;
//左键抬起
case cv::EVENT_LBUTTONUP:
{
//停止绘制
g_bDrawingBox=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;
}
//在src绘制最终矩形
DrawRectangle(image,g_rectangle);
}
break;
}
}
//【对于绘图】
void DrawRectangle(cv::Mat &img,cv::Rect box){
//直接修改img:调用rectangle构造函数
cv::rectangle(img,box.tl(),box.br(),cv::Scalar(g_rng.uniform(0,255),g_rng.uniform(0,255),g_rng.uniform(0,255)));
}
//box.tl()左上角 box.br()右下角