PS の明るさ/コントラスト/彩度/カラー スケール アルゴリズム - OpenGL 実装

1.明るさ

  • PS の明るさ調整は、主に画像の全体的な明るさを制御することであり、光で補う必要がある露出オーバーや補助露出の問題を補うことができます。
    ここに画像の説明を挿入
  • RGB 画像の場合、多くの輝度アルゴリズムがあり、最も単純なものは、ピクセル全体の RGB 値を直接増減することです。(RGB 値は 0 ~ 1、0 は純粋な黒、1 は純粋な白)
  • 式は次のとおりです。
    • 新しい RGB 値 = 古い RGB 値 + 輝度値
    • -1 から 1 までの明るさの値
    • 新しい RGB 値は、範囲 0 から 1 を制御する必要があります
OpenGL を使用して実装:

頂点シェーダー:

attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 texcoordOut;

void main()
{
    
    
    texcoordOut = a_texCoord;
    gl_Position = vec4(a_position, 0.0, 1.0);
}

Fragment shader:
u_texture元画像に対して、brightness明るさの値を調整するため、変更範囲は-1~1

precision highp float;

uniform sampler2D u_texture;
varying vec2 texcoordOut;

uniform float brightness;

void main()
{
    
    
    vec4 srcColor = texture2D(u_texture, texcoordOut);
    gl_FragColor = vec4(clamp(srcColor.rgb + brightness, 0.0, 1.0), srcColor.a);
}
効果:

写真の説明を追加してください

2.コントラスト

  • PS でのコントラスト調整により、写真の明暗の差が大きくなり、2 つの場所はより明るくなり、暗い場所はより暗くなり、明暗がより明確になります。ここに画像の説明を挿入

  • RGB 画像の場合、まだ多くのコントラスト アルゴリズムがありますが、画像の平均輝度がわからない場合は、画像の平均輝度として 0.5 を使用できます。0.5 を超えるピクセルは同様に明るくなり、0.5 未満のピクセルは同様に暗くなります。(RGB 値は 0 ~ 1、0 は純粋な黒、1 は純粋な白)

  • 式は次のとおりです。

    • 新しい RGB 値 = 古い RGB 値 + (古い RGB 値 - 0.5) × コントラスト値
    • 0 ~ 1 のコントラスト値
    • 新しい RGB 値は、範囲 0 から 1 を制御する必要があります
OpenGL を使用して実装:

頂点シェーダー:

attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 texcoordOut;

void main()
{
    
    
    texcoordOut = a_texCoord;
    gl_Position = vec4(a_position, 0.0, 1.0);
}

Fragment shader:
u_texture元画像に対して、contrastコントラスト値を調整するため、変更範囲は 0 ~ 1 です

precision highp float;

uniform sampler2D u_texture;
varying vec2 texcoordOut;

uniform float contrast;

void main()
{
    
    
    vec4 srcColor = texture2D(u_texture, texcoordOut);
    vec3 contrastColor = srcColor.rgb + (srcColor.rgb - vec3(0.5)) * contrast;
    gl_FragColor = vec4(clamp(contrastColor, 0.0, 1.0), srcColor.a);
}
効果:

写真の説明を追加してください

3.彩度

  • PS の彩度調整により、色をより豊かで鮮やかにすることができます。彩度を下げると、画像はグレーに近づきます (すべての色が失われるのと同じです)。
    ここに画像の説明を挿入

  • 彩度調整アルゴリズムは、最初に RGB カラーを HSV カラーに変換し、次にその S 部分を調整し、最後に RGB カラーをコールバックする必要があります。彩度を線形に調整するという目的を達成するため。(RGB 値は 0 ~ 1、0 は純粋な黒、1 は純粋な白)

  • PS 彩度調整アルゴリズムは、主に HSL 色空間を使用して彩度 S の上限と下限を制御し、RGB 空間でパッチ調整を実行します。調整処理はRGB空間で行われますが、原理は単純に各画素のR/G/B値が平均値よりも大きいか小さいかを判断し、調整値より大きければ小さくなります。各ピクセルの計算方法 調整係数がポイントです。このアルゴリズムの主なアイデアは、HSL を使用して各ポイントの調整係数を計算することです。

  • 式は次のとおりです。
    ここに画像の説明を挿入
    ここに画像の説明を挿入
    ここに画像の説明を挿入

OpenGL を使用して実装:

頂点シェーダー:

attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 texcoordOut;

void main()
{
    
    
    texcoordOut = a_texCoord;
    gl_Position = vec4(a_position, 0.0, 1.0);
}

Fragment shader:
u_texture元画像に対して、saturation彩度値を調整するため、変更範囲は-1~1

precision highp float;

uniform sampler2D u_texture;
varying vec2 texcoordOut;

uniform float saturation;

void main()
{
    
    
    vec4 srcColor = texture2D(u_texture, texcoordOut);
    
    float rgbMax = max(max(srcColor.r, srcColor.g), srcColor.g);
    float rgbMin = min(min(srcColor.r, srcColor.g), srcColor.g);
    
    float delta = rgbMax - rgbMin;
    
    float value = rgbMax + rgbMin;
    
    // HSL
    float L = value / 2.0;
    float S;
    if (L < 0.5) {
    
    
        S = delta / value;
    } else {
    
    
        S = delta / (2.0 - value);
    }
    
    float alpha;
    vec3 resultColor;
    if (saturation < 0.0) {
    
    
        alpha = saturation;
        resultColor = vec3(L) + (srcColor.rgb - vec3(L)) * (1.0 + alpha);
    } else {
    
    
        if (saturation + S >= 1.0) {
    
    
            alpha = S;
        } else {
    
    
            alpha = 1.0 - saturation;
        }
        alpha = 1.0 / alpha - 1.0;
        resultColor = srcColor.rgb + (srcColor.rgb - vec3(L)) * alpha;
    }
    
    gl_FragColor = vec4(clamp(resultColor, 0.0, 1.0), srcColor.a);
}
効果:

写真の説明を追加してください

4. カラースケール

  • カラー スケールとは: カラー スケールは、ヒストグラムによって表される画像全体の明暗の情報です。
  • 左から暗いところから明るいところへのピクセル分布で、黒い三角が最も暗い場所(純黒)、白い三角が最も明るい場所(純白)を表しています。灰色の三角形は中間調を表します。

ここに画像の説明を挿入

  • 各カラー スケール定義には、次の 2 つの値のセットがあります。

    • 1 つのグループは入力カラー スケール値で、黒、グレー、白の 3 つの値を含みます。上の図では、黒点の値は 0、グレー点は 1.0、白点は 255 です。
    • もう 1 つのグループは入力カラー スケール値です, これには黒と白の 2 つの値が含まれます. 上の図では: 出力カラー スケールは黒の場合は 0 で、白の場合は 255 です。
  • カラー スケール調整の実装は次のとおりです。

    • 入力値<黒点値の場合は、すべて出力レベルの黒値となります。
    • 入力値>白色点の場合、全て出力レベルの白色値になります。
    • 入力値が黒値と白値の間にある場合、ガンマ係数と組み合わせて比例的に再計算され、新しい値になります。
OpenGL を使用して実装:

頂点シェーダー:

attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 texcoordOut;

void main()
{
    
    
    texcoordOut = a_texCoord;
    gl_Position = vec4(a_position, 0.0, 1.0);
}

フラグメント シェーダ:
u_texture元のイメージの場合、highLightこれはホワイト ポイント値で、範囲は 0 ~ 1、shadowブラック ポイント値、範囲は 0 ~ 1、midtoneグレー ポイント値、範囲は 0 ~ 1 です。満たす必要があることに注意してください: shadow < midtone < highLight

precision highp float;

uniform sampler2D u_texture;
varying vec2 texcoordOut;

uniform float highLight;
uniform float shadow;
uniform float midtone;

void main()
{
    
    
    vec4 srcColor = texture2D(u_texture, texcoordOut);
    
    float diff = highLight - shadow;
    vec3 rgbDiff = max(srcColor.rgb - shadow, 0.0);
    
    gl_FragColor = vec4(clamp(pow(rgbDiff / diff, vec3(1.0 / midtone)), 0.0, 1.0), srcColor.a);
}
効果:

結果として、黒点の値は 0.1、白点の値は 0.9 になり、グレー点の値のみが移動されます。
写真の説明を追加してください

おすすめ

転載: blog.csdn.net/q345911572/article/details/127462885