2012/11/21

カラー画像のガンマ補正とコントラスト調整


概要

ガンマ補正 http://gori-naru.blogspot.jp/2012/11/blog-post_21.html 
コントラスト調整 http://gori-naru.blogspot.jp/2012/11/blog-post_8647.html
上にあげる投稿では輝度の調整について扱った。
しかし、カラー画像は扱っていない。
そこで本投稿ではカラー画像のガンマ補正とコントラストを調整するプログラムを実装しよう。

デジタルクロスプロセスと称し、色味をいじって写真をそれっぽくするのは素人ゴリラの常とう手段だ。(インスタグラムなど)


実装

int main() {
    // 画像をカラーで読み込む
    string fileName = "images\\face.jpg";
    Mat originalBGR = imread(fileName, CV_LOAD_IMAGE_COLOR);
    
    // チャンネルを分離する
    vector<Mat> planes;
    split(originalBGR, planes);
    
    // 入力パラメータ
    // コントラスト調整用(各チャンネルでのシグモイド関数のゲイン)
    float as[] = {-0.5f, 2.0f, 6.0f};
    // ガンマ補正用(各チャンネルでのシグマ値)
    float gammas[] = {0.5f, 0.8f, 0.3f};
    
    uchar lut[256];
    for (int ch = 0; ch < 3; ch++) {
        float a = as[ch];
        float gamma = gammas[ch];
        Mat original = planes[ch];

        // 出力画像
        Mat result;
        
        // コントラスト調整
        // ルックアップテーブル作成
        for (int i = 0; i < 256; i++) 
            lut[i] = 255.0 / (1+exp(-a*(i-128)/255));
        LUT(original, Mat(Size(256, 1), CV_8U, lut), result);

        
        // ガンマ補正
        if (gamma != 1) {
            double gm = 1.0 / gamma;
            // ルックアップテーブル作成
            for (int i = 0; i < 256; i++)
                lut[i] = pow(1.0*i/255, gm) * 255;
        
            LUT(result, Mat(Size(256, 1), CV_8U, lut), result);
        }

        planes[ch] = result;
    }
    // チャンネルを合成する
    Mat resultColor;
    merge(planes, resultColor);

    // 元画像の表示
    imshow("original", originalBGR);
    imwrite("images\\res.jpg", resultColor);
    // 結果画像の表示
    imshow("result", resultColor);
    waitKey(0);

    return 0;
}


解説

Matについて理解していれば問題ないよ。
http://gori-naru.blogspot.jp/search/label/Mat


出力結果

元画像

変換後
あらおしゃれ
パラメータをいじって遊んでみてね☆

いやそうじゃない

と思っている人へ色空間を変換してから処理するのも用意したよ。


int main() {
    // 画像をカラーで読み込む
    string fileName = "images\\face.jpg";
    Mat originalBGR = imread(fileName, CV_LOAD_IMAGE_COLOR);
    
    // チャンネルを分離する
    vector<Mat> planes;
    
    // お好きな色空間に変換する(ここではHSV)
    Mat hsv;
    cvtColor(originalBGR, hsv, CV_BGR2HSV);
    split(hsv, planes);
    
    // 入力パラメータ
    // 色の補正を行うか
    bool modColor[] = {false, true, true}; // Hueはいじらない
    // コントラスト調整用(各チャンネルでのシグモイド関数のゲイン)
    float as[] = {0, 2.0f, 6.0f};
    // ガンマ補正用(各チャンネルでのシグマ値)
    float gammas[] = {0, 0.8f, 0.3f};
    
    uchar lut[256];
    for (int ch = 0; ch < 3; ch++) {
        if (!modColor[ch]) continue;

        float a = as[ch];
        float gamma = gammas[ch];
        Mat original = planes[ch];

        // 出力画像
        Mat result;
        
        // コントラスト調整
        // ルックアップテーブル作成
        for (int i = 0; i < 256; i++) 
            lut[i] = 255.0 / (1+exp(-a*(i-128)/255));
        LUT(original, Mat(Size(256, 1), CV_8U, lut), result);

        
        // ガンマ補正
        if (gamma != 1) {
            double gm = 1.0 / gamma;
            // ルックアップテーブル作成
            for (int i = 0; i < 256; i++)
                lut[i] = pow(1.0*i/255, gm) * 255;
        
            LUT(result, Mat(Size(256, 1), CV_8U, lut), result);
        }

        planes[ch] = result;
    }
    // チャンネルを合成する
    Mat resultColor;
    merge(planes, resultColor);
    
    // 色空間BGRに戻す
    cvtColor(resultColor, resultColor, CV_HSV2BGR);
     

    // 元画像の表示
    imshow("original", originalBGR);
    imwrite("images\\res.jpg", resultColor);
    // 結果画像の表示
    imshow("result", resultColor);
    waitKey(0);

    return 0;
}

出力結果

あらおしゃれ

0 件のコメント:

Related Posts Plugin for WordPress, Blogger...