Я преобразовал матрицу 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 на матрице. Я думаю, что я сделал это правильно, я взял 2x2 подматрицы из матрицы YUV, упорядочил значения от наименьшего к наибольшему и взял среднее значение между двумя значениями в середине.
Затем я использовал эту формулу из Википедии, чтобы получить доступ к плоскостям 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 (двойное значение)
{
возврат (значение> 255)? 255: (значение <0)? 0: значение;
} </p>