OpenCV C++窗口滑动条插件

OpenCV C++滑动条插件
这个就是Opecv3中文版的例程,做了些注释,以及排坑指南。

#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<iostream>

using namespace cv;
using namespace std;

int g_slider_position = 0;
//储存滑动条的位置,用g_表全局变量,增加代码可读性
int g_run = 1;
//在新的跳转之后置0,若为正,则表示,在下一次停止前要播放多少帧。
int g_dontset = 0;
//用来避免在自动运行进度条位置时触发单步模式。

VideoCapture g_cap;

void onTrackbarSlide(int pos,void *)//回调函数,作为之后创建滑动条的参数实时返回滑动条实时位置,在下面的createTrackbar函数中会使用。
{
	g_cap.set(CAP_PROP_POS_FRAMES, pos);
	if (!g_dontset)g_run = 1;//如果g_dontset!=0(用户调整滑动条时)则进入单步模式
	g_dontset = 0;//使creatTrackbar里调用回调函数时不进入单步模式
}//只有在用户鼠标移动滑动条时才进如单步模式,而自动移动滑动条时,不进入单步模式

int main()
{
	namedWindow("Example", WINDOW_AUTOSIZE);
	g_cap.open("C:\\Users\\hl\\Desktop\\led.mp4");
	int frames = (int)g_cap.get(CAP_PROP_FRAME_COUNT);//得到视频的总帧数
	int tmpw = (int)g_cap.get(CAP_PROP_FRAME_WIDTH);//得到视频的宽
	int tmph = (int)g_cap.get(CAP_PROP_FRAME_HEIGHT);//得到视频的高
	cout << "Video has" << frames << "frames of dimension(" << tmpw << "," << tmph << ")." << endl;

	//创建一个滑动条(滑动条名称/窗口名称/引用滑动条当前位置/总帧数(最大值)/回调函数不要可以NULL)
	createTrackbar("Position", "Example", &g_slider_position, frames,onTrackbarSlide);
	//这个滑动条的名称千万别打错了,就因为我打成一次position,并不报错,但是运行的时候滑动条始终不动!!!因为动的是另一个看不见的滑动条....
	//像这种P和p的错误,找起来太费劲了,我服了。
	Mat frame;
	while (1)
	{	
		if (g_run != 0)
		{
			g_cap >> frame;//VideoCapture重载了>>运算符,得到帧。
			
			if (frame.empty())break;
			int current_pos = (int)g_cap.get(CAP_PROP_POS_FRAMES);
			g_dontset = 1;
			//g_donset不为0时,回调函数内部会设置g_run=1进入单步模式

			setTrackbarPos("Position", "Example", current_pos);

			imshow("Example", frame);
			if(g_run>0) g_run -= 1;
			//只有在g_run大于0时才-1,不然在播放视频的时候,每帧都要多做一次减法,减少一些运算量嘛,能节约一点是一点。
		}

		char c = (char)waitKey(10);
		if (c =='s')//逐帧模式
		{
			g_run = 1;
			cout << "Single step ,run=" << g_run << endl;
		}
		if (c == 'r')//运行模式
		{
			g_run = - 1;
			cout << "Run mode ,run=" << g_run << endl;
		}
		if (c == 27)break;//点击ESC退出程序
	}
	waitKey(0);
	destroyWindow("Example");//销毁窗口习惯,减少内存泄漏的机会
	return 0;

}

效果成功后
点击r即为播放
点击s为播放一帧
当然如果你像点击s后播放十帧,那就将if(c==‘s’)下面的g_run=1改成=10即可。

Z
核心问题就是这个集成好的createTrackbar()函数的回调过程不太理解,既然他集成过了,我们直接记一下常用的用法,会用就行。

此外,对于一般的调参数改变图像的例子。

#include<opencv2/opencv.hpp>
using namespace cv;

Mat img;//输入图片
Mat out;//输出图片

int g_slide_position = 0;//滑动条当前位置
const int g_max_position = 8;//滑动条最大位置

void onTrackbarSlide(int, void*)
{
	out = img.clone();//将原图复制一份到输出图里
//******************************************************************
//*内的内容可替换成需要的参数以及函数,这边为降采样的次数
	for (int i = 0; i < g_slide_position; i++)
	{
		pyrDown(out, out);//降采样一次
	}
//******************************************************************
	imshow("输出图像", out);
}

int main()
{
	img = imread("C:\\Users\\hl\\Desktop\\lena1.jpg");

	namedWindow("输出图像", WINDOW_NORMAL);

	createTrackbar("降采样次数", "输出图像", &g_slide_position, g_max_position, onTrackbarSlide);
	onTrackbarSlide(0,0);

	waitKey();
	return 0;
}

lena
另外一个好玩的例子,受第4章练习第一题的启发,做了个滑动条。

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

Mat screen = Mat(10, 10, CV_8UC1, Scalar(0));
int g_slide_position = 0;


Mat code(int num)//数字编码
{
	Mat_<uchar> num_code;
	switch (num)
	{
	case 0:
		num_code = Mat(10, 10, CV_8UC1,Scalar(0));
		for(int i=2;i<8;i++)
		{
			num_code(1, i) = 255;
			num_code(7, i) = 255;
			num_code(i, 2) = 255;
			num_code(i, 7) = 255;
		}
		return num_code;

	case 1:
		num_code = Mat(10, 10, CV_8UC1, Scalar(0));
		for (int i = 1; i < 9; i++)
		{
			num_code(i,7) = 255;
		}
		return num_code;

	case 2:
		num_code = Mat(10, 10, CV_8UC1, Scalar(0));
		for (int i = 2; i < 8; i++)
		{
			num_code(1, i) = 255;
			num_code(4, i) = 255;
			num_code(7, i) = 255;
		}
		num_code(2, 7) = 255;
		num_code(3, 7) = 255;
		num_code(5, 2) = 255;
		num_code(6, 2) = 255;
		return num_code;

	case 3:
		num_code = Mat(10, 10, CV_8UC1, Scalar(0));
		for (int i = 2; i < 8; i++)
		{
			num_code(1, i) = 255;
			num_code(4, i) = 255;
			num_code(7, i) = 255;
		}
		num_code(2, 7) = 255;
		num_code(3, 7) = 255;
		num_code(5, 7) = 255;
		num_code(6, 7) = 255;
		return num_code;

	case 4:
		num_code = Mat(10, 10, CV_8UC1, Scalar(0));
		for (int i = 1; i < 8; i++)
		{
			num_code(i, 7) = 255;
		}
		for (int i = 1; i < 5; i++)
		{
			num_code(i, 2) = 255;
		}
		num_code(4, 3) = 255;
		num_code(4, 4) = 255;
		num_code(4, 5) = 255;
		num_code(4, 6) = 255;
		return num_code;

	case 5:
		num_code = Mat(10, 10, CV_8UC1, Scalar(0));
		for (int i = 2; i < 8; i++)
		{
			num_code(1, i) = 255;
			num_code(4, i) = 255;
			num_code(7, i) = 255;
		}
		num_code(2, 2) = 255;
		num_code(3, 2) = 255;
		num_code(5, 7) = 255;
		num_code(6, 7) = 255;
		return num_code;

	case 6:
		num_code = Mat(10, 10, CV_8UC1, Scalar(0));
		for (int i = 2; i < 8; i++)
		{
			num_code(1, i) = 255;
			num_code(4, i) = 255;
			num_code(7, i) = 255;
		}
		num_code(2, 2) = 255;
		num_code(3, 2) = 255;
		num_code(5, 2) = 255;
		num_code(6, 2) = 255;
		num_code(5, 7) = 255;
		num_code(6, 7) = 255;
		return num_code;

	case 7:
		num_code = Mat(10, 10, CV_8UC1, Scalar(0));
		for (int i = 3; i < 8; i++)
		{
			num_code(1, i) = 255;
		}
		for (int i = 2; i < 9; i++)
		{
			num_code(i, 7) = 255;
		}
		return num_code;

	case 8:
		num_code = Mat(10, 10, CV_8UC1, Scalar(0));
		for (int i = 2; i < 8; i++)
		{
			num_code(1, i) = 255;
			num_code(4, i) = 255;
			num_code(7, i) = 255;
		}
		num_code(2, 2) = 255;
		num_code(3, 2) = 255;
		num_code(5, 2) = 255;
		num_code(6, 2) = 255;
		num_code(5, 7) = 255;
		num_code(6, 7) = 255;
		num_code(2, 7) = 255;
		num_code(3, 7) = 255;
		return num_code;

	case 9:
		num_code = Mat(10, 10, CV_8UC1, Scalar(0));
		for (int i = 2; i < 8; i++)
		{
			num_code(1, i) = 255;
			num_code(4, i) = 255;
			num_code(7, i) = 255;
		}
		num_code(2, 2) = 255;
		num_code(3, 2) = 255;
		num_code(2, 7) = 255;
		num_code(3, 7) = 255;
		num_code(5, 7) = 255;
		num_code(6, 7) = 255;
	}
	return num_code;
}


void screen_initial()//展示初始化
{
	for (int i = 1; i < 9; i++)
	{
		screen.at<uchar>(i, 1) = 255;
		screen.at<uchar>(i, 4) = 255;
		screen.at<uchar>(i, 6) = 255;
	}
	for (int i = 7; i < 9; i++)
	{
		screen.at<uchar>(8, i) = 255;
	}
	screen.at<uchar>(4, 2) = 255;
	screen.at<uchar>(4, 3) = 255;


}

void onTrackbarSlide(int, void*)//滑动条回调函数
{
	screen = code(g_slide_position);
	imshow("out", screen);
}

int main()
{
	screen_initial();//初始化展示 我的名字啊HL
	namedWindow("out", WINDOW_NORMAL);
	imshow("out", screen);

	createTrackbar("num", "out", &g_slide_position, 9, onTrackbarSlide);

	waitKey(0);
	return 0;
}

运行程序显示初始化界面:我的名字哈哈。
初始化
然后滑动滑动条即可,这边数字编码是自己编的,还凑合。
6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值