FFmpeg中RGB到YUV转换的错误

时间:2016-12-06 12:11:04

标签: c++ opencv image-processing colors ffmpeg

我正在尝试将RGB图像转换为YUV。 我正在使用openCV加载图像。

我按如下方式调用该函数:

//I know IplImage is outdated 
IplImage* im = cvLoadImage("1.jpg", 1);
//....
bgr2yuv(im->imageData, dst, im->width, im->height);

将彩色图像转换为yuv图像的功能如下。 我正在使用ffmpeg来做到这一点。

void bgr2yuv(unsigned char *src, unsigned char *dest, int w, int h)
{
  AVFrame *yuvIm = avcodec_alloc_frame();
  AVFrame *rgbIm = avcodec_alloc_frame();
  avpicture_fill(rgbIm, src, PIX_FMT_BGR24, w, h);
  avpicture_fill(yuvIm, dest, PIX_FMT_YUV420P, w, h);
  av_register_all();

  struct SwsContext * imgCtx = sws_getCachedContext(imgCtx,
                                         w, h,(::PixelFormat)PIX_FMT_BGR24,
                                         w, h,(::PixelFormat)PIX_FMT_YUV420P,
                                         SWS_BICUBIC, NULL, NULL, NULL);

  sws_scale(imgCtx, rgbIm->data, rgbIm->linesize,0, h, yuvIm->data, yuvIm->linesize);
  av_free(yuvIm);
  av_free(rgbIm);
}

转换后输出错误。 我认为这是由于IplImage中发生了填充。 (我的输入图像宽度不是4的倍数。)

我更新了lineize变量,即使之后我没有得到正确的输出。 当我使用宽度为4的倍数的图像时,它的工作正常。

任何人都可以告诉代码中的问题。

2 个答案:

答案 0 :(得分:1)

检查IplImage::alignIplImage::widthStep并使用这些设置AVFrame::linesize。例如,对于RGB帧,您可以设置:

frame->linesize[0] = img->widthStep;

dst数组的布局可以是您想要的任何内容,具体取决于您之后如何使用它。

答案 1 :(得分:0)

我们需要做如下:

rgbIm->linesize[0] = im->widthStep;

但我认为来自sws_scale()的输出数据未被填充以使其成为4的倍数。 因此,当您将此数据(dest)再次复制到IplImage时,这将是 在显示,保存等方面产生问题。

所以我们需要设置widthStep=width如下:

IplImage* yuvImage = cvCreateImageHeader(cvGetSize(im), 8, 1);
yuvImage->widthStep = yuvImage->width;
yuvImage->imageData = dest;