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では複雑なループでプログラムを記述するのではなく、積極的に外部ライブラリを使うと、記述がシンプルで高速に動作するプログラムやアルゴリズムが書けるということである。
Pythonでプログラムを書く時、2次元のデータをforループで書くと非常に遅いが、Numpyのような行列やテンソルを扱うライブラリをimportして使うと、高速に動作するのは実行ベース(exe)で動作するためである。だから、Pythonでは複雑なループでプログラムを記述するのではなく、積極的に外部ライブラリを使うと、記述がシンプルで高速に動作するプログラムやアルゴリズムが書けるということである。
ではopencvを使って画像を読み込んで、新しいウィンドウを開いて表示して、's'キーを押すとファイルセーブ、'Esc'キーを押すと終了するプログラムを書いてみる。
-----
import numpy as np #Numpyをインポート
import cv2 as cv #opencvをインポート
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を閉じる
-----
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 カラー画像として読み込む
・
・
-1:IMREAD_UNCHANGED 元の画像フォーマットのまま読み込む
0 :IMREAD_GRAY_SCALE グレースールに変換して読み込む
1 :IMREAD_COOR カラー画像として読み込む
・
・
次にPCに付属しているカメラから動画を取り込み、表示してみる。
-----
import numpy as np
import cv2 as cv
-----
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0) #カメラをオープン
while(True):
ret, frame = cap.read() #画像を1枚frameに読み込む
ret, frame = cap.read() #画像を1枚frameに読み込む
cv.imshow('frame',frame) #画像を表示
if cv.waitKey(1) & 0xFF == ord('q'): #1msecキー入力待ち'q'で終了
break
if cv.waitKey(1) & 0xFF == ord('q'): #1msecキー入力待ち'q'で終了
break
cap.release() #入力openしたファイルをリリース(クローズ)
cv.destroyAllWindows() #すべてのWindowを閉じる
cv.destroyAllWindows() #すべてのWindowを閉じる
-----
では、mp4ファイルから動画を読み込み、aviファイルとして書き出す。
-----
import numpy as np
import cv2 as cv
-----
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を参照
# 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を閉じる
-----
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()
-----
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++で作成すると大変な作業である。