我使用以下公式将 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 子矩阵,将值从最小到最大排序,并取中间 2 个值之间的平均值。
然后我使用维基百科上的这个公式来访问 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
问题是我的图像没有恢复到原来的颜色。
以下是供参考的图像:https://i.stack.imgur.com/vQkpT.jpg https://i.stack.imgur.com/vQkpT.jpg(二次采样)https://i.stack.imgur.com/Oucc5.jpg https://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)
>> 是否意味着我应该移位?
我将不胜感激任何帮助/评论!谢谢
Update
尝试进行 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 剪辑(双精度值)
{
返回(值> 255)? 255:(值