2012-07-03 122 views
6

我試圖從IP攝像頭實時捕捉圖像。這個流在VLC中運行得非常好,但是OpenCV的cvQueryFrame()似乎混亂和腐敗了傳入的圖像,以至於無法識別。OpenCV/FFMpeg圖像捕捉問題

同樣,從文件捕獲工作正常,但不是直播流。如果它有所作爲,我使用rtsp連接URL;我也嘗試過兩種不同的相機型號(不同品牌),問題依然存在。

此外,(我假設)編解碼器正在輸出以下幾種錯誤: Error at MB: 1746concealing 6000 DC, 6000 AC, 6000 MV errors

我該怎麼辦?

更新:序列中的第一個錯誤是總是cannot parallelize deblocking type 1, decoding such frames in sequential order

更新2:好吧,似乎OpenCV的/ FFmpeg中有RTSP/H264流的問題。我試過了Qt Phonon庫,這也不起作用,並且我已經給出了一個快速概覽庫。這個最後一個看起來很有效,因爲大家都說它的確如此,而應用程序示例(OpenRTSP)實際上可以很好地發揮我的流。然而,說實話,處理Live555代碼看起來像是一件漫長的事情,我現在幾乎無法承受。除了其他選擇,我想我必須走這條路。

是否還有其他解決方案?

更新3:我從LIVE555代碼工作的測試RTSP客戶端,所以我知道如何提取從流H264幀信息,但現在我需要重組該幀信息轉化爲實際顯示的幀,這似乎並不像直截了當!熟悉Live555的人都知道如何做到這一點?謝謝。

+0

你使用的是什麼版本的OpenCV?在Linux或Windows上? – Mohammad

+0

Win 7上的OpenCV 2.3.1。 –

+0

'cvQueryFrame()'可能會返回NULL圖像。一定要在做這件事之前測試一下。 – karlphillip

回答

2

轉碼從VLC流看來你需要一個額外的軟件層捕獲流包並在本地重建幀,然後將它們饋送到openCV。您可以使用libVLC輕鬆實現此目的。這也可以避免編解碼器問題,因爲您可以使用libVLC解析幾乎所有的編解碼器,然後將原始幀提供給openCV。

+0

就是這樣。 libVLC工作正常。非常感謝! –

+2

我正在處理類似的問題。您可以請張貼代碼從libVLC提供原始幀到openCV嗎? – Sergiy

1

這是我用來從WebCam捕獲幀的代碼片段。它的工作對我來說,希望它爲你的作品,以及...

int main(int argc, char* argv[]) 
{ 
    CvCapture *capture = NULL; 
    IplImage* frame=NULL; 
    int key =0; 
    capture = cvCaptureFromCAM(0); 

    if (!capture) { 
     printf("Cannot initailize webcam"); 
     return 1; 
    } 

    cvNamedWindow("result",CV_WINDOW_AUTOSIZE); 

    while(key != 'q') 
    { 
     frame=cvQueryFrame(capture); 

     if(!frame) break; 

     cvShowImage("result",frame); 
     key=cvWaitKey(10); 
     frame=NULL; 
    } 
    cvDestroyWindow("result"); 
    cvReleaseCapture(&capture); 
    return 0; 
} 
+0

因此,問題不在於OpenCV,而在於它使用的底層FFMpeg庫。這不起作用。 –

0

對於OpenCV的2.3.1我寫了這個代碼,它正常工作,那就是,我從相機飼料獲得的圖像。

VideoCapture cap(0); 
if(!cap.isOpened()) 
{ 
    cout<<"Camera is not connected"<<endl; 
    getchar(); 
} 
namedWindow("Camera Feed",1); 
for(;;) 
{ 
    Mat frame; 
    cap >> frame; 
    imshow("Camera Feed", frame); 
    if(!frame.empty()) 
     detectAndDisplay(frame); 
    else 
     cout<<"No frame as input"<<endl; 
    int c=waitKey(10); 
    if(c==27) 
     break; 
} 
return 0; 

正如您所看到的,它會接受輸入並持續顯示,並在您按鍵盤上按ESC時退出。 Here's CV 2.1的文檔與CV 2.3具有相同的命令集。我想,這個命令從2.4開始改變,儘管我對此不太確定。希望它有幫助:)

+0

嗯,即使在這種情況下,我總能設法從相機獲取圖片,儘管在這種情況下圖像已損壞。這是在OpenCV中獲取視頻捕獲的C++版本,但結果相同,因爲它包裝了相同的FFMpeg功能。 –

+0

@ KristianD'Amato這就是我擁有的一切。圖像已損壞?那不會發生。 –

+0

謝謝Prakhar;是的圖像看起來扭曲和錯誤。 –

3

我不知道它是否有幫助(因爲我不是一個有經驗的C++開發),但我最近設法從IP Camera得到一個流。 下面是一個簡單的測試:

#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 
#include <iostream> 
#include <stdio.h> 

using namespace cv; 
using namespace std; 

int main(int, char**) 
{ 
    VideoCapture ipCam; 
    Mat frame; 
    const string LOCATION = "rtsp://192.168.0.200:554/rtsph264vga"; 

    if(!ipCam.open(LOCATION)) { 
     cout << "Error opening video stream or file" << endl; 
     return -1; 
    } 

    for(;;) { 
     if(!ipCam.read(frame)) { 
      cout << "No frame" << endl; 
      waitKey(); 
     } 
     imshow("cam", frame); 
     if(waitKey(1) >= 0) break; 
    } 

    return 0; 
} 

標題到C++之前我設置相機導出到H264 VGA(因爲它是默認情況下不上我一起工作的凸輪啓用),並確保我已經有VLC中的流運行。 我在啓用fffmpeg的情況下使用OpenCV 2.4.1。據我所知,與OpenCV的ffmpeg集成可從OpenCV 2.0以上版本獲得。

當我必須將cv代碼與其他C++代碼合併時,我遇到了一些問題,因爲我擁有爲64位arch構建的OpenCV和ffmpeg +依賴關係。另一個代碼依賴於許多32位庫。 VideoCapture類是highgui lib的一部分,主要是您需要擔心的一個。如果未使用ffmpeg支持進行編譯,您將收到錯誤或警告,因爲VideoCapture無法轉碼內容。

不知道它這是最好的選擇,但你可以嘗試流/(在開源/網絡選項卡滴答流/保存)