背景
shapelyで扱う図形を特定のピクセル数の画像として描画が必要な場面があったので、方法を把握しました。備忘録として記事に残します。
使ったもの
python 3.10.12shapely 2.0.6
matplotlib 3.10.0
プログラム解説
全体像を共有して要所を解説します。図形は以前の記事( pythonで2次元の領域を扱うのにshapelyが便利だった )からの流用です。
画像の大きさ指定方法は下記のサイトを参考にしました。
How to create a figure with no axes ( frameless ) or labels using matplotlib ?
#!/usr/bin/python上記のプログラムを実行するとpatplotlibの処理で下記の画像が表示されます。
import os
from shapely import Polygon, Point
import matplotlib.pyplot as plt
# import numpy as np
# import cv2
dir_output = os.path.join(os.path.dirname(__file__), "output")
os.makedirs(dir_output, exist_ok=True)
width = 320
height = 240
dpi = 200
fig = plt.figure(figsize=(width/dpi, height/dpi), dpi=dpi)
fig.canvas.manager.set_window_title("%dx%d %ddpi" % (width, height, dpi))
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
arrPoligon = [
Polygon([(36.17615365206663, 139.29274439262977),
(36.176069213304274, 139.29292611226978),
(36.17615744098333, 139.29299383803968),
(36.17625487020672, 139.2928342466215)]),
Polygon([(36.17610006593953, 139.29270885336436),
(36.17600209524877, 139.29289124355657),
(36.17592306907745, 139.29284095214328),
(36.17603565428372, 139.29261698771606)]),
]
arrPoint = [
Point(36.17614534102644, 139.29286477985536),
Point(36.17608958979661, 139.2928252172769),
Point(36.17601110498835, 139.29275883261136),
]
for polygon in arrPoligon:
# plt.fill(*polygon.exterior.xy, color="green")
plt.plot(*polygon.exterior.xy, color="green")
for point in arrPoint:
isPointInSomePolygon = False
for polygon in arrPoligon:
if polygon.contains(point):
print("%s contains %s" % (polygon, point))
isPointInSomePolygon = True
break
plt.scatter(*point.xy, color= "orange" if isPointInSomePolygon else "black")
fig.savefig(os.path.join(dir_output, "output.png"), dpi=dpi)
plt.plot()
plt.show()
生成されるpng画像はこちらです。
figureで大きさと解像度を指定
描画する画像の幅、高さ、解像度をfigure関数に渡して描画領域を定義後に描画処理を行うと、指定された寸法で図形が描画されます。このプログラムでは320x240の領域に描画しています。
width = 320
height = 240
dpi = 200
fig = plt.figure(figsize=(width/dpi, height/dpi), dpi=dpi)
figureのx軸とy軸を非表示化
今回はx軸とy軸が不要だったので非表示にしました。非表示にしたaxesをfigureに渡すと非表示になります。
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
dpiが大きいほうが点や線が太くなる
dpiが大きいと点や線が太くなり、小さいと細くなります。50dpi
300dpi
てっきりdpiが小さい方がドットが荒くなって点や線が太くなるのかと思っていましたが、逆でした。
figureを生成物として処理
このプログラムではfigureからpng画像を生成しています。fig.savefig(os.path.join(dir_output, "output.png"), dpi=dpi)
figureの情報を変換することで、opencvやPILへの情報受け渡しも可能なようです。
PythonのMatplotlibのグラフをNumPy行列に変換してOpenCVやPillowで使う
matplotlibの画像からPIL画像を取得する





0 件のコメント :
コメントを投稿