time:2015年 10月 03日 星期六 13:54:17 CST

opencv笔记3:trackbar简单使用


当需要测试某变量的一系列取值取值会产生什么结果时,适合用trackbar。看起来就是debug的一种技术手段了。

主要是使用createTrackbar函数。具体讲,是把trackbar放到一个窗口中,并为trackbar设定回调函数,步骤还是有点繁琐的:

  • 定义图像
  • 定义窗口
  • 定义回调函数
  • 创建trackbar
  • 回调函数初始化
  • 善后工作

其中回调函数参数规定为(int, void*)格式,然而在我看来并没有卵用,迟早要去掉的。

创建trackbar时要指定window的名字,好把自己放进去。

创建trackbar时还传入了int* value参数,表示进度条滑动后改变的量。注意到传入类型是指针,是真的改变这个变量的值。显然,多个trackbar可以共用同一个回调函数,只要回调函数中用到了各trackbar对应的变量。

这里回调函数的例子是,混合两张图片,而trackbar进度条的值是混合公式中的alpha值。代码:

#include <iostream>
#include <opencv2/opencv.hpp> using namespace std;
using namespace cv; Mat src1, src2, dst;
int init_slider, slider_max; void callback_trackbar(); void callback_trackbar(int, void*) {
double alpha = (double) init_slider/slider_max ;
double beta = ( 1.0 - alpha ); addWeighted( src1, alpha, src2, beta, 0.0, dst); imshow( "Linear Blend", dst );
} int main() {
src1 = imread("/home/chris/workspace/clion/LinuxLogo.jpg");
src2 = imread("/home/chris/workspace/clion/WindowsLogo.jpg"); string trackbar_name = "进度条调节";
string window_name = "显示窗口";
namedWindow(window_name); init_slider = 100; //trackbar初始值
slider_max = 255; //trackbar最大值
createTrackbar(trackbar_name, window_name, &init_slider, slider_max, callback_trackbar);
callback_trackbar(0, 0);
waitKey(0);
destroyAllWindows();
return 0;
}

上面是最简单的例子。稍微变化下,可以弄两个进度条,一个控制对比度,一个控制亮度,回调函数中把亮度和对比度都使用到,就可以了。其理论依据是,

g(x,y)=contractValue*f(x,y)+brightValue

也就是,对比度是和图像灰度值相乘的,而亮度是和灰度值相加的。

那么对应的完整代码为:

#include <iostream>
#include <opencv2/opencv.hpp> using namespace std;
using namespace cv; static void ContrastAndBright(int, void *); int g_nContrastValue; //对比度值
int g_nBrightValue; //亮度值
Mat g_srcImage,g_dstImage; int main(){
g_srcImage= imread( "/home/chris/workspace/clion/mogu.jpg");
if(!g_srcImage.data ) {
printf("Oh,no,读取g_srcImage图片错误~!\n"); return false;
}
g_dstImage= Mat::zeros( g_srcImage.size(), g_srcImage.type() ); //设定对比度和亮度的初值
g_nContrastValue=80;
g_nBrightValue=80; //创建窗口
namedWindow("【效果图窗口】", 1); //创建轨迹条
createTrackbar("对比度:", "【效果图窗口】",&g_nContrastValue,300,ContrastAndBright );
createTrackbar("亮 度:","【效果图窗口】",&g_nBrightValue,200,ContrastAndBright ); //调用回调函数
ContrastAndBright(g_nContrastValue,0);
ContrastAndBright(g_nBrightValue,0); //输出一些帮助信息
cout<<endl<<"\t嗯。好了,请调整滚动条观察图像效果~\n\n"
<<"\t按下“q”键时,程序退出~!\n"
<<"\n\n\t\t\t\tby浅墨"; //按下“q”键时,程序退出
while(char(waitKey(1)) != 'q') {}
return 0;
} //-----------------------------【ContrastAndBright( )函数】------------------------------------
// 描述:改变图像对比度和亮度值的回调函数
//-----------------------------------------------------------------------------------------------
static void ContrastAndBright(int, void *) {
//创建窗口
namedWindow("【原始图窗口】", 1); //三个for循环,执行运算 g_dstImage(i,j) =a*g_srcImage(i,j) + b
for(int y = 0; y < g_srcImage.rows; y++ )
{
for(int x = 0; x < g_srcImage.cols; x++ )
{
for(int c = 0; c < 3; c++ )
{
g_dstImage.at<Vec3b>(y,x)[c]= saturate_cast<uchar>( (g_nContrastValue*0.01)*(g_srcImage.at<Vec3b>(y,x)[c] ) + g_nBrightValue );
}
}
} //显示图像
imshow("【原始图窗口】", g_srcImage);
imshow("【效果图窗口】", g_dstImage);
}

为了访问图像的每一个像素,我们使用这样的语法: image.at(y,x)[c]

其中,y是像素所在的行, x是像素所在的列, c是R、G、B(对应0、1、2)其中之一。

因为我们的运算结果可能超出像素取值范围(溢出),还可能是非整数(如果是浮点数的话),所以我们要用saturate_cast对结果进行转换,以确保它为有效值。

这里的a也就是对比度,一般为了观察的效果,取值为0.0到3.0的浮点值,但是我们的轨迹条一般取值都会整数,所以在这里我们可以,将其代表对比度值的nContrastValue参数设为0到300之间的整型,在最后的式子中乘以一个0.01,这样就可以完成轨迹条中300个不同取值的变化。所以在式子中,我们会看到saturate_cast( (g_nContrastValue0.01)(image.at(y,x)[c] ) + g_nBrightValue )中的g_nContrastValue*0.01。

opencv笔记3:trackbar简单使用的更多相关文章

  1. opencv笔记4:模板运算和常见滤波操作

    time:2015年10月04日 星期日 00时00分27秒 # opencv笔记4:模板运算和常见滤波操作 这一篇主要是学习模板运算,了解各种模板运算的运算过程和分类,理论方面主要参考<图像工 ...

  2. opencv笔记2:图像ROI

    time:2015年 10月 03日 星期六 12:03:45 CST # opencv笔记2:图像ROI ROI ROI意思是Region Of Interests,感兴趣区域,是一个图中的一个子区 ...

  3. OpenCV笔记大集锦(转载)

    整理了我所了解的有关OpenCV的学习笔记.原理分析.使用例程等相关的博文.排序不分先后,随机整理的.如果有好的资源,也欢迎介绍和分享. 1:OpenCV学习笔记 作者:CSDN数量:55篇博文网址: ...

  4. opencv笔记6:角点检测

    time:2015年10月09日 星期五 23时11分58秒 # opencv笔记6:角点检测 update:从角点检测,学习图像的特征,这是后续图像跟踪.图像匹配的基础. 角点检测是什么鬼?前面一篇 ...

  5. opencv笔记5:频域和空域的一点理解

    time:2015年10月06日 星期二 12时14分51秒 # opencv笔记5:频域和空域的一点理解 空间域和频率域 傅立叶变换是f(t)乘以正弦项的展开,正弦项的频率由u(其实是miu)的值决 ...

  6. opencv笔记1:opencv的基本模块,以及环境搭建

    opencv笔记1:opencv的基本模块,以及环境搭建 安装系统 使用fedora22-workstation-x86_64 安装opencv sudo dnf install opencv-dev ...

  7. how tomcat works 读书笔记(二)----------一个简单的servlet容器

    app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...

  8. Python编程从入门到实践笔记——变量和简单数据类型

    Python编程从入门到实践笔记——变量和简单数据类型 #coding=gbk #变量 message_1 = 'aAa fff' message_2 = 'hart' message_3 = &qu ...

  9. Spring MVC 学习笔记10 —— 实现简单的用户管理(4.3)用户登录显示全局异常信息

    </pre>Spring MVC 学习笔记10 -- 实现简单的用户管理(4.3)用户登录--显示全局异常信息<p></p><p></p>& ...

随机推荐

  1. YOU ARE MY SUNSHINE

    /*you are sunshine, my only sunshine, you make me happy when skies are grey. you'll never know dear ...

  2. android studio 使用入门 (快捷键等收集)

    1. 解决 android studio cannot resolve symbol 1) file->import proj->create proj from exit proj .. ...

  3. [Usaco2008 Nov]mixup2 混乱的奶牛 简单状压DP

    1231: [Usaco2008 Nov]mixup2 混乱的奶牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 685  Solved: 383[S ...

  4. 04SpringMvc_映射器_BeanNameUrlHanderMapping

    这篇文章我们讲的是映射器,映射器的作用是什么样的请求交给Action,如果我们没有在xml配置文件中进行配置,默认的就是BeanNameUrlHanderMapping. 我们讲一个案例增加用户的案例 ...

  5. Install MySQL on Mac OS X——MAC安装MySQL

    很多关于如何安装MySQL的教程已经过时了,或者比必须的步骤复杂得多.这篇教程将展示如何安装MySQL,启动MySQL,以root用户进入MySQL,以及创建删除退出数据库. Step 1: 下载My ...

  6. REST签名认证

    139 开放平台与应用之间以REST协议进行通讯,为了保证通信的安全性,开放平台加入签名认证机制.应用一旦创建,系统生成唯一并且不公开的secretkey,只有应用的拥有者和开放平台知道.因此,当应用 ...

  7. UI设计师零基础入门到精通精品视频教程【155课高清完整版】

    [福吧资源网分享]课程是非常完整的,也是非常零基础的,适合任何学员,有需要的可以下载看看!课程目录:第1章 Adobe Photoshop CS6课时1 Adobe Photoshop CS6入门基础 ...

  8. Node.js文件系统、路径的操作函数

    Node.js文件系统.路径的操作函数 目录 Node.js文件系统.路径的操作函数 1.读取文件readFile函数 2.写文件 3.以追加方式写文件 4.打开文件 5.读文件,读取打开的文件内容到 ...

  9. SSM三大框架整合详细教程(Spring+SpringMVC+MyBatis)

    使用 SSM ( Spring . SpringMVC 和 Mybatis )已经有三个多月了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,当然肯定有很多可以改进的地方.之前没 ...

  10. [CareerCup] 1.8 String Rotation 字符串的旋转

    1.8 Assume you have a method isSubstring which checks if one word is a substring of another. Given t ...