文章出處


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。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()