【OpenCV】HighGUI图形用户界面

【OpenCV】HighGUI图形用户界面

#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
//查看OpenCV版本:宏
CV_VERSION

读取图像 imread()

cv::Mat imread(图片路径,int flags=1);

图片路径支持:
image
※关于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()右下角
posted @ 2025-01-06 20:06  White_ink  阅读(51)  评论(0)    收藏  举报