2017-02-22 58 views
0

The issue in shortбилинейной интерполяцией Byte опрокидывании Java

Так я работал на 3d программного рендеринга и нужен метод билинейной интерполяции. Я работаю с 3-байтовым BGR растром для скорости, и я не могу понять, как мой код функционально отличается от того, что работает, я соскабливал вместе, напрямую обращаясь к самому изображению. Я выложу код перед результатами.

float lerp(float x1, float x2, float a) { 
    return x1 * (1 - a) + x2 * a; 
} 

Базовая линейная интерполяция algorithem

void berp(float sourceX, float sourceY, int destPos, byte[] source, byte[] dest, int sourceWidth) { 
    float ax = sourceX - 0.5f; 
    float bx = sourceX + 0.5f; 
    float xa = ax - (int) (ax); 
    float ay = sourceY - 0.5f; 
    float by = sourceY + 0.5f; 
    float ya = ay - (int) (ay); 
    int pos1 = (((int) ay) * sourceWidth + ((int) ax)) * 3; 
    int pos2 = (((int) ay) * sourceWidth + ((int) bx)) * 3; 
    int pos3 = (((int) by) * sourceWidth + ((int) ax)) * 3; 
    int pos4 = (((int) by) * sourceWidth + ((int) bx)) * 3; 

Просто установите его так, что Pos1 через pos4 позиции в исходном массиве 4 ближайших точек к coards (sourceX & sourceY) данного. xa и ya - расстояние от углов до центра пикселя до вершины, а пиксель - влево, так что в основном просто, чтобы пробовать от каждого пикселя.

dest[destPos] = (byte) lerp(lerp(source[pos1], source[pos2], xa), lerp(source[pos3], source[pos4], xa), ya); 
    dest[destPos + 1] = (byte) lerp(lerp(source[pos1 + 1], source[pos2 + 1], xa), lerp(source[pos3 + 1], source[pos4 + 1], xa), ya); 
    dest[destPos + 2] = (byte) lerp(lerp(source[pos1 + 2], source[pos2 + 2], xa), lerp(source[pos3 + 2], source[pos4 + 2], xa), ya); 
} 

Здесь я интерполяция между RGB1 и RGB2 затем rgb3 и rgb4 с помощью Xa. Затем я беру результаты этих операций и интерполирую между ними с помощью ya. Повторите для зеленого и красного цветов, и он должен выглядеть золотым.

КРОМЕ:

Just look at this pic, there is no way to describe it using words.

Я уверен, что вы видите мое затруднительное положение.

Любая помощь вообще на этом этапе была бы рада, я пробовал в течение многих часов безрезультатно, похоже, что это опрокидывание с использованием плавающего байта, но я действительно не вижу, как это может быть дано, что lerp только когда-либо дают значение между x1 и x2 и только байты идут в так ...

*

*

*

*

*

Только что пришло в голову, что было бы полезно добавить код, который создал правильное изображение. Некоторые имена и вещи могут быть разными, но суть этого все есть :)

private int getColorBilinear (float x, float y, BufferedImage s) { 
    float nx = x - 0.5f; 
    float xa = nx - (int) (nx); 
    float ny = y - 0.5f; 
    float ya = ny - (int) (ny); 
    int rgb1 = s.getRGB((int) (x - 0.5), (int) (y - 0.5)); 
    int rgb2 = s.getRGB((int) (x + 0.5), (int) (y - 0.5)); 
    int rgb3 = s.getRGB((int) (x - 0.5), (int) (y + 0.5)); 
    int rgb4 = s.getRGB((int) (x + 0.5), (int) (y + 0.5)); 

    return (int) (interpolate(
      interpolate(((rgb1 >> 16) & 0x000000FF), ((rgb2 >> 16) & 0x000000FF), xa), 
      interpolate(((rgb3 >> 16) & 0x000000FF), ((rgb4 >> 16) & 0x000000FF), xa), 
      ya)) << 16 
      | (int) (interpolate(
      interpolate(((rgb1 >> 8) & 0x000000FF), ((rgb2 >> 8) & 0x000000FF), xa), 
      interpolate(((rgb3 >> 8) & 0x000000FF), ((rgb4 >> 8) & 0x000000FF), xa), 
      ya)) << 8 
      | (int) (interpolate(interpolate((rgb1 & 0x000000FF), (rgb2 & 0x000000FF), xa), 
      interpolate((rgb3 & 0x000000FF), (rgb4 & 0x000000FF), xa), ya)); 
} 

ответ

0

Сам процесс заключается в следующем:

  • Значение пикселя оцифровываются как беззнаковый байт
  • байт (предполагается, которые должны быть подписаны) интерполируются
  • интерполированное значение, чем используется в целевом изображении, как байт без знака

Теперь потрясающе это действительно работает в большинстве случаев. Проблема возникает, когда одно из значений источника выше 127, а другое - ниже. Например, метод интерполяции будет видеть (129,125) как (-127,125) и пытается интерполировать как таковой. Одним из способов борьбы с этой проблемой было бы сначала преобразовать в int, затем интерполяцию; реализация которых приводится ниже.

float lerp(byte x1, byte x2, float a) { 

return unsignedByteToInt(x1) * (1 - a) + unsignedByteToInt(x2) * a; 

} 

int unsignedByteToInt(byte x) {return (((int) x) + 255) % 255;} 

 Смежные вопросы

  • Нет связанных вопросов^_^