createTrackbar
函数用于创建一个可以调整数值的滑动条:
int cv::createTrackbar(const cv::String &trackbarname, const cv::String &winname, int *value, int count, cv::TrackbarCallback onChange = (cv::TrackbarCallback)0, void *userdata = (void *)0)
trackbarname:轨迹条的名字,用来代表我们创建的轨迹条。
winname:窗口的名字,表示这个轨迹条会依附到哪个窗口上,即对应
namedWindow
创建窗口时填的某一个窗口名。value:一个指向整型的指针,表示滑块的位置。在创建时,滑块的初始位置就是该变量当前的值。
count:滑块可以达到的最大位置的值。滑块最小位置的值始终为0。
onChange:这是一个指向回调函数的指针,有默认值0。每次滑块位置改变时,这个函数都会进行回调。并且这个函数的原型必须为
void XXXX(int, void);
,其中第一个参数是轨迹条的位置,第二个参数是用户数据(看下面的第六个参数)。如果回调是NULL指针,则表示没有回调函数的调用,仅第三个参数value有变化。userdata:这个参数是用户传给回调函数的数据,用来处理轨迹条事件,有默认值0。如果使用的第三个参数value实参是全局变量的话,完全可以不去管这个userdata参数。
使用方法如下(混合两张输入图片):
//为窗口标题定义的宏
#define WINDOW_NAME "【线性混合示例】"
//Alpha值的最大值
const int Max_AlphaValue = 100;
//滑动条对应的变量
int Slider_AlphaValue;
//定义Alpha和Beta的值
double AplhaValue;
double BetaValue;
//声明存储图像的变量
Mat srcImage1;
Mat srcImage2;
Mat dstImage;
//响应滑动条的回调函数
void on_Trackbar(int, void*)
{
//求出当前Alpha值相对于最大值的比例
AplhaValue = (double) Slider_AlphaValue / Max_AlphaValue;
//Beta = 1 - Alpha
BetaValue = (1.0 - AplhaValue);
//根据Alpha和Beta进行线性混合
addWeighted(srcImage1, AplhaValue, srcImage2, BetaValue, 0.0, dstImage);
//显示效果图
imshow(WINDOW_NAME, dstImage);
}
int main()
{
//加载图像(两图像的尺寸需相同)
srcImage1 = imread("../1.jpg");
srcImage2 = imread("../2.jpg");
//设置滑动条初值为70
Slider_AlphaValue = 70;
//创建窗体
namedWindow(WINDOW_NAME, 1);
//在创建的窗体中创建一个滑动条控件
char TrackbarName[50];
sprintf(TrackbarName, "透明值 %d", Max_AlphaValue);
createTrackbar(TrackbarName, WINDOW_NAME, &Slider_AlphaValue, Max_AlphaValue, on_Trackbar);
//结果在回调函数中显示
on_Trackbar(Slider_AlphaValue, 0);
waitKey(0);
destroyAllWindows();
}
getTrackbarPos
函数用于获取当前轨迹条的位置并返回:
int cv::getTrackbarPos(const cv::String &trackbarname, const cv::String &winname)
trackbarname:表示轨迹条的名字
winname:表示轨迹条的父窗口的名字
OpenCV中的鼠标操作和滑动条的消息映射方式很类似,都是通过一个中介函数配合一个回调函数来实现的。创建和指定滑动条回调函数的函数为createTrackbar
,而指定鼠标操作消息回调函数的函数为setMouseCallback
。
void cv::setMouseCallback(const cv::String &winname, cv::MouseCallback onMouse, void *userdata = (void *)0)
winname:窗口的名字
onMouse:指定窗口里每次鼠标时间发生的时候,被调用的函数指针。
userdata:用户定义的传递到回调函数的参数,有默认值0。
使用方法如下(利用鼠标绘制矩形):
//为窗口标题定义的宏
#define WINDOW_NAME "【程序窗口】"
//全局函数的声明
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawRectangle(Mat& img, Rect box);
//全局变量的声明
Rect rect = Rect(-1, -1, 0, 0);
bool flag_DrawingBox = false; //是否进行绘制
RNG rand_num(12345); //产生随机数
int main()
{
//准备参数
Mat srcImage(600, 800, CV_8UC3);
Mat tempImage;
srcImage.copyTo(tempImage);
srcImage = Scalar::all(0);
//设置鼠标操作回调函数
namedWindow(WINDOW_NAME);
setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);
//程序主循环,当进行绘制的标识符为真时,进行绘制
while(1)
{
//复制源图到临时变量
srcImage.copyTo(tempImage);
//当进行绘制的标识符为真,则进行绘制
if(flag_DrawingBox)
{
DrawRectangle(tempImage, rect);
}
imshow(WINDOW_NAME, tempImage);
//按下ESC键,程序退出
if(waitKey(10)==27)
{
break;
}
}
return 0;
}
//鼠标回调函数,根据不同的鼠标事件进行不同的操作
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
Mat& image = *(Mat*) param;
switch(event)
{
//鼠标移动消息
case EVENT_MOUSEMOVE:
{
//如果是否进行绘制的标识符为真,则记录下长和宽到RECT型变量中
if(flag_DrawingBox)
{
rect.width = x - rect.x;
rect.height = y - rect.y;
}
}
break;
//左键按下消息
case EVENT_LBUTTONDOWN:
{
flag_DrawingBox = true;
rect = Rect(x, y, 0, 0); //记录起始点
}
break;
//左键抬起消息
case EVENT_LBUTTONUP:
{
flag_DrawingBox = false; //置标识符为false
//对宽小于0的处理
if(rect.width < 0)
{
rect.x += rect.width;
rect.width *= -1;
}
//对高小于0的处理
if(rect.height < 0)
{
rect.y += rect.height;
rect.height *= -1;
}
//调用函数进行绘制
DrawRectangle(image, rect);
}
break;
}
}
//自定义的矩形绘制函数
void DrawRectangle(Mat& img, Rect box)
{
//随机颜色绘制矩形框
rectangle(img, box.tl(), box.br(), Scalar(rand_num.uniform(0,255), rand_num.uniform(0,255), rand_num.uniform(0,255)));
}