OpenCV ビデオ処理
ビデオは一連の連続した画像フレームで構成され、各フレームは静止画像です。
ビデオ処理の核心は、これらの画像フレームを処理することです。一般的なビデオ処理タスクには、ビデオの読み取り、ビデオの再生、ビデオの保存、ビデオフレームの処理などがあります。
ビデオ処理の応用
- ビデオ分析: ビデオ処理技術を使用して、ビデオ内の動き、オブジェクト、イベントなどを分析できます。
- ビデオ強調: ビデオにノイズ除去、強調、安定化などの処理を施し、ビデオ品質を向上させます。
- ビデオ編集: ビデオのカット、結合、エフェクト追加などの操作を行います。
- リアルタイム監視: カメラでシーンをリアルタイムに監視し、オブジェクト検出、行動分析などを行います。
OpenCV は提供しますcv2.VideoCaptureとcv2.VideoWriter2つのクラスは、それぞれビデオの読み取りと書き込みに使用されます。さらに、OpenCV はビデオフレームにさまざまな操作を実行できる豊富な画像処理関数も提供しています。
ビデオの読み取りと再生
ビデオファイルの読み取り
ビデオファイルを読み取るには、まず VideoCapture を作成し、cv2.VideoCaptureそのオブジェクトにビデオファイルのパスを指定します。
例
# VideoCapture オブジェクトを作成し、ビデオファイルを読み取る
cap = cv2.VideoCapture('example.mp4')
# ビデオが正常に開かれたか確認する
if not cap.isOpened():
print("Error: Could not open video.")
exit()
# ビデオフレームを読み取る
while True:
ret, frame = cap.read()
# 最後のフレームを読み取ったら、ループを終了する
if not ret:
break
# 現在のフレームを表示する
cv2.imshow('Video', frame)
# 'q' キーを押して終了する
if cv2.waitKey(25) & 0xFF == ord('q'):
break
# リソースを解放する
cap.release()
cv2.destroyAllWindows()
カメラビデオの読み取り
ビデオファイルの読み取りに加えて、OpenCV はカメラから直接ビデオを読み取ることもできます。その場合は、cv2.VideoCaptureのパラメータをカメラのインデックス(通常は0)に設定するだけです。
例
# VideoCapture オブジェクトを作成し、カメラビデオを読み取る
cap = cv2.VideoCapture(0)
# カメラが正常に開かれたか確認する
if not cap.isOpened():
print("Error: Could not open camera.")
exit()
# ビデオフレームを読み取る
while True:
ret, frame = cap.read()
# 最後のフレームを読み取ったら、ループを終了する
if not ret:
break
# 現在のフレームを表示する
cv2.imshow('Camera', frame)
# 'q' キーを押して終了する
if cv2.waitKey(25) & 0xFF == ord('q'):
break
# リソースを解放する
cap.release()
cv2.destroyAllWindows()
ビデオフレーム処理
フレームの基本操作
ビデオフレームを読み取った後、各フレームにさまざまな画像処理操作を実行できます。
例えば、フレームをグレースケール画像に変換できます:
例
cap = cv2.VideoCapture('example.mp4')
while True:
ret, frame = cap.read()
if not ret:
break
# フレームをグレースケール画像に変換する
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# グレースケールフレームを表示する
cv2.imshow('Gray Video', gray_frame)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
フレームの保存
ビデオフレームを処理する際、処理後のフレームを新しいビデオファイルとして保存する必要がある場合があります。
使用できますcv2.VideoWriterクラスを使用して実現します:
例
cap = cv2.VideoCapture('example.mp4')
# ビデオのフレームレートとサイズを取得する
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# VideoWriter オブジェクトを作成し、処理後のビデオを保存する
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, fps, (width, height))
while True:
ret, frame = cap.read()
if not ret:
break
# フレームをグレースケール画像に変換する
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# グレースケールフレームを出力ビデオに書き込む
out.write(cv2.cvtColor(gray_frame, cv2.COLOR_GRAY2BGR))
# グレースケールフレームを表示する
cv2.imshow('Gray Video', gray_frame)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
ビデオ処理の高度な応用
ビデオ内の物体検出
OpenCV は、Haar 特徴分類器、HOG + SVM など、さまざまな物体検出アルゴリズムを提供しています。
以下は、Haar 特徴分類器を使用した顔検出の例です:
例
# Haar 特徴分類器を読み込む
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture('example.mp4')
while True:
ret, frame = cap.read()
if not ret:
break
# フレームをグレースケール画像に変換する
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 顔を検出する
faces = face_cascade.detectMultiScale(gray_frame, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
# フレーム上に矩形を描画して顔をマークする
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
# 顔マーク付きのフレームを表示する
cv2.imshow('Face Detection', frame)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
ビデオ内の動体検出
動体検出はビデオ処理における重要な応用の1つです。フレーム間の差分を計算することで動く物体を検出できます。
以下は、簡単な動体検出の例です:
例
cap = cv2.VideoCapture('example.mp4')
# 最初のフレームを読み取る
ret, prev_frame = cap.read()
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
while True:
ret, frame = cap.read()
if not ret:
break
# 現在のフレームをグレースケール画像に変換する
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 現在のフレームと前のフレームの差分を計算する
frame_diff = cv2.absdiff(prev_gray, gray_frame)
# 差分画像に二値化処理を施す
_, thresh = cv2.threshold(frame_diff, 30, 255, cv2.THRESH_BINARY)
# 動体検出結果を表示する
cv2.imshow('Motion Detection', thresh)
# 前のフレームを更新する
prev_gray = gray_frame
if cv2.waitKey(25) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
よく使う関数
| 機能 | 関数/メソッド | 説明 |
|---|---|---|
| ビデオの読み取り | cv2.VideoCapture() | ビデオファイルまたはカメラを読み取ります。 |
| フレームごとにビデオを読み取る | cap.read() | フレームごとにビデオを読み取ります。 |
| ビデオ属性の取得 | cap.get(propId) | ビデオの属性(幅、高さ、フレームレートなど)を取得します。 |
| ビデオの保存 | cv2.VideoWriter() | ビデオ書き込みオブジェクトを作成し、ビデオを保存します。 |
| ビデオフレーム処理 | 画像処理関数(例:cv2.cvtColor()) | ビデオフレームに画像処理を施します。 |
| オブジェクト追跡 | cv2.TrackerKCF_create() | オブジェクト追跡アルゴリズムを使用して、ビデオ内の物体を追跡します。 |
| 動体検出 | cv2.createBackgroundSubtractorMOG2() | 背景差分アルゴリズムを使用して、ビデオ内の動く物体を検出します。 |
cv2.VideoCapture
定義:cv2.VideoCaptureビデオファイルまたはカメラからビデオフレームをキャプチャするために使用されます。
構文:
cv2.VideoCapture(source)
パラメータの説明:
source: ビデオファイルのパスまたはカメラのインデックス(通常は0でデフォルトのカメラを表します)。
例
# デフォルトのカメラを開く
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
cv2.imshow('Frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
cv2.VideoWriter
定義:cv2.VideoWriterビデオフレームをビデオファイルに書き込むために使用されます。
構文:
cv2.VideoWriter(filename, fourcc, fps, frameSize)
パラメータの説明:
filename: 出力ビデオファイル名。fourcc: ビデオコーデック(例:cv2.VideoWriter_fourcc(*'XVID'))。fps: フレームレート。frameSize: フレームサイズ(幅、高さ)。
例
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
out.write(frame)
cv2.imshow('Frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
cv2.cvtColor
定義:cv2.cvtColor画像をある色空間から別の色空間に変換するために使用されます。
構文:
cv2.cvtColor(src, code)
パラメータの説明:
src: 入力画像。code: 色空間変換コード(例:cv2.COLOR_BGR2GRAY)。
例
img = cv2.imread('image.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('Gray Image', gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.resize
定義:cv2.resize画像のサイズを調整するために使用されます。
構文:
cv2.resize(src, dsize)
パラメータの説明:
src: 入力画像。dsize: 出力画像サイズ(幅、高さ)。
例
img = cv2.imread('image.jpg')
resized = cv2.resize(img, (320, 240))
cv2.imshow('Resized Image', resized)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.Canny
定義:cv2.Cannyエッジ検出に使用されます。
構文:
cv2.Canny(image, threshold1, threshold2)
パラメータの説明:
image: 入力画像。threshold1: 1つ目のしきい値。threshold2: 2つ目のしきい値。
例
img = cv2.imread('image.jpg', 0)
edges = cv2.Canny(img, 100, 200)
cv2.imshow('Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.findContours
定義:cv2.findContours画像内の輪郭を検出するために使用されます。
構文:
cv2.findContours(image, mode, method)
パラメータの説明:
image: 入力画像。mode: 輪郭検索モード(例:cv2.RETR_TREE)。method: 輪郭近似手法(例:cv2.CHAIN_APPROX_SIMPLE)。
例
img = cv2.imread('image.jpg', 0)
contours, _ = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, contours, -1, (0, 255, 0), 3)
cv2.imshow('Contours', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.drawContours
定義:cv2.drawContours画像内の輪郭を描画するために使用されます。
構文:
cv2.drawContours(image, contours, contourIdx, color, thickness)
パラメータの説明:
image: 入力画像。contours: 輪郭リスト。contourIdx: 輪郭インデックス(-1はすべての輪郭を描画することを示します)。color: 輪郭の色。thickness: 輪郭の線幅。
例
img = cv2.imread('image.jpg', 0)
contours, _ = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, contours, -1, (0, 255, 0), 3)
cv2.imshow('Contours', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.putText
定義:cv2.putText画像上にテキストを描画するために使用されます。
構文:
cv2.putText(image, text, org, fontFace, fontScale, color, thickness)
パラメータの説明:
image: 入力画像。text: 描画するテキスト。org: テキストの左下隅の座標。fontFace: フォントタイプ(例:cv2.FONT_HERSHEY_SIMPLEX)。fontScale: フォントの拡大縮小率。color: テキストの色。thickness: テキストの線幅。
例
img = cv2.imread('image.jpg')
cv2.putText(img, 'Hello, OpenCV!', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
cv2.imshow('Text', img)
cv2.waitKey(0)
cv2.destroyAllWindows()