ルックアップテーブル

OpenCVではマトリクスに対して一定の関数カーブを適用する際に、ルックアップテーブルを使う。
例えば、画像のガンマ値を調整したい場合、OpenCVにはそのものズバリのファンクションは無いが、ルックアップテーブルを利用することでガンマ調整を実装できる。

OpenCVによるガンマ調整(C++)
    // 出力画像
    cv::Mat result;

    // ルックアップテーブル作成
    int lut[256];
    double gm = 1.0 / gamma; //gammaはガンマ値
    for (int i = 0; i < 256; i++)
    {
        lut[i] = pow(1.0*i/255, gm) * 255;
    }
    // 出力画像に適用
    cv::LUT(src, cv::Mat(cv::Size(256, 1), CV_8U, lut), result);
    • ルックアップテーブル

ルックアップテーブル(Lookup Table)は、入力に対して出力が必ず1つの値となる場合、予め出力を配列(テーブル)に格納しておくことで計算する代わりに配列を参照することで効率的に処理を行う手法。
この"ルックアップテーブル"だが、別に画像処理ではなくても比較的経験の長いプログラマであれば、必ずどこかで使ったことがあるはずだ。それ位にクラシックな最適化手法である。

上記のコードではlutがガンマカーブの値を格納したルックアップテーブルであり、cv::LUTはそのテーブルをMatに適用するメソッドである。テーブルに格納する値の関数を変えることで、例えばコントラスト調整用カーブ等を格納しておくことで、画像に様々なフィルタを適用することができる。

最後にJava(android)の例を書いて終わろう。

OpenCVによるガンマ調整(android)
    // 出力画像
    Mat result = new Mat(); 
    src.copyTo(result);
	    
    // ルックアップテーブル作成
    Mat lut = new Mat(1, 256, CvType.CV_8UC1);
    lut.setTo(new Scalar(0));

    double gm = 1.0 / gamma; //gammaはガンマ値
    for (int i = 0; i < 256; i++)
    {
    	lut.put(0, i, Math.pow((double)(1.0 * i/255), gm) * 255);
    }
	    
    // 出力画像に適用
    Core.LUT(src, lut, result);

cよりかはc++で書いた方がJava(android)への移行はやりやすい。