YUV TO RGB приводит к отрицательному значению

Я разрабатываю приложение с использованием 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 отрицательны. Может кто-то помочь мне с этим? Спасибо!


person Junfei Wang    schedule 07.12.2012    source источник
comment
stackoverflow.com/ вопросы/2905597/ дублируются   -  person 0x90    schedule 07.12.2012


Ответы (2)


У YUV много «ароматов», и иногда их смешивают с YCbCr. Ваша формула кажется подходящей для форматов, где Y находится в [16,235], но я могу сказать вам, что это неверно для формата изображения NV21 (тип стандартного плоского YUV), возвращаемого в Android.

person Sean Owen    schedule 07.12.2012
comment
Вот пост, который, кажется, противоречит этому ответу. Есть ли что-то другое, что они делают? Кажется, они применяют эту точную формулу (хотя и в целочисленном приближении) к 8-битным значениям YUV (NV21). - person maverick1989; 15.09.2014
comment
Я уверен, что значения яркости Android находятся в пределах [0,255]. Я не знаю, неправильно ли называть тот или иной NV21, но я думаю, что NV21 использует полные 8 бит Y. Рассматриваемый пост, кажется, подтверждает это, хотя я согласен, что формула выглядит так, как будто она делает что-то еще. - person Sean Owen; 16.09.2014
comment
Я еще немного почитал об этом. Формула в посте, указанном выше, работает. Это довольно быстрое целочисленное приближение (мобильные устройства обычно делают это примерно в 2 раза быстрее). Значения YUV находятся в [0,255], как вы говорите. Однако МОЖНО получить отрицательные значения R, G или B при преобразовании YUV в RGB. Также возможны значения больше 255. Они просто устанавливаются на 0 или 255 соответственно. - person maverick1989; 17.09.2014

Аналогичное преобразование в C++ находится на этой странице Википедии YUV.

После формульного кода преобразования значения R, G, B фиксируются в диапазоне 0-255.

Вы пробовали что-то подобное на Java?

@MelindaGreen ответ на другой вопрос включает метод, который выполняет преобразование yuv->rgb, которое также дает отрицательные значения RGB.

Установка отрицательных значений на 0 произвела цвета, которые мне кажутся правильными.

person Ryan    schedule 02.08.2016