なぜ普通の反転アプリだと顔が青くなる?C-41ネガの「オレンジ色かぶり除去」の仕組み
顔が青くなる反転ツールは、どれも同じ誤りを犯しています。濃度空間の問題を線形の問題として扱っているのです。式の導出とシェーダーを示します。
翻拍したネガを一般的な画像編集アプリで「色を反転」すると、顔がシアンに転びます。よくある診断である「ホワイトバランスがずれている」は誤りで、だから色温度スライダーをいくら動かしても最後まで合いません。この色かぶりはフィルムに意図的に焼き込まれており、除去に必要なのは減算ではなく除算です。
1. そもそもなぜフィルムベースはオレンジ色なのか
カラーネガのシアン・マゼンタ色素は分光的に純粋ではなく、本来吸収すべきでない波長まで吸収します(不要吸収)。放置すればネガから再現される全ての色が濁ります。C-41 全般で採用されている対策がカラードカプラーで、未反応のカプラーが黄橙色のまま残り、補正すべき不要吸収とちょうど同じ形のポジマスクを形成します。あのオレンジは欠陥ではなく、内蔵された補正フィルターです。
そこから導かれる帰結
現像済みC-41ネガは意図的に中性ではありません。ベースが中性だと仮定する反転処理は、開始時点で別の方程式を解いています。
2. 線形反転(1 − RGB)という罠
フィルムの応答は指数的です。光学濃度は D = log₁₀(1 / T)(T は透過率)で定義され、露光に対して線形なのは透過率ではなく濃度のほうです。8bit sRGB 値を 255 - x で反転すると透過率を反転することになり、オレンジ成分はシアンに反転して残り、透過率スケールの圧縮された側にある暗部は紺色のベタに潰れます。
3. 濃度空間でのマスク減算
濃度空間ではベース除去は単純な減算です:D_image = D_pixel − D_base。両辺を指数に戻すと減算は除算になり、T_image = T_pixel / T_base となります。シェーダーがサンプリングしたマスク色で「割る」のはこのためです。その後の1つのべき関数が、乳剤の非線形応答を復元します。
vec3 inverted = pow(max(vec3(0.0), 1.0 - (pixel / mask)), vec3(u_filmCurve));
inverted = clamp((inverted - u_black) / (u_white - u_black), 0.0, 1.0);
inverted = pow(inverted, vec3(1.0 / u_gamma));pixel / mask— 濃度空間におけるオレンジベースの減算。u_filmCurve(約1.45〜1.60)— 平坦なランプではなくS字の乳剤特性を復元。u_black/u_white— レベル伸張。白飛び黒潰れなくヒストグラムを使い切る。u_gamma(1.8)— 表示系の伝達関数を補償。これがないと中間調が暗く濁ります。
4. `mask` を正しく取る:40×40+外れ値除去
補正全体がチャンネルごとの1つの数値に依存するため、ホコリ1ピクセルで1コマ全体が破綻します。NegaScan は未露光ベース(歯孔の隙間やコマ間)の 40×40 領域を平均し、平均前に標準偏差1.5倍を超えるサンプルを棄却します。手作業のマスク切りなしに、粒状ノイズ・ホコリ・キズを除外できます。
5. 実際に動かしてみる
ワークベンチと同じシェーダーが、あなたのGPU上で動作します。仕切りをドラッグし、手元のネガ画像をドロップして挙動を確認してください。
どのピクセルをフィルムベースとして使ったか答えられない反転ツールは、推測しています。その推測の後始末を、あなたが毎コマ引き受けることになります。
あわせて読みたい