opencv笔记3:trackbar简单使用


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。

时间: 2024-10-11 02:15:28

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

opencv笔记2:图像ROI

time:2015年 10月 03日 星期六 12:03:45 CST # opencv笔记2:图像ROI ROI ROI意思是Region Of Interests,感兴趣区域,是一个图中的一个子区域. OpenCV中定义的ROI是矩形的. ROI的用处包括而不限于:提取出ROI区域做进一步处理(比如人脸识别.车牌识别):将另一张图片贴放到ROI区域. 这里以第二种用处为例,将一个logo图像添加到一张大图上指定的ROI区域. 图像贴放 粗略想想,包括这四个步骤 定义大图和小图 在大图上定义R

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

time:2015年10月04日 星期日 00时00分27秒 # opencv笔记4:模板运算和常见滤波操作 这一篇主要是学习模板运算,了解各种模板运算的运算过程和分类,理论方面主要参考<图像工程--图像处理>(章毓晋)一书第3章,空域增强:模板操作.同时也有个疑问:此书第四章,频域图像增强,讲了低通滤波和高通滤波,然而这些东西和模板运算中的平滑.锐化操作有什么区别?... 以下是正文: 模板运算 首先我们把所有图像看作矩阵. 模板一般是nxn(n通常是3.5.7.9等很小的奇数)的矩阵.模板

opencv笔记6:角点检测

time:2015年10月09日 星期五 23时11分58秒 # opencv笔记6:角点检测 update:从角点检测,学习图像的特征,这是后续图像跟踪.图像匹配的基础. 角点检测是什么鬼?前面一篇学习笔记是各种模板操作,是图像增强技术. 那么我节写来应该继续找下有没有别的图像增强技术. 但是,我对增强还不是特别理解.图像增强:划定ROI区域,然后想方设法将感兴趣的特征有选择的突出.注意,这可是不去考虑图像质量下降的原因的.图像恢复:针对图像降质的原因,设法去补偿降质因素,从而使改善后的图像尽

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

time:2015年10月06日 星期二 12时14分51秒 # opencv笔记5:频域和空域的一点理解 空间域和频率域 傅立叶变换是f(t)乘以正弦项的展开,正弦项的频率由u(其实是miu)的值决定.因为积分后左边剩下的为一变量是频率,所以我们说傅立叶变换域是频率域. (<数字图像处理>冈萨雷斯,中文第三版P128) 当变量t用于说明图像时,我们一般将变量t的域称为空间域. 按<图像处理>(章毓晋)的理解,首先是认同模板操作的,然后借助卷积定理,将模板操作转化为傅立叶的乘积,也

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

opencv笔记1:opencv的基本模块,以及环境搭建 安装系统 使用fedora22-workstation-x86_64 安装opencv sudo dnf install opencv-devel 安装cmake sudo dnf install cmake 查看opencv的基本模块 cd /usr/include/opencv2/ vim opencv_modules.hpp 内容如下: #define HAVE_OPENCV_CALIB3D #define HAVE_OPENCV_

[Eclipse笔记]一个最简单的SWT程序

笔记|程序 我们来看一段最简单的SWT程序是什么样子:package sean.test.swt;import org.eclipse.swt.widgets.Display;import org.eclipse.swt.widgets.Shell;public class SimplestSWT {    public static void main(String[] args) {        Display display = new Display();        Shell s

JavaScript高级程序设计(第3版)学习笔记3 js简单数据类型_基础知识

ECMAScript是一种动态类型的语言,构建于5种简单数据类型(Undefined.Null.Boolean.Number.String)和一种复杂数据类型(Object)的基础之上.这篇文章就来复习一下简单数据类型,我会尽量从编程实践的角度来描述,下面代码运行环境为FireFox 14.0.1. 简单数据类型 简单数据类型 取值 Undefined undefined(只有一个值) Null null(只有一个值) Boolean true|false(只有两个值) Number 数值 St

MySql官方手册学习笔记1 MySql简单上手_Mysql

连接与断开服务器 连接服务器通常需要提供一个MySQL用户名并且很可能需要一个 密码.如果服务器运行在登录服务器之外的其它机器上,还需要指定主机名: shell> mysql -h host -u user -p Enter password: ******** host代表MySQL服务器运行的主机名,user代表MySQL账户用户名,******** 代表你的密码. 如果有效,你应该看见mysql>提示符后的一些介绍信息: shell> mysql -h host -u user -

WindowsApi学习笔记-创建一个简单的窗口

#include <windows.h> LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM);//窗口函数的函数原型 int APIENTRY WinMain( //APIENTRY是__stdcall的宏定义 HINSTANCE hInstance, //本模块的实例句柄 HINSTANCE hPrevInstance, //Win16留下的废物 LPSTR lpCmdLine, //命令行参数 int nCmdShow //主窗口初始