目录
1.OpenCV下的GUI接口
OpenCV提供了功能强大的GUI接口,可以在MFC,Qt,WinForms,Cocoa等平台下使用。
新的HighGUI接口功能包括如下:
- 创建并控制窗口,用于显示图片并记录其内容
- 为窗口添加了滑动控制杆,可以方便利用鼠标,键盘进行控制
- UI接口函数主要包含如下:
- createTrackbar
- getTracbarPos
- setTrackbarPos
- imshow
- namedWindow
- destroyWindow
- destroyAllWindows
- MoveWindow
- ResizeWindow
- setMouseCallback
- waitKey
(1)回调函数
回调函数是指当一个事件(比如滑杆控制的滑块滑动,鼠标操作,键盘操作等)发生时自动调用的函数。
(1)滑杆控件trackbars
createTrackbar(const string &trackbarname,const string&winname,int * value,int count,TrackbarCallback onChange=0,void*userdata=0);
1.trackbarname: 是控件标签
2.winname: 是要添加滑杆控件的窗口名称
3.value: 是存储滑杆位置的变量地址,其范围为0~alpha_slider_max
4.count: 是滑杆的最大值,其最小值为0
5.onChange: 是移动滑杆时调用的回调函数,应具备void Foo(int,void*)的形式,其中,第一个参数为滑块当前的位置,第二个参数为用户的数据
6.userdata: 是需要传递给回调函数的数据。
OpenCV中Mat类模板的一些基本操作(实例)(关于ColorReduce详解)
#include <iostream>
#include<opencv2/core.hpp>
#include<opencv2/highgui.hpp>
using namespace cv;
using namespace std;
const int slider_max = 64;
int slider;
Mat image;
Mat result;
void colorReduce(Mat&inputImage,Mat&outputImage,int div){
outputImage = inputImage.clone();
int rows = outputImage.rows;
int cols = outputImage.cols * outputImage.channels();
if(outputImage.isContinuous()){
cols = cols * rows;
rows = 1;
}
for(int i = 0; i < rows ; i++){
uchar*dataout = outputImage.ptr<uchar>(i);
for(int j = 0; j < cols; j++){
dataout[j] = dataout[j] / div * div + div / 2;
}
}
}
//rackbar事件的回调函数
void on_trackbar(int pos,void*){
if(pos <= 0){
result = image;
}else{
colorReduce(image,result,pos);
}
imshow("result image!",result);
}
int main()
{
//读取图片
image = imread("../images/cat.png");
//创建两个窗口
namedWindow("Original image!");
namedWindow("result image!");
slider = 0;
createTrackbar("colorReduce","result image!",&slider,slider_max,on_trackbar);
//显示图像
imshow("Original image!",image);
imshow("result image!",image);
waitKey(0);
return 0;
}
(2)鼠标操作回调函数
setMouseCallback(const string&winname,MouseCallback onMouse,void*,userdata);
1.winname: 表示要添加的回调函数的窗口名称
2.onMouse: 是鼠标操作回调函数,函数原型如下:
void Foo(int event,int x,int y,int flags,void * param);
1.event:表示EVENT_*变量之一,
2.x,y:表示鼠标指针在图像坐标位置(注意不是窗口坐标系)
3.flags: 表示EVENT_FLAG的组合,
4.param: 是用户定义的传递到setMouseCallback函数调用的参数
3.userdata:需要传递给回调函数的数据。
#include <iostream>
#include<opencv2/core.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
using namespace cv;
using namespace std;
//鼠标按键标志
bool ldown = false,lup = false;
//原始图像
Mat image;
//矩形起始点和终点坐标
Point corner1,corner2;
//感兴趣区域
Rect box;
//鼠标事件的回调函数
static void mouse_callback(int event,int x,int y,int ,void*){
//当鼠标左键按下时,记录器状态和坐标
if(event == EVENT_LBUTTONDOWN){
ldown = true;
corner1.x = x;
corner1.y = y;
cout<<"Corner1 recorded at" <<corner1<<endl;
}
//当鼠标左键放开时,记录器状态和坐标
if(event == EVENT_LBUTTONUP){
//判断选取的ROI区域是否大于20个像素
if(abs(x - corner1.x) > 20 && abs(y - corner1.y) > 20){
lup = true;
corner2.x = x;
corner2.y = y;
cout<<"Corner2 recorded at" <<corner2<<endl;
}else{
cout<<"Please select a bigger region"<<endl;
ldown = false;
}
}
//当移动鼠标时,更新选择区域,并绘制矩形选择区域图形
if(ldown == true && lup == false){
Point pt;
pt.x = x;
pt.y = y;
Mat local_img = image.clone();
rectangle(local_img,corner1,pt,Scalar(0,0,255));
imshow("Cropping app",local_img);
}
//定义ROI区域,并对原始图像进行裁剪
if(ldown == true && lup == true){
box.width = abs(corner1.x - corner2.x);
box.height = abs(corner1.y - corner2.y);
box.x = min(corner1.x,corner2.x);
box.y = min(corner1.y,corner2.y);
//对原始图像进行裁剪,并生成新的图像
Mat crop(image,box);
namedWindow("Crop");
imshow("Crop",crop);
ldown = false;
lup = false;
}
}
int main()
{
//读取图片
image = imread("../images/cat.png");
//创建两个窗口
namedWindow("Cropping app");
imshow("Cropping app",image);
//设置鼠标事件回调函数
setMouseCallback("Cropping app",mouse_callback);
//按下q关闭窗口
while(char(waitKey(1)) != 'q'){}
return 0;
}
(3)键盘响应函数
函数原型:
int waiKey(int delay = 0);
1.当delay<=0时,会永久的等待;
2.当delay>0时,表示等待delay毫秒,返回所按下键的扫描码
3.若为按下键,则返回-1.