Help us understand the problem. What is going on with this article?

セピア調フィルタのうんちく

セピア調について

18世紀中頃〜19世紀初頭にかけて様々な感光剤による写真が発明され、多くのモノクロ写真が作られました。

それらは経年劣化で白が黄ばみ黒はくすみ、全体として色材のセピア(イカ墨)を思わせる茶色味がかった色になる傾向があった故に、古い写真の色調を表す代名詞としてセピア調(sepia-tone)の言葉が生まれました。

セピア調に退色した写真 セピアインクを使った図面
image.png

https://en.wikipedia.org/wiki/Photographic_print_toning#Sepia_toning

セピア色について

セピア色という単語は、主に以下の3つの意味で使われているようです。

  • 顔料としてのイカ墨のセピア
  • セピアで書かれた古い絵の退色した様子 (セピア調の元ネタ)
  • 古ぼけた写真の色調としてのセピア (本記事がターゲットとするセピア調)

顔料としてのセピアはイカ墨を乾燥させてインクとするもので歴史は古く、紀元前のまだギリシア文化の残る(Greco-Roman)古代ローマの頃には筆記用に使われていました。それからだいぶ時代が進み、18世紀末〜19世紀頭に水彩画家の間で絵の具としても流行しています。日本でも江戸時代、借用書にイカ墨で書いて時間が経つと読めなくなるイカサマの語源となる逸話が有名です。

JIS慣用色名としてのセピア色はマンセル値で 5.2YR 3.3/3.9 と定義されています。
対応する RGB 値は目安として以下の値が Wikipedia に載っています。

ja.wikipedia セピア (参考)en.wikipedia Sepia_(color)
(107, 74, 43) (112, 66, 20)
sepia-ja.png sepia-en.png

一方、セピア色に細分化した定義を与える例もあります。

Marrón sepia Sepia Sepia aclarado
(92, 83, 67) (82, 75, 59) (112, 99, 64)
92-83-67.png 82-75-59.png 112-99-64.png

Marrón, aclarado はスペイン語で Brown(茶色)、clear(透明)の意味です。水彩画に使うのが Marrón sepia で筆記インクの方が Sepia です。

JISセピア色はこの Sepia aclarado に近い事から、セピアで書かれた絵の全体的な雰囲気を想定する色で、おそらくですが、塗られた色が時代経過と共に退色して少し茶色がかった印象に引き摺られている可能性が高そうです。

アナログのセピア調

古くから知られる銀板写真は劣化しやすく様々な保護の努力がなされ、コーティングのみならず、感光剤を別の安定した金属(金やプラチナ等)に置き換えて長持ちさせる事もありました。

銀以外の金属だと無彩色が出にくいので更に色材を混ぜ調色します。様々な色調の写真が作られましたが、セピア調の人気が高かったようです。
はじめから劣化した見た目にして長持ちさせるのは興味深い話です。
ちなみにやり過ぎると逆に劣化を早めますが、それも含めての懐深い技術とも言えます。

鶏卵紙 (Albumen Print)

セピア調の写真として鶏卵紙が有名です。

albumen_material-400x400.jpg
http://kenshidaito.com/alt_process/albumen_print_2/

より精度の高い手法が普及した後でも、温かみがありノスタルジックな感性を刺激する写真が好評な事から、19世紀半ばから20世紀初頭の長い間流行しました。

デジタルのセピア調フィルタ

基本的な考え方として、まずグレースケール変換を行い、そこからセピア調に合わせて R,G,B の割合を偏らせます。
3x3 色マトリックスを使えば、その2つを一度に処理できます。

original grayscale sepia
image.png image.png image.png

よく知られたセピア調フィルタ

CSS sepia filter が採用している係数です。

| R_sepia |   | 0.393 0.769 0.189 |   | R |   | 0.393*R + 0.769*G + 0.189*B |
| G_sepia | = | 0.349 0.686 0.168 | x | G | = | 0.349*R + 0.686*G + 0.168*B |
| B_sepia |   | 0.272 0.534 0.131 |   | B |   | 0.272*R + 0.534*G + 0.131*B |

任意の画像ファイルを渡して試せるデモページを作ったので、どうぞ。ビネット(トンネル効果)フィルタは vinette radius を最大値にすれば、ほぼ無効に出来ます。

original sepia
image.png image.png

なお、2005年1月号の MSDN Magazine でこの係数が使われているのは確認しました。

更にそれより古いソースをご存知の方、教えていただけると幸いです。(すごく知りたい。数値の根拠も謎ですし)

行列の分解

行列を小数3桁の精度で2つのベクトルに分解してみました。
grayscale と sepia-tone の組み合わせで作られた想定です。
真ん中の列が完璧には合わせらないので、予想外の処理が含まれるのかもしれません。

| 0.393 0.769 0.189 |
| 0.349 0.686 0.168 | (例の行列)
| 0.272 0.534 0.131 |

                  grayscale 
             | 0.291 0.571 0.140 |
sepia-tone 
 | 1.351 |   | 0.393 0.771 0.189 |
 | 1.200 |   | 0.349 0.685 0.168 |
 | 0.934 |   | 0.272 0.533 0.131 |

これはつまり、以下の処理でもほぼ同じ結果が出せるという事です。

V = 0.291 x R + 0.571 x G + 0.140 x B
R" = 1.351 * V
G" = 1.200 * V
B" = 0.934 * V

255 clamp の効果

white(255,255,255) に対応する sepia-tone を計算すると R,G の値が最大値255を超えてしまいます。オーバーシュートです。

| 345 |   | 0.393 0.769 0.189 |   | 255 |
| 307 | = | 0.349 0.686 0.168 | x | 255 |
| 239 |   | 0.272 0.534 0.131 |   | 255 |

例えば、グレースケール色であれば、(189, 189, 189) でギリギリ 255 に収まります。ここで赤が頭打ちします。

| 255 |   | 0.393 0.769 0.189 |   | 189 |
| 227 | = | 0.349 0.686 0.168 | x | 189 |
| 177 |   | 0.272 0.534 0.131 |   | 189 |

更に輝度をあげると (212,212,212) で緑も頭うちして、それより先は青だけ増えます。

| 286 |   | 0.393 0.769 0.189 |   | 212 |
| 255 | = | 0.349 0.686 0.168 | x | 212 |
| 199 |   | 0.272 0.534 0.131 |   | 212 |

255 を超える R,G の値は、通常だと 255 で clamp (頭打ち処理)するでしょう。 グレイスケール 189 に対応する (255,227,177) の時点ではだいぶ色味がありますが、255 の (255,255,239) ではほとんど白に近い淡い黄色になっています。
つまり、clamp によって中輝度の茶色と高輝度の薄い黄ばみを両立しています。

grayscale level 0 79(R:107) 189(赤天井) 212(緑天井) 255
(R,G,B) (0,0,0) (107,95,74) (255,227,177) (255,255,192) (255,255,239)
sepia-tone color 0-0-0.png 107-95-74.png 255-227-177.png 255-255-199.png 255-255-239.png

些細な問題ですが、189/255 と 212/255 で輝度変化の傾きが急に変わります。いわゆるC1不連続です。グラデーションにすると不自然な場所が分かる人もいるかもしれません。(発色の歪みのない高性能なモニタでないと判別できない事に注意)

grayscale image.png
sepia-tone image.png
188/255 188.png

より厳密に処理したければグレースケール>セピア変換を曲線で近似するか、CLUT にすれば良いのですが、そもそも雰囲気を合わせるだけで正確な色調でないので、そこまで気にする意義はないと思います。

Wikipedia に貼られた sepia-tone の実物の写真と、このよく知られたセピア調フィルタの x:Red, y:Blue のグラフをみてみましょう。

sepia-tone (x:Red, y:Blue)
sepia-CSS-RB.png

そもそも sepia color を通ってさえいないんですよね。低輝度が駄目なんです。ただ中輝度から高輝度にかけてはそこそこ良い感じです。

駄目なセピア調フィルタ

駄目といいますか、高輝度の変換が苦手なセピア調フィルタです。
以下で解説されている方式です。残念ながらそこそこ普及しています。

V = 0.299 x R + 0.587 x G + 0.114 x B
R" = V x 107/107
G" = V x 74/107
B" = V x 43/107

- 3x3 マトリックス (小数4桁目を四捨五入)

|R" |   | 0.299 0.587 0.114 |   | R | 
|G" | = | 0.207 0.406 0.079 | x | G |
|B" |   | 0.120 0.236 0.046 |   | B |

こちらで試せます。

original sepia (BAD)
image.png image.png

駄目な点

セピア色の RGB値が (107, 74, 43) なので、R,G,B をその割合にする意図が見えますが、セピア色を正規化した色(255,176,102)を最大輝度とするので彩度が高すぎて黄ばみを表現できませんし、全体としても暗すぎます。どちらかというと琥珀色で、これはこれでノスタルジックですが、セピア調とは明らかに異なります。

grayscale level 0 107 255
(R,G,B) (0,0,0) (107,74,43) (255,176,102)
sepia-tone(?) color 0-0-0.png 107-74-44.png 255-176-102.png
grayscale image.png
sepia-tone(?) image.png

古ぼけた写真の中にはこういったくすみ方をした写真もありますが、一般的とは言えません。
昔のコンテンツには、この誤った方式で変換してる残念なセピア調写真が散見され、画像検索にも混ざってくるので迷惑なものです。

sepia-tone (x:Red, y:Blue)
sepia-BAD-RB.png

実は低輝度は意外と良いです。sepia color を基準にした計算式なので当然、sepia color を通ります。ただ、そのまま直線を伸ばすので高輝度が明後日な方向に行ってしまいます。何度も言いますが色味はおかしいし輝度も低すぎる。全然駄目です。

蛇足ですが、上記の駄目な係数でもリニアRGBで計算するとそこそこマシになります。

original sepia (BAD) linear
image.png image.png

まぁでもやっぱり少し暗いですね。惜しい。

間をとったセピア調フィルタ(実験)

上で紹介した2つの色マトリックスの丁度真ん中をとったセピア調フィルタを作ってみました。

| R_sepia |   | 0.346 0.678 0.151 |   | R |
| G_sepia | = | 0.278 0.546 0.124 | x | G |
| B_sepia |   | 0.196 0.385 0.089 |   | B |
original sepia (SOSO)
image.png image.png

セピア調と言って良いのか微妙なところ。個人的にはこれも好きです。
あと、リニアRGB処理すると、独特の色あせた古ぼけた雰囲気を出せます。

original sepia (SOSO)
image.png image.png

こっちは利用できるケースがあるかも?

CLUT 方式

モノクロ写真の経年劣化は主に、紙の劣化で黄ばむのと感光剤の焼き付けが薄くなる現象で減色混合の要素が大きく、これを再現するのに加法混色RGBを使って色マトリックスで線形変換する手法は正直無理があります。

例えば、Wikipedia のセピア調に古ぼけた写真を RGB 3D色空間にプロットすると以下のように、直線には並びません。

http://ikaflower.org/3dplotcolor/
3dplotcolor.png

いっその事、ここから代表的な色を抽出して、CLUT にしてしまう手もあります。
ImageMagick-7.0.9-10 で -kmeans オプションがサポートされたので、早速これを使ってみましょう。

% convert Photograph.sept1895.jpg -kmeans 10 10.png
% identify -verbose 10.png | grep Colormap -A 11
  Colormap entries: 11
  Colormap:
         0: (142,107, 84,255) #8E6B54FF srgba(142,107,84,1)
         1: (122, 82, 58,255) #7A523AFF srgba(122,82,58,1)
         2: (162,135,114,255) #A28772FF srgba(162,135,114,1)
         3: (181,158,137,255) #B59E89FF srgba(181,158,137,1)
         4: (198,176,153,255) #C6B099FF srgba(198,176,153,1)
         5: (213,193,168,255) #D5C1A8FF srgba(213,193,168,1)
         6: (224,207,184,255) #E0CFB8FF srgba(224,207,184,1)
         7: (102, 60, 37,255) #663C25FF srgba(102,60,37,1)
         8: ( 80, 41, 23,255) #502917FF srgba(80,41,23,1)
         9: ( 55, 23, 13,255) #37170DFF srgba(55,23,13,1)
        10: (255,255,255,255) #FFFFFFFF white

最後の white を除いた 10色を元にします。なお、k-means の都合で端っこが少し切れます。
足りない分は上限と下限を線形に伸ばして1つずつ追加して、合計12色にします。

sepia-tone (x:Red, y:Blue) colors for CLUT
sepia-photo-RB.png montage.png

この 12 色を線形補完して CLUT を生成します。

CLUT (Color LookUp Table) for sepia-tone
image.png

以下のような結果になります。

original sepia
image.png image.png

色が等間隔で並ぶ仮定は k-means なので大丈夫として、学習サンプルがたったの一つですし、レンジとか補間とかツッコミどころ満載ですが、まぁまぁ良さそうです。

なお、ImageMagick では -clut オプションで処理できます。なお、残念ながら pseudo color ズバリの機能はありません。

% convert original.png -type grayscale clut.png -clut sepia.png
original.png clut.png sepia.png
image.png clut.png sepia.png

参考

yoya
画像処理の事ばかり考えてます。ImageMagick ウォッチングが趣味です。
http://pwiki.awm.jp/~yoya/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away