ソースに絡まるエスカルゴ

貧弱プログラマの外部記憶装置です。

【OpenCV】Webカメラから取得したキャプチャが過去のものになっている時の対処方法

 今回はタイトルにあるようにOpenCVで時々ある問題についての解決方法です。

 このタイトルにあるような現象は、例えばRaspberry PiなどでOpenCVを使ってWebカメラからの画像を取得するといった場合に起こることがあります。また1台のPCで大量にWebカメラの画像を取得する場合などにも発生しうるかと思います。

 解決方法と共に原因も合わせて説明していきます。


OpenCVWebカメラから取得したキャプチャが過去のものになっている時の対処方法
 ・原因1:電力不足
 対処方法は「電源付きUSBハブを使用する」というものです。

 例に出したRaspberry Pi本体のUSBコネクタからの給電でWebカメラを動かす場合、Raspberry Piからの電力供給でWebカメラが動くことになります。一般的にPCについているUSBケーブルは5V-0.5A程度の給電能力ですが、Raspberry Piの電源自体がせいぜい5V-3A程度なのでWebカメラにかなり電力を取られてしまってRaspberry Piの処理能力が低下し、結果OpenCVのキャプチャのバッファが溜まってしまうということから過去の画像取得になっているということのようです。

 ・原因2:バッファが溜まってしまっている
 対処方法は「バッファに溜まっているものを読み飛ばす」というものです。

import cv2

cap = cv2.VideoCapture(0)

while (True):
    ret, frame = cap.read()

    # 何か重い処理

    cv2.imshow("camera", frame)
    key = cv2.waitKey(1) & 0xff
    if key == 27:
        break

 上記のようなプログラムがあった場合、重い処理の部分で時間がかかってしまってVideoCaptureが保持しているバッファが溜まり続けてしまうことがあります。

 そのような場合は以下のようにバッファをまとめて読み飛ばす処理を追加します。

import cv2

cap = cv2.VideoCapture(0)

while (True):
    ret, frame = cap.read()

    # 何か重い処理

    cv2.imshow("camera", frame)


    ### 読み飛ばし処理を追加 ###
    for i in range (5) :
        img = cap.read()
    ### 読み飛ばし処理を追加ここまで ###

    key = cv2.waitKey(1) & 0xff
    if key == 27:
        break


 以上がWebカメラからのキャプチャが過去の画像になっている時の対処方法です。これで必ず解決するという訳ではありませんが、調べてもなかなか出てこない情報だったりするので、メモとして残しておいた次第です。


・参考文献