简体   繁体   English

在OpenCV中从RGB转换为YUYV

[英]Convert from RGB to YUYV in OpenCV

Is there a way to convert from RGB to YUYV (YUY 4:2:2) format? 有没有办法从RGB转换为YUYV(YUY 4:2:2)格式? I noted that OpenCV has reverse operation, but not RGB to YUYV for some reason. 我注意到OpenCV有反向操作,但由于某种原因没有RGB到YUYV。 Maybe someone can point to code which does that (even outside of OpenCV library)? 也许有人可以指向那样做的代码(即使在OpenCV库之外)?

UPDATE UPDATE

I found libyuv library which may work for this purpose by doing BGR to ARGB conversion and then ARGB to YUY2 format (hopefully this is the same as YUYV 4:2:2). 我找到了libyuv库,它可以通过BGR到ARGB转换然后ARGB到YUY2格式来工作(希望这与YUYV 4:2:2相同)。 But it doesn't seem to work. 但它似乎没有用。 Do you happen to know what yuyv buffer dimensions/type should look like? 你碰巧知道yuyv缓冲区尺寸/类型应该是什么样的吗? What its stride? 它的步伐是什么?

To clarify YUYV and YUY2 are the same formats if it helps. 澄清YUYV和YUY2是相同的格式,如果它有帮助。

UPDATE 2 Here is my code of using libyuv library: 更新2这是我使用libyuv库的代码:

  Mat frame;
  // Convert original image im from BGR to BGRA for further use in libyuv
  cvtColor(im, frame, CVX_BGR2BGRA);
  // Actually libyuv requires ARGB (i.e. reverse of BGRA), so I swap channels here
  int from_to[] = { 0,3, 1,2, 2,1, 3,0 };
  mixChannels(&frame, 1, &frame, 1, from_to, 4);
  // This is the most confusing part. Not sure what argb_stride suppose to be - length of a row in bytes or size of single value in the array?
  const uint8_t* argb_data = frame.data;
  int argb_stride = 8;

  // Also it is not clear what size of yuyv frame should be since we duplicate one Y 
  Mat yuyv(frame.rows, frame.cols, CVX_8UC2);
  uint8_t* yuyv_data = yuyv.data;
  int yuyv_stride = 16;
  // Do actual conversion
  libyuv::ARGBToYUY2(argb_data, argb_stride, yuyv_data, yuyv_stride, 
  frame.cols, frame.rows);
  // Then I feed yuyv_data to video stream buffer and see green or purple image instead of video stream.

UPDATE 3 更新3

  Mat frame;
  cvtColor(im, frame, CVX_BGR2BGRA);

  // ARGB
  int from_to[] = { 0,3, 1,2, 2,1, 3,0 };
  Mat rgba(frame.size(), frame.type());
  mixChannels(&frame, 1, &rgba, 1, from_to, 4);
  const uint8_t* argb_data = rgba.data;
  int argb_stride = rgba.cols*4;

  Mat yuyv(rgba.rows, rgba.cols, CVX_8UC2);
  uint8_t* yuyv_data = yuyv.data;
  int yuyv_stride = width * 2;
  int res = libyuv::ARGBToYUY2(argb_data, argb_stride, yuyv_data, yuyv_stride, rgba.cols, rgba.rows);

在此输入图像描述

似乎虽然方法被称为ARGBToYUY2,但它需要BGRA的频道顺序(而不是反向)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM