お手軽なHDRI計画(1) 色数の問題

HDRIに憧れる少年がいたとする。まあ実際は30代のオッサンですけど。自分のコンパクトデジカメでできるだけHDRIな人になるにはどうしたらいいのか。いくつか方法を考えてみたいなぁと。

HDRIっていうのはいろんな文脈で使われるようだが、私が言っているのはこっちに近いかな。写真っぽくない、絵画みたいな雰囲気。といっても非現実的になるわけじゃなくて、人間の目で見たものにより近い感じになる。写真だと逆光だのなんだので条件が悪いと猛烈に色が飛んで、目にははっきり見えるものがぜんぜん写らないじゃないですか。芸術を追求したいわけじゃなくて、あれがむかつくんですね。だからHDRIに憧れるといっても、「スクリプトを通せばある程度きれいになります」というレベルでいい。

そんなことができるのか。

このカメラにはオートブラケットの機能がついている。明るさ(用語はわからないが)を変えながら3回シャッターが切られて、3つの画像が保存される。これを組み合わせて、明るい部分を暗い画像から、暗い部分を明るい画像から採用すればそれっぽくなるような気がする。これならPythonのPILで簡単なスクリプトを書くか、Gimp(Script-Fu?)で頑張ればどうにかなるレベル。3枚のうち、暗すぎる部分と明るすぎる部分を捨てながら色を採用orブレンドしていけばいい。ただ、何の単位かわからないが、±0.5までしかないのであまりアグレッシブな(?)絵にはならないかもしれないし、三脚ではなく手で持って液晶を見ながらいい加減に撮るし、ずれると悲惨かもしれないね。ちょっとブレやすい程度で済めばいいけど。

ズレの解消法として、3つの画像をautopano-SIFTとhuginで重ねて、enblendの部分を自分で書くとか? 自分で書かなくても、enblendのオプションでどうにかなるのかもしれない。ありものをつなぎ合わせるだけでスクリプトにもしやすい(huginの部分はnonaを直接呼べばいいだけ?)。調べてみる価値はあるだろう。

また、このカメラはRaw(AdobeのDNG形式=tiffの拡張)でも保存できる。Rawでオートブラケットは効かないようだが、とにかくjpegでは飛んでしまう色まで記録できるように作られているはずだから、HDRIに近づけるだろう。OpenEXRに変換すれば、exrtoolsあたりでがんばれば、それなりになるかもしれないし、Pythonのモジュールもあるからどうにかなる可能性が高まる。

ざっと考えるとこの2つ。他にもやりようがあるのかもしれないが。

どっちがいいのかな。最初に気になるのは、Rawのデータのビット数。これが8ビットだと、何やってるんだという話になる。さすがにないか。調べる方法が分からないが手探りでやってみると、

# dcraw -i -v xxx.dng
Filename: xxx.dng
Timestamp: Fri Feb 15 19:15:27 2008
Camera: RICOH GR DIGITAL 2
DNG Version: 1.0.0.0
ISO speed: 100
Shutter: 1/125.0 sec
Aperture: f/3.4
Focal length: 5.9 mm
Embedded ICC profile: no
Number of raw images: 1
Thumb size: 160 x 120
Full size: 3656 x 2744
Image size: 3656 x 2744
Output size: 3656 x 2744
Raw colors: 3
Filter pattern: BGGRBGGRBGGRBGGR
Daylight multipliers: 2.036647 0.923390 1.364861
Camera multipliers: 2.240003 1.000000 1.580001 0.000000

出てこない。

# tiffinfo xxx.dng
xxx.dng: LensInfo: Rational with zero denominator (num = 0).
TIFF Directory at offset 0x8 (8)
Subfile Type: reduced-resolution image (1 = 0x1)
Image Width: 160 Image Length: 120
Resolution: 72, 72 pixels/inch
Bits/Sample: 8
Compression Scheme: None
Photometric Interpretation: RGB color
Orientation: row 0 top, col 0 lhs
Samples/Pixel: 3
Rows/Strip: 120
Planar Configuration: single image plane
SubIFD Offsets: 902
ImageDescription:
Make: RICOH
Model: GR DIGITAL 2
DateTime: 2008:02:15 19:15:27
Copyright: (C) by GR DIGITAL 2 User
EXIFIFDOffset: 1248
DNGVersion: 1,0,0,0
DNGBackwardVersion: 1,0,0,0
UniqueCameraModel: Ricoh GR DIGITAL 2
ColorMatrix1: 1.018600,-0.422100,0.022900,-0.391800,1.101300,0.335100,-0.073000,0.131500,0.627000
ColorMatrix2: 0.884600,-0.270400,-0.072900,-0.526500,1.270800,0.287100,-0.147100,0.195500,0.621800
AnalogBalance: 1.000000,1.000000,1.000000
AsShotNeutral: 0.446428,1.000000,0.632911
BaselineExposure: -0.500000
BaselineNoise: 4.000000
BaselineSharpness: 1.330000
LinearResponseLimit: 1.000000
MakerNoteSafety: 0
CalibrationIlluminant1: 17
CalibrationIlluminant2: 21
TIFFReadCustomDirectory: Warning, computer.dng: unknown field with tag 40961 (0xa001) encountered.
TIFF Directory at offset 0x4e0 (1248)
zsh: segmentation fault tiffinfo xxx.dng

SEGVで落ちてしまったが、まさか8ビットなの? これはさすがにサムネイル用の画像の情報だと思いますね。色を数えてみると、8ビットの画像に変換した場合は、

# dcraw -c xxx.dng| pnmcolormap all > /dev/null
pnmcolormap: making histogram…
pnmcolormap: Scanning image 0
pnmcolormap: 612025 colors so far
pnmcolormap: 612025 colors found

16ビットの画像に変換した場合は、

# dcraw -4 -c xxx.dng| pnmcolormap all > /dev/null
pnmcolormap: making histogram…
pnmcolormap: Scanning image 0
pnmcolormap: 4835063 colors so far
pnmcolormap: 4835063 colors found

どうよ。4835063/612025≒8だから、8倍の色があるんじゃーyeah! でも、8倍ということは、2x2x2だから、RGBの一つの色につき2倍にしかなってないよね。これは物足りない。8ビットが16ビットになれば256倍、それが3色ぶんなら16M倍にならなければおかしいだろう。それが、RGBそれぞれ1ビット増えただけに過ぎない値とは…納得いかん。

ところでjpegで保存されたデータ(Rawの場合は同時にjpegでも保存される)の色数はというと、

# jpegtopnm xxx.jpg | pnmcolormap all > /dev/null
pnmcolormap: making histogram…
pnmcolormap: Scanning image 0
jpegtopnm: WRITING PPM FILE
pnmcolormap: 64341 colors so far
pnmcolormap: 64341 colors found

といったところ(テスト用で、あまりカラフルでない写真を撮影しました)。Rawから16ビット画像にした場合と比べると、およそ1/75ですね。2ビット違いって感じ? jpegは基本8ビットのはずです(exifデータにも8bit/sampleと書いてあります)が、Rawからdcrawで8ビット画像を出したときよりも1/9程度しか色数を使っていないのは少し驚きました。

今日の知見としては、色数で言うと

jpeg<<Raw(8ビットに変換)<<Raw(16ビット)

という関係になるらしい。

…画像を一つも示さないまま、次回に続く(つもり)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です