こんにちは!みやしんです。
今回はPythonで鳥瞰図を作ってみましたので、メモ的に残したいと思います。
サンプルコード付ですのでコピペしてお使いください。
鳥瞰図って皆さんご存じですか?
地図とか人や車の流れを表現したりするときに、上空から見た感じにプロットする手法ですね!
空飛ぶ鳥の目線で描かれた地図のようなものです!

ドラゴンレーダーも鳥瞰図だにや!!
おお!確かにそうですね!ドラゴンレーダーってこれですね!

と、いうことで遊び心も含めまして、鳥瞰図をドラゴンレーダー風に作ってみたいと思います!
完成はこんな感じで動画にもしちゃいたいと思います。
サンプルデータやスクリプトも公開しておりますので、是非作ってみてくださいね^^。
あっ・・・、ちなみに何か願いをかなえたい方は、こちらもオススメです。
ドラゴンレーダー風、鳥瞰図作成用データ
以下のリンクからドラゴンレーダー作成用のcsvファイルをダウンロードできます。
A列に時間、B列以降に7つのドラゴンボールの座標が記載されております。
DragonBallPositin.csv

ドラゴンレーダー風、鳥瞰図画像作成スクリプト (サンプルコード)
スクリプトは以下になります。
ドラゴンレーダーを作ってみたい方はコピペしてお使いください^^
スクリプトのファイル(DragonRadar.py)と同じ階層に「output」という名前のフォルダを作成ください。そこにドラゴンレーダー画像を1フレーム毎に出力します。
フォルダ構成

outputフォルダには、こんな感じでたくさんドラゴンレーダー風鳥瞰図の画像が出力されます。

スクリプトです。
ファイル名:DragonRadar.py
# coding;utf-8
# --- overview ---
# author : miyashin
# description : DragonRadar
#
# --- import ---
import pandas as pd
# csvファイル DragonBallPosition.csv を読込む
def Readcsv(IndexNum):
df = pd.read_csv('./DragonBallPosition.csv')
row = df.loc[[IndexNum], :]
return row
# 秒毎のドラゴンレーダー画像を作成、出力
def DragonRadarSnapshot(row, outputfile):
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np
plt.ioff() #インタラクティブモード(対話モード)offにより図の表示を回避
# ドラゴンボールの座標を変数に格納
ball1_X = row['ball1_X']
ball1_Y = row['ball1_Y']
ball2_X = row['ball2_X']
ball2_Y = row['ball2_Y']
ball3_X = row['ball3_X']
ball3_Y = row['ball3_Y']
ball4_X = row['ball4_X']
ball4_Y = row['ball4_Y']
ball5_X = row['ball5_X']
ball5_Y = row['ball5_Y']
ball6_X = row['ball6_X']
ball6_Y = row['ball6_Y']
ball7_X = row['ball7_X']
ball7_Y = row['ball7_Y']
ball_X = []
ball_Y = []
# 型をfloatに調整
for i in [ball1_X, ball2_X, ball3_X, ball4_X, ball5_X, ball6_X, ball7_X]:
ii = pd.to_numeric(i, downcast='float')
iii = float(ii)
ball_X.append(iii)
for j in [ball1_Y, ball2_Y, ball3_Y, ball4_Y, ball5_Y, ball6_Y, ball7_Y]:
jj = pd.to_numeric(j, downcast='float')
jjj = float(jj)
ball_Y.append(jjj)
# --- Settings -----
YLIM_MIN = -140
YLIM_MAX = 140
XLIM_MIN = -140
XLIM_MAX = 140
# ドラゴンレーダー画面を作る
figsizeX = 5
figsizeY = figsizeX
fig, ax = plt.subplots(figsize=(figsizeX, figsizeY), facecolor='black', subplot_kw=dict(facecolor='black'))
ax.set_xticks(np.arange(-140, 141, 20)) # x軸に目盛設定
ax.set_yticks(np.arange(YLIM_MIN, YLIM_MAX + 1, 20))
ax.set_title("Dragon Radar", color="white")
ax.set_xlabel("West <= | => East", color="white")
ax.set_ylabel("South <= | => North", color="white")
ax.spines['bottom'].set_color('white') # 軸の色設定
ax.spines['top'].set_color('white')
ax.spines['left'].set_color('white')
ax.spines['right'].set_color('white')
ax.tick_params(colors='white', grid_color='black')
plt.grid(which='both', linewidth=0.25, linestyle='dotted')
plt.xticks(fontsize=8)
plt.yticks(fontsize=8)
plt.xlim(XLIM_MAX, XLIM_MIN)
plt.ylim(YLIM_MIN, YLIM_MAX)
#ドラゴンレーダー上部のボタン部分を実装
ax.add_patch(patches.Rectangle((-5, 115), 10, 5,
edgecolor='white',
facecolor='white',
linewidth=0.25,
fill=True))
ax.add_patch(patches.Rectangle((-15, 120), 30, 10,
edgecolor='gray',
facecolor='white',
linewidth=0.25,
fill=True))
ax.add_patch(patches.Rectangle((-10, 110), 20, 5,
edgecolor='gray',
facecolor='white',
linewidth=0.25,
fill=True))
# ドラゴンレーダーの白い枠を表示
ax.add_patch(patches.Circle(xy=(0, 0), radius=110, facecolor='white', edgecolor='gray'))
# ドラゴンレーダー画面を表示
ax.add_patch(patches.Circle(xy=(0, 0), radius=95, facecolor='darkgreen', edgecolor='darkgreen'))
# 自分の位置(原点)
ax.add_patch(patches.Polygon(xy = [(0, 5), (-4.33, -2.5), (4.33, -2.5)],
facecolor = "orangered", edgecolor = "red"))
for a, b in zip(ball_X, ball_Y):
if (a != 999) or (b != 999):
ax.add_patch(patches.Circle(xy=(a, b), radius=3, facecolor='yellow', edgecolor='tomato'))
# .pngファイルで保存
plt.savefig(outputfile, dpi=150, transparent=False, facecolor=fig.get_facecolor())
print(outputfile)
# 図をクリア
plt.clf()
plt.cla()
plt.close() #Figureモードオフ
return outputfile
if __name__ == '__main__':
for i in range(0,100): #100枚画像をアウトプット(10fpsで10秒)
row = Readcsv(i)
if i <= 9:
outputfile = r'.\output\DragonRadar000' + str(i) + '.png'
elif (i >= 10)and(i <= 99):
outputfile = r'.\output\DragonRadar00' + str(i) + '.png'
elif (i >= 100)and(i <= 999):
outputfile = r'.\output\DragonRadar0' + str(i) + '.png'
elif (i >= 1000)and(i <= 9999):
outputfile = r'.\output\DragonRadar' + str(i) + '.png'
DragonRadarSnapshot(row, outputfile)
出力した複数の画像から動画を作成する(cv2.VideoWriter)
以下のスクリプトを実行して出力した複数の画像を連結して動画にします。
outputフォルダー内にたくさんの画像と一緒にスクリプト(MakeMovie.py)を配置して実行します。

MakeMovie.py
import sys
import cv2
# encoder(for mp4)
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
# output file name, encoder, fps, size(fit to image size)
video = cv2.VideoWriter('DragonRadar.mp4',fourcc, 10, (750, 750)) # 10fps
if not video.isOpened():
print("can't be opened")
sys.exit()
for i in range(0, 1132):
# DragonRadar0000.png
img = cv2.imread('./DragonRadar%04d.png' % i)
# can't read image, escape
if img is None:
print("can't read")
break
# add
video.write(img)
print(i)
video.release()
print('written')
MakeMovie.pyを実行すると、この記事の最初にあったような動画にすることができます!
以上で完成、よし、ドラゴンボールを7つ集めて願いを叶えるにゃ!!!





コメント