使用ffmpeg将cv :: Mat图像从BGR转换为YUV

时间:2016-03-10 03:35:56

标签: opencv ffmpeg

我正在尝试将BGR图像转换为YUV420P,但当我尝试分别查看每个YUV平面时,this is what I see.

不应该以相同的方式打包 cv :: Mat :: data AVFrame :: data [0] 吗?我应该能够直接记忆。我错过了什么吗?

有什么想法吗?

Mat frame;
VideoCapture cap;
if(!cap.open(0)){
    return 0;
}

// capture a frame
cap >> frame;
if( frame.empty() ) return 0;

cv::Size s = frame.size();
int height = s.height;
int width = s.width;

// Creating two frames for conversion
AVFrame *pFrameYUV =av_frame_alloc();
AVFrame *pFrameBGR =av_frame_alloc();

// Determine required buffer size and allocate buffer for YUV frame 
int numBytesYUV=av_image_get_buffer_size(AV_PIX_FMT_YUV420P, width,
                height,1);          

// Assign image buffers
avpicture_fill((AVPicture *)pFrameBGR, frame.data,      AV_PIX_FMT_BGR24,
    width, height);

uint8_t* bufferYUV=(uint8_t *)av_malloc(numBytesYUV*sizeof(uint8_t));
avpicture_fill((AVPicture *)pFrameYUV, bufferYUV, AV_PIX_FMT_YUV420P,
        width, height);

// Initialise Software scaling context
struct SwsContext *sws_ctx = sws_getContext(width,
    height,
    AV_PIX_FMT_BGR24,
    width,
    height,
    AV_PIX_FMT_YUV420P,
    SWS_BILINEAR,
    NULL,
    NULL,
    NULL
    );

// Convert the image from its BGR to YUV
sws_scale(sws_ctx, (uint8_t const * const *)pFrameBGR->data,
      pFrameYUV->linesize, 0, height,
      pFrameYUV->data, pFrameYUV->linesize);



// Trying to see the different planes of YUV
Mat MY = Mat(height, width, CV_8UC1);
memcpy(MY.data,pFrameYUV->data[0], height*width);
  imshow("Test1", MY); // fail
Mat MU = Mat(height/2, width/2, CV_8UC1);
memcpy(MU.data,pFrameYUV->data[1], height*width/4);
  imshow("Test2", MU); // fail
Mat MV = Mat(height/2, width/2, CV_8UC1);
memcpy(MV.data,pFrameYUV->data[2], height*width/4);
  imshow("Test3", MV); // fail  

waitKey(0); // Wait for a keystroke in the window

1 个答案:

答案 0 :(得分:1)

对于SharedPreference,第三个参数不应该是Editor,而应是sws_scale(),即指向 width * 3 的指针。