Slide 1

Slide 1 text

Web技術を最⼤限活⽤して RAW画像を現像する sssssota / #fec_tokyo

Slide 2

Slide 2 text

⾃⼰紹介 ssssota (冨川宗太郎) sは4つ テックリード(写真・現像は素人) { x: "ssssotaro", gh: "ssssota", cameras: ["S5IIX", "S9", "fp L"] }

Slide 3

Slide 3 text

RAW画像とは何か カメラをやっているとRAW画像という概念に出会う (最近ではiPhoneなどのスマホでもRAW画像を出力できる) 一般的な写真のフォーマットであるJPEGはRGB各8bit、 計24bitで色を表現する すると (28)3=約1680万色 になる

Slide 4

Slide 4 text

RAW画像とは何か カメラのセンサーは各色12bit〜16bitといった解像能を持つ 8bit→1680万色だったのが14bit→4兆色になる すると、ファイルサイズがでかくなる。(30MiB〜100MiB)

Slide 5

Slide 5 text

RAW画像とは何か そんなとても大きいRAW画像 カメラメーカー各社が独自規格で出力してくれる オープンな規格(TIFF, DNG)も存在するが 日本の大手メーカー各社は使わず...

Slide 6

Slide 6 text

RAW画像を現像する とにかくデカい、独自規格なバイナリ 一般的には デスクトップアプリケーション・モバイルアプリケーションで ネイティブな並列処理、GPU処理を活用しながら行う

Slide 7

Slide 7 text

Webエンジニアなので Webで完結させたい

Slide 8

Slide 8 text

resolve.photos

Slide 9

Slide 9 text

概観

Slide 10

Slide 10 text

課題の整理 1. カメラメーカー各社の独自フォーマット 2. デカいファイルに対する処理速度

Slide 11

Slide 11 text

LibRaw RAW画像を読めるOSS メーカー独自の規格の多くを自前でサポートするのは困難 ただしC++

Slide 12

Slide 12 text

C++のLibRawをブラウザで動かすためにWASMを使う WASMへのコンパイルにはEmscriptenを使う libraw.wasm

Slide 13

Slide 13 text

WebAssemblyの制約 現在も仕様の策定が進行しているが、JS - WASM間で 文字列や構造体などの非数な値をやりとりするのは難しい メモリ空間は共有できるので、 構造体をメモリに直接読み書きする手法を用いる

Slide 14

Slide 14 text

メモリから構造体を読むために C/C++の構造体は定義からメモリレイアウトが確定する struct Sample { uint8_t foo; uint16_t bar; }

Slide 15

Slide 15 text

typed-cstruct 構造体の定義をTypeScriptで書き下すと型付きで バイナリを読み書きできるようになるライブラリ 構造体がたくさんあると手書きが大変なので @typed-cstruct/generator でCのヘッダーファイルからTypeScriptも生成

Slide 16

Slide 16 text

WebAssemblyは速いが WebAssemblyはそれなりに速いが、 JavaScriptと同じスレッドで動くために メインスレッドでヘビーな利用をするとUIが硬直する

Slide 17

Slide 17 text

Web Worker WebAssemblyで動かすようなCPUヘビーな処理は 往々にしてWeb Workerに逃がす Web Workerに逃がすことでUIをブロッキングせずに 処理を進める Comlinkやbidcを用いてWeb Workerとの通信を 抽象化するのが一般的

Slide 18

Slide 18 text

レンダリングする ここまででビットマップ画像が得られる Canvas APIではRGB各色16bitのビットマップを扱えない WebGL 2.0を使うことになる

Slide 19

Slide 19 text

現像する 現状resolve.photosはノイズ除去や収差補正はサポートせず とある動画編集ソフトを参考にノードベースのLUT適用を実現

Slide 20

Slide 20 text

⾼速なLUT適⽤ 6000x4000ピクセルの色を取得、1つずつLUTに入れて... とするととても遅い 1つのことを繰り返しするのはGPUが得意 → WebGPU WebGL2でレンダリング時に

Slide 21

Slide 21 text

LUTをテクスチャとして読み込み、WebGLで画像に対し適用 ノードベースで複数のノード(=LUT)があることもあるので WebGLのフラグメントシェーダーは動的に生成する WebGLを⽤いたLUT適⽤

Slide 22

Slide 22 text

概観

Slide 23

Slide 23 text

改善余地 ● そもそも機能数が全く足りてない ○ 技術的におもしろい部分だけ作って満足している節がある ○ PoCとしては十分... ● WebAssembly Multithreading ○ 検証不足 ● RAW画像解析をそもそもGPGPUできる説 ○ 現実的ではないが夢はある ● 最近はAI現像っていうのが流行ってるらしい ○ マルチモーダルなローカルLLMがWebにきたらアツいですね

Slide 24

Slide 24 text

おわり 参考 ● https://github.com/ssssota/resolve.photos ● https://github.com/ssssota/libraw.wasm ● https://github.com/LibRaw/LibRaw ● https://github.com/ssssota/typed-cstruct