plant-raspberrypi3のブログ

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

scikit-imageのお勉強 第3回 drawモジュール ~図形の描画~

scikit-imageの便利機能の備忘録シリーズ。

これまでの回はコチラ。

第1回 dataモジュールとioモジュール ~画像の入出力~

第2回 colorモジュール ~色空間~

今回は第3回です。drawモジュールについてメモしていきます。

drawモジュールでできること

様々な図形を描画し、画像に上書きできます。

公式ページ: Module: draw — skimage v0.14.0 docs

次のような図形が描けます。

直線

  • draw.line
  • draw.line_aa

ベジェ曲線

  • draw.bezier_curve

多角形

  • draw.polygon
  • draw.polygon_perimeter

四角形

  • draw.rectangle

楕円

  • draw.ellipse
  • draw.ellipse_perimeter

正円

  • draw.circle
  • draw.circle_perimeter
  • draw.circle_perimeter_aa

手順としては以下の通り。

  1. draw.xxx関数を使って描画したい座標群rr, ccを指定
  2. NumPyの座標指定の機能を使って、rr,cc座標群を塗りつぶす

直線

直線を描く関数はdraw.linedraw.line_aaの2種類あります。

いずれも引数は以下の通り。

第1引数:始点の座標(縦)
第2引数:始点の座標(横)
第3引数:終点の座標(縦)
第4引数:終点の座標(横)

draw.line_aa()のほうは自然な感じに描けますが、valというパラメーターが増えます。

まず前回と同じように、テスト画像をdataモジュールで読み込みます。

・code 

%matplotlib inline
import matplotlib.pyplot as plt
from skimage import draw, data

def image_show(img):
    plt.imshow(img)
    plt.xticks([])
    plt.yticks([])
    plt.show()

rocket = data.rocket()
image_show(rocket)

・元画像

f:id:plant-raspberrypi3:20180903162440p:plain

直線を描いてみます。

・code 

rr,cc = draw.line(51,101,301,601) 
print(rr[:10]) #10番目までの座標群(縦)
print(cc[:10]) #10番目までの座標群(横)
rocket2 = data.rocket()
rocket2[rr,cc] = 255
image_show(rocket2)
image_show(rocket2[50:100,125:175])

#出力結果
[51 52 52 53 53 54 54 55 55 56]  #10番目までの座標群(縦)
[101 102 103 104 105 106 107 108 109 110]   #10番目までの座標群(横)

・出力画像

f:id:plant-raspberrypi3:20180903163857p:plain

・出力画像(拡大)

f:id:plant-raspberrypi3:20180903163905p:plain

draw.line_aaも試してみます。

・code 

rr,cc,val = draw.line_aa(51,101,301,601) #valも計算される
rocket2 = data.rocket()
for i in range(3):
    rocket2[rr,cc,i] = val*255 #各色チャネルに対して塗りつぶし処理する必要がある
image_show(rocket2)
image_show(rocket2[50:100,125:175])

・出力画像

f:id:plant-raspberrypi3:20180903163929p:plain

・出力画像(拡大)

f:id:plant-raspberrypi3:20180903163938p:plain

ベジェ曲線

draw.bezier_curveを使うとベジェ曲線も描けちゃいます。
ただし、思うような曲線を描くためには試行錯誤が必要かもしれません。

第1引数:始点の座標(縦)
第2引数:始点の座標(横)
第3引数:中間点の座標(縦)
第4引数:中間点の座標(横)
第5引数:終点の座標(縦)
第6引数:終点の座標(横)
第7引数:重み

引数が多くてややこしいです。

・code 

for i in range(1,5):
    rr,cc = draw.bezier_curve(51,101,301,301,301,601,i)
    rocket2 = data.rocket()
    rocket2[rr,cc] = 255
    image_show(rocket2)

・重み=1

f:id:plant-raspberrypi3:20180903164422p:plain

・重み=2

f:id:plant-raspberrypi3:20180903164438p:plain

・重み=3

f:id:plant-raspberrypi3:20180903164450p:plain

・重み=4

f:id:plant-raspberrypi3:20180903164501p:plain

多角形

draw.polygon(塗りつぶし)またはdraw.polygon_perimeter(輪郭)で描けます。

第1引数:頂点の座標群(縦・Numpyアレイで与える)
第2引数:頂点の座標群(横・Numpyアレイで与える)

・code 

import numpy as np

rr,cc = draw.polygon(np.array([101,301,201,101,51]),np.array([101,201,401,401,301]))
rocket2 = data.rocket()
rocket2[rr,cc] = 255
image_show(rocket2)

・出力画像

f:id:plant-raspberrypi3:20180903164651p:plain

・code 

rr,cc = draw.polygon_perimeter(np.array([101,301,201,101,51]),np.array([101,201,401,401,301]))
rocket2 = data.rocket()
rocket2[rr,cc] = 255
image_show(rocket2)

・出力画像

f:id:plant-raspberrypi3:20180903164736p:plain

四角形

scikit-imageのversion0.14.xで足されたようです。

draw.rectangleで描きます。

第1引数:始点の座標([縦、横])
第2以降の引数(end=):終点の座標([縦、横])

・code 

rr,cc = draw.rectangle([101,101],end=[201,301])
rocket2 = data.rocket()
rocket2[rr,cc] = 255
image_show(rocket2)

・出力画像

f:id:plant-raspberrypi3:20180903165858p:plain

楕円

draw.ellipse(塗りつぶし)またはdraw.ellipse_perimeter(輪郭)で描けます。

第1引数:中心の座標(縦)
第2引数:中心の座標(横)
第3引数:長軸・短軸方向の径(縦)
第4引数:長軸・短軸方向の径(横)

・code 

rr,cc = draw.ellipse(251,251,50,150)
rocket2 = data.rocket()
rocket2[rr,cc] = 255
image_show(rocket2)

・出力画像

f:id:plant-raspberrypi3:20180903164847p:plain

・code 

rr,cc = draw.ellipse_perimeter(251,251,50,150)
rocket2 = data.rocket()
rocket2[rr,cc] = 255
image_show(rocket2)

・出力画像

f:id:plant-raspberrypi3:20180903165341p:plain

正円

正円を描く方法はdraw.circledraw.circle_perimeterdraw.circle_perimeter_aaの3種類です。

第1引数:中心の座標(縦)
第2引数:中心の座標(横)
第3引数:直径(縦)

・code 

rr,cc = draw.circle(251,251,50)
rocket2 = data.rocket()
rocket2[rr,cc] = 255
image_show(rocket2)

・出力画像

f:id:plant-raspberrypi3:20180903165532p:plain

・code 

rr,cc = draw.circle_perimeter(251,251,50)
rocket2 = data.rocket()
rocket2[rr,cc] = 255
image_show(rocket2)
image_show(rocket2[190:240,190:240])

・出力画像

f:id:plant-raspberrypi3:20180903165543p:plain

・出力画像(拡大)

f:id:plant-raspberrypi3:20180903165556p:plain

・code 

rr,cc,val = draw.circle_perimeter_aa(251,251,50)
rocket2 = data.rocket()
for i in range(3):
    rocket2[rr,cc,i] = val*255  #各色チャネルに対して塗りつぶし処理する必要がある
image_show(rocket2)
image_show(rocket2[190:240,190:240])

・出力画像

f:id:plant-raspberrypi3:20180903165620p:plain

・出力画像(拡大)

f:id:plant-raspberrypi3:20180903165629p:plain

今回は以上です。