【问题标题】:Convert from YUV to RGB in c++ (android-ndk)在 C++ 中从 YUV 转换为 RGB (android-ndk)
【发布时间】:2017-04-28 01:20:50
【问题描述】:

我在android中开发,并且想将字节数组从相机的previewCallback(YUV格式)转换为rgb格式。

我已经使用了这个答案中给出的函数:Getting frames from Video Image in Android

它在java中完美运行,但我的问题是我想用c++制作函数(我使用的是ndk,对c++不是很熟悉)。

我尝试用c++创建函数,但总是产生奇怪的结果(例如图片全是绿色)。

有没有人有类似的功能或这个功能在 c++ 中工作?

谢谢。

【问题讨论】:

  • 在另一篇文章中发布您对该函数的 c++ 转换。我使用用户“Codevalley”的答案取得了巨大的成功。

标签: android c++ java-native-interface rgb yuv


【解决方案1】:

在 C++ 中从 YUYV 转换为 RGB:

unsigned char* rgb_image = new unsigned char[width * height * 3]; //width and height of the image to be converted

int y;
int cr;
int cb;

double r;
double g;
double b;

for (int i = 0, j = 0; i < width * height * 3; i+=6 j+=4) {
    //first pixel
    y = yuyv_image[j];
    cb = yuyv_image[j+1];
    cr = yuyv_image[j+3];

    r = y + (1.4065 * (cr - 128));
    g = y - (0.3455 * (cb - 128)) - (0.7169 * (cr - 128));
    b = y + (1.7790 * (cb - 128));

    //This prevents colour distortions in your rgb image
    if (r < 0) r = 0;
    else if (r > 255) r = 255;
    if (g < 0) g = 0;
    else if (g > 255) g = 255;
    if (b < 0) b = 0;
    else if (b > 255) b = 255;

    rgb_image[i] = (unsigned char)r;
    rgb_image[i+1] = (unsigned char)g;
    rgb_image[i+2] = (unsigned char)b;

    //second pixel
    y = yuyv_image[j+2];
    cb = yuyv_image[j+1];
    cr = yuyv_image[j+3];

    r = y + (1.4065 * (cr - 128));
    g = y - (0.3455 * (cb - 128)) - (0.7169 * (cr - 128));
    b = y + (1.7790 * (cb - 128));

    if (r < 0) r = 0;
    else if (r > 255) r = 255;
    if (g < 0) g = 0;
    else if (g > 255) g = 255;
    if (b < 0) b = 0;
    else if (b > 255) b = 255;

    rgb_image[i+3] = (unsigned char)r;
    rgb_image[i+4] = (unsigned char)g;
    rgb_image[i+5] = (unsigned char)b;
}

这个方法假设你的 yuyv_image 也是一个 unsigned char*。

更多关于YUYV的信息可以找到here

关于 YUYV 的更多说明 --> RGB 请查看this

【讨论】:

  • 我认为有一种更好的方法可以防止颜色失真:我知道的解决方案是将输入范围限制为 Y、Cb 和 Cr 的有效范围。 Y的有效范围为[16, 235],Cb,Cr的有效范围为[16, 240]。钳位输入:y = max(min(y, 235), 16); Cb = max(min(y, 240), 16); Cr = max(min(y, 240), 16);
  • 为什么你的 YUV 图像有 (3 * width * height) 字节的数据?它不应该有 (1.5 * width * height) 像素吗?
  • 此代码不完整且有错误。 rgb_image[+1] 之类的东西必须被根除
  • 这里的缩放因子之一似乎不正确。对于红色通道,此处使用 1.4065,但与其他来源的交叉检查表明正确的数字是 1.4075。所有其他数字与从数千个其他来源引用的数字完全匹配,但这个数字略有不同,表明它被错误地复制。
  • 这令人印象深刻,而且效果很好。 OpenCV 变得很烦人,所以我直接从 OpenBSD 的 v4l 层抓取网络摄像头镜头。这种转换是缺失的部分。另外,你是不是直接从脑子里打出来的? (for 循环中 i+=6 j+=4 之间缺少的 ',' 表明了这一点)。所以这更令人印象深刻;)
【解决方案2】:

看看这个: http://pastebin.com/mDcwqJV3

从 YUYV 到 RGB24 的定点转换

另外,有些相机返回的原始图像是 'UYVY' 字节排列的,所以在转换函数中做相应的更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多