createTrackbar用于创建滑动条
int **createTrackbar**(conststring& trackbarname, conststring& winname,int* value, int count, TrackbarCallback onChange=0,void* userdata=0);
1——const string&类型的trackbarname,表示轨迹条的名字,用来代表我们创建的轨迹条。
2——const string&类型的winname,填窗口的名字,表示这个轨迹条会依附到哪个窗口上,即对应namedWindow()创建窗口时填的某一个窗口名。
3——int* 类型的value,一个指向整型的指针,表示滑块的位置。并且在创建时,滑块的初始位置就是该变量当前的值。
4——int类型的count,表示滑块可以达到的最大位置的值。PS:滑块最小的位置的值始终为0。
5——TrackbarCallback类型的onChange,首先注意他有默认值0。这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。并且这个函数的原型必须为void XXXX(int,void*);其中第一个参数是轨迹条的位置,第二个参数是用户数据(看下面的第六个参数)。如果回调是NULL指针,表示没有回调函数的调用,仅第三个参数value有变化。
6——void*类型的userdata,他也有默认值0。这个参数是用户传给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value实参是全局变量的话,完全可以不去管这个userdata参数
#include<iostream>
#include<opencv2/opencv.hpp>
#include"opencv2/highgui/highgui.hpp"
#define WINDOW_NAME "线性混合示例"
using namespace cv;
using namespace std;
const int valuemax = 100;
int value1slider;//滑动条对应的变量
double value1;
double value2;
Mat src1;
Mat src2;
Mat dst;
void on_Trackbar(int,void*) //此回调函数形式必须为void XXX(int,void*),书上73页原话
{
value1 = (double)value1slider / valuemax;
//权重1=滑动条值/滑动条最大值
value2 = (1.0 - value1);
//权重2=1-权重1
addWeighted(src1, value1, src2, value2, 0.0, dst);
imshow(WINDOW_NAME, dst);
}
int main()
{
Mat img = imread("1.png");
Mat logo = imread("2.png");
Mat roi = img(Rect(100, 200, 150, 150));
src1 = roi;
src2 = logo;
if (!src1.data) { cout << "读取错误" << endl; return -1; }
if (!src2.data) { cout << "读取错误" << endl; return -1; }
value1slider = 50;//滑动条初始值
namedWindow(WINDOW_NAME);
char TrackbarName[50];
//sprintf_s(TrackbarName, "透明值%d", valuemax);
//把"透明值%d"写入字符数组TrackbarName中
createTrackbar(TrackbarName, WINDOW_NAME, &value1slider, valuemax, on_Trackbar);
on_Trackbar(value1slider, 0);
waitKey(0);
return 0;
}
getTrackbarPos() 获取当前滑动条的位置
int getTrackbarPos(conststring& trackname,conststring& winname );
1——conststring& trackbarname表示滑动条名字
2——conststring& winname,表示滑动条的父窗口的名称
setMousecallback()
void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0)
winname:窗口的名字
onMouse:鼠标响应函数,回调函数。指定窗口里每次鼠标时间发生的时候,被调用的函数指针。 这个函数的原型应该为void on_Mouse(int event, int x, int y, int flags, void* param);
userdate:传给回调函数的参数
#include<opencv2/opencv.hpp>
#include"opencv2/highgui/highgui.hpp"
#define WINDOW_NAME "【程序窗口】"
using namespace cv;
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawRectangle(Mat& img, Rect box);
void ShowHelpText();
//全局变量声明
Rect g_rectangle;
bool g_bDrawingBox = false; //标识符,是否进行绘制
RNG g_rng(12345);//随机数产生器
int main()
{
//【1】准备参数
g_rectangle = Rect(-1, -1, 0, 0);
Mat srcImage(600, 800, CV_8UC3), tempImage;//预创建600*800的3通道图像矩阵
//srcImage.copyTo(tempImage);
srcImage = Scalar::all(0);//对整个矩阵赋值全0,可任意修改,即运行显示的背景颜色
//【2】设置鼠标操作回调函数
namedWindow(WINDOW_NAME);
setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);//调用此函数,在srcImage上等待回调函数
//【3】程序主循环,当绘制的标识符为真时,进行绘制
while (1)
{
srcImage.copyTo(tempImage);//把前一个画完的图存到tempImage中,没有这句话会不停的刷新
if (g_bDrawingBox)//若标识符为真
DrawRectangle(tempImage, g_rectangle);//画矩形
imshow(WINDOW_NAME, tempImage);
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 (g_bDrawingBox)//如果绘制标识符为真,则记录长宽到Rect变量中
{
g_rectangle.width = x - g_rectangle.x;
g_rectangle.height = y - g_rectangle.y;
}
}break;
case EVENT_LBUTTONDOWN://左键按下
{
g_bDrawingBox = true;
g_rectangle = Rect(x, y, 0, 0);//记录起点
}break;
case EVENT_LBUTTONUP:
{
g_bDrawingBox = false;//置标识符为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(cv::Mat& img, cv::Rect box)
{
rectangle(img, box.tl(), box.br(), Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));
//rectangle(图像矩阵,左上点,右下点,颜色)
}