zoukankan      html  css  js  c++  java
  • 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图片错误~!
    "); 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<<"	嗯。好了,请调整滚动条观察图像效果~
    
    "
        <<"	按下“q”键时,程序退出~!
    "
        <<"
    
    				by浅墨";
    
        //按下“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。

  • 相关阅读:
    LAMP课程(3)
    LAMP课程
    vim文本编辑
    mysql常用语句
    mysql双机互相备份
    Java NIO
    适配器模式
    对象的序列化与反序列化
    字符流
    Java Socket
  • 原文地址:https://www.cnblogs.com/zjutzz/p/4854176.html
Copyright © 2011-2022 走看看