Pythonで自分用のAIを作ろう6-opencvを使ってみる1 | グラ山ギターのブログ

グラ山ギターのブログ

毎週健康のために山登りをしています。低い山ばかりですが播磨の山々は岩山が多く景観がすばらしい所が多いです。山頂などで演奏しています。 井上陽水のカバーが多いです。
暑い時期は山登りは控えています。

テーマ:

Pythonの外部ライブラリとして、画像や動画を処理するopencv(オープンソース コンピュータ ビジョン ライブラリ)というものがあり、誰でも無償で使え最新の画像・動画処理アルゴリズムを使うことができる。
フィルタ―処理から特徴点認識や画像認識に至るまで広範囲の関数を利用することができ、またPythonで記述すると数行ですごいことができてしまう。

https://www.buildinsider.net/small/opencv/001 を参照

https://docs.opencv.org/master/d6/d00/tutorial_py_root.html

をアクセスすると、Pythonでのopencvの使用例がチュートリアルという形で、色々と紹介されている。

OpenCVは、元々はCまたはC++のコンピュータビジョンライブラリの面を充実させていましたが、javaやPythonもサポートするように拡張されてきました。Cythonを使えば、C++で記述したライブラリやクラスをPythonの実行ベースのライブラリに変換してくれるので、インタープリタ言語であるPythonの遅さを全く感じさせない。
Pythonでプログラムを書く時、2次元のデータをforループで書くと非常に遅いが、Numpyのような行列やテンソルを扱うライブラリをimportして使うと、高速に動作するのは実行ベース(exe)で動作するためである。だから、Pythonでは複雑なループでプログラムを記述するのではなく、積極的に外部ライブラリを使うと、記述がシンプルで高速に動作するプログラムやアルゴリズムが書けるということである。
ではopencvを使って画像を読み込んで、新しいウィンドウを開いて表示して、's'キーを押すとファイルセーブ、'Esc'キーを押すと終了するプログラムを書いてみる。
-----
import numpy as np #Numpyをインポート
import cv2 as cv #opencvをインポート
img = cv.imread('flower.jpg',1) #flower.jpgをカラー画像としてimgに読み込む
cv.imshow('image',img)  #新しいWindowに'image'という名前を付けて、imgを表示する
k = cv.waitKey(0)  #何かキーが押されるのを待つ、kにはASCIIコードが返される
if k == 27:           # wait for ESC key to exit
    cv.destroyAllWindows() #Windowを閉じる
elif k == ord('s'):   # wait for 's' key to save and exit
    cv.imwrite('grayflower.png',img) #imgをpngファイルとして書き込む
    cv.destroyAllWindows()  #Windowを閉じる
-----
imreadの2個めのパラメータは、
-1:IMREAD_UNCHANGED 元の画像フォーマットのまま読み込む
0 :IMREAD_GRAY_SCALE グレースールに変換して読み込む
1 :IMREAD_COOR  カラー画像として読み込む

次にPCに付属しているカメラから動画を取り込み、表示してみる。
-----
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)    #カメラをオープン
while(True):
    ret, frame = cap.read()    #画像を1枚frameに読み込む
    cv.imshow('frame',frame)    #画像を表示
    if cv.waitKey(1) & 0xFF == ord('q'):  #1msecキー入力待ち'q'で終了
        break
cap.release()                  #入力openしたファイルをリリース(クローズ)
cv.destroyAllWindows()    #すべてのWindowを閉じる
-----
 
では、mp4ファイルから動画を読み込み、aviファイルとして書き出す。
-----
import numpy as np
import cv2 as cv
cap = cv.VideoCapture('vtest.mp4') #vtest.mp4をオープン
#ビデオ圧縮形式を指定 4文字の記号と圧縮フォーマットの関係は、
# ffmpeg.org/doxygen/trunk/raw_8c_source.html#l00136を参照
fourcc = cv.VideoWriter_fourcc(*'XVID')
#書込みファイル名を'output.avu'にして'XVID'のフォーマットで20fps,640x480に設定
out = cv.VideoWriter('output.avi',fourcc, 20.0, (640,480))
while(cap.isOpened()):  #vtest.mp4がopenの間
    ret, frame = cap.read() #画像を一枚読み込む
    if ret==True:  #読み込みOKなら
        out.write(frame) #frame画像を1フレーム書込み
        cv.imshow('frame',frame) #Windowに表示
        if cv.waitKey(1) & 0xFF == ord('q'): #1msecキー入力待ち'q'で終了
            break
    else:
        break
# Release everything if job is finished
cap.release()   #入力openしたファイルをリリース(クローズ)
out.release()   #出力openしたファイルをリリース(クローズ)
cv.destroyAllWindows()  #全てのwindowを閉じる
-----

mp4ファイルを読み込み、リアルタイムにエッジ抽出をしてみよう。
-----
import numpy as np
import cv2 as cv
cap = cv.VideoCapture('水中映像.mp4') #水中映像.mp4をオープン
while(1):
    ret, frame = cap.read() #画像を一枚frameに読み込む
    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) #グレイスケールに変換
    edges = cv.Canny(gray,25,50) #Cannyエッジ抽出
    cv.imshow('frame',frame) #原画を表示
    cv.imshow('edge',edges) #エッジ画像を表示
    k = cv.waitKey(5) & 0xFF #5msecキー入力待ち
    if k == 27:   #Escキーなら終了
        break
cap.release()
cv.destroyAllWindows()
-----
このように数行のプログラム記述でこんなことができてしまう。
javaやc/c++で作成すると大変な作業である。