如何将 OpenCV C++ 代码中的帧流式传输到 Video4Linux 或 ffmpeg?

2023-12-08

我正在尝试使用 OpenCV 处理视频流中的帧。目标是从流中获取帧,对其进行处理,然后将处理后的帧放入新的/新鲜的流中。

我已经能够使用 OpenCV 视频捕获功能成功读取流。但不知道如何使用处理后的帧创建输出流。

为了进行一些基本测试,我使用 ffmpeg 从本地视频文件创建了一个流,如下所示:

ffmpeg -i sample.mp4 -v 0 -vcodec mpeg4 -f mpegts \
        "udp://@127.0.0.1:23000?overrun_nonfatal=1&fifo_size=50000000"

在我的 C++ 代码中,使用 OpenCV 库的 VideoCapture 功能,我能够捕获上面创建的流。我想要实现的基本布局附在下面:

cv::VideoCapture capture("udp://@127.0.0.1:23000?overrun_nonfatal=1&fifo_size=50000000", cv::CAP_FFMPEG);

cv::Mat frame;

while (true) 
{
    // use the above stream to capture a frame
    capture >> frame;
    
    // process the frame (not relevant here)
    ...

    // finally, after all the processing is done I 
    // want to put this frame on a new stream say at
    // udp://@127.0.0.1:25000, I don't know how to do
    // this, ideally would like to use Video4Linux but
    // solutions with ffmpeg are appreciated as well
}

正如您从上面代码中的注释中看到的,我不知道应该如何开始处理这个问题,我尝试搜索类似的问题,但我能找到的只是如何使用流进行 VideoCapture,与输出到溪流。

我对此比较陌生,对你们许多人来说这似乎是一个非常基本的问题,请原谅。


我们可以使用与我的相同的技术以下 Python 代码示例.

  • 将FFmpeg作为子进程执行,打开stdin管道进行写入

     FILE *pipeout = popen(ffmpeg_cmd.c_str(), "w")
    
  • Write frame.data到 FFmpeg 子进程的标准输入管道(在循环中)

     fwrite(frame.data, 1, width*height*3, pipeout);
    
  • 最后关闭管道(会关闭子进程)

     pclose(pipeout);
    

以下示例是一个通用示例 - 构建编号帧并将编码视频写入 MKV 输出文件。

该示例使用以下等效命令行:
ffmpeg -y -f rawvideo -r 10 -video_size 320x240 -pixel_format bgr24 -i pipe: -vcodec libx264 -crf 24 -pix_fmt yuv420p output.mkv

您可以根据您的具体要求调整参数(替换output.mkv with udp://@127.0.0.1:25000).

将编号框架替换为capture >> frame,并调整大小和帧速率。


代码示例:

#include <stdio.h>
#include <chrono>
#include <thread>
#include "opencv2/opencv.hpp"

int main()
{
    int width = 320;
    int height = 240;
    int n_frames = 100;
    int fps = 10;

    //Use a "generic" example (write the output video in output.mkv video file).
    //ffmpeg -y -f rawvideo -r 10 -video_size 320x240 -pixel_format bgr24 -i pipe: -vcodec libx264 -crf 24 -pix_fmt yuv420p output.mkv
    std::string ffmpeg_cmd = std::string("ffmpeg -y -f rawvideo -r ") + std::to_string(fps) +
                             " -video_size " + std::to_string(width) + "x" + std::to_string(height) +
                             " -pixel_format bgr24 -i pipe: -vcodec libx264 -crf 24 -pix_fmt yuv420p output.mkv";

    //Execute FFmpeg as sub-process, open stdin pipe (of FFmpeg sub-process) for writing.
    //In Windows we need to use _popen and in Linux popen
#ifdef _MSC_VER
    FILE *pipeout = _popen(ffmpeg_cmd.c_str(), "wb");   //Windows (ffmpeg.exe must be in the execution path)
#else
    //https://batchloaf.wordpress.com/2017/02/12/a-simple-way-to-read-and-write-audio-and-video-files-in-c-using-ffmpeg-part-2-video/
    FILE *pipeout = popen(ffmpeg_cmd.c_str(), "w");     //Linux (assume ffmpeg exist in /usr/bin/ffmpeg (and in path).
#endif

    for (int i = 0; i < n_frames; i++)
    {
        cv::Mat frame = cv::Mat(height, width, CV_8UC3);
        frame = cv::Scalar(60, 60, 60); //Fill background with dark gray
        cv::putText(frame, std::to_string(i+1), cv::Point(width/2-50*(int)(std::to_string(i+1).length()), height/2+50), cv::FONT_HERSHEY_DUPLEX, 5, cv::Scalar(30, 255, 30), 10);  // Draw a green number

        cv::imshow("frame", frame);cv::waitKey(1); //Show the frame for testing

        //Write width*height*3 bytes to stdin pipe of FFmpeg sub-process (assume frame data is continuous in the RAM).
        fwrite(frame.data, 1, width*height*3, pipeout);
    }

    // Flush and close input and output pipes
    fflush(pipeout);

#ifdef _MSC_VER
    _pclose(pipeout);   //Windows
#else
    pclose(pipeout);    //Linux
#endif

    //It looks like we need to wait one more second at the end. //https://stackoverflow.com/a/62804585/4926757
    std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // sleep for 1 second

    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 OpenCV C++ 代码中的帧流式传输到 Video4Linux 或 ffmpeg? 的相关文章

  • 在 Xamarin Android 中将图像从 URL 异步加载到 ImageView 中

    我有一个包含多个项目的 ListView 列表中的每个项目都应该有一个与之关联的图像 我创建了一个数组适配器来保存每个列表项并具有我希望加载的图像的 url 我正在尝试使用 Web 请求异步加载图像 并设置图像并在加载后在视图中更新它 但视
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • 如何针对 Nancy 中的 Active Directory 进行身份验证?

    这是一篇过时的文章 但是http msdn microsoft com en us library ff650308 aspx paght000026 step3 http msdn microsoft com en us library
  • HttpClient 像浏览器一样请求

    当我通过 HttpClient 类调用网站 www livescore com 时 我总是收到错误 500 可能服务器阻止了来自 HttpClient 的请求 1 还有其他方法可以从网页获取html吗 2 如何设置标题来获取html内容 当
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • Windows 10 中 Qt 桌面应用程序的缩放不当

    我正在为 Windows 10 编写一个简单的 Qt Widgets Gui 应用程序 我使用的是 Qt 5 6 0 beta 版本 我遇到的问题是它根本无法缩放到我的 Surfacebook 的屏幕上 这有点难以判断 因为 SO 缩放了图
  • 网络参考共享类

    我用 Java 编写了一些 SOAP Web 服务 在 JBoss 5 1 上运行 其中两个共享一个类 AddressTO Web 服务在我的 ApplycationServer 上正确部署 一切都很顺利 直到我尝试在我的 C 客户端中使用
  • 将应用程序从 Microsoft Access 迁移到 VB 或 C#.NET

    我目前正试图说服管理层需要将我们的应用程序之一移植到 NET 该应用程序已经发展成为 Access 中的一个庞然大物 SQL 后端 拥有 700 个链接表 650 个表单 子表单 130 个模块和 850 个查询 我几乎知道这样做的所有主要
  • EPPlus Excel 更改单元格颜色

    我正在尝试将给定单元格的颜色设置为另一个单元格的颜色 该单元格已在模板中着色 但worksheet Cells row col Style Fill BackgroundColor似乎没有get财产 是否可以做到这一点 或者我是否必须在互联
  • 作为字符串的动态属性名称

    使用 DocumentDB 创建新文档时 我想设置属性名称动态地 目前我设置SomeProperty 像这样 await client CreateDocumentAsync dbs db colls x new SomeProperty
  • char指针或char变量的默认值是什么[重复]

    这个问题在这里已经有答案了 下面是我尝试打印 char 变量和指针的默认值 值的代码 但无法在控制台上看到它 它是否有默认值或只是无法读取 ASCII 范围 include
  • 在Linux中使用C/C++获取机器序列号和CPU ID

    在Linux系统中如何获取机器序列号和CPU ID 示例代码受到高度赞赏 Here http lxr linux no linux v2 6 39 arch x86 include asm processor h L173Linux 内核似
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud
  • 更改显示的 DPI 缩放大小使 Qt 应用程序的字体大小渲染得更大

    我使用 Qt 创建了一些 GUI 应用程序 我的 GUI 应用程序包含按钮和单选按钮等控件 当我运行应用程序时 按钮内的按钮和字体看起来正常 当我将显示器的 DPI 缩放大小从 100 更改为 150 或 200 时 无论分辨率如何 控件的

随机推荐

  • nginx x-accel-redirect 上“location”和“proxy_pass”的不同行为

    我的 nginx 配置如下 location mount points mount point1 internal alias repos mount point one location to proxy internal proxy p
  • Networkx 弹簧布局边缘权重

    我想知道如何spring layout考虑边缘权重 来自维基百科 另一种模型考虑每对节点 i j 的类似弹簧的力 其中每个弹簧的理想长度 delta ij 与节点 i 和 j 之间的图论距离成正比 而不使用单独的排斥力 最小化节点之间的欧几
  • 计算季度衰退和复苏

    给定这个数据框 GDP quarter 0 250 2015q1 1 260 2015q1 2 250 2015q3 3 240 2015q4 4 250 2016q1 5 260 2016q2 我怎样才能知道哪些季度是衰退 哪些季度是复苏
  • android中如何获取sd卡上的文件路径

    大家好 我的 SD 卡中有 mp3 文件 如何从sd卡获取mp3歌曲的文件路径 请帮助我 您可以从以下代码获取sdcard的路径 File extStore Environment getExternalStorageDirectory 然
  • 我可以压缩所有 python 标准库并且 python 仍然能够导入它吗?

    我读过一个教程 您可以将所有 libs 文件编译为 pyc 然后将所有 pyc 打包为压缩文件 然后蟒蛇仍然像魔法一样发挥作用 而且它变得明显变小了 但是当我将所有 pyc 文件压缩为 python36 zip 并将它们保存在 lib py
  • CSS 背景图像未加载

    我已经遵循了所有教程 它们都说了要说的话 我在 css 样式表中指定了主体内部的背景 但页面仅显示空白的白色背景 图像与 html 和 css 页面位于同一目录中 教程说的是 已被弃用 所以我在 css 中使用 body backgroun
  • 在html中链接jquery

    我无法成功将 jQuery 链接到我的 html 我已经编写了最简单的 jQuery 代码 这样我就知道它是正确的 并且我已经尝试了我能想到的一切 搜索并没有帮助 我的 html 文件名 test html
  • Python lxml:忽略 XML 声明(错误)

    我正在尝试解析文件浏览器 Thunar 的自定义操作文件 config Thunar uca xml 与lxmlPython 模块 由于某种原因 Thunar 显然写了一个malformed declaration进入这些文件 显然 ver
  • 从编译的发行版 exe 中删除类字符串名称

    我编译我的应用程序项目的发行版本 当我使用二进制编辑器查看编译后的最终 exe 时 我可以看到我自己创建的对象的所有类名称 例如 TPolygon TRectangle 等 作为 exe 内的二进制文本数据 我如何从 exe 中删除此信息
  • 安全下载文件

    我想要一个文件夹 我们称之为文档 其中包含登录用户可以下载的文档 这些包含非常敏感的信息 如何才能最好地保护该文件夹 我有 PHP 背景 所以想知道我是否忽略了任何事情 我将使用 htaccess 保护该文件夹 并且当用户单击下载时 他们永
  • 与一个进程进行多次通信而不破坏管道?

    这不是我第一次遇到这个问题 而且它确实困扰着我 每当我使用 Python 打开管道时subprocess模块 我只能communicate正如文档所指定的那样 使用它一次 Read data from stdout and stderr u
  • Java 输入不起作用(初学者)

    由于某种原因 我的代码不接受最后一行的输入 您想订购什么 谁能告诉我我的错误是什么 它编译正确 一切顺利 我只是一个初学者 所以请告诉我基本术语 import java util Scanner import java util class
  • 添加带有 NSEventMaskKeyDown 掩码的全局监视器不会触发

    我正在开发一个 MacOS 菜单栏应用程序 它需要跟踪一些全局快捷方式 以便于调整外部显示器上的显示亮度 但是 我无法让它在任何键盘相关事件上触发处理程序 鼠标事件工作得很好 我正在使用以下代码检查可访问性 NSDictionary opt
  • 如何缓存解析的 JSON 以供离线使用

    我已经成功解析了 JSON 但现在我想缓存它以供离线使用 即使互联网不可用 如果有任何新条目出现 我也想缓存它 缓存数据的最佳选择是什么 SharedPreferences or SQLite database 这是我的代码 我用它来解析
  • Eclipse CDT 自动包含共享库

    我正在 Eclipse 中工作 Helios Service Release 1 使用 Eclipse CDT 使用 g 进行编译 我刚刚开始尝试在我的项目中使用共享库 但遇到了一个小问题 我有三个项目 A B 和 C A 和 B 都是共享
  • 是否可以用javascript或css实现overflow:ellipsis的效果?

    我想展示 when overflow发生 但遗憾的是在CSS中只有overflow hidden这接近但不完全是我想要的 可以实施吗 text overflow ellipsis See http www quirksmode org cs
  • 运行时错误 2448 您无法为此对象赋值

    我在用大卫 W 芬顿对此问题的回答尝试允许用户在单击控件时打印报告 但我收到以下错误消息 runtime error 2448 you cannot assign a value to this object 触发错误的代码行是 Me tx
  • 如何在grails中为createCriteria编写from和to日期的子句?

    我想使用以下代码获取两个日期之间的结果 def c TestCase createCriteria resultss c list like testStatus Dummy and between testTime date1 date2
  • 沿任一轴翻转 UIImage

    我正在尝试创建一种沿 X 轴 Y 轴或两者翻转 UIImage 的方法 我一直在接近 但我的变换知识还不够好 无法一路到达那里 这是我到目前为止的代码 UIImage flippedImageByAxis MVImageFlip axis
  • 如何将 OpenCV C++ 代码中的帧流式传输到 Video4Linux 或 ffmpeg?

    我正在尝试使用 OpenCV 处理视频流中的帧 目标是从流中获取帧 对其进行处理 然后将处理后的帧放入新的 新鲜的流中 我已经能够使用 OpenCV 视频捕获功能成功读取流 但不知道如何使用处理后的帧创建输出流 为了进行一些基本测试 我使用