9、OpenCV使用trackBar

一、学习目标

  • 了解并学会使用trackBar
  • 应用trackBar实例调整图像的对比度和亮度

二、了解trackBar

在图像处理的教程中,我们经常会涉及到某个参数的调整,从而使图像算法具有不同的效果,调参是图像处理中很重要的一门艺术。

为了更方便地和用户进行交互,使得参数的调整和结果的显示更为灵活,OpenCV提供了trackBar这个控件来完成,它类似于窗体应用上的滑块,拖动滑块到不同值,则响应不同的操作。

为了更好地使用trackBar,我们需要熟悉以下两个函数。

  • void cv::namedWindow
  • int cv::createTrackbar

1、void cv::namedWindow 介绍

在之前的教程中,我们已经使用过namedWindow函数,这儿进行一个详细地介绍。通常情况下我们只是为了显示图像的话则不需要调用namedWindow函数提前建立窗体,但要使用creatBar时,需要指定窗体的名称,则我们要提前建立好对应名称的窗体实例。

namedWindow函数的原型为:

void cv::namedWindow(const String & 	winname,
					 int 				flags = WINDOW_AUTOSIZE)	
  • 参数 winname:用于指定窗体的名称
  • 参数 flags:窗体的flag。枚举自cv::WindowFlags

该函数的作用是创建一个名为winname的窗体,可以用作图像和轨迹条的占位符。创建的窗体通过它们的名称来引用。如果已经存在同名窗体,则该函数不执行任何操作。可以调用cv::destroyWindowcv::destroyAllWindows来关闭窗口并取消分配任何相关的内存。对于一个简单的程序,实际上不必调用这些函数,因为应用程序的所有资源和窗口都会在退出时由操作系统自动关闭。

对于 flags参数,其取值见下表:

参数取值取值说明
WINDOW_NORMAL用户可以调整窗口的大小(没有限制)/也可以使用切换全屏窗口到正常大小
WINDOW_AUTOSIZE用户不能调整窗口的大小,大小受所显示图像的限制
WINDOW_OPENGL窗体支持opengl
WINDOW_FULLSCREEN将窗口更改为全屏
WINDOW_FREERATIO图像尽可能多地展开(没有宽高比例限制),即与图像尺寸和显示器分辨率相关
WINDOW_KEEPRATIO保持图像的宽高比例
WINDOW_GUI_EXPANDED状态栏和工具栏
WINDOW_GUI_NORMAL老fashious方式

其中我们通常使用WINDOW_NORMALWINDOW_AUTOSIZE这两个值,默认为WINDOW_AUTOSIZE

2、int cv::createTrackbar函数介绍
int cv::createTrackbar函数原型为:

int cv::createTrackbar	(const String & 	trackbarname,
						 const String & 	winname,
						 int * 				value,
						 int 				count,
						 TrackbarCallback 	onChange = 0,
						 void * 			userdata = 0)	
  • 参数 trackbarname:创建的轨迹条的名称
  • 参数 winname:将被用于创建trackbar的父窗口的名称,上一步namedWindow函数创建
  • 参数 value: 可选指针,指向一个整型变量,其值反映滑块的初始位置。在创建时,滑块的位置由这个变量定义
  • 参数 count:滑块的最大位置,最小的位置总是0
  • 参数 onChange:函数指针,指向每次滑动块改变位置时调用的函数。这个函数的原型应该是void Foo(int,void*),其中第一个参数是trackbar的当前位置,第二个参数是用户数据(参见下一个参数)。如果回调函数是空指针,则不调用回调函数,只更新值
  • 参数 userdata:按原样传递给回调函数的用户数据,有了它就可以在不使用全局变量的情况下处理trackbar事件

函数createTrackbar使用指定的名称和范围创建一个trackbar(滑块或范围控件),分配一个变量值作为与trackbar同步的位置,并指定回调函数onChangetrackbar位置改变时被调用。创建的轨迹条显示在指定的窗口名中。

3、cv::setTrackbarPos函数介绍
setTrackbarPos函数原型为:

void cv::setTrackbarPos	(const String & 	trackbarname,
						 const String & 	winname,
						 int 				pos)	
  • 参数 trackbarname:需要设置trackbar的名称,与创建的名称相对应
  • 参数 winname:trackbar所在窗体的名称
  • 参数 pos:设置该trackbar的值

该函数设置指定轨迹条在指定窗口中的位置。与此对应,可以调用cv::getTrackbarPos函数获取指定窗口指定trackbar的值。

三、使用实例(调整图像对比度和亮度)

调整图像对比度和亮度的笔记见我的上一节笔记:调整图像对比度和亮度

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

// 提前声明三个回调函数
void onChangedConvertToAlpha(int value, void* data);
void onChangedConvertToBeta(int value, void* data);
void onChangedConvertToGama(int value, void* data);
int main(int argc, char** argv)
{
    // 读取图像,判断是否读入成功
	string fileName = samples::findFile("O:\\CSDN\\7.jpg");
	Mat src = imread(fileName, IMREAD_COLOR);
	if (src.empty())
	{
		fprintf(stderr, "failed to load image: %s\n", fileName);
		system("pause");
		return EXIT_FAILURE;
	}

	int alpha = 10;
	int beta = 0;
	int gama = 10;
    
    // 创建三个trackBar 在窗体demo上
	namedWindow("demo", WINDOW_AUTOSIZE);
	createTrackbar("alpha", "demo", &alpha, 30, onChangedConvertToAlpha, (void*)&src);

	createTrackbar("beta", "demo", &beta, 100, onChangedConvertToBeta, (void*)&src);

	createTrackbar("gama", "demo", &gama, 20, onChangedConvertToGama, (void*)&src);
    // 显示地调用一次回调函数,显示默认值
	onChangedConvertToAlpha(alpha, (void*)&src);

	system("pause");
	return EXIT_SUCCESS;
}

// 当改变alpha值时的响应函数
void onChangedConvertToAlpha(int value, void* data)
{
	Mat src = (*(Mat*)data).clone();
	Mat dst = Mat::zeros(src.size(), src.type());
	int beta = getTrackbarPos("beta", "demo");
	src.convertTo(dst, -1, (double)value / 10, beta);
	setTrackbarPos("gama", "demo", 10);
	imshow("demo", dst);
	waitKey(0);
}
// 当改变beta值时的响应函数
void onChangedConvertToBeta(int value, void* data)
{
	Mat src = (*(Mat*)data).clone();
	Mat dst = Mat::zeros(src.size(), src.type());
	int alpha = getTrackbarPos("alpha", "demo");
	src.convertTo(dst, -1, (double)alpha / 10.0, value);
	setTrackbarPos("gama", "demo", 10);
	imshow("demo", dst);
	waitKey(0);
}
// 当改变gama值时的响应函数
void onChangedConvertToGama(int value, void* data)
{
	Mat lookUpTable(1, 256, CV_8U);
	uchar* p = lookUpTable.ptr();
	double gama = value / 10.0;
	for (int i = 0; i < 256; ++i)
		p[i] = saturate_cast<uchar>(pow(i / 255.0, gama) * 255.0);
	Mat src = (*(Mat*)data).clone();
	Mat dst = Mat::zeros(src.size(), src.type());
	LUT(src, lookUpTable, dst);
	imshow("demo", dst);
	waitKey(0);
}

在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值