261.ラズパイ無双[8_VideoCapture]
初回:2022/6/15
Raspberry Pi (ラズベリーパイ、通称"ラズパイ")で何か作ってみようという新シリーズです。今回からは『openCV』関連のシステム作りに取り掛かりたいと思います。まずは、カメラ画像の取込と表示の基本パターンを作ってみます。
P子「まずは基礎からって事ね」※1
1.基本パターン
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import cv2 # openCV のimport
################################################
# 動作確認用のテストプログラムです。
def main():
cap = cv2.VideoCapture(0) # デバイス 0 からの画像読取
try:
while True :
ret,frame=cap.read() # 戻り値は、読取成否と画像
cv2.imshow('testCamera',frame) # 画面に画像を表示
k = cv2.waitKey(10) # キーボード入力待ち(10ms)
# これがないと、画像が表示されない
if k == ord('q') or k == 27: # q または、ESC で終了
break
except KeyboardInterrupt : # Ctl+Cが押されたらループを終了
print( "\nCtl+C Stop" )
except Exception as ex:
print( ex ) # 例外処理の内容をコンソールに表示
import traceback
traceback.print_exc() # Exception のトレース
finally :
if cap is not None : cap.release() # 動画やカメラデバイスを閉じる
cv2.destroyAllWindows() # すべてのウィンドウを閉じる
print( "終了" )
################################################
if __name__ == '__main__':
main()
コメントを入れていますので、解説は不要でしょう。
cv2.VideoCapture(0) の 0 は、デバイス番号で、ラズパイにUSBカメラを1台付けた場合は、大抵0番で構いません。2台、3台とつないだ場合は、この番号が変わります。
よく、1,2,3...と増えると言われていますが、私の環境では、2づつ(0,2,4...)という感じで増えましたので、そのあたりは色々試してみてください。
ちなみに、USBカメラとデバイス番号の関係は、固定ではなく、認識順の様です。これを自動設定できるスクリプト等もあるようですが、ラズパイのOSによって変化するみたいなので、一筋縄ではいかなさそうです。
2.動画ファイルの読取
動画ファイルを読み込む場合はVideoCapture()の引数に動画ファイルのパスを指定します。
例) cap = cv2.VideoCapture('sample_video.mp4')
動画ファイルのパスは、絶対パスでも相対パスでもOKです。動画の読取と、USBカメラからの入力を同じように扱えるというのは、非常に便利です。
≪一部抜粋≫
def main():
file = "output.avi"
cap = cv2.VideoCapture(file) # ファイルのアドレスを指定します。
cnt = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
try:
# while True : # ret でファイルの終了を判断する
for i in range(cnt) : # フレーム数だけループを回す
ret,frame=cap.read() # 戻り値は、読取成否と画像
# if not ret : # ファイルから読め無くなれば終了
# break
cv2.imshow('testCamera',frame) # 画面に画像を表示
k = cv2.waitKey(10) # キーボード入力待ち(10ms)
# これがないと、画像が表示されない
if k == ord('q') or k == 27: # q または、ESC で終了
break
・・・・
ファイルから読み取る場合は、カメラと異なり無制限ではありません。whileでループする場合は、cap.read()の戻り値で終了を判断します。
または、先にフレーム数を求めておき、forループで回す方法もあります。
3.静止画ファイルの読取
静止画を読み取る場合は、imread を使用します。
例) img = cv2.imread('Lenna.png')
Lenna.png というのは、画像処理の分野での標準画像と言われている画像です。
≪参考資料≫
https://ja.wikipedia.org/wiki/%E3%83%AC%E3%83%8A_(%E7%94%BB%E5%83%8F%E3%83%87%E3%83%BC%E3%82%BF)
レナ (画像データ)
出典: フリー百科事典『ウィキペディア(Wikipedia)』
4.静止画ファイルの書込み
読み取った画像を、openCV で色々と加工した後セーブしたいことがあると思います。まずは、静止画の保存方法からです。
例) cv2.imwrite('Lenna.jpeg', img)
先ほど読み取った『Lenna.png』を、jpeg形式で保存します。画像ファイルのフォーマットは、ファイルのパスの拡張子から自動的に決定されます。
≪一部抜粋≫
def main():
try:
img = cv2.imread('Lenna.png')
height, width, ch = img.shape # 画像の幅、高さ、チャネル
size = width * height # img.size の画素数(カラーの場合 3倍)
# 情報表示
print("幅:", width)
print("高さ:", height)
print("チャンネル数:", ch)
print("画素数:", size)
print("データ型:", img.dtype)
cv2.imshow('testCamera',img) # 画面に画像を表示
k = cv2.waitKey(0) # 0 で無制限に待つ
if k == ord('q') or k == 27: # q または、ESC で終了
return
cv2.imwrite('Lenna.jpeg', img) # 画像の書き出し
・・・・
# VideoCapture が未使用なので、cap.release() 不要
finally :
cv2.destroyAllWindows() # すべてのウィンドウを閉じる
print( "終了" )
≪参考資料≫
https://algorithm.joho.info/programming/python/opencv-image-width-height-channel-pixcels-py/
【Python/OpenCV】画像の高さ・幅・チャンネル数・画素数を調べる方法
5.動画ファイルの書込み
動画ファイルの生成は少し難しいです。というほどの事もありませんが、1行で済むというものではありません。
# 幅と高さとフレームレートを取得
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(cap.get(cv2.CAP_PROP_FPS))
fourcc = cv2.VideoWriter_fourcc(*'XVID')
writer = cv2.VideoWriter('output.avi',fourcc, fps, (w,h))
# # 'M','P','4','V' または、*'MP4V' を指定します。
# fourcc = cv2.VideoWriter_fourcc('M','P','4','V')
# writer = cv2.VideoWriter('output.mp4',fourcc, fps, (w,h))
try:
while True :
ret,frame=cap.read() # 戻り値は、読取成否と画像
writer.write(frame) # イメージを書き込む
cv2.imshow('testCamera',frame) # 画面に画像を表示
k = cv2.waitKey(10) # キーボード入力待ち(10ms)
# これがないと、画像が表示されない
if k == ord('q') or k == 27: # q または、ESC で終了
break
・・・・
# VideoWriter をオープンしているので、writer.release() が必要
finally :
if writer is not None : writer.release() # 動画やカメラデバイスを閉じる
if cap is not None : cap.release() # 動画やカメラデバイスを閉じる
cv2.destroyAllWindows() # すべてのウィンドウを閉じる
print( "終了" )
6.ストリーミングからの読取
ネットワーク・カメラなどのRTSP(Real Time Streaming Protocol)の映像を読み取る場合も簡単です。
例) rtsp = rtsp://user:password@ip:port/ipcam_h264.sdp
cap = cv2.VideoCapture(rtsp)
≪参考資料≫
https://www.roboticsware.com/dev-jp/faq/faq-96/
ネットワークカメラに接続するためのURL
httpプロトコルのストリーミングデータの受信も同様に簡単です。
例) url = http://192.168.X.X:port/stream
cap = cv2.VideoCapture(url)
httpプロトコルのストリーミングデータの生成(ストリーミングサーバー)については、このシリーズ内で作成しますので、お楽しみに。
7.YouTubeからの読取
YouTube の動画を読み取る場合は、追加のモジュールが必要です。
pafy は、Youtube動画のURLをVideoCaptureで受信できるURLに変換できます。見るだけなら、これだけで十分です。
youtube_dl は、YouTubeの動画をダウンロード・セーブできます。
$ pip install pafy
$ sudo pip install --upgrade youtube_dl
≪一部抜粋≫
import pafy
# キャプチャするYouTube動画のURLを設定します
url = "https://youtu.be/PaCyCcWseO4"
video = pafy.new(url)
best = video.getbest(preftype="mp4")
cap = cv2.VideoCapture(best.url)
≪参考資料≫
https://qiita.com/suo-takefumi/items/4c63399e39edecdcf323
YouTube動画をOpenCVでキャプチャするスクリプト
openCV で画像や動画を取り込むことができれば、各種画像処理を行うことができます。これは、本当にすごい事だと思います。
ほな、さいなら
======= <<注釈>>=======
※1 P子「まずは基礎からって事ね」
P子とは、私があこがれているツンデレPythonの仮想女性の心の声です。