Среднее значение байтов

Я пытаюсь создать (среднюю) шкалу серого для изображения и, похоже, не получаю значения для каждого пикселя. Я думаю, что при суммировании среднего я не правильно делаю расчеты, но я не могу найти, что не так.

public byte[] changePixelValues(byte blue, byte green, byte red) {
            //Convert to greyscale by average
            byte avg;
            int sum = 0;
            sum +=blue;
            sum += green;
            sum += red;
            avg = (byte) (sum / 3);

            //System.out.println("avg: " +  avg);
            byte[] values = new byte[3];

            values[0] = avg;
            values[1] = avg;
            values[2] = avg;

            return values;

Что-то я упустил при преобразовании типов?

РЕДАКТИРОВАТЬ:

Ниже приведены входные данные, где данные byte [] - это необработанные данные из BufferedImage, который в данном случае не имеет alphaRaster.

for (int i = 0; i < data.length; i += 3) {
      byte [] newData = changer.changePixelValues(data[i], data[i+1], data[i+2]);
      System.arraycopy(newData,0,data,i,3);
}

person Daniel Eineving    schedule 25.07.2015    source источник
comment
Вы можете показать нам несколько примеров входов и выходов? Ваш код выглядит нормально.   -  person Tim Biegeleisen    schedule 25.07.2015
comment
sum / 3 - целочисленное деление. Вы можете использовать sum / 3.0, чтобы сделать его двойным делением с последующим округлением до байта: avg = (byte) (Math.round(sum / 3.0)). Не уверен, правда ли в этом ваша проблема.   -  person Seelenvirtuose    schedule 25.07.2015
comment
Просто добавил правку в вопрос, описывающий использование.   -  person Daniel Eineving    schedule 25.07.2015
comment
Вы все еще не сказали нам, в чем именно заключается проблема. Вы не получаете изображение в оттенках серого? Неправильно ли байтовые выходы из changePixelValues()?   -  person Tim Biegeleisen    schedule 25.07.2015
comment
Судя по всему, я могу предположить, что ваш метод усреднения верен. Предоставьте некоторые входные и выходные данные, как уже предлагали другие.   -  person Turing85    schedule 25.07.2015
comment
Никакой помощи по вашей проблеме, но см. stackoverflow.com/questions / 687261 / для правильного средневзвешенного значения для преобразования оттенков серого.   -  person Mark Schäfer    schedule 25.07.2015
comment
Ваш код не показывает, как вы обрабатываете массив байтов, но если вы получили его из вызова BufferedImage.getData(), обратите внимание, что он возвращает копию данных изображения, это означает, что изменение содержимого массива не меняет BufferedImage.   -  person EmirCalabuch    schedule 25.07.2015
comment
Изображения в градациях серого обычно усредняют пиксели с некоторыми коэффициентами, не так, как вы делаете, потому что человеческие глаза не воспринимают 3 основных цвета одинаково. Например, в PAL он рассчитывается как Y′ = 0.299 R′ + 0.587 G′ + 0.114 B′ Почему шкала серого работает именно так?   -  person phuclv    schedule 25.07.2015
comment
Преобразование RGB в монохромный   -  person phuclv    schedule 25.07.2015


Ответы (1)


Прежде всего, если вы хотите преобразовать изображение в оттенки серого, ваш метод должен возвращать только одно байтовое значение, а не массив байтов. Если вы вернете один байт, вы можете присвоить это значение каждому каналу RGB, и вы получите изображение в градациях серого или установите это значение на 8-битное изображение.

Вам нужно помнить, что байт в java подписан (диапазон от -128 до 127), поэтому, если у вас есть, например, значение R-канала, равное 200 (значения канала могут быть в диапазоне от 0 до 255), и вы приводите его к байту, значение равно равно -56. Итак, если вы вычисляете среднее значение (предположим, что G = B = 100), у вас среднее значение равно 48 (должно быть 133).

person Springfield762    schedule 25.07.2015