昨夜はいわゆるcv2.meanshiftを利用してTrackingを試みたが、第四夜はこれに物体識別機能を追加して、さらに撮影した動画を保存するように改良した。
一応の目標
①とにかく飛行させる
②GamePadで飛ばす
③PCで飛ばす
④Pythonで飛ばす
⑤画像入力する
⑥物体検出搭載
⑦トラッキングする
⑧物体を探して見つける
⑨...
今回やったこと
⑦物体識別機能付きトラッキングする
コードは以下に置いた
⑦物体識別機能付きトラッキングする
以前取り上げたものをTelloに応用した。
ほとんどコードは同じで、カメラ部分だけ変更している。
肝心なところは以下のように画像サイズをVGG16のサイズに合わせている。
# 追跡する枠の座標とサイズ
x = 200
y = 200
w = 224
h = 224
track_window = (x, y, w, h)
また、動画を保存できるように以下のとおり、cv2.VideoWriterを定義し、cv.fouce関数を定義した。
OUT_FILE_NAME = "meanshiftObjDet_result.mp4"
FRAME_RATE=8
out = cv2.VideoWriter(OUT_FILE_NAME, \
cv_fourcc('M', 'P', '4', 'V'), \
FRAME_RATE, \
(w, h), \
True)
def cv_fourcc(c1, c2, c3, c4):
return (ord(c1) & 255) + ((ord(c2) & 255) << 8) + \
((ord(c3) & 255) << 16) + ((ord(c4) & 255) << 24)
また、drone.takeoffはtラッキングする物体を確定してからtakeoffすることとした。
そして、識別した物体の名称を動画に張った。
cv2.putText(img_dst, txt, (x+3,y+10), cv2.FONT_HERSHEY_SIMPLEX, 2, (0,0,0), 1)
さらに動画のfpsを計算して同じく動画に張り付けた。
curr_time = timer()
exec_time = curr_time - prev_time
prev_time = curr_time
accum_time = accum_time + exec_time
curr_fps = curr_fps + 1
if accum_time > 1:
accum_time = accum_time - 1
fps = "FPS: " + str(curr_fps)
curr_fps = 0
cv2.putText(img_dst, fps, (x+3,y+10), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,0), 1)
動画保存は以下のとおり
img_dst = cv2.resize(img_dst, (int(h), w))
out.write(img_dst)
結果
安定して物体識別しつつ、動画撮影・保存できた。
撮影した動画は再生もできたが、公開するには絵がもう一つ気に入らないので後日フィールドで撮影したいと思う。
まとめ
・Tello飛行における、VGG16による物体識別付きトラッキングを実装・成功した
・動画を保存できるようにした
・物体検出したいと思う
おまけ
物体識別は以下のようにVGG16を使っている。
def yomikomi(img):
batch_size = 2
num_classes = 1000
img_rows, img_cols=img.shape[0],img.shape[1]
input_tensor = Input((img_rows, img_cols, 3))
# 学習済みのVGG16をロード
# 構造とともに学習済みの重みも読み込まれる
model = VGG16(weights='imagenet', include_top=True, input_tensor=input_tensor)
model.summary()
# 引数で指定した画像ファイルを読み込む
# サイズはVGG16のデフォルトである224x224にリサイズされる
# 読み込んだPIL形式の画像をarrayに変換
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
#preds = model.predict(preprocess_input(x))
preds = model.predict(x)
results = decode_predictions(preds, top=1)[0]
return str(results[0][1])