[kaze's test] プログラミングメモ →目次


画像のガンマ値、明るさ、コントラストの調整

  画像のガンマ値、明るさ、コントラストの調整方法のメモです。 調整前の光の強度をinとし調整後の値をoutすると、調整処理はout=f(in)のような関数計算です。

 

 上図は、ガンマ値調整、明るさ調整及びコントラスト調整のグラフです。光の強度を0.0~1.0の範囲にします。調整前(入力)の値をX軸で表し、調整後(出力)の値をY軸で表します。 
 各図にある青い線で調整していないのを表し、言わばout = inで、45度の直線になります。
 ガンマ値調整は、out = power(in, γ)です。赤い線はout=power(in, 0.5)で、緑線はout=power(in, 2)です。
 明るさ調整は、out = in + in*(調整できる範囲の割合)です。赤い線はout=in + (1.0 - in)*(10%)で、緑線はout=in - in*(1.0-10%)です。
 コントラスト調整は、out = (in - 0.5)*tan((割合+1)*45°)+0.5です。赤い線はout = (in - 0.5)*tan((20%+1)*45°)+0.5で、緑線はout = (in - 0.5)*tan((-20%+1)*45°)+0.5です。 
 

 パソコンでは、光の強度の範囲は0~255とされる場合はほとんどですので、調整する前に値の範囲を0~255から0.0~1.0に変換しておきます。返還後また0~255に戻します。下のC++の関数は、ガンマ値、明るさ、コントラストを調整する例です。パラメータのdelta_gamma(ガンマ値調整量), delta_brightness(明るさの調整量), delta_contrast(コントラストの調整量)は、すべて-100%~100%とします。この関数は、証明写真印刷ツールというアプリケーションにそのまま使っています。

void AdjustProcess(BYTE& color, 
                   double delta_gamma, 
                   double delta_brightness, 
                   double delta_contrast)
{
    double val = color / 256.0;

    if (delta_gamma < 0.0)
        val = pow(val, 1.0 + delta_gamma);
    else if (delta_gamma > 0.0)
        val = pow(val, 1.0 / (1 - delta_gamma));

    if (delta_brightness < 0.0)
        val = val * (1.0 + delta_brightness);
    else if (delta_brightness > 0.0)
        val = min(1.0, val + (1.0 - val) * delta_brightness);

    if (delta_contrast != 0.0)
    {
        val = (val - 0.5) * tan((1.0 + delta_contrast) * atan(1.0)) + 0.5;
        val = min(1.0, val);
        val = max(0.0, val);
    }

    color = min(255, (BYTE)(val*255));
}