ProRAW が iOS 14.3 から対応されました.
自前ツールで読めるようにしたいですね. とりあえず読めました. Semantic map layer もいけました.
ProRAW とは?
Halide Camera(ちなみに Camera image processing を高速化したりなどの Halide lang https://halide-lang.org/ とは別. 紛らわしいですね)による解説があります.
Understanding ProRAW
https://blog.halide.cam/understanding-proraw-4eed556d4c54
ありがとうございます.
フォーマットは他の RAW と同じく DNG(TIFF) です.
ProRAW(DNG)とありますが, 他の DNG(通常 1 channel の mosaiced 画像)とは異なり, 画像データはすでに demosaic されたあとの RGB データになっています.
denoise やら HDR 合成などを 専用 IP で処理したあとの結果のため, 実際に bayer の状態のデータを出すのが HW 的に無理(or 出したくない)というのもあるかもしれません.
したがって sensor RAW 値を取得して物理量で何か処理したいとか, 自前の debayer/denoise と組み合わせてなにか処理したい場合には向かない形式ですね.
Lightroom 的な感じでレタッチメインのアプリ開発をしている場合は, demosaic や noise reduction を考慮しなくて良いので扱いが楽になります.
また, channel とタイルごとに huffman テーブルがあるので実質的なダイナミックレンジが高い(各チャネル 16bit で [0, 65535])画像が得られます(+ 肌領域などの semantic map もある)ので, レタッチやフィルタ処理がしやすくなっています
Raw Digger で見てみる.
とりあえず Raw Digger https://www.rawdigger.com/ で見てみます.
EXIF は以下の感じです.
---- ExifTool ----
ExifTool Version Number : 12.06
---- File ----
File Name : IMG_***.DNG
Directory :
File Size : 25 MB
File Modification Date/Time :
File Access Date/Time :
File Creation Date/Time :
File Permissions : rw-rw-rw-
File Type : DNG
File Type Extension : dng
MIME Type : image/x-adobe-dng
Exif Byte Order : Big-endian (Motorola, MM)
---- EXIF ----
Make : Apple
Camera Model Name : iPhone 12 Pro Max
Preview Image Start : 64112
Orientation : Rotate 90 CW
Rows Per Strip : 3024
Preview Image Length : 3744713
Software : 14.3
Modify Date :
Image Width : 4032
Image Height : 3024
Bits Per Sample : 12 12 12
Compression : JPEG
Photometric Interpretation : Linear Raw
Samples Per Pixel : 3
Planar Configuration : Chunky
Tile Width : 504
Tile Length : 378
Tile Offsets : (Binary data 557 bytes, use -b option to extract)
Tile Byte Counts : (Binary data 447 bytes, use -b option to extract)
Linearization Table : (Binary data 23273 bytes, use -b option to extract)
Black Level : 0 0 0
White Level : 65535 65535 65535
Noise Profile : 3e-005 3e-008
Default Black Render : None
Subfile Type : Transparency mask, [16]
Strip Offsets : 3808828
Strip Byte Counts : 58984
Exposure Time : 1/121
F Number : 1.6
Exposure Program : Program AE
ISO : 100
Exif Version : 0232
Date/Time Original :
Create Date :
Offset Time : +09:00
Offset Time Original : +09:00
Offset Time Digitized : +09:00
Shutter Speed Value : 1/121
Aperture Value : 1.6
Brightness Value : 3.986063072
Exposure Compensation : 0
Metering Mode : Multi-segment
Flash : Auto, Did not fire
Focal Length : 5.1 mm
Subject Area : 2002 1503 2213 1327
Sub Sec Time Original : 175
Sub Sec Time Digitized : 175
Exif Image Width : 4032
Exif Image Height : 3024
Sensing Method : One-chip color area
Scene Type : Directly photographed
Exposure Mode : Auto
White Balance : Auto
Focal Length In 35mm Format : 26 mm
Lens Info : 1.539999962-7.5mm f/1.6-2.4
Lens Make : Apple
Lens Model : iPhone 12 Pro Max back triple camera 5.1mm f/1.6
GPS Latitude Ref : North
GPS Longitude Ref : East
GPS Altitude Ref : Above Sea Level
GPS Speed Ref : km/h
GPS Speed : 0
GPS Img Direction Ref :
GPS Img Direction :
GPS Dest Bearing Ref :
GPS Dest Bearing :
GPS Date Stamp :
GPS Horizontal Positioning Error :
DNG Version : 1.4.0.0
DNG Backward Version : 1.3.0.0
Unique Camera Model : iPhone13,4 back camera
Color Matrix 1 : 1.2890625 -0.6268655658 -0.237611264 -0.4374913871 1.49353826 -0.02780930698 -0.04431796074 0.1669107676 0.6011510491
Color Matrix 2 : 0.954613328 -0.3694036305 -0.1263036281 -0.4197171032 1.302622795 0.09318488836 -0.1094128639 0.2405354381 0.4359321594
As Shot Neutral : 0.3930902183 1 0.653686583
Baseline Exposure : 2.005519629
Baseline Sharpness : 1.5
Calibration Illuminant 1 : Standard Light A
Calibration Illuminant 2 : D65
Noise Reduction Applied : 0.9499999881
Profile Name : Apple Embedded Color Profile
Profile Tone Curve : (Binary data 7182 bytes, use -b option to extract)
Preview Image : (Binary data 3744713 bytes, use -b option to extract)
---- XMP ----
XMP Toolkit : XMP Core 6.0.0
Semantic Segmentation Matte Version : 65536
Auxiliary Image Type : urn:com:apple:photo:2020:aux:semanticskymatte
---- MakerNotes ----
Run Time Flags : Valid
Run Time Value : 137468691052833
Run Time Scale : 1000000000
Run Time Epoch : 0
Acceleration Vector : -0.0118339099 -0.991778612 -0.004879828543
---- Composite ----
Run Time Since Power Up : 1 days 14:11:09
Aperture : 1.6
Image Size : 4032x3024
Lens ID : iPhone 12 Pro Max back triple camera 5.1mm f/1.6
Megapixels : 12.2
Scale Factor To 35 mm Equivalent : 5.1
Shutter Speed : 1/121
Create Date :
Date/Time Original :
Modify Date :
GPS Altitude :
GPS Latitude :
GPS Longitude :
Circle Of Confusion : 0.006 mm
Field Of View : 69.4 deg
Focal Length : 5.1 mm (35 mm equivalent: 26.0 mm)
GPS Position :
Hyperfocal Distance : 2.76 m
Light Value : 8.3
Maker note は独自のは無い? のかな.
カスタムデータは XMP(Adobe のなんか独自 specification)であるようです.
それ以外は普通の EXIF データなので扱いが楽です.
ProRAW の構造
デフォルトのカメラアプリ利用の場合, おおむね撮影条件によって 3 or 4 layers で構成されています.
(RAW, JPEG に加えて, semantic map が 1 or 2 レイヤー)
- ProRAW データ?(12 bit)
- LosslessJPEG
- 画像を 8x8 分割したタイルになっている.
- component 3 なので, RGB レイヤーごと.
- semantic map
- 撮影条件によって 1 or 2 枚ある模様.
- JPEG データ(8bit)
RAW は LosslessJPEG での可逆圧縮になっています.
(channel 3, predicator 7 でした)
lossless jpeg の channel 3, predicator 7 はあまり無い形式のようで, RawTherapee など対応していないので開くとてへんな結果になります. 最近 RawTherapee で対応されました https://github.com/Beep6581/RawTherapee/issues/6036
(Darktable はまだのようです)
dcraw ですとうまくデコードできました
TinyDNGLoader で使っている lj92 に channel > 2 & predicator > 2
のときにデコードがうまくいかないのがわかったので修正して, TinyDNGLoader でも読めるようにしました
(長く険しいデバッグを二営業日ほどかけてなんとか対応した)
ねんがんの Apple ProRAW データのデコードに成功したぞ!!! 🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🥳🥳🥳🥳🥳🥳🥳🥳🥳🎊🎊🎊🎊🎊🎊🎊🎊🍣🍣🍣🍣🍣🍣🍣🍣✌️✌️✌️✌️✌️✌️ pic.twitter.com/Aa3xmLeviX
— Syoyo Fujita 🌸 レイトラ ® 🐯 2 周年 🎉 (@syoyo) December 20, 2020
TinyDNGLoader の最新を引けばいけます.
Dynamic range
ProRAW は 12bit(4096 段階) の Lossless 圧縮ですが, 展開後のピクセル値は 16bit([0, 65535]
)になります.
blacklevel はゼロのため, 16bit の全体を使うことができます.
また, Lossless 圧縮では前のピクセルの平均(predictor 7)を取ってから huffman 圧縮している(huffman はテーブルは最大 12bit の 4096 エントリ?)を作っているのと, RGB とタイルごとに huffman テーブルがあるため, 実質的に高いダイナミックレンジを期待できます.
たとえば日の入りのデータですと, [0, 65535]
の範囲にピクセル値が入ることが実現できていています
(0 に近いほうは quantization によるものなのか, ヒストグラムでみるとすこし歯抜けになっていますが)
ProRAW は画像を 8x8 のタイルに分割しており, タイルと channel ごとに huffman テーブルは変わっていますから, 空間的な輝度変化のあるダイナミックレンジの高いシーンに強い気もします(e.g. 海に沈む夕日などのショット).
タイルの境界で量子化誤差が気になりそうな気がしますが, 実際のところは知覚できるほどのアーティファクトはさそうです(もしくはエンコード前にうまく処理しているのかもしれません).
Semantic map
SemanticName
TIFF Tag 52526 に Semantic map 用の識別子があります.
とりあえず以下の文字列を取得できました.
urn:com:apple:photo:2018:aux:portraiteffectsmatte
(ポートレート用のマット画像)
urn:com:apple:photo:2019:aux:semanticskinmatte
(skin 領域のマット画像と思われます)
urn:com:apple:photo:2020:aux:semanticskynmatte
(空領域のマット画像と思われます)
データ自体は通常の 8bit grayscale JPEG でした.
(compression 34892 で, DNG 仕様上は lossy JPEG とありますが実際には普通の JPEG データ. したがって stb_image などでパースできます)
例えば Front camera の画像ですと以下のようなマップが取得できました.
ねんがんの Apple ProRAW から semantic map の extraction に成功したぞ!!!! 🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎊🎊🎊🎊🎊🎊🎊🎊🎊🎊🎊㊗️㊗️㊗️㊗️㊗️㊗️㊗️㊗️㊗️😍😍😍😍😍😍😍😍 Front camera だと portrait alpha と skin segmentation map が取得できるっぽい. 勝てます ✌️ pic.twitter.com/4h2UDn3dUS
— Syoyo Fujita 🌸 レイトラ ® 🐯 2 周年 🎉 (@syoyo) December 20, 2020
depth は対応していない
LiDAR データなど生の depth 出力は対応していません. 特許関連なのですかね?
depth も DNG に埋め込みたい場合, 自前で iOS コードを書くになるでしょうか.
rawpy で読む
rawpy で普通に読めました
pixel 値の検証(linear かどうかなど)は python(e.g. JupyterLab) でやるのがよさそうです!
python rawpy で ProRAW 48MP DNG 読めました 🤘 pic.twitter.com/60KwmyHj5V
— syoyo.eth 🌸 レイトラ ® 🐯 4 周年 🎉 (@syoyo) November 24, 2022
TODO, 今後
- LosslessJPEG decoder を修正する
- semantic map を読み込む
- デコードした画像(camera matrix などで補正する前)がリニアになっているか確認する
References
- JavaScript での lossless JPEG のデコード: https://github.com/rawdevjs/lossless-jpeg-decoder
- CR2ファイルのRawデータを読み取ってみる その7 Lossless JPEGのデコード1- DHT https://www.swetake.com/photo/cr2/cr2-7.html