【问题标题】:YUV TO RGB results to negative valueYUV TO RGB 结果为负值
【发布时间】:2012-12-07 00:39:11
【问题描述】:

我正在使用 java 开发一个应用程序,它将 YUV 像素(x,y)转换为 RGB 像素,这就是我所做的:(数据是 YUV 字节数组)

int Y = data[ y * width + x];
            int U = data[ (int) (width * height + Math.floor(y/2) * Math.floor(width/2) + Math.floor(x/2) + 1)];
            int V = data[ (int) (width * height + Math.floor(y/2) * (width/2) + Math.floor(x/2) + 0)];

            int B = (int) (1.164*(Y - 16)+ 2.018*(U - 128));

            int G = (int) (1.164*(Y - 16) - 0.813*(V - 128) - 0.391*(U - 128));

            int R = (int) (1.164*(Y - 16) + 1.596*(V - 128));

但是最后我发现我得到的RGB值是负数。有人可以帮我弄这个吗? 谢谢!

【问题讨论】:

标签: java android image rgb yuv


【解决方案1】:

YUV 有很多“味道”,有时会与 YCbCr 混淆。您的公式似乎适用于 Y 在 [16,235] 中的格式,但是,我可以告诉您,这对于 Android 中返回的 NV21 图像格式(一种标准 YUV 平面)是不正确的。

【讨论】:

  • Here 是一个似乎与这个答案相矛盾的帖子。他们在做什么不同的事情吗?他们似乎将这个精确的公式(尽管是整数近似)应用于 8 位 YUV 值(NV21)。
  • 我确信 Android 亮度值在 [0,255] 范围内。我不知道调用一个或另一个 NV21 是否错误,但我认为 NV21 使用了完整的 8 位 Y。有问题的帖子似乎证实了这一点,尽管我同意这个公式看起来像是在做其他事情。
  • 我对此进行了更多阅读。上面链接的帖子中的公式有效。这是一个非常快的整数逼近(移动设备的 int 速度通常快 2 倍)。正如你所说,YUV 值在 [0,255] 中。但是,在进行 YUV 到 RGB 转换时,可能会得到负的 R、G 或 B 值。大于 255 的值也是可能的。这些只是分别设置为 0 或 255。
【解决方案2】:

this YUV Wikipedia page. 上有类似的 C++ 转换

在公式转换代码之后,R、G、B 值被限制在 0-255 之间。

您是否在 Java 中尝试过类似的东西?

@MelindaGreen 的answer to a different question 包含一个进行 yuv->rgb 转换的方法,它也会产生负 RGB 值。

将负值设置为 0 产生的颜色对我来说很合适。

【讨论】:

    【解决方案3】:
    //
    // C++ code to convert between RGB and YUV where values are 0..255.
    //
    
    typedef struct XYZ {
        double x,y,z;
    };
    
    XYZ rgb2yuv(double r, double g, double b)
    {
        XYZ xyz;
    
        double R = r/255.0;
        double G = g/255.0;
        double B = b/255.0;
    
        double Y =  0.299*R + 0.587*G + 0.114*B;
        double U = -0.147*R - 0.289*G + 0.436*B;
        double V =  0.615*R - 0.515*G - 0.100*B;
    
        xyz.x = Y*255.0;
        xyz.y = (U+0.5)*255.0;
        xyz.z = (V+0.5)*255.0;
    
        return xyz;
    }
    
    XYZ yuv2rgb(double y, double u, double v)
    {
        XYZ xyz;
    
        double Y = y/255.0;
        double U = u/255.0-0.5;
        double V = v/255.0-0.5;
    
        double R = Y + 1.140*V;
        double G = Y - 0.395*U - 0.581*V;
        double B = Y + 2.032*U;
    
        xyz.x = R*255.0;
        xyz.y = G*255.0;
        xyz.z = B*255.0;
    
        return xyz;
    }
    

    【讨论】:

      猜你喜欢
      • 2017-04-23
      • 1970-01-01
      • 2012-11-25
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 2014-09-18
      • 2012-05-20
      • 2013-07-27
      相关资源
      最近更新 更多