2016-05-11 52 views
5

私はwebcam opencvとpythonから画像を取得しようとしています。コードは次のように基本的です:BeagleBone Black OpenCV Pythonが遅すぎる

import cv2 
import time 
cap=cv2.VideoCapture(0) 
cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH,640) 
cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT,480) 
cap.set(cv2.cv.CV_CAP_PROP_FPS, 20) 

a=30 
t=time.time() 
while (a>0): 
     now=time.time() 
     print now-t 
     t=now 
     ret,frame=cap.read() 
     #Some processes 
     print a,ret 
     print frame.shape 
     a=a-1 
     k=cv2.waitKey(20) 
     if k==27: 
       break 
cv2.destroyAllWindows() 

しかし、それはゆっくりと機能します。プログラムの出力:

VIDIOC_QUERYMENU: Invalid argument 
VIDIOC_QUERYMENU: Invalid argument 
VIDIOC_QUERYMENU: Invalid argument 
VIDIOC_QUERYMENU: Invalid argument 
VIDIOC_QUERYMENU: Invalid argument 
VIDIOC_QUERYMENU: Invalid argument 
HIGHGUI ERROR: V4L: Property <unknown property string>(5) not supported by device 
8.82148742676e-06 
select timeout 
30 True 
(480, 640, 3) 
2.10035800934 
select timeout 
29 True 
(480, 640, 3) 
2.06729602814 
select timeout 
28 True 
(480, 640, 3) 
2.07144904137 
select timeout 

構成:

  • BeagleboneブラックREVC
  • のDebian-wheezly
  • OpenCVの2.4
  • のpython 2.7
+1

それはおそらく助けにはなりませんが、あなたは実際のCVものを行うためにOpenCVのを使用している場合、あなたはおそらく、あなたが使用しているOpenCVのは、NEON拡張に対してコンパイルされていることを確認したいです。 (google opencv beaglebone neonを実行すると便利な詳細が見つかるでしょう。たとえば、http://blog.lemoneerlabs.com/3rdParty/Darling_BBB_30fps_DRAFT.html) – Foon

+0

"opencv 2.4" - より具体的にする必要があります。2.4 .xリリースのOpenCVは数年の間にリリースされました。 –

答えて

3

は私が上で働いていた同様の問題に遭遇しましたインテルEdisonプラットフォームでOpenCV 2.4.9を使用しているプロジェクト。何らかの処理をする前に、フレームグラブを実行するのにおよそ80msかかりました。 OpenCVのLinux用カメラキャプチャロジックは、少なくとも2.4.9リリースでは適切に実装されていないようだ。下位のドライバは1つのバッファしか使用しないため、アプリケーション層でマルチスレッドを使用して回避することはできません。次のフレームを取得するまで、V4L2ドライバの唯一のバッファはロックされます。

解決策は、OpenCVのVideoCaptureクラスを使用しないことです。ある時点で相当数のバッファを使用するように修正されたかもしれませんが、2.4.9以降はそうではありませんでした。実際、あなたが@Nickil Maveliが提供するリンクと同じ著者によるthisの記事を見ると、彼はラズベリーパイのFPSを改善する提案を出した時点で、OpenCVのVideoCaptureの使用をやめます。私はそれが偶然だとは思わない。

ここは、Intel Edisonフォーラムの投稿です:https://communities.intel.com/thread/58544です。

私は基本的にV4L2を使用してフレームグラブを処理するために自分のクラスを書くことを巻いた。そうすれば、循環バッファリストを提供し、フレームグラブとアプリケーションロジックを適切に分離することができます。これはC++アプリケーションではC++で行われました。上記のリンクが約束を果たしているとすれば、はるかに簡単なアプローチかもしれません。 BeagleBoneで動作するかどうかは分かりませんが、PiCameraに似たものがあるかもしれません。がんばろう。

編集:私はOpenCVの2.4.11のソースコードを見てきました。今は4つのバッファを使用するようになっているようですが、V4L2を使用してそれを利用する必要があります。エラーメッセージHIGHGUI ERROR: V4L: Property...をよく見ると、V4LではなくV4Lを参照していることがわかります。これは、使用しているOpenCVのビルドが古いV4Lドライバに戻っていることを意味します。パフォーマンス上の問題を引き起こす特異バッファーに加えて、独自の多くの制限とパフォーマンス上の問題があるかもしれない古代のドライバーを使用しています。

OpenCVをビルドして、V4L2を使用していることを確認することをお勧めします。 OpenCVの設定プロセスは、V4L2ドライバがマシンにインストールされているかどうかをチェックし、それに応じてビルドするかどうかをチェックするので、OpenCVをビルドするマシンにV4L2および関連するすべての開発パッケージがインストールされていることを確認します。

+0

バッファはハードウェアメモリにあります(私の経験から)。 – user5698387

3

"秘密"取得するまでOpenCVでビデオストリームを処理する場合のI/O(すなわち、カメラセンサからのフレームの読み取り)を別のスレッドに移すことである。 cv2.VideoCapture機能と共にread()メソッドを呼び出すとき、それは次の(Blocking Process)に移動するため、各I/O動作が完了することを待たなければならないよう

、それは全体のプロセスは非常に遅くなります。

このFPSの増加/レイテンシの減少を達成するために、私たちの目標は、ウェブカメラまたはUSBデバイスからのフレームの読み取りを、メインのPythonスクリプトとは完全に別のスレッドに移動することです。

これにより、私たちのルートスレッドが現在のフレームを処理している間に、I/Oスレッドからフレームを連続的に読み取ることができます。ルートスレッドがフレームの処理を終了すると、現在のフレームをI/Oスレッドから取得するだけで済みます。これは、I/O操作をブロックするのを待たずに実行されます。

Increasing webcam FPS with Python and OpenCVを読むと、スレッドを実装する手順を知ることができます。私たちのコメントで議論を踏まえ


EDIT

は、私は次のようにコードを書き換えることができ感じる:

import cv2 

cv2.namedWindow("output") 
cap = cv2.VideoCapture(0) 

if cap.isOpened():    # Getting the first frame 
    ret, frame = cap.read() 
else: 
    ret = False 

while ret: 
    cv2.imshow("output", frame) 
    ret, frame = cap.read() 
    key = cv2.waitKey(20) 
    if key == 27:     # exit on Escape key 
     break 
cv2.destroyWindow("output") 
+0

私は同じことをしましたが、pythonとopencvはまだ遅すぎます – acs

+0

カメラのfpsを 'cap.set(cv2.cv.CV_CAP_PROP_FPS、30)'に設定し、その結果を見てください。 –

+0

まだ同じです。質問に編集 – acs

1

これを試してみてください!私はcap.set()セクションのいくつかのコードを置き換えました

import cv2 
import time 
cap=cv2.VideoCapture(0) 
cap.set(3,640) 
cap.set(4,480) 
cap.set(5, 20) 

a=30 
t=time.time() 
while (a>0): 
     now=time.time() 
     print now-t 
     t=now 
     ret,frame=cap.read() 
     #Some processes 
     print a,ret 
     print frame.shape 
     a=a-1 
     k=cv2.waitKey(20) 
     if k==27: 
       break 
cv2.destroyAllWindows() 

出力(PCウェブカメラ)コードが間違っていました。この問題については

>>0.0 
>>30 True 
>>(480, 640, 3) 
>>0.246999979019 
>>29 True 
>>(480, 640, 3) 
>>0.0249998569489 
>>28 True 
>>(480, 640, 3) 
>>0.0280001163483 
>>27 True 
>>(480, 640, 3) 
>>0.0320000648499 
+0

元の 'cap.set'関数呼び出しは正常でした。 @acs定数は、手動で指定した値と同じ値に評価されます。これはパフォーマンス問題の原因ではありません。 – Aenimated1

関連する問題