【Tello】トイ・ドローンで遊んでみた♪～cv2.meanshiftでTracking

昨夜はPythonで飛ばして、かつ動画撮影をやったが、第三夜はいわゆるcv2.meanshiftを利用してTrackingを試みた。厳密にいうとTrackingじゃないので、アプリ的にはまだまだ改善が必要だが、一応できたのでアップしようと思います。

###一応の目標
①とにかく飛行させる
②GamePadで飛ばす
③PCで飛ばす
④Pythonで飛ばす
⑤画像入力する
⑥物体検出搭載
⑦トラッキングする
⑧物体を探して見つける
⑨...
今回やったこと
⑦トラッキングする
###コードは以下に置いた
[Tello/meanshift.py](https://github.com/MuAuan/Tello/blob/master/meanshift.py)
###⑦トラッキングする
[以前PCのカメラでやったmeanshift.py](https://github.com/MuAuan/OpenCV/blob/master/meanshift.py)をTelloのカメラ入力に変更した。
ということで、主なコードの変更は以下の通り
①Telloに接続して、takeoffし、入力をdrone.get_video_streamに変更

```meanshift.py
if __name__ == '__main__':
    drone = tellopy.Tello()
    drone.connect()
    drone.wait_for_connection(60.0)
    drone.takeoff()
        
    container = av.open(drone.get_video_stream()) 
    #cap = cv2.VideoCapture(0)
```
②フレーム取得も変更、While True:を止めて、containerからframe単位に入力して、ターゲット画像を決める

```py
    # フレームの取得
    #ret,frame = cap.read()
    # 追跡する枠を決定
    #while True:
    for frame in container.decode(video=0):
        if 0 < frame_skip:
            frame_skip = frame_skip - 1
            continue
        start_time = time.time()
        image = cv2.cvtColor(numpy.array(frame.to_image()), cv2.COLOR_RGB2BGR)
        cv2.imshow("org",image)
        roi = image[y:y+h, x:x+w]
        cv2.imshow("roi",roi)
        k = cv2.waitKey(1)
        if k == ord('q'):
            cv2.destroyWindow("org")
            break
```
③物体検出の枠と全体画像を表示

```py
while(True):
        #ret, frame = cap.read()
        for frame in container.decode(video=0):
            if 0 < frame_skip:
                frame_skip = frame_skip - 1
                continue
            start_time = time.time()
            image = cv2.cvtColor(numpy.array(frame.to_image()), cv2.COLOR_RGB2BGR)
        
 
        #if ret == True:
            # フレームをHSV変換する
            hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
            # 上で計算したヒストグラムを特徴量として、画像の類似度を求める
            dst = cv2.calcBackProject([hsv],[0],roi_hist,[0,180], 1)
 
            # 物体検出する
            ret, track_window = cv2.meanShift(dst, track_window, term_crit)
            #ret, track_window = cv2.CamShift(dst, track_window, term_crit)
 
            # 物体検出で取得した座標を元のフレームで囲う
            x,y,w,h = track_window
            img_dst = cv2.rectangle(image, (x,y), (x+w, y+h), 255, 2)
            #cv2.imshow('SHOW MEANSHIFT IMAGE', img_dst)
            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, 0.35, (0,0,0), 1)
            #cv2.putText(img_dst, str(dst), (x+3,y+10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0,0,0), 1)
            
            cv2.imshow('SHOW MEANSHIFT IMAGE', img_dst)
```
④最後にdroneを着陸させて終了

```py
            # qを押したら終了。
            k = cv2.waitKey(1)
            if k == ord('q'):
                drone.land()
                sleep(5)
                drone.quit()
                cv2.destroyWindow('SHOW MEANSHIFT IMAGE')
                break
            else:
                break

```
###結果
一応、ターゲット決めて、動かすと動画に枠が出るが、Trackingというより。。。
ただ動いたレベル。
また、どうもおまけに掲載した出力（一部）の様にバグも出ている。
###まとめ
・cv2.meanshiftを利用したTrackingのアプリが出来た

・まだまだバグが消えていないので改善が必要
・物体の動きに合わせた、いわゆるTrackingをしたいと思う
・いわゆる物体検出もやりたい

###おまけ

```
>python -m tellopy.examples.meanshift
Tello: 19:23:35.922:  Info: start video thread
Tello: 19:23:35.922:  Info: send connection request (cmd="conn_req:9617")
Tello: 19:23:35.922:  Info: video receive buffer size = 524288
Tello: 19:23:35.922:  Info: state transit State::disconnected -> State::connecting
Tello: 19:23:35.954:  Info: connected. (port=9617)
Tello: 19:23:35.954:  Info: send_time (cmd=0x46 seq=0x01e4)
Tello: 19:23:35.954:  Info: state transit State::connecting -> State::connected
Tello: 19:23:35.954:  Info: set altitude limit 30m
Tello: 19:23:35.969:  Info: takeoff (cmd=0x54 seq=0x01e4)
Tello: 19:23:35.969:  Info: get video stream
Tello: 19:23:35.969:  Info: start video (cmd=0x25 seq=0x01e4)
Tello: 19:23:36.016:  Info: recv: ack: cmd=0x54 seq=0x0000 cc 60 00 27 b0 54 00 00 00 00 a1 81
Tello: 19:23:36.016:  Info: recv: ack: cmd=0x34 seq=0x0000 cc 60 00 27 90 34 00 00 00 00 72 a5
Tello: 19:23:36.016:  Info: recv: ack: cmd=0x20 seq=0x0000 cc 60 00 27 b0 20 00 00 00 00 42 b9
Tello: 19:23:36.016:  Info: recv: ack: cmd=0x34 seq=0x0000 cc 60 00 27 90 34 00 00 00 00 72 a5
Tello: 19:23:36.016:  Info: recv: ack: cmd=0x20 seq=0x0000 cc 60 00 27 b0 20 00 00 00 00 42 b9
Tello: 19:23:38.953:  Info: video data 890227 bytes 431.4KB/sec
non-existing PPS 0 referenced
last message repeated 1 times
decode_slice_header error
no frame!
non-existing PPS 0 referenced
last message repeated 1 times
decode_slice_header error
no frame!
。。。
non-existing PPS 0 referenced
last message repeated 1 times
decode_slice_header error
no frame!
Tello: 19:23:40.968:  Info: video data 756974 bytes 366.8KB/sec
Tello: 19:23:42.999:  Info: video data 757885 bytes 364.4KB/sec
Tello: 19:23:45.014:  Info: video data 755524 bytes 366.1KB/sec
Tello: 19:23:46.201:  Info: VideoStream.seek(-1, 2)
Tello: 19:23:46.201:  Info: VideoStream.seek(-1, 2)
Tello: 19:23:47.029:  Info: video data 759222 bytes 367.9KB/sec
Tello: 19:23:49.060:  Info: video data 763572 bytes 367.2KB/sec
Tello: 19:23:51.091:  Info: video data 763625 bytes 367.2KB/sec
Tello: 19:23:53.122:  Info: video data 763779 bytes 367.3KB/sec
Tello: 19:23:55.137:  Info: video data 751175 bytes 364.1KB/sec
Tello: 19:23:57.168:  Info: video data 763667 bytes 367.2KB/sec
Tello: 19:23:59.198:  Info: video data 763380 bytes 367.1KB/sec
Tello: 19:24:01.229:  Info: video data 763814 bytes 367.3KB/sec
Tello: 19:24:03.260:  Info: video data 763621 bytes 367.2KB/sec
Tello: 19:24:05.291:  Info: video data 763451 bytes 367.1KB/sec
Tello: 19:24:07.321:  Info: video data 763732 bytes 367.3KB/sec
Tello: 19:24:09.337:  Info: video data 751305 bytes 364.1KB/sec
error while decoding MB 37 39, bytestream -10
Tello: 19:24:11.352:  Info: video data 761810 bytes 369.2KB/sec loss=1
Tello: 19:24:13.367:  Info: video data 754348 bytes 365.6KB/sec
Tello: 19:24:15.398:  Info: video data 760255 bytes 365.6KB/sec
Tello: 19:24:17.429:  Info: video data 763784 bytes 367.3KB/sec
Tello: 19:24:17.585:  Info: video recv: 1460 bytes 7300 +140
error while decoding MB 57 40, bytestream -8
Tello: 19:24:17.725:  Info: video recv: 1460 bytes 7700 +125
Tello: 19:24:17.866:  Info: video recv: 1460 bytes 7b00 +125
error while decoding MB 22 39, bytestream -6
error while decoding MB 29 38, bytestream -10
error while decoding MB 59 4, bytestream -6
error while decoding MB 12 42, bytestream -6
```