À±°û¼± °ËÃâ

3X3 ÄÁ¹ú·ç¼Ç( convolution ) ÇÊÅ͸¦ ÀÌ¿ëÇØ ¿Ü°û¼±À» °ËÃâÇØ º»´Ù.

À±°û¼±( Edge)À» °ËÃâÇϱâ À§Çؼ­´Â ¼Òº§( Sobel) ¿¬»êÀÚ¸¦ »ç¿ëÇÑ´Ù.
À±°û¼± °ËÃâ¿¡ »ç¿ëµÇ´Â ¸¶½ºÅ©´Â ´ÙÀ½°ú °°´Ù.

ÁÂ¿ì ¿Ü°û¼± °ËÃâ

»óÇÏ ¿Ü°û¼± °ËÃâ

-1

0

1

-2

0

2

-1

0

1

1

0

1

0

0

0

-1

-2

-1

ÁÂ¿ì ¿Ü°û¼± °ËÃâ ¼³¸í : Áß¾ÓÀ» Áß½ÉÀ¸·Î 3 X 3 Çȼ¿ÀÇ ¸ðµç°ªÀÌ µ¿ÀÏÇÏ¸é °á°ú °ªÀº 0ÀÌ´Ù.
      ¿ÞÂÊ Çȼ¿ÀÌ Å©¸é À½¼ö°ªÀÌ µÇ°í, ¿À¸¥ÂÊ Çȼ¿ÀÌ Å©¸é ¾ç¼ö°ªÀÌ µÈ´Ù.
      °á°ú ¸í¾Ï°ªÀ» lx¶ó ÇÏÀÚ.

»óÇÏ ¿Ü°û¼± °ËÃâ ¼³¸í ÁÂ¿ì ¿Ü°û¼± °ËÃâ°ú ºñ½ÁÇÑ ¿ø¸®ÀÌ´Ù.
       °á°ú ¸í¾Ï°ªÀ» ly¶ó ÇÏÀÚ.

lx¿Í lyÀÇ ±â¿ï±â Å©±â¸¦ ±¸ÇÑ´Ù.       

ÇÁ·Î±×·¥À» °£°áÇÏ°Ô ÇÒ·Á¸é ´ÙÀ½°ú °°ÀÌ ÇÑ´Ù.    L = |lx| + |ly|

Æнº ¼³Á¤

ColorConversion.rfx ÆÄÀÏ¿¡ À±°û¼± °ËÃâ ÆнºÀÎ Edge Æнº¸¦ Ãß°¡ÇÑ´Ù.

Sepia Æнº¿¡¼­ ¿À¸¥ÂÊ ¹öÆ°À» ´­·¯ Copy¸¦ ¼±ÅÃÇÑ´Ù.
ColorConversion Æнº¿¡¼­ ¿À¸¥ÂÊ ¹öÆ°À» ´­·¯ Paste¸¦ ¼±ÅÃÇÑ´Ù.
Æнº À̸§Àº Edge·Î ÇÑ´Ù.

Sepia Æнº´Â µðÁîºí ½ÃŲ´Ù.

Àü¿ª º¯¼ö Ãß°¡

Àü¿ªº¯¼ö gPixelOffsetÀ» Ãß°¡ÇÑ´Ù.

float2 gPixelOffset  

·»´õ¸ùÅ°¿¡¼­ [Add Variable - Float - Float2]¸¦ Ãß°¡ÇÑ´Ù.
À̸§À» gPixelOffsetÀ¸·Î ¹Ù²Û´Ù.
º¯¼ö ½Ã¸àƽÀ» ViewportDimensionsInverse·Î ¼³Á¤ÇÑ´Ù.

½Ã¸àƽ ¼³¸í : ·»´õ¸ùÅ°¿¡¼­ Áö¿øÇÏ´Â ½Ã¸àƽÀÌ´Ù. ¿£Áø¿¡¼­ º¯¼ö°ªÀ» Á÷Á¢ ¼³Á¤ÇØ ÁÖ¾î¾ß Çϳ®.

ViewportDimensions : ·»´õ¸ùÅ° PreviewÀÇ width¿Í height¸¦ ³ªÅ¸³½´Ù.
ViewportDimensionsInverse : ·»´õ¸ùÅ° PreviewÀÇ 1/width¿Í 1/height¸¦ ³ªÅ¸³½´Ù.

 

Çȼ¿ ½¦ÀÌ´õ

 

struct PS_INPUT
{
   float2 uv : TEXCOORD0;
};

float3x3 convX = { -1, 0, 1,
                   -2, 0, 2,
                   -1, 0, 1};
                     
float3x3 convY = { 1, 2, 1,
                   0, 0, 0,
                  -1, -2, -1};                     
   
float2 gPixelOffset;
   
sampler2D SceneSampler;

float4 ps_main( PS_INPUT input) : COLOR
{   
   float lx = 0;
   float ly = 0;
  
   for(int y = -1; y <= 1; ++y)
   {
      for(int x = -1; x <= 1; ++x)
      {
         float2 offset = float2(x, y) * gPixelOffset;
         float3 tex = tex2D( SceneSampler, input.uv + offset).rgb;
         float luminace = dot(tex, float3( 0.3, 0.59, 0.11));
      
         lx += luminace * convX[y+1][x+1];
         ly += luminace * convY[y+1][x+1];
      }
   }
   
   float l = sqrt(( lx*lx) + (ly*ly));
   return float4( l.xxx, 1);
}

¸¶½ºÅ©¸¦ 3 X 3 Çà·Ä·Î ¼±¾ðÇÑ´Ù.

float3x3 convX = { -1, 0, 1,
                   -2, 0, 2,
                   -1, 0, 1};
                     
float3x3 convY = { 1, 2, 1,
                   0, 0, 0,
                  -1, -2, -1};

ÇöÀç Çȼ¿À» Áß¾Ó¿¡ µÎ°í 3 X 3 Çà·ÄÀ» -1¿¡¼­ 1±îÁö ¹Ýº¹ÇÑ´Ù.

for(int y = -1; y <= 1; ++y)
{
   for(int x = -1; x <= 1; ++x)
   {

x, y¿¡ µû¶ó Çȼ¿ÀÇ ¿ÀÇÁ¼ÂÀ» ±¸ÇÑ´Ù.
UVÁÂÇ¥´Â 0 ~ 1 ¹üÀ§ÀÌ´Ù. ÇÑ °³ÀÇ Çȼ¿ÀÇ Å©±â´Â Çȼ¿ÀÇ 1/Çȼ¿ÀÇ Æø°ú  1/Çȼ¿ÀÇ ³ôÀÌ·Î ±¸ÇÒ ¼ö ÀÖ´Ù.
gPixelOffsetÀº ÇÑÇȼ¿ÀÇ Å©±âÀÌ´Ù.
ÅؽºÃÄ·Î °ªÀ» ÀÐ¾î ¿Â´Ù.

float2 offset = float2(x, y) * gPixelOffset;
float3 tex = tex2D( SceneSampler, input.uv + offset).rgb;

¸í¾ÏÀÇ Â÷ÀÌ·Î À±°û¼±À» ã´Â´Ù. Ä®¶ó¸¦ Èæ¹éÀ¸·Î º¯È¯ ½ÃŲ´Ù.

float luminace = dot(tex, float3( 0.3, 0.59, 0.11));

¼Òº§ ¿¬»êÀÚÀÇ ¸¶½ºÅ© °ª°ú ¸í¾ÏÀ» ´õÇÑ´Ù.

lx += luminace * convX[y+1][x+1];
ly += luminace * convY[y+1][x+1];

±â¿ï±â¸¦ ±¸ÇÑ´Ù.

float l = sqrt(( lx*lx) + (ly*ly));

¸í¾ÏÀÇ º¯È­°¡ ¾ø´Â°÷Àº °ËÀº»ö, Àִ°÷Àº ÇϾá»öÀ» ¹ÝȯÇÑ´Ù.
Ä®¶ó°ªÀÌ µ¿ÀÏÇØ¾ß Èæ¹éÀ¸·Î ³ª¿À±â ¶§¹®¿¡ xxx¸¦ ¹ÝȯÇÑ´Ù.

return float4( l.xxx, 1);

´Ù¿î·Îµå : ColorConversion_edge.rfx      fieldstone_SM.tga

Âü°í)
http://harmony.cs.pusan.ac.kr/lecture/ipcv/imageprocessing.htm