VideoCapture类一般用于视频,图片序列,IPC的接收,
一般视频的压缩格式不可能时RGB,IPC一般时YUV420p;经过VideoCapture的read函数读取后,颜色空间是哪种类型?是原来的还是统一转换成某种格式;
查看源码:
bool VideoCapture::open(const String& filename, int apiPreference)
{
CV_INSTRUMENT_REGION()
if (isOpened()) release();
icap = IVideoCapture_create(filename);
if (!icap.empty())
return true;
cap.reset(cvCreateFileCaptureWithPreference(filename.c_str(), apiPreference));
return isOpened();
}
bool VideoCapture::open(const String& filename)
{
CV_INSTRUMENT_REGION()
return open(filename, CAP_ANY);
}
这里会默认带上参数CAP_ANY;
/** @brief %VideoCapture API backends identifier.
Select preferred API for a capture object.
To be used in the VideoCapture::VideoCapture() constructor or VideoCapture::open()
@note Backends are available only if they have been built with your OpenCV binaries.
See @ref videoio_overview for more information.
*/
enum VideoCaptureAPIs {
CAP_ANY = 0, //!< Auto detect == 0
CAP_VFW = 200, //!< Video For Windows (platform native)
..........................................................
CAP_ARAVIS = 2100 //!< Aravis SDK
};
这个参数会自动检测获取流的格式;
在此头文件中还有
/** @brief Generic camera output modes identifier.
@note Currently, these are supported through the libv4l backend only.
*/
enum VideoCaptureModes {
CAP_MODE_BGR = 0, //!< BGR24 (default)
CAP_MODE_RGB = 1, //!< RGB24
CAP_MODE_GRAY = 2, //!< Y8
CAP_MODE_YUYV = 3 //!< YUYV
};
经验证确实read函数将数据流统一转换成了BGR24;
opencv-3.2.0/modules/videoio/include/opencv2/videoio.hpp:173: CAP_MODE_YUYV = 3 //!< YUYV
opencv-3.2.0/modules/videoio/include/opencv2/videoio/videoio_c.h:462: CV_CAP_MODE_YUYV = 3 // YUYV
opencv-3.2.0/modules/videoio/src/cap_avfoundation_mac.mm:752: } else if (mMode == CV_CAP_MODE_YUYV) {
opencv-3.2.0/modules/videoio/src/cap_avfoundation_mac.mm:753: // For CV_CAP_MODE_YUYV, read frames directly as 422.
opencv-3.2.0/modules/videoio/src/cap_avfoundation_mac.mm:853: } else if (mMode == CV_CAP_MODE_YUYV) {
opencv-3.2.0/modules/videoio/src/cap_avfoundation_mac.mm:927: } else if (mMode == CV_CAP_MODE_YUYV) {
opencv-3.2.0/modules/videoio/src/cap_avfoundation_mac.mm:1065: case CV_CAP_MODE_YUYV:
opencv-3.2.0/modules/videoio/src/cap_libv4l.cpp:659: case CV_CAP_MODE_YUYV:
opencv-3.2.0/modules/videoio/src/cap_libv4l.cpp:735: case CV_CAP_MODE_YUYV:
opencv-3.2.0/modules/videoio/src/cap_libv4l.cpp:959: case CV_CAP_MODE_YUYV:
opencv-3.2.0/modules/videoio/src/cap_libv4l.cpp:1554: case CV_CAP_MODE_YUYV:
opencv-3.2.0/modules/videoio/src/cap_libv4l.cpp:1830: case CV_CAP_MODE_YUYV:
这个文件opencv-3.2.0/modules/videoio/src/cap_avfoundation_mac.mm:
// Capture in a pixel format that can be converted efficiently to the output mode.
741 OSType pixelFormat;
742 if (mMode == CV_CAP_MODE_BGR || mMode == CV_CAP_MODE_RGB) {
743 // For CV_CAP_MODE_BGR, read frames as BGRA (AV Foundation's YUV->RGB conversion is slightly faster than OpenCV' s CV_YUV2BGR_YV12)
744 // kCVPixelFormatType_32ABGR is reportedly faster on OS X, but OpenCV doesn't have a CV_ABGR2BGR conversion.
745 // kCVPixelFormatType_24RGB is significanly slower than kCVPixelFormatType_32BGRA.
746 pixelFormat = kCVPixelFormatType_32BGRA;
747 mFormat = CV_8UC3;
748 } else if (mMode == CV_CAP_MODE_GRAY) {
749 // For CV_CAP_MODE_GRAY, read frames as 420v (faster than 420f or 422 -- at least for H.264 files)
750 pixelFormat = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
751 mFormat = CV_8UC1;
752 } else if (mMode == CV_CAP_MODE_YUYV) {
753 // For CV_CAP_MODE_YUYV, read frames directly as 422.
754 pixelFormat = kCVPixelFormatType_422YpCbCr8;
755 mFormat = CV_8UC2;
756 } else {
757 fprintf(stderr, "VIDEOIO ERROR: AVF Mac: Unsupported mode: %d\n", mMode);
758 return false;
759 }
大致调用流程
Ptr
Ptr
包含这两个类;
主要调用关系:
VideoCapture::open(const String& filename, int apiPreference)
----->icap = IVideoCapture_create(filename);
------->capture = createMotionJpegCapture(filename);
--------> Ptr
------->m_file_stream.open(filename);------->m_f = fopen(filename.c_str(), "rb");
------->parseRiff(m_file_stream);
分析read函数
bool VideoCapture::read(OutputArray image)
{
CV_INSTRUMENT_REGION()
if(grab())
retrieve(image);
else
image.release();
return !image.empty();
}
bool VideoCapture::read(OutputArray image)
-----> grab()
------->icap->grabFrame()
----->retrieve(image); //关键函数
------>icap->retrieveFrame(channel, image);
------>_img = cvRetrieveFrame(cap, channel);
----->capture->retrieveFrame(idx)