【问题标题】:Can't grab frames from an ip camera (rtsp) with a C++ dll using OpenCv 3.4.5无法使用 OpenCv 3.4.5 从带有 C++ dll 的 ip camera (rtsp) 抓取帧
【发布时间】:2020-09-28 23:41:12
【问题描述】:

我正在用 c++(32 位)构建一个简单的应用程序,它使用 opencv 从 rtsp 相机中抓取帧。

抓取相机帧的函数在与主程序分开的线程中运行。

我已经用一个 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();
}

我使用的 OpenCv 版本是 3.4.5

链接:rtsp://&lt;user&gt;:&lt;pass&gt;@&lt;ip&gt;:&lt;port&gt;/media

感谢您对此事的任何帮助。


编辑1:

我尝试过的:

  • 我试过这个this,但没用
  • 还尝试使用预构建的 64 位 opencv 3.4.0 版本,但仍然相同

【问题讨论】:

  • 你的 Python 环境是 64 位还是 32 位。我会查看 procmon 哪些 dll 已加载/未加载(您可能会遇到静默失败)。也可以使用 Wireshark 检查流量以查看该协议是否发生任何通信。
  • 我已经在这两种环境中进行了测试,并且都有效。现在我正在使用与 python opencv 相同的标志从源代码重新编译我的 opencv。所以至少我让它们保持相同的配置。

标签: c++ windows opencv


【解决方案1】:

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

但是经过大量试验和错误,并阅读了有关在 Windows 中使用 cv::VideoCapture 问题的各种 SO 线程。

我发现了问题,

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

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

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

感谢您的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-17
    • 2016-10-13
    • 1970-01-01
    • 2018-01-23
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    相关资源
    最近更新 更多