OpenCV不会从RTMP源捕获帧,而FFmpeg会这样做

时间:2015-05-07 08:56:15

标签: opencv video ffmpeg rtmp

我的目标是每秒从rtmp流中捕获一个帧,然后使用OpenCV处理它。我使用FFmpeg版本N-71899-g6ef3426和OpenCV 2.4.9与Java接口(但我首先尝试使用Python)。 目前,我只能采用简单而肮脏的解决方案,即使用FFmpeg捕获图像,将它们存储在磁盘中,然后从我的OpenCV程序中读取这些图像。这是我使用的FFmpeg命令:

ffmpeg -i "rtmp://antena3fms35livefs.fplive.net:1935/antena3fms35live-live/stream-lasexta_1 live=1" -r 1 capImage%03d.jpg

目前这对我有用,至少对于这个具体的rtmp来源。然后我需要以适当的方式从我的OpenCV程序中读取这些图像。我实际上没有实现这部分,因为我试图找到更好的解决方案。

我认为理想的方法是直接从OpenCV捕获rtmp帧,但我找不到这样做的方法。这是Python中使用的代码:

cv2.namedWindow("camCapture", cv2.CV_WINDOW_AUTOSIZE)
cap = cv2.VideoCapture()
cap.open('"rtmp://antena3fms35livefs.fplive.net:1935/antena3fms35live-live/stream-lasexta_1 live=1"')
if not cap.open:
    print "Not open"
while (True):
    err,img = cap.read()
    if img and img.shape != (0,0):
        cv2.imwrite("img1", img)
        cv2.imshow("camCapture", img)
    if err:
        print err
        break
    cv2.waitKey(30)

我没有使用read()函数,而是尝试使用grab()和retrieve()函数而没有任何好的结果。 read()函数每次都在执行,但没有" img"或者"错误"收到了。 还有其他办法吗?或者也许没有办法从这样的流中直接从OpenCV 2.4.9获取帧?

我读过OpenCV使用FFmpeg来执行这类任务,但正如您所看到的,在我的情况下,FFmpeg能够从流中获取帧而OpenCV不是。

在我无法找到直接从OpenCV获取帧的方法的情况下,我的下一个想法是以某种方式管道,FFmpeg输出到OpenCV,这似乎更难实现。

任何想法, 谢谢!

更新1: 我在Windows 8.1中。因为我从Eclipse PyDev运行python脚本,所以这次我从cmd运行它,我收到以下警告:

warning: Error opening file (../../modules/highgui/src/cap_ffmpeg_impl.hpp:545)

就我所知,这个警告意味着文件路径错误,或者不支持编解码器。现在,问题是一样的。 OpenCV无法从此源获取帧吗?

2 个答案:

答案 0 :(得分:6)

实际上,我花了一天时间来弄清楚如何解决这个问题。最后,我在this link的帮助下解决了这个问题。 这是客户端代码。

    #include <opencv2/core/core.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/opencv.hpp>

    using namespace cv;

    int main(int, char**) {
        cv::VideoCapture vcap;
        cv::Mat image;
        const std::string videoStreamAddress = "rtmp://192.168.173.1:1935/live/test.flv";
        if(!vcap.open(videoStreamAddress)) {
            std::cout << "Error opening video stream or file" << std::endl;
            return -1;
        }

        cv::namedWindow("Output Window");
        cv::Mat edges;
        for(;;) {
            if(!vcap.read(image)) {
                std::cout << "No frame" << std::endl;
                cv::waitKey();
            }
            cv::imshow("Output Window", image);
            if(cv::waitKey(1) >= 0) break;
        }
    }

注意:在这种情况下,我创建了一个Android应用程序来获取实时视频并将其发送到部署在PC中的rtmp服务器wowza。这是我为实时视频处理创建此c ++实现的地方。

答案 1 :(得分:1)

python -c "import cv2; print(cv2.getBuildInformation())"   

使用ffmpeg检查构建opencv。如果它是正确的,你的代码应该没问题。

enter image description here

如果没有,请使用ffmpeg重建opencv。 在osx下

brew install opencv --with-ffmpeg