forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Алгоритмика (http://forum.boolean.name/forumdisplay.php?f=21)
-   -   Карта высот из картинки (http://forum.boolean.name/showthread.php?t=16023)

pax 12.12.2011 12:51

Карта высот из картинки
 
Подскажите, есть ли какие-то специальные алгоритмы построения карты высот по картинке?

Нужно для дальнейшего преобразования в карту нормалей.

dsd 12.12.2011 13:50

Ответ: Карта высот из картинки
 
Насчет специальных алгоритмов я не знаю, по моему карта высот она и в Африке карта высот и вся подготовка может быть выполнена в графическом редакторе. А вот по нормалям чутка есть.

Код:

        for(int i=0;i<uppersize;i++){
            for(int j=0;j<uppersize;j++){
            int x0=i-1,x1=i+1,y0=j-1,y1=j+1;
            //check of indexes size
            if(i==0){x0=uppersize-1;}
            if(i==uppersize-1){x1=0;}
            if(j==0){y0=uppersize-1;}
            if(j==uppersize-1){y1=0;}
            //normals
            float3  a00(-1,first->seed[x0][y0]-first->seed[i][j],-1); a00.normalize();
            float3  a10(0,first->seed[i][y0]-first->seed[i][j],-1); a10.normalize();
            float3  a20(1,first->seed[x1][y0]-first->seed[i][j],-1); a20.normalize();

            float3  a01(-1,first->seed[x0][j]-first->seed[i][j],0); a01.normalize();
            float3  a11(0,first->seed[i][j]-first->seed[i][j],0); a11.normalize();
            float3  a21(1,first->seed[x1][j]-first->seed[i][j],0); a21.normalize();

            float3  a02(-1,first->seed[x0][y1]-first->seed[i][j],1); a02.normalize();
            float3  a12(0,first->seed[i][y1]-first->seed[i][j],1); a12.normalize();
            float3  a22(1,first->seed[x1][y1]-first->seed[i][j],1); a22.normalize();

            //result normal
            float3 result=a00*a10+a10*a20+a20*a21+a21*a22+a22*a12+a12*a02+a02*a01+a01*a00;result.normalize();
            norm[i][j]=-1*result;
            }}

first->seed[x0][y1] - это моя карта высот там :)
Плюс даже из гладкой карты высот получится наждачная бумага вместо приличной карты нормалей, но она довольно легко сглаживается gausian blur'ом

Код:

            int radius=32;
            gauss_mask=new float*[radius];
            for(int i=0;i<radius;i++){gauss_mask[i]=new float[radius];}
            for(int i=0;i<radius;i++){
                for(int j=0;j<radius;j++){

                    gauss_mask[i][j]=gaussian_blur(i,j, 12.4);

                }}

float gaussian_blur(int x,int y, float sigma)
{

    float koff=(1/sqrt(2*M_PI*pow(sigma,2)))*pow(M_E,-(x*x+y*y)/(2*sigma*sigma));
    return koff;

}

и после построения маски и применения её к изначальной карте нормалей получался более приличный результат.

        for(int i=0;i<uppersize;i++){
        for(int j=0;j<uppersize;j++){
            for(int x=0;x<radius;x++){
            for(int y=0;y<radius;y++){
              //now will sum all here
              if(x==0 && y==0){normb[i][j]=gauss_mask[x][y]*norm[i][j];}
              else if((x==0 && y!=0) ||(x!=0 && y==0)){
              int x0=i-x,x1=i+x,y0=j-y,y1=j+y;
              if(x0<0){x0=uppersize+x0;}
              if(x1>=uppersize){x1=x1-uppersize;}
              if(y0<0){y0=uppersize+y0;}
              if(y1>=uppersize){y1=y1-uppersize;}
              normb[i][j]=normb[i][j]+ 0.5*gauss_mask[x][y]*(norm[x0][y0]+norm[x1][y0]+norm[x0][y1]+norm[x1][y1]);
              }
              else{
              int x0=i-x,x1=i+x,y0=j-y,y1=j+y;
              if(x0<0){x0=uppersize+x0;}
              if(x1>=uppersize){x1=x1-uppersize;}
              if(y0<0){y0=uppersize+y0;}
              if(y1>=uppersize){y1=y1-uppersize;}
              normb[i][j]=normb[i][j]+gauss_mask[x][y]*(norm[x0][y0]+norm[x1][y0]+norm[x0][y1]+norm[x1][y1]);
              }
            }}
          normb[i][j].normalize();
        }}


pax 12.12.2011 13:55

Ответ: Карта высот из картинки
 
Нормали я считать умею, а вот карту высот по цветному изображению построить тяжело.

pax 12.12.2011 13:57

Ответ: Карта высот из картинки
 
Попробую использовать формулу grayscale
PHP код:

Lum := Red 0.299 Green 0.587 Blue 0.114


dsd 12.12.2011 14:06

Ответ: Карта высот из картинки
 
В смысле фотку со спутника к карте высот образовывающей похожий ландшафт привести?

pax 12.12.2011 14:18

Ответ: Карта высот из картинки
 
Ну похожий явно не получится, но ты понял задачу)

dsd 12.12.2011 14:30

Ответ: Карта высот из картинки
 
А почему нельзя топологическую карту очищенную от мусора использовать? Зря что ли геодезисты с теодолитами ноги по горам ломали? Тем паче, что там есть явная зависимость высоты от цвета, плюс линиями одинаковая высота показана.

Mr_F_ 12.12.2011 14:52

Ответ: Карта высот из картинки
 
если необязательно свой код, то CrazyBump умеет что-то подобное

pax 12.12.2011 15:02

Ответ: Карта высот из картинки
 
Цитата:

Сообщение от dsd (Сообщение 213684)
А почему нельзя топологическую карту очищенную от мусора использовать? Зря что ли геодезисты с теодолитами ноги по горам ломали? Тем паче, что там есть явная зависимость высоты от цвета, плюс линиями одинаковая высота показана.

не не, у меня не связано с ландшафтом)

Вопрос в экономии ресурсов в проекте. Если например можно не скачивать нормалмэпы с сервера а генерировать.

radiobutton 12.12.2011 16:27

Ответ: Карта высот из картинки
 
(red+green+blue) /(255*3)
ne?

pax 12.12.2011 16:36

Ответ: Карта высот из картинки
 
не, grayscale дает лучший эффект в таком случае.

dsd 12.12.2011 17:17

Ответ: Карта высот из картинки
 
А если пытаться выделить на текстуре те участки, где цвет меняет оттенок по трем каналам одинаково. То получается, что текущий цвет в пятне/ максимальный цвет в пятне => cos(угол между нормаль текущей точки и нормаль само светлой в пятне(0,1,0)). Потом исходя из расстояния и угла вектора от точки до точки на изображении получать еще один вектор. Потом неведомым образом после разглядывания результата, бааац и нормалмапа?

pax 12.12.2011 17:19

Ответ: Карта высот из картинки
 
Если получится, то дай знать)))
Я пока остановился на grayscale.

dsd 20.12.2011 23:46

Ответ: Карта высот из картинки
 
В рендерманке есть один шейдер, который из

делает:
вершинный
Код:

struct VS_OUTPUT {
  float4 Pos: POSITION;
  float2 texCoord: TEXCOORD;
};

VS_OUTPUT main(float4 Pos: POSITION){
  VS_OUTPUT Out;

  // Clean up inaccuracies
  Pos.xy = sign(Pos.xy);

  Out.Pos = float4(Pos.xy, 0, 1);
  // Image-space
  Out.texCoord.x = 0.5 * (1 + Pos.x);
  Out.texCoord.y = 0.5 * (1 - Pos.y);

  return Out;
}


пиксельный
Код:

float TextureSize: register(c1);
float4 lightness: register(c0);
sampler BaseMap: register(s0);
// The Sobel filter extracts the first order derivates of the image,
// that is, the slope. The slope in X and Y directon allows us to
// given a heightmap evaluate the normal for each pixel. This is
// the same this as ATI's NormalMapGenerator application does,
// except this is in hardware.
//
// These are the filter kernels:
//
//  SobelX      SobelY
//  1  0 -1      1  2  1
//  2  0 -2      0  0  0
//  1  0 -1    -1 -2 -1

float4 main(float2 texCoord: TEXCOORD) : COLOR {
  float off = 1.0 / TextureSize;

  // Take all neighbor samples
  float4 s00 = tex2D(BaseMap, texCoord + float2(-off, -off));
  float4 s01 = tex2D(BaseMap, texCoord + float2( 0,  -off));
  float4 s02 = tex2D(BaseMap, texCoord + float2( off, -off));

  float4 s10 = tex2D(BaseMap, texCoord + float2(-off,  0));
  float4 s12 = tex2D(BaseMap, texCoord + float2( off,  0));

  float4 s20 = tex2D(BaseMap, texCoord + float2(-off,  off));
  float4 s21 = tex2D(BaseMap, texCoord + float2( 0,    off));
  float4 s22 = tex2D(BaseMap, texCoord + float2( off,  off));

  // Slope in X direction
  float4 sobelX = s00 + 2 * s10 + s20 - s02 - 2 * s12 - s22;
  // Slope in Y direction
  float4 sobelY = s00 + 2 * s01 + s02 - s20 - 2 * s21 - s22;

  // Weight the slope in all channels, we use grayscale as height
  float sx = dot(sobelX, lightness);
  float sy = dot(sobelY, lightness);

  // Compose the normal
  float3 normal = normalize(float3(sx, sy, 1));

  // Pack [-1, 1] into [0, 1]
  return float4(normal * 0.5 + 0.5, 1);
}

NormalMapFilter называется


Часовой пояс GMT +4, время: 16:06.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot