Processing Flow - YuukiToriyama/imageCompare GitHub Wiki
このページではこのアプリの処理の流れについて説明する。
読み込んだ画像はLeafletを用いて表示させたいので、 要素や要素として置いておくのではなく、base64エンコードされたDataURLの形に変換しておく必要がある。 また、読み込んだファイルのファイル名や縦横のサイズは今後の処理の中で度々参照するため、 base64にエンコードした画像データはメタデータとともに下記のようなオブジェクトに格納し、これを他の処理とも共有することにする。
{
name: 'IMG_20160813.jpg',
type: 'image/jpeg',
size: 645,
base64: 'data:image/jpeg;base64,/9j/4SzyRXhpZgAATU0AKgA...',
file: File,
width: 320,
height: 260
}
続いて読み込んだ画像の位置合わせを行なうために、二つの画像の間の対応関係をセットする。 当初は素のcanvasに画像を読み込み、クリックした点に直接点を描画する形でポイントを設定していたが、 その方法だと点を取り直す処理が複雑になるため取りやめることにした。 canvasはレイヤー表示が得意でないためLeafletを用いて機能を構築することにした。 Leafletに画像を読み込むのには、L.imageOverlayという関数を用いる。 この関数は引数に画像のURLと貼る位置を指定することで、 地図上に画像を重ねることができる。
var imageBounds = new latLngBounds([
[-image.height / 2, -image.width / 2],
[ image.height / 2, image.width / 2]
]);
L.imageOverlay(image.base64, imageBounds).addTo(viewer);
また、画像の対応関係を設定するのにはL.markerを利用している。 L.markerはLeafletの基本機能の一つで、地図上の指定した地点にピンを置くことができる機能である。 このマーカーにdraggableのオプションを与えると、マウスを使って自由に動かすことができる。 また、移動後のマーカーの座標はgetLatLngメソッドを使うことにより取得できる。 このことを利用して、画像の対応点を指定するのに利用している。
ホモグラフィを計算するには最低四点の対応関係が必要である。そのため標準では右と左にそれぞれ4点のマーカーを用意しているが、 設定を書き換えることによりマーカーを追加することもできる。対応関係が多いほうがより正確なホモグラフィ推定ができるとされている。
- L.imageOverlayについて
- L.markerについて
ホモグラフィの計算にはOpenCV.jsのfindHomography関数を用いた。 findHomographyは、二つの平面の間の射影変換を計算する関数で、変換元と変換先の座標の対応関係を入力すると、3×3のホモグラフィ行列を返す。 また、画像の変形にはwarpPerspective関数を用いた。 warpPerspective関数は、Mat型の画像と3x3の変換行列を与えることにより、射影変換を行なう関数である。類似のものにwarpAffineという関数があるが、これは2x3の行列しか受け付けず、一次変換と平行移動しか行なうことができないので今回は用いることができない。
- cv.findHomographyについて
- cv.warpPerspectiveについて
最後に読み込んだ画像とOpenCVによって位置合わせの加工を施した画像をLeafletを用いて表示する。 Leafletは標準でレイヤーによる表示に対応しているが、 Yasunori Kirimoto氏によって開発されたプラグインleaflet.control.opacityを用いることにより、 動的にレイヤーの透明度を変更してレイヤー同士を透かしてみることが可能になる。
また、2画像を横に並べ比較をするモードでは、Jan Pieter Waagmeester氏が開発したプラグインLeaflet.Syncを用いることにより、一方の画面での操作をもう一方にも反映させ、画面上の移動や拡大縮小の動きをシンクロナイズさせることができる。
- dayjournal/Leaflet.Control.Opacity
- jieter/Leaflet.Sync