Linux下opencv通过V4L获取摄像头图像的底层源码icvRetrieveFrameCAM_V4L

以下是icvRetrieveFrameCAM_V4L(CvCaptureCAM_V4L* capture,int)的源码,在Opencv3.1.0源码中cap_v4l.cpp中第1438行,被cap_v4l.cpp中第1794行retrieveFrame(int)调用,retrieveFrame(int)被cap.cpp第100行cvRetrieveFrame( CvCapture* capture, int idx )调用,cvRetrieveFrame( CvCapture* capture, int idx )被cap.cpp中第620行bool VideoCapture::retrieve(OutputArray image, int channel)调用,而bool VideoCapture::retrieve(OutputArray image, int channel)即为bool VideoCapture::read(OutputArray image)中调用的读取图像的函数。

static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) {
    /* Now get what has already been captured as a IplImage return */
    // we need memory iff convert_rgb is true
    bool recreate_frame = capture->frame_allocated != capture->convert_rgb;

    if (!capture->convert_rgb) {
        // for mjpeg streams the size might change in between, so we have to change the header
        recreate_frame += capture->frame.imageSize != (int)capture->buffers[capture->bufferIndex].length;
    }

    if(recreate_frame) {
        // printf("realloc %d %zu\n", capture->frame.imageSize, capture->buffers[capture->bufferIndex].length);
        if(capture->frame_allocated)
            cvFree(&capture->frame.imageData);
        v4l2_create_frame(capture);
    }

    if(!capture->convert_rgb) {
        capture->frame.imageData = (char*)capture->buffers[capture->bufferIndex].start;
        return &capture->frame;
    }

    switch (capture->palette)
    {
    case V4L2_PIX_FMT_BGR24:
        memcpy((char *)capture->frame.imageData,
               (char *)capture->buffers[capture->bufferIndex].start,
               capture->frame.imageSize);
        break;

    case V4L2_PIX_FMT_YVU420:
        yuv420p_to_rgb24(capture->form.fmt.pix.width,
                 capture->form.fmt.pix.height,
                 (unsigned char*)(capture->buffers[capture->bufferIndex].start),
                 (unsigned char*)capture->frame.imageData);
        break;

    case V4L2_PIX_FMT_YUV411P:
        yuv411p_to_rgb24(capture->form.fmt.pix.width,
                 capture->form.fmt.pix.height,
                 (unsigned char*)(capture->buffers[capture->bufferIndex].start),
                 (unsigned char*)capture->frame.imageData);
        break;
#ifdef HAVE_JPEG
    case V4L2_PIX_FMT_MJPEG:
    case V4L2_PIX_FMT_JPEG:
        if (!mjpeg_to_rgb24(capture->form.fmt.pix.width,
                    capture->form.fmt.pix.height,
                    (unsigned char*)(capture->buffers[capture->bufferIndex]
                             .start),
                    capture->buffers[capture->bufferIndex].length,
                    &capture->frame))
          return 0;
        break;
#endif

    case V4L2_PIX_FMT_YUYV:
        yuyv_to_rgb24(capture->form.fmt.pix.width,
                  capture->form.fmt.pix.height,
                  (unsigned char*)(capture->buffers[capture->bufferIndex].start),
                  (unsigned char*)capture->frame.imageData);
        break;
    case V4L2_PIX_FMT_UYVY:
        uyvy_to_rgb24(capture->form.fmt.pix.width,
                  capture->form.fmt.pix.height,
                  (unsigned char*)(capture->buffers[capture->bufferIndex].start),
                  (unsigned char*)capture->frame.imageData);
        break;
    case V4L2_PIX_FMT_SBGGR8:
        bayer2rgb24(capture->form.fmt.pix.width,
                capture->form.fmt.pix.height,
                (unsigned char*)capture->buffers[capture->bufferIndex].start,
                (unsigned char*)capture->frame.imageData);
        break;

    case V4L2_PIX_FMT_SN9C10X:
        sonix_decompress_init();
        sonix_decompress(capture->form.fmt.pix.width,
                 capture->form.fmt.pix.height,
                 (unsigned char*)capture->buffers[capture->bufferIndex].start,
                 (u
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值