plant-raspberrypi3のブログ

ラズベリーパイ3とPythonに挑戦して、植物を愛でたり画像を加工したりします。最近はscikit-imageの勉強してます。

scikit-imageのお勉強 番外編 〜台形補正にチャレンジ!~

先日から行なっているscikit-imageの機能を網羅していくシリーズ。

transformモジュールについては以前も取り上げました。

plant-raspberrypi3.hatenablog.com

今回は、このとき取り上げることができなかった台形補正にチャレンジしてみました。

Scikit-imageでの台形補正のやり方については、以下のページを参考にしました。

Computer vision in geoscience: recover seismic data from images – part 2mycarta.wordpress.com

環境

Jupyter lab上で操作。

準備

台形補正の効果がわかりやすいように、以下のサンプル画像を使用します。

%matplotlib inline
import matplotlib.pyplot as plt
from skimage import data,transform
import numpy as np

f = 'brick.png'
loaded_img = data.load(f)
plt.imshow(loaded_img)
plt.show()

f:id:plant-raspberrypi3:20181016141313j:plain

サンプル画像の呼び出し方は以前の記事をご参照ください。

plant-raspberrypi3.hatenablog.com

次に、台形の四隅の座標を調べます。調べる順番は「左上->左下->右下->右上」の反時計回り。

座標はImageJで手作業で調べました。

四隅の座標は以下のようなNumPyアレイとして、cornerCoordsに代入しておきます。

#[縦, 横]の順番
cornerCoords = np.array([[83,79],[446,31],[443,482],[76,450]])

plt.imshow(loaded_img)
plt.scatter(cornerCoords[:,1],cornerCoords[:,0], s=60, 
 color=['magenta', 'cyan', 'yellow', 'red'])
plt.show()

f:id:plant-raspberrypi3:20181016141416j:plain

手順その1

変換に使うための長方形の枠(?)を四隅の座標を元にして準備します。

w1 = np.sqrt(((cornerCoords[0, 1]-cornerCoords[3, 1])**2)
  +((cornerCoords[0, 0]-cornerCoords[3, 0])**2))
w2 = np.sqrt(((cornerCoords[1, 1]-cornerCoords[2, 1])**2)
  +((cornerCoords[1, 0]-cornerCoords[2, 0])**2))

h1 = np.sqrt(((cornerCoords[0, 1]-cornerCoords[1, 1])**2)
  +((cornerCoords[0, 0]-cornerCoords[1, 0])**2))
h2 = np.sqrt(((cornerCoords[3, 1]-cornerCoords[2, 1])**2)
  +((cornerCoords[3, 0]-cornerCoords[2, 0])**2))

w = max(int(w1), int(w2))
h = max(int(h1), int(h2))

dst = np.array([
  [0, 0],
  [h-1, 0],
  [h-1, w-1],
  [0, w-1]], dtype = 'float32')

手順その2

その1で求めたdstの値と四隅の座標のX,Yをひっくり返しておきます。(必要らしい)

dst[:,[0,1]] = dst[:,[1,0]]
cornerCoords[:,[0,1]] = cornerCoords[:,[1,0]]

手順その3

1. transform.ProjectiveTransformクラスのインスタンス
tform = transform.ProjectiveTransform()
2. 手順その2で準備したdstと四隅の座標をestimate関数に適用
tform.estimate(dst,cornerCoords)
3. アフィン変換でも使用したtransform.warp関数で台数補正を画像に適用
warped =transform.warp(loaded_img, tform, output_shape=(h-1,w-1))

plt.imshow(warped)
plt.show()

f:id:plant-raspberrypi3:20181016142151j:plain

できました!

以上です。