OpenCVで遊んでみた♬

つまり、OpenCVのことわかっていないということで、少し遊んでみました。

・本来なら動画から物体検出してその結果を元動画に書き込んで保存
・カメラから入力した動画をリアルタイムで物体検出して、その結果を元動画に書き込んで保存

ということで、今回の目標は
・動画を加工して*任意の形式*で保存すること。
  >>gifアニメーションできるかな？？

ということで以下のサイトが参考になりそうです。
⓪読んでれば、すべてわかりそうだけど、。。。pythonなら①のサイトが便利かな？？

【参考】
⓪[Welcome to opencv documentation!](https://docs.opencv.org/2.4/index.html)
①[OpenCV-Python チュートリアル文書のページへようこそ!](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/index.html)から
[OpenCVで動画をリアルタイムに変換してみる](https://qiita.com/hitomatagi/items/ce00fab38d829965db3b)
②[動画を扱う](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_gui/py_video_display/py_video_display.html)
③[OpenCV / webcam / webcam.py](https://github.com/olympic2020/OpenCV/blob/master/webcam/webcam.py)
###今回のコード
[OpenCV / read_save_doga.py](https://github.com/MuAuan/OpenCV/blob/master/read_save_doga.py)
※(追記)下に置いといたけどどうもGifアニメのせいでときどきバグるので上に置く
###動画を読み込み、保存する
 基本は参考②から以下のとおり
シンプルである意味わかりやすいです。

```read_doga.py
import numpy as np
import cv2

cap = cv2.VideoCapture('vtest.avi')   #動画ファイル読込準備
while(cap.isOpened()):
    ret, frame = cap.read()   #動画ファイルのframe読込
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  #frameをgray画像に変換

    cv2.imshow('frame',gray)    #grayを表示
    if cv2.waitKey(1) & 0xFF == ord('q'):   #q-keyを押すと脱出
        break
cap.release()     #capを開放
cv2.destroyAllWindows()   #windowを開放
```
以下は元はカメラから読込でしたが、上記にそろえてファイル読込に変更しました。
※カメラの場合は```cap = cv2.VideoCapture(0)```
  usbカメラの場合は1(1台目)だそうです。。試してません

```read_save_doga.py
import numpy as np
import cv2

cap = cv2.VideoCapture('vtest.avi')

# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')  #fourccを定義
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))  #動画書込準備

while(cap.isOpened()):
    ret, frame = cap.read()
    if ret==True:
        frame = cv2.flip(frame,0)  #frameを左右反転
        # write the flipped frame　　
        out.write(frame)           #output.aviにframe毎書込み
        cv2.imshow('frame',frame)  #反転frameを表示
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break
# Release everything if job is finished
cap.release()
out.release()  #書込み開放
cv2.destroyAllWindows()
```
そして、参考①は以下のように元カラー動画とグレー動画に変換したものを表示して、グレー動画を保存するコードです。
ほとんど上記のコードと被っているので再掲はしませんが、以下が気になるところ。。

```movie.py
rec = cv2.VideoWriter(GRAY_FILE_NAME, \
                      cv2.VideoWriter_fourcc(*'XVID'), \
                      FRAME_RATE, \
                      (width, height), \
                      False)
```
つまり、以下の部分を中心に考察したいと思います。
①保存形式cv2.VideoWriter_fourcc(*'XVID')のところがどうもややこしい
②FRAME_RATEは元動画あればいいけど、リアルタイムの場合は必ずしも当初はわからない
③Falseの意味
※カメラの場合はret, frame = cap.read()の位置がWhileの外に置いて最初に諸所動画属性を指定してから、Whileに入っています。最後にその後を読込む仕様。

因みに、上記３つのアプリはまんま動きました。
ちょっと、合成したものをread_doga_save.py等としてこの記事の最下段に置きました。

###①保存形式のところがどうもややこしい
つまり、以下の二か所です。

①cv2.VideoWriter_fourcc(*'XVID')や
　fourcc = cv2.VideoWriter_fourcc(*'XVID')  #fourccを定義
　の引数の意味と
②out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))  #動画書込準備
　の各引数の意味ですね。特に第三引数。
ここで、①は答えは無理そうなので、とりあえず後に回して、②はcv2.VideoWriter()の引数見ればわかります。
ということで、[動画を扱う](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_gui/py_video_display/py_video_display.html)より以下の通りでした。

*動画ファイルとして保存するために VideoWriter 型のオブジェクトを生成します．第1引数は保存する動画名(例: output.avi)を指定します．第2~第4引数は FourCC コード(詳細は次の段落で説明)を指定し，動画の再生速度(fps)と解像度を設定します．最後の引数は isColor フラグを指定します．このフラグが True であればカラーの動画，そうでなければグレースケールの動画として保存されます．*

で、ここで①のFourCCが出てきます。
ここの説明を読むとだいたいわかるけど、やはり分からない。（何か理由はあるんだろが）
※直前の説明は「MJPG用のFourCC コードは cv2.VideoWriter_fourcc('M','J','P','G') もしくは cv2.VideoWriter_fourcc(*'MJPG) です．」なのに
例は、cv2.VideoWriter_fourcc(*'XVID')　.avi

ということで、例をたくさん見ることにしました。
そして、動かしながら、結果をみたところ、以下の二つが圧倒的に多く具合よさそうです。

```
ファイルは、.avi
cv2.VideoWriter_fourcc(*'XVID')
または、
 int fourcc   = cv::VideoWriter::fourcc('X', 'V', 'I', 'D');
※C++だけど、。。
# cv2.cv.CV_FOURCC
def cv_fourcc(c1, c2, c3, c4):
    return (ord(c1) & 255) + ((ord(c2) & 255) << 8) + \
        ((ord(c3) & 255) << 16) + ((ord(c4) & 255) << 24)
※上記関数付きで、以下のように使う
rec = cv2.VideoWriter(GAUSSIAN_FILE_NAME, \
                          cv_fourcc('X', 'V', 'I', 'D'), \
                          FRAME_RATE, \
                          (width, height), \
                          True)
```
【参考】
・[OpenCV / webcam / webcam.py](https://github.com/olympic2020/OpenCV/blob/master/webcam/webcam.py)
・[初めてのOpenCV開発 ― highgui／imgcodecs／videoioモジュール【OpenCV 3.1.0】](https://www.buildinsider.net/small/opencv/006)
![fourcc.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/e5e8b9ce-0c8c-f2f9-8277-c372a19c31bb.jpeg)
[初めてのOpenCV開発 ― highgui／imgcodecs／videoioモジュール【OpenCV 3.1.0】](https://www.buildinsider.net/small/opencv/006)より
【追記】cv_fourcc('M', 'P', '4', 'V')、
　　　　ファイル名：OUT_FILE_NAME = "real_SSD_result.mp4"で動きました。
    　　ファイルサイズちょっと減少：9,420(avi)⇒9,387KB(mp4)
###②FRAME_RATEは元動画あればいいけど、リアルタイムの場合は必ずしも当初はわからない
これは、どうもいい加減に設定しても大きいときは最大限のパフォーマンスで動くし、逆に小さな値の時は小さいなりに動作は遅くなるようです。
ということで、FRAME_RATE=30としました。
###③Falseの意味
これ調べれば簡単だけど、少しはまりました。(上の説明にもありますが。。)
だって、グレー画像は保存できるのにカラーというか、各処理したときできるものとできないことがあってほんと判じものでした。
が、調べればなーんだという感じです。
![VideoWriter.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/078d4ef8-e6a8-7be2-3170-3f977b5ff67a.jpeg)
ということで、isColor=Trueが大切です。
###そのほか
実は、調べていると面白い機能が盛りだくさんで、。。使いきれないので後日とします。
しかし、以下のものは直接画像処理できたので遊んでみました。

```
    cv2.imshow('frame',frame)
    cv2.imshow('gray',gray)
    cv2.imshow('hsv',hsv)
    cv2.imshow('mask',mask)
    cv2.imshow('res',res)
    cv2.imshow('gaussian',g_frame)
```
そして、たいしたことないけど、止めたいときなんかesp-keyやq-keyなど固定のKeyを押すようにしているPGが圧倒的だけど、以下のようにするとどれかのKeyを押せば止まるようになる。
って、案外大切かも。。。

```
 if cv2.waitKey(25) >= 0:
     break
```
###まとめ
【今回の目標】
・動画を加工して*任意の形式*で保存すること。
  >>gifアニメーションできるかな？？>できませんでした
でしたが、一応、OpenCVについて動画処理について基本的な知識を得ました。

ということで、次回はこれを使ってカメラ動画の物体検出をしてその結果を保存するのをやろうと思います。
【次回の目標】
・本来なら動画から物体検出してその結果を元動画に書き込んで保存
・カメラから入力した動画をリアルタイムで物体検出して、その結果を元動画に書き込んで保存

###参考出力
cv2.imshow('frame',frame)＞元動画
![frame_dougasozai_car.gif](https://qiita-image-store.s3.amazonaws.com/0/233744/1c5c5e71-1c09-9971-b4f9-f324f9c5f914.gif)
cv2.imshow('hsv',hsv)＞HSV色空間
![hsv_dougasozai_car.gif](https://qiita-image-store.s3.amazonaws.com/0/233744/e191c526-89ec-1f11-e8e0-356c3e86d22a.gif)
cv2.imshow('res',res)＞青のみを抽出
![res_dougasozai_car.gif](https://qiita-image-store.s3.amazonaws.com/0/233744/abbee285-3339-d7e1-1d34-2b29c2060a1a.gif)
。。。