ラズパイ

ラズベリーパイでOpenCVを使い録画保存して再生すると倍速再生、スロー再生となる原因と対策

ラズベリーパイでOpenCVを使い録画保存して再生すると倍速再生、スロー再生となる原因と対策

ラズベリーパイを使い、

カメラ映像を保存するには、

画像処理ライブラリ『OpenCV』を

使うと動画保存が簡単に

プログラミングできます。

 

この時、注意することがあります。

録画時間と再生時間が合わない症状が

でることがあります。

ここでは、録画時間と再生時間が

合わない時の対処法を紹介します。

 

なにが原因ですか?

OpenCVを使い撮影した動画を

保存します。

保存した動画を再生すると

撮影した時間と再生時間が

あわない症状がでました。

 

倍速再生、またはスロー再生に

なることがあります。

 

【起きた現象】

10秒の動画撮影して、

その動画を再生すると、

2秒で再生され動画が終わります。

 

このような倍速再生の現象がでた場合、

どのような対処法があるか

考えられる原因を

順番に確認していきます。

 

カメラのFPS設定は良いか

使用するカメラ性能により、

使用できる

最大フレームレート【FPS】が

違います。

 

使用するカメラの使用できる

最大フレームレートを確認します。

 

使用カメラ:ロジクール C270

最大フレームレート:30fps

画素数:120万画素

 

 

FPSは、1秒間あたりに表示される

画像(フレーム)数で

動画再生の滑らかさに影響されます。

自分で録画したい

FPSの値を設定します。

 

FPSの設定が正常に行われているかを

確認します。

・FPSの設定値の登録

・設定されたFPSが登録されているか確認する

 

確認する方法は、

次のプログラムで確認できます。

fmt = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')     #MP4形式指定
fps = 30                                             #フレーム指定
size = (640, 480)                                    #画像サイズ   

# 指定した大きさにリサイズする。
frame = cv2.resize(frame, (size))     #保存形式指定のフレーム   
cv2.imshow("frame", frame)            #カメラ映像をウインドウ表示
print(cap.get(cv2.CAP_PROP_FPS))      #FPS チェック

 

フレームレート設定(FPS)をします。

cv2.resize()

 

設定したフレームレート(FPS)を

確認します。

print(cap.get(cv2.CAP_PROP_FPS))

 

登録されているフレーム(FPS)を

確認して次に進みます。

 

OpenCVの動画再生

カメラから映像はリアルタイムに

入ってきます。

OpenCVは、read()で

新しい映像が読み込まれ、

imshow()で映像表示します。

 

rem, frame = cap.read()       #画像読み込み
cv2.imshow('frame', frame)    #frameに表示

 

カメラ映像を保存してみます。

カメラ映像を保存する

サンプルプログラムの使い方は

次の通りです。

・キー入力『r』で録画開始

・キー入力『q』で録画停止

・キー入力『ENTER』で終了

 

カメラ映像を保存する

サンプルプログラム

import cv2
import sys
import numpy as np
import os

#VideoCapture
cap = cv2.VideoCapture(0)

#動画保存形式
fmt = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')     #MP4形式指定
fps = 30                                             #フレーム指定
size = (640, 480)                                    #画像サイズ   

while(True):

#カメラ正常確認      
    ret, frame = cap.read()    
    if not ret:
        print("映像取得失敗")
        break
        
#画面表示
    frame = cv2.resize(frame, (size))     #保存形式指定のフレーム   
    cv2.imshow("frame", frame)            #カメラ映像出力/取得した映像をウインドウに表示

#キーボード入力受付
    key = cv2.waitKey(1)

    if key == 13:                         #enter keyで終了
        inkey = 0
        print("録画終了")
        break
    
    if key == 114:                        #'r'keyで録画開始 
        inkey = 1                         #録画開始
        print("●Rec")     
        writer = cv2.VideoWriter(movie.mp4', fmt, fps, size)
        
#映像保存
    if inkey == 1:
        #print("●Rec")
        _, frame = cap.read()              #映像読込
        frame = cv2.resize(frame, size)
        writer.write(frame)                #映像保存処理
        cv2.imshow('frame', frame)         #映像表示      
        
#終了処理
writer.release()                           #映像書込終了
cap.release()                              #カメラデバイスクローズ
cv2.destroyAllWindows()                    #カメラウィンドウクローズ
print("正常終了")
 

 

このプログラムを使用すると、

10秒録画して動画を再生すると

5秒の倍速再生する症状現象になります。

(動作環境により再生速度が

変化することがあります)

 

保存した動画再生する場合、

フレームレートの値が30FPSの場合

1フレームあたり1/30秒です。

read()からwriter.write()までの処理を

FPSの処理以下にする必要があります。

 

OpenCVを使用すると、

動画はread() で読み込んだ画像を

imshow()で表示します。

 

read() ~ imshow() の間に

何も処理がなければ問題ありません。

 

サンプルプログラムでは、

キーボード入力受付処理や

他の条件分岐処理など、

様々な処理がされているため

それが遅延につながります。

 

キーボード入力受付処理に使う

waitkey()では、

waitkey() キー入力処理を

プログラムに入れ込むと

 

waitkey(1)としているため

処理時間は1msとなりますが

waitkey()の処理には注意が必要です。

 

公式でもあるように

waitkey()による処理時間は不確定ため

実際の処理時間は、

もっと時間がかかっているため

考慮する必要があります。

 

30FPSの動画保存したファイルを

waitkey(1)とした時、

2倍速で再生される場合があるので

注意が必要です。

 

倍速再生の対処法

保存した動画再生する場合、

30FPSが、

1フレームあたり1/30秒です。

read()からwriter.write()までの処理を

FPSの処理以下にする必要があります。

 

今回の場合は、

FPSの処理以下になっていないため

FPSを下げることで対処できます。

 

FPS設定値

FPS:15

 

FPS:15に設定することで

正常な再生時間になります。

 

FPSをもっと良くしたい場合は

必要のない処理、print()など

不要な処理をなくし

プログラムをシンプルにすることで

対処することができます。