Can';t使用C+从ip摄像头(rtsp)抓取帧+;使用OpenCv 3.4.5的dll 我在C++中使用了一个简单的应用程序(32位),它使用OpenCV来从RTSP相机中获取帧。

Can';t使用C+从ip摄像头(rtsp)抓取帧+;使用OpenCv 3.4.5的dll 我在C++中使用了一个简单的应用程序(32位),它使用OpenCV来从RTSP相机中获取帧。,c++,windows,opencv,C++,Windows,Opencv,获取相机帧的函数在主程序的独立线程中运行 我用一个mp4视频测试了这个应用程序,效果很好。我能够抓取帧并处理它们。 然而,当我使用rtsp链接时,尽管我能够打开与摄像头的连接,但每当我尝试读取grab()和read()函数时,返回False 首先,我认为这是rtsp链接的一个问题,但我制作了一个简单的Python应用程序来测试它,它也可以工作。所以这不是联系 这是我用来抓取帧的代码: #ifndef _IMAGE_BUFFER_H_ #define _IMAGE_BUFFER_H_ #incl

获取相机帧的函数在主程序的独立线程中运行

我用一个mp4视频测试了这个应用程序,效果很好。我能够抓取帧并处理它们。 然而,当我使用rtsp链接时,尽管我能够打开与摄像头的连接,但每当我尝试读取grab()和read()函数时,返回False

首先,我认为这是rtsp链接的一个问题,但我制作了一个简单的Python应用程序来测试它,它也可以工作。所以这不是联系

这是我用来抓取帧的代码:

#ifndef _IMAGE_BUFFER_H_
#define _IMAGE_BUFFER_H_

#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>

.
.
.

VideoCapture capture_;

string address_;
atomic<bool> keep_alive_;
thread thread_;
int fps_;
mutex mutex_;
list<FramePair> frames_;

int Run()
{

    capture_.open(address_, cv::CAP_ANY);

    if (!capture_.isOpened()) {
        printf("Could not open Camera feed! \n");
        return -1;
    }

    uint64_t period = uint64_t((float(1) / float(fps_)) * float(1000));

    period = period - (period / 20);

    uint64_t t0 = getCurrentTimeInMilli();
    while (keep_alive_) {

        uint64_t difftime = getCurrentTimeInMilli() - t0;
        if (difftime < period) {
            uint64_t sleep_time = period - difftime;
            if (sleep_time < period) {
                std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time));
            }
        }

        t0 = getCurrentTimeInMilli();

        CaptureFrame();
    }

    return 0;
}

void CaptureFrame()
{
    Mat frame;

    bool ret = capture_.read(frame);
    if (!ret) {
        printf("Error in frame reading! \n");
    }

    vector<uint8_t> jpeg;
    cv::imencode(".jpg", frame, jpeg, vector<int>());

    mutex_.lock();

    frames_.push_back(FramePair(getCurrentTimeInMilli(), jpeg));

    if (frames_.size() > FRAME_QUEUE_SIZE)
        frames_.pop_front();

    mutex_.unlock();
}
#ifndef(图像)缓冲区(H)_
#定义图像缓冲区_
#包括
#包括
#包括
.
.
.
视频捕获;
字符串地址;
原子能保持生命;
螺纹螺纹;
int fps_2;;
互斥互斥;
列出框架;
int运行()
{
捕获打开(地址,cv::CAP\U ANY);
如果(!capture.isOpened()){
printf(“无法打开相机馈送!\n”);
返回-1;
}
uint64_t期间=uint64_t((浮动(1)/浮动(fps_))*浮动(1000));
期间=期间-(期间/20);
uint64_t t0=getCurrentTimeInMilli();
同时(让你活着){
uint64\u t difftime=getCurrentTimeInMilli()-t0;
如果(扩散时间<周期){
uint64\u t sleep\u time=周期-离散时间;
if(睡眠时间<周期){
std::this_thread::sleep_for(std::chrono::ms(sleep_time));
}
}
t0=getCurrentTimeInMilli();
CaptureFrame();
}
返回0;
}
void CaptureFrame()
{
垫架;
bool ret=捕获读取(帧);
如果(!ret){
printf(“帧读取错误!\n”);
}
矢量jpeg;
cv::imencode(“.jpg”,frame,jpeg,vector());
互斥锁;
帧。向后推(帧对(getCurrentTimeInMilli(),jpeg));
if(帧大小()>帧队列大小)
框架u.pop_front();
互斥锁.解锁();
}
我使用的OpenCv版本是3.4.5

链接:
rtsp://:@:/media

我感谢您在这件事上的帮助。


编辑1: 我所尝试的:
  • 我试过了,但没用
  • 还尝试了预构建的64位opencv 3.4.0版本,但仍然相同


很抱歉回答了我自己的问题

但是经过大量的尝试和错误,阅读了关于在Windows中使用cv::VideoCapture的各种SO线程

我发现了问题

我试图在我的应用程序中静态链接OpenCv,但由于许可证问题,ffmpeg无法与应用程序一起静态编译

我通过复制opencv_ffmpegxxx.dll解决了这个问题,它可以在/bin/中找到。并按照中的建议将其粘贴到我的.exe文件夹中

按照中的建议,在应用程序中嵌入ffmpeg dll可能有一些解决方法,但我还没有尝试。我希望其他人能从这个问题中受益


谢谢您的帮助。

您的Python环境是64位还是32位。我将使用procmon查看哪些DLL未加载(可能会出现无声故障)。还可以检查Wireshark的通信量,看看该协议是否有任何通信。我在两个环境中都做了测试,都成功了。现在,我正在使用python opencv中相同的标志从源代码重新编译我的opencv。所以至少我让它们保持相同的配置。