我使用以下公式将RGB矩阵转换为YUV矩阵:
Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16
Cr = V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128
Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128
然后我在矩阵上做了一个4:2:0的色度子样本。我认为我做得正确,我从YUV矩阵中取出2x2子矩阵,将值从最小值排序到最大值,然后取中间值的平均值。
然后我使用维基百科的这个公式来访问Y,U和V平面:
size.total = size.width * size.height;
y = yuv[position.y * size.width + position.x];
u = yuv[(position.y / 2) * (size.width / 2) + (position.x / 2) + size.total];
v = yuv[(position.y / 2) * (size.width / 2) + (position.x / 2) + size.total + (size.total / 4)];
我正在使用OpenCV,所以我尽力解释这个:
y = src.data[(i*channels)+(j*step)];
u = src.data[(j%4)*step + ((i%2)*channels+1) + max];
v = src.data[(j%4)*step + ((i%2)*channels+2) + max + (max%4)];
src是YUV子采样矩阵。我是否正确地解释了这个公式?
以下是我将颜色转换回RGB的方法:
bgr.data[(i*channels)+(j*step)] = (1.164 * (y - 16)) + (2.018 * (u - 128)); // B
bgr.data[(i*channels+1)+(j*step)] = (1.164 * (y - 16)) - (0.813 * (v - 128)) - (0.391 * (u - 128)); // G
bgr.data[(i*channels+2)+(j*step)] = (1.164 * (y - 16)) + (1.596 * (v - 128)); // R
问题是我的图像没有恢复原来的颜色。
以下图片供参考: http://i.stack.imgur.com/vQkpT.jpg(子样本) http://i.stack.imgur.com/Oucc5.jpg(输出)
我看到我现在应该从YUV444转换为RGB,但我不太清楚我在Wiki上找到的示例中的剪辑功能是什么。
C = Y' − 16
D = U − 128
E = V − 128
R = clip(( 298 * C + 409 * E + 128) >> 8)
G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
B = clip(( 298 * C + 516 * D + 128) >> 8)
是>>我的意思是我应该换位?
感谢任何帮助/评论!感谢
更新
尝试进行YUV444转换,但它只是使我的图像以绿色阴影显示。
y = src.data[(i*channels)+(j*step)];
u = src.data[(j%4)*step + ((i%2)*channels+1) + max];
v = src.data[(j%4)*step + ((i%2)*channels+2) + max + (max%4)];
c = y - 16;
d = u - 128;
e = v - 128;
bgr.data[(i*channels+2)+(j*step)] = clip((298*c + 409*e + 128)/256);
bgr.data[(i*channels+1)+(j*step)] = clip((298*c - 100*d - 208*e + 128)/256);
bgr.data[(i*channels)+(j*step)] = clip((298*c + 516*d + 128)/256);
我的剪辑功能: int clip(double value) { 返回(值> 255)? 255 :(值<0)? 0:价值; }
答案 0 :(得分:2)
将WebM帧解码为RGB时遇到了同样的问题。经过几个小时的搜索,我终于找到了解决方案。
从此处获取SCALEYUV功能:http://www.telegraphics.com.au/svn/webpformat/trunk/webpformat.h
然后从YUV解码RGB数据,请参阅此文件: http://www.telegraphics.com.au/svn/webpformat/trunk/decode.c
搜索“py = img-&gt; planes [0];”,有两种算法可以转换数据。我只尝试了一个简单的(在“//然后回到更便宜的方法之后。”)。
代码中的注释也可以参考此页面:http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC30
非常适合我。
答案 1 :(得分:1)
由于UV会压缩图像,因此您无法完全恢复相同的图像 你没有说结果是完全错误(即错误)还是不完美
R = clip(( 298 * C + 409 * E + 128) >> 8)
G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
B = clip(( 298 * C + 516 * D + 128) >> 8)
&gt;&gt; 8是一个位移,相当于除以256.这只是为了让你以整数单位而不是浮点速度来做所有的算术
答案 2 :(得分:0)
正在试验维基上的公式并发现混合公式:
byte c = (byte) (y - 16);
byte d = (byte) (u - 128);
byte e = (byte) (v - 128);
byte r = (byte) (c + (1.370705 * (e)));
byte g = (byte) (c - (0.698001 * (d)) - (0.337633 * (e)));
byte b = (byte) (c + (1.732446 * (d)));
生产&#34;更好&#34;我的图像的错误,只是使一些黑点纯绿色(即rgb = 0x00FF00),这更好地检测和纠正......
wiki来源:https://en.wikipedia.org/wiki/YUV#Y.27UV420p_.28and_Y.27V12_or_YV12.29_to_RGB888_conversion