关于OpenCV3中VideoCapture的疑问

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 cap;
    Ptr icap;

包含这两个类;

主要调用关系:

VideoCapture::open(const String& filename, int apiPreference)

         ----->icap = IVideoCapture_create(filename);

                         ------->capture = createMotionJpegCapture(filename);

                                       --------> Ptr mjdecoder(new MotionJpegCapture(filename));

                                                      ------->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)

 

                               

       

你可能感兴趣的:(OpenCV)