opencv2——Trackbar图像融合、鼠标操作

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(图像矩阵,左上点,右下点,颜色)
}






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值