简体   繁体   English

从 OpenCV 捕获设备捕获 YUV 帧

[英]Capture YUV frames from OpenCV capture device

I need to extract YUV frames directly from a web camera using OpenCV from C++ on the Windows platform.我需要在 Windows 平台上使用 C++ 中的 OpenCV 直接从网络摄像头中提取 YUV 帧。 In other words: a setup in OpenCV that makes the capture device's read() method return a YUV Mat.换句话说:OpenCV 中的设置使捕获设备的 read() 方法返回 YUV Mat。 I'm looking for a working example or documentation on how to do this.我正在寻找有关如何执行此操作的工作示例或文档。

The specific YUV subformat isn't that important for starters.特定的 YUV 子格式对于初学者来说并不重要。 The camera can produce YUV output.相机可以产生YUV输出。 I cannot simply convert a BGR Mat to YUV - I need to capture it from the device without any conversions.我不能简单地将 BGR Mat 转换为 YUV - 我需要从设备中捕获它而不进行任何转换。

So far I've tried and combined到目前为止,我已经尝试并结合

  • connecting using several specific APIs (CV_CAP_DSHOW, CV_CAP_FFMPEG, CV_CAP_GSTREAMER, etc.)使用几个特定的​​ API(CV_CAP_DSHOW、CV_CAP_FFMPEG、CV_CAP_GSTREAMER 等)进行连接
  • changing between different FOURCCs (MJPG, UYVY, etc.)在不同的 FOURCC(MJPG、UYVY 等)之间切换
  • toggling the CAP_PROP_CONVERT_RGB setting切换 CAP_PROP_CONVERT_RGB 设置
  • to find out what CAP_PROP_MODE might do找出 CAP_PROP_MODE 可能会做什么

All to no avail as I'm still just getting output in BGR.一切都无济于事,因为我仍然只是在 BGR 中获得输出。 So, any hints, links, three-liners?那么,任何提示,链接,三行?

(I'm using OpenCV 4.5.2) (我使用的是 OpenCV 4.5.2)

You suppose to use the CAP_PROP_CONVERT_RGB.您假设使用 CAP_PROP_CONVERT_RGB。

From the docs :文档

Boolean flags indicating whether images should be converted to RGB.指示图像是否应转换为 RGB 的布尔标志。 GStreamer note: The flag is ignored in case if custom pipeline is used. GStreamer 注意:如果使用自定义管道,该标志将被忽略。 It's user responsibility to interpret pipeline output.解释管道输出是用户的责任。

There a lot of issues with this flag.这个标志有很多问题。 In this post the author added a fix for FFMPEG:在这篇文章中,作者为 FFMPEG 添加了一个修复程序:

void cv_VideoCapture_setConvertToRGB(
        cv::VideoCapture& cap,
        const bool convertFormat)
{
    cap.set(cv::CAP_PROP_CONVERT_RGB, convertFormat);
#if CV_VERSION_MAJOR >= 4
    const cv::VideoCaptureAPIs backend =
            static_cast<cv::VideoCaptureAPIs>(qRound(cap.get(cv::CAP_PROP_BACKEND)));
    switch (backend) {
    case cv::CAP_MSMF:
        // Note in case something needs to change here:
        // MSMF backend uses fourcc codes for format and uses
        //  CAP_PROP_FORMAT and CAP_PROP_FOURCC interchangeably
        break;
    case cv::CAP_FFMPEG:
        // See cap_ffmpeg_impl.hpp
        cap.set(cv::CAP_PROP_FORMAT, convertFormat ? 0 : -1);
        break;
    default:
        break;
    }
#endif // CV_VERSION_MAJOR >= 4
}

Seems that OpenCV under windows is made with Direct Show which cannot grab YUV variants directly.好像windows下的OpenCV是用Direct Show做的,不能直接抓取YUV变体。 So the solution is not to use OpenCV but Windows Media Foundation.所以解决方案不是使用 OpenCV,而是使用 Windows Media Foundation。 OpenCV under other OS'es may be able to grab YUV.其他操作系统下的 OpenCV 或许可以抓取 YUV。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM