从 OpenCV 捕获设备捕获 YUV 帧
Capture YUV frames from OpenCV capture device
我需要在 Windows 平台上使用 C++ 中的 OpenCV 直接从网络摄像头提取 YUV 帧。换句话说:OpenCV 中的设置使捕获设备的 read() 方法 return 成为 YUV Mat。我正在寻找有关如何执行此操作的工作示例或文档。
特定的 YUV 子格式对于初学者来说并不那么重要。相机可以产生 YUV 输出。我不能简单地将 BGR Mat 转换为 YUV - 我需要在不进行任何转换的情况下从设备中捕获它。
到目前为止,我已经尝试并结合了
- 使用几个特定的 API 进行连接(CV_CAP_DSHOW、CV_CAP_FFMPEG、CV_CAP_GSTREAMER 等)
- 在不同的 FOURCC(MJPG、UYVY 等)之间切换
- 切换 CAP_PROP_CONVERT_RGB 设置
- 找出 CAP_PROP_MODE 可能做什么
一切都无济于事,因为我仍然只是在 BGR 中获取输出。那么,任何提示、链接、三行代码?
(我使用的是 OpenCV 4.5.2)
您假设使用 CAP_PROP_CONVERT_RGB。
来自docs:
Boolean flags indicating whether images should be converted to RGB.
GStreamer note: The flag is ignored in case if custom pipeline is used. It's user responsibility to interpret pipeline output.
这个标志有很多问题。在此 post 中,作者添加了对 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
}
似乎windows下的OpenCV是用Direct Show制作的,不能直接抓取YUV变体。所以解决方案不是使用 OpenCV,而是 Windows Media Foundation。其他OS下的OpenCV或许可以抓取YUV。
我需要在 Windows 平台上使用 C++ 中的 OpenCV 直接从网络摄像头提取 YUV 帧。换句话说:OpenCV 中的设置使捕获设备的 read() 方法 return 成为 YUV Mat。我正在寻找有关如何执行此操作的工作示例或文档。
特定的 YUV 子格式对于初学者来说并不那么重要。相机可以产生 YUV 输出。我不能简单地将 BGR Mat 转换为 YUV - 我需要在不进行任何转换的情况下从设备中捕获它。
到目前为止,我已经尝试并结合了
- 使用几个特定的 API 进行连接(CV_CAP_DSHOW、CV_CAP_FFMPEG、CV_CAP_GSTREAMER 等)
- 在不同的 FOURCC(MJPG、UYVY 等)之间切换
- 切换 CAP_PROP_CONVERT_RGB 设置
- 找出 CAP_PROP_MODE 可能做什么
一切都无济于事,因为我仍然只是在 BGR 中获取输出。那么,任何提示、链接、三行代码?
(我使用的是 OpenCV 4.5.2)
您假设使用 CAP_PROP_CONVERT_RGB。
来自docs:
Boolean flags indicating whether images should be converted to RGB. GStreamer note: The flag is ignored in case if custom pipeline is used. It's user responsibility to interpret pipeline output.
这个标志有很多问题。在此 post 中,作者添加了对 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
}
似乎windows下的OpenCV是用Direct Show制作的,不能直接抓取YUV变体。所以解决方案不是使用 OpenCV,而是 Windows Media Foundation。其他OS下的OpenCV或许可以抓取YUV。