LoginSignup
1
3

More than 1 year has passed since last update.

画像認識技術で空港の飛行機数を数えてツイート投稿する

Posted at

休日にやることないから、画像認識を使って羽田空港の飛行機を数えてツイートに投稿するシステムを開発しました。
Darkflowというオープンソースの物体検出のライブラリを使います。

Darkflow のgitリンク
https://github.com/thtrieu/darkflow

環境:
Windows 10
Anaconda3
tensorflow 1.14.0
Python 3.7.0
OpenCV 4.5.1

まず、githubからクーロンしましょう

git clone https://github.com/thtrieu/darkflow.git
cd darkflow

darkflow-masterフォルダ内にbinフォルダを作成し、binフォルダ内にyolo.weightsをダウロードしましょう。
★少し時間かかります。直接ウェブサイトからダウンロードしてもOKです。

cd bin
pip download  https://pjreddie.com/media/files/yolov2.weights

darkflowをインストールする.
★darkflowディレクトリで実行(どれでもいい)

python3 setup.py build_ext --inplace
pip3 install -e .
pip3 install .

今回こちらの羽田空港のYoutubeライブカメラを使います。
https://www.youtube.com/watch?v=Ls9p1htZsXM

ツイートを利用するためのライブラリをインストール

pip install tweepy

出力結果の整形するライブラリをインストール

pip install pprint

実際のソースコード

#!/usr/bin/env python
# coding: utf-8

from darkflow.net.build import TFNet
import cv2
import pafy
import numpy as np
import tweepy
from pprint import pprint
import datetime

#タイムゾーン設定
t_delta = datetime.timedelta(hours=9)
JST = datetime.timezone(t_delta, 'JST')


# API情報を記入
BEARER_TOKEN  = "自分の情報"
ACCESS_TOKEN = "自分の情報"
ACCESS_TOKEN_SECRET = "自分の情報"
API_KEY = "自分の情報"
API_SECRET = "自分の情報"

# ツイートクライアント関数を作成
def ClientInfo():
    client = tweepy.Client(bearer_token    = BEARER_TOKEN,
                           consumer_key    = API_KEY,
                           consumer_secret = API_SECRET,
                           access_token    = ACCESS_TOKEN,
                           access_token_secret = ACCESS_TOKEN_SECRET,
                          )
    
    return client


# ツイート送信関数
def CreateTweet(message):
    tweet = ClientInfo().create_tweet(text=message)
    return tweet

#yolov2.weightsを使用、Darkflowはyolov3以上非対応のようです。
options = {"model": "cfg/yolo.cfg", "load": "bin/yolov2.weights", "threshold": 0.1}
tfnet = TFNet(options)

# カメラの起動
#cap = cv2.VideoCapture(0)
                   
#ライブカメラ映像
url="https://www.youtube.com/watch?v=Ls9p1htZsXM"
video = pafy.new(url)
best = video.getbest(preftype="mp4")
cap = cv2.VideoCapture(best.url)

# 動画のプロパティを取得
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = cap.get(cv2.CAP_PROP_FPS)
frame_num = cap.get(cv2.CAP_PROP_FRAME_COUNT)

# 動画のプロパティを表示
print("WIDTH:", width)
print("HEIGHT:", height)
print("FPS:", fps)
print("FRAME NUM:", frame_num)

#クラス種別
class_names = ['aeroplane', 'bicycle', 'bird', 'boat', 'bottle',
              'bus', 'car', 'cat', 'chair', 'cow', 'diningtable',
              'dog', 'horse', 'motorbike', 'person', 'pottedplant',
              'sheep', 'sofa', 'train', 'tvmonitor']

num_classes = len(class_names)
class_colors = []
for i in range(0, num_classes):
    hue = 255*i/num_classes
    col = np.zeros((1,1,3)).astype("uint8")
    col[0][0][0] = hue
    col[0][0][1] = 128
    col[0][0][2] = 255
    cvcol = cv2.cvtColor(col, cv2.COLOR_HSV2BGR)
    col = (int(cvcol[0][0][0]), int(cvcol[0][0][1]), int(cvcol[0][0][2]))
    class_colors.append(col)

def main():
    
    while(True):
        # 動画ストリームからフレームを取得
        ret, frame = cap.read()
        result = tfnet.return_predict(frame)
        n=0
        for item in result:
            tlx = item['topleft']['x']
            tly = item['topleft']['y']
            brx = item['bottomright']['x']
            bry = item['bottomright']['y']
            label = item['label']
            conf = item['confidence']
            
            #confで精度はある程度調整できます。
            if conf > 0.3:
                
                for i in class_names:
                    if label == i:
                        class_num = class_names.index(i) 
                        #飛行機をカウントする
                        if label=='aeroplane':
                            n=n+1   
                        break
                    
                    
                #枠の作成
                cv2.rectangle(frame, (tlx, tly), (brx, bry), class_colors[class_num], 2)

                #ラベルの作成
                text = label + " " + ('%.2f' % conf)
                cv2.rectangle(frame, (tlx, tly - 15), (tlx + 100, tly + 5), class_colors[class_num], -1)
                cv2.putText(frame, text, (tlx, tly), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 1)
                
        # メッセージを指定
        now = datetime.datetime.now(JST)
        t = now.time().strftime('%X') 
        print(t)
        message = "Python自動送信:現在時刻"+t+"、羽田空港の飛行機数は"+str(n)+"機"+"ライブ映像:https://www.youtube.com/watch?v=T8yogtAUSfg"
        #12時になったら自動送信
        if t=='12:00:00':
            print(message)
            pprint(CreateTweet(message))
        
       
        
        # 表示
        img_resize = cv2.resize(frame,dsize=(800, 600))
        cv2.imshow("Videos Detection", img_resize)
       

        # qを押したら終了。
        k = cv2.waitKey(10);
        if k == ord('q'):  break;

    cap.release()
    cv2.destroyAllWindows()

if __name__ == '__main__':    
    main() 

実行コード

Python aeroplane_count.py

飛行機が認識されていた様子
aeroplane_count.png

設定された時刻になったらツイートも送信されました。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3