2016-11-21 34 views
0

私はOpenCV C++と2つのウェブカメラを使用してライブステレオビジョンセットアップをしようとしています。 2つのウェブカメラからフレームを別々に取得することは可能です。しかし、私はスレッドで同時にそれらにアクセスしようとすると、私はランタイムエラーを取得:次のように'メモリを割り当てることができません' - OpenCV複数のウェブカメラストリーム

VIDIOC_STREAMON: Cannot allocate memory 
OpenCV Error: Assertion failed (size.width>0 && size.height>0) in imshow, file /home/lorre851/Downloads/opencv-3.1.0/modules/highgui/src/window.cpp, line 281 
terminate called after throwing an instance of 'cv::Exception' 
    what(): /home/lorre851/Downloads/opencv-3.1.0/modules/highgui/src/window.cpp:281: error: (-215) size.width>0 && size.height>0 in function imshow 

私のコードは次のとおりです。

#include <iostream> 
#include <thread> 
#include "opencv2/opencv.hpp" 

using namespace std; 
using namespace cv; 

void stream(int camera) { 
    VideoCapture cap(camera); // open the default camera 
    if(cap.isOpened()) { // check if we succeeded 
     while(true) { 
      Mat frame; 
      cap >> frame; // get a new frame from camera 
      imshow("Stream " + to_string(camera), frame); 
      if (waitKey(30) >= 0) break; 
     } 
    } 
} 

int main() { 
    thread cam1 (stream, 1); 
    thread cam2 (stream, 2); 


    cam1.join(); 
    cam2.join(); 

    return 0; 
} 

誰もがこれを引き起こしている可能性がどのような任意のアイデアを得ましたか。私はUbuntu 15.10 LTEでCLionを使用しています。

UPDATE 1:私は内蔵されているので、カメラ私のラップトップに(0)カメラのためのインデックス1と2を使用して2つのUSBカメラの(1および2)に接続したUSBカメラのですよ。ターゲットハードウェアはここにあります。

UPDATE 2:は、両方のカメラを置くことは1つのスレッドでフィード(以下のコードを参照してください)(そうしないと、エラー「デバイス上に残されたSPACE」を取得していないだろう、あなたのUSBポートは、別のバスを使用すると仮定すると)うまく動作しますが、 2つのフレーム間の遅延が目立ち、ステレオビジョンセットアップには理想的ではありません。

cv::VideoCapture camera0(0); 
cv::VideoCapture camera1(1); 

if(!camera0.isOpened()) return 1; 
if(!camera1.isOpened()) return 1; 
cv::Mat3b frame0; 
cv::Mat3b frame1; 

while(true) { 
    camera0 >> frame0; 
    camera1 >> frame1; 
    if(mat_is_empty(frame0)) cout << "SKIPPED FRAME IN 0"; 
    else cv::imshow("Stream 0", frame0); 

    if(mat_is_empty(frame1)) cout << "SKIPPED FRAME IN 1"; 
    else cv::imshow("Stream 1", frame1); 

    int c = cvWaitKey(40); 

    //exit the loop if user press "Esc" key (ASCII value of "Esc" is 27) 
    if(27 == char(c)) break; 
} 
+0

あなたは別に言いますが、あなたは1つのスレッド 'を試しましたが、while(1){cap1 >> frame1; cap2 >> frame2; /// ... 'あなたのカメラに「共同で」アクセスしますか?あなたのエラーは割り当てではなく、空の 'cv :: Mat'です。 USBがその速度(33Hz)で配信できないことがあります。 – mainactual

+0

それは働いているようです。しかし、フレームをキャプチャするまでの遅延時間が目立つので、ステレオビジョンの設定にこのアプローチを使用できるかどうかはわかりません。しかし、チップのおかげで、私は 'Can not allocate memory'の問題を常に見つめていました... OpenCVソースを掘り下げたり、何か他のものを一緒に書き込んで両方のカメラを同時に動かすことができます。 –

+0

'cv :: VideoCapture :: grab' + retrieveは価値のある代用品ですが、http://stackoverflow.com/questions/30286144/c-opencv-image-not-display-inside-the-boost-スレッド – mainactual

答えて

0

多分、私は愚かな答えがあります。あなたのコードは、ゼロから..

enter image description here

カウントカメラを正常に動作します。

thread cam1 (stream, 0); THIS works 
// thread cam2 (stream, 1); I dont have second camera 

まず、私はWindowsマシンです。私のカメラは0,1,2から数えます 私は2番目のWebカメラを持っていません。

私はちょうどあなたのコードを使用して、私のウェブカメラ と私はテストrtspストリームを使用して私のウェブカメラ(0)を貼り付けます。

#include <iostream> 
#include <thread> 
#include "opencv2/opencv.hpp" 

using namespace std; 
using namespace cv; 

void stream(int camera) { 
    VideoCapture cap; 
    if (camera == 0) { 
     cap.open(0); // open the default camera 
    } 
    if (camera == 1) { 
     cap.open("rtsp://mpv.cdn3.bigCDN.com:554/bigCDN/definst/mp4:bigbuckbunnyiphone_400.mp4"); // open the default camera 
    } 



if (cap.isOpened()) { // check if we succeeded 
     while (true) { 
      Mat frame; 
      cap >> frame; // get a new frame from camera 
      imshow("Stream " + to_string(camera), frame); 
      if (waitKey(30) >= 0) break; 
     } 
    } 
} 

int main() { 
    thread cam1(stream, 0); 
    thread cam2(stream, 1); 


    cam1.join(); 
    cam2.join(); 

    return 0; 
} 
+0

これは動作します。したがって、少なくともスレッドが正しく動作していることを確認できます(cmakeファイルにリンクさせるのは苦痛でした)。問題は、2つの物理的なキャプチャデバイスを直接開こうとすると発生し続けます。 Sidenote、ノートパソコンとUSB Logitechの2つのWebカメラにカメラが内蔵されているので、1と2をインデックスとして使用しています(私の記事でこれを更新します)。 –

+0

そのうちの1つだけを試してみたら?あなたは何とかキャプチャすることができますか? – globalex

+0

はい、問題なく別々に動作します –

関連する問題