블로그는 귀차니즘

First Sensation
  • 공지
  • 지역로그
  • 태그
  • 방명록

Bitmap Filtering - 비트맵 필터링

Program 2008/04/04 23:01 귀차니스트
  작년 9월쯤, 어떻게 하다보니 회사 내부 아는 분들의 부탁으로 작성했었던 프로그램입니다. 그냥 과제를 해야 하는데 프로젝트 때문에 시간이 없다보니 제가 하게 되어 만들었던 프로그램이죠. 비트맵이라는 것이 실질적으로 그림정보를 들고 있는 것이기 때문에 아주 복잡한 기능은 적용하지 않고 간단한 기능들을 추가해보았습니다.



  프로그램 모습은 위 그림과 같습니다. 대충 메뉴를 소개하자면 아래와 같습니다.



  기능은 간단하게 1명당 1개의 기능으로 구성을 했었기 때문에 명도, 블러, 경계값, 반전, 모자이크 기능을 넣었었죠. 그럼 기능을 수행하면 어떻게 되는지 한 번 살펴보겠습니다.



  명도를 선택하면 다음과 같이 RGB 전체의 값을 일정 크기만큼 증가시키는 기능으로 구현했습니다. 코드는 다음과 같죠. 실제적으로 명도를 증가시키려면 HSI 로 나눈 뒤, 작업을 해야 할 것입니다.

CBrightness.cpp (Language : cpp)
  1. void CBrightness::Convert2Filter( DWORD *inData, DWORD *OurData, int RawWidth, int RawHeight )
  2. {
  3.     this->ImgWidth  = RawWidth;
  4.     this->ImgHeight = RawHeight;
  5.  
  6.     // 설정 창을 표시 하고 BlurFactor 에 세팅한 다음 작업한다.
  7.    
  8.     if( -150 <= InputFactor && InputFactor <= 150 ) {
  9.  
  10.         AtomFactor = InputFactor / 3;
  11.  
  12.         for( int i = 0; i < RawHeight; i++ )    {
  13.             for( int j = 0; j < RawWidth; j++ ) {
  14.                 ColorUnion ColorData = GetBrightnessPixel( inData, j, i );
  15.                 SetPixel( OurData, j, i, ColorData );
  16.             }
  17.         }
  18.     }
  19. }
  20.  
  21. ColorUnion CBrightness::GetBrightnessPixel( DWORD *inData, int X, int Y )
  22. {
  23.     ColorUnion ColorData = GetPixel( inData, X, Y );
  24.     int Red = ColorData.ColorPixel.Red, Green = ColorData.ColorPixel.Green, Blue = ColorData.ColorPixel.Blue;
  25.  
  26.     Red  += AtomFactor;
  27.     Green   += AtomFactor;
  28.     Blue    += AtomFactor;
  29.  
  30.     if( Red < 0 )
  31.         Red = 0;
  32.     else if( 254 < Red )
  33.         Red = 254;
  34.  
  35.     if( Green < 0 )
  36.         Green = 0;
  37.     else if( 254 < Green )
  38.         Green = 254;
  39.  
  40.     if( Blue < 0 )
  41.         Blue = 0;
  42.     else if( 254 < Blue )
  43.         Blue = 254;
  44.  
  45.     return MakePixel( 0xFF, Red, Green, Blue );
  46. }

  복잡한것 같지만 32비트 이미지를 1바이트 마다 나누어 RGB 값을 일정 크기만큼 더해주는 기능입니다.



  다음은 블러기능입니다. 보통 포토샵을 보면 뽀샤시 효과를 위해서 자주 사용하는 필터죠. 사실 블러에는 가우시안 블러, 모션 블러를 비롯해서 많은 종류가 존재하지만 위 같은 경우엔 그냥 뿌옇게 흐리는 기능만을 구현했죠.

CBlur.cpp (Language : cpp)
  1. void CBlur::Convert2Filter( DWORD *inData, DWORD *OurData, int RawWidth, int RawHeight )
  2. {
  3.     this->ImgWidth  = RawWidth;
  4.     this->ImgHeight = RawHeight;
  5.  
  6.     // 설정 창을 표시 하고 BlurFactor 에 세팅한 다음 작업한다.
  7.    
  8.     for( int i = 0; i < RawHeight; i++ )    {
  9.         for( int j = 0; j < RawWidth; j++ ) {
  10.             ColorUnion ColorData = GetBlurPixel( inData, j, i );
  11.             SetPixel( OurData, j, i, ColorData );
  12.         }
  13.     }
  14. }
  15.  
  16. ColorUnion CBlur::GetBlurPixel( DWORD *inData, int X, int Y )
  17. {
  18.     int Red = 0, Green = 0, Blue = 0;
  19.     ColorUnion OriginalColor = GetPixel( inData, X, Y );
  20.  
  21.     for( int i = Y - InputFactor; i <= Y + InputFactor; i++ )   {
  22.         for( int j = X - InputFactor; j <= X + InputFactor; j++ )   {
  23.            
  24.             if( IsContain( j, i ) ) {
  25.                 ColorUnion ColorData = GetPixel( inData, j, i );
  26.  
  27.                 Red  += ColorData.ColorPixel.Red;
  28.                 Green   += ColorData.ColorPixel.Green;
  29.                 Blue    += ColorData.ColorPixel.Blue;
  30.             }
  31.             else    {
  32.                 Red  += OriginalColor.ColorPixel.Red;
  33.                 Green   += OriginalColor.ColorPixel.Green;
  34.                 Blue    += OriginalColor.ColorPixel.Blue;
  35.             }
  36.         }
  37.     }
  38.  
  39.     int DividerNumber = static_cast< int >( std::pow( 2 * InputFactor + 1, 2.0 ) );
  40.  
  41.     Red  /= DividerNumber;
  42.     Green   /= DividerNumber;
  43.     Blue    /= DividerNumber;
  44.    
  45.     return MakePixel( 0xFF, Red, Green, Blue );
  46. }

  일정 범위의 픽셀에 대하여 RGB값을 서로 더하여 평균값을 구하는 것인데 물론 모자이크 필터가 아니다보니 가중치를 주어 원래 자기의 색이 다른 픽셀의 값에 밀리지 않도록 구현을 해주어야 합니다.


  이 것 또한 포토샵에서 볼 수 있는 Threshold 필터 입니다. 이 것은 어떠한 점에 존재하는 픽셀값이 일정 값 이상이면 하얀색 아닐 경우 검은색으로 표시하는 기능입니다. 보통 이미지패턴 처리를 위하여 자주 사용하는 기본 필터이기도 하죠.

CThreshold.cpp (Language : cpp)
  1. void CThreshold::Convert2Filter( DWORD *inData, DWORD *OurData, int RawWidth, int RawHeight )
  2. {
  3.     this->ImgWidth  = RawWidth;
  4.     this->ImgHeight = RawHeight;
  5.  
  6.     // 쓰레숄드 값 세팅 입력 받고
  7.  
  8.     for( int i = 0; i < RawHeight; i++ )    {
  9.         for( int j = 0; j < RawWidth; j++ ) {
  10.            
  11.             ColorUnion ColorData = GetThresholdColor( inData, j, i );
  12.             SetPixel( OurData, j, i, ColorData );
  13.         }
  14.     }
  15. }
  16.  
  17. ColorUnion CThreshold::GetThresholdColor( DWORD *inData, int X, int Y )
  18. {
  19.     int AvgData = 0;
  20.     ColorUnion ColorData = GetPixel( inData, X, Y );
  21.    
  22.     AvgData = ( ColorData.ColorPixel.Red + ColorData.ColorPixel.Green + ColorData.ColorPixel.Blue ) / 3;
  23.    
  24.     if( AvgData >= InputFactor )
  25.         ColorData = MakePixel( 0xFF, 0xFF, 0xFF, 0xFF );
  26.     else
  27.         ColorData = MakePixel( 0x00, 0x00, 0x00, 0x00 );
  28.  
  29.     return ColorData;
  30. }


  Invert 필터입니다. 바로 반전 기능이죠. 뭔가 느낌이 그로테스크 하지 않나요?^^ 사실 이 기능은 위 쓰레숄드 만큼이나 구현하기 쉽습니다. 왜냐하면 RGB 값을 바로 ~ 연산 취하면 되기 때문이죠.

CInvert.cpp (Language : cpp)
  1. void CInvert::Convert2Filter( DWORD *inData, DWORD *OurData, int RawWidth, int RawHeight )
  2. {
  3.     this->ImgWidth  = RawWidth;
  4.     this->ImgHeight = RawHeight;
  5.  
  6.     for( int i = 0; i < RawHeight; i++ )    {
  7.         for( int j = 0; j < RawWidth; j++ ) {
  8.            
  9.             ColorUnion ColorData = GetPixel( inData, j, i );
  10.  
  11.             ColorData.ColorPixel.Red    = ~ColorData.ColorPixel.Red;
  12.             ColorData.ColorPixel.Green  = ~ColorData.ColorPixel.Green;
  13.             ColorData.ColorPixel.Blue   = ~ColorData.ColorPixel.Blue;
  14.  
  15.             SetPixel( OurData, j, i, ColorData );
  16.         }
  17.     }
  18. }
  19.  


  마지막으로 모자이크 필터입니다. 이 것 또한 대충 구현하는 방법이 짐작되시죠?^^ 위에 언급한 블러 필터에서 모자이크 필터 얘기가 나왔으므로 아마 다들 짐작하실 것으로 생각합니다. 약간의 응용만 하시면 됩니다.

CMosaic.cpp (Language : cpp)
  1. void CMosaic::Convert2Filter( DWORD *inData, DWORD *OurData, int RawWidth, int RawHeight )
  2. {
  3.     this->ImgWidth  = RawWidth;
  4.     this->ImgHeight = RawHeight;
  5.  
  6.     // 모자이크 팩터 입력 받고
  7.  
  8.     for( int i = 0; i < RawHeight; i += InputFactor )   {
  9.         for( int j = 0; j < RawWidth; j += InputFactor )    {
  10.            
  11.             ColorUnion ColorData = GetMosaicPixel( inData, j, i );
  12.  
  13.             for( int YIdx = i; YIdx < i + InputFactor; YIdx++ ) {
  14.                 for( int XIdx = j; XIdx < j + InputFactor; XIdx++ ) {
  15.  
  16.                     if( IsContain( XIdx, YIdx ) )
  17.                         SetPixel( OurData, XIdx, YIdx, ColorData );
  18.                 }
  19.             }
  20.         }
  21.     }
  22. }
  23.  
  24. ColorUnion CMosaic::GetMosaicPixel( DWORD *inData, int X, int Y )
  25. {
  26.     int Red = 0, Green = 0, Blue = 0;
  27.     ColorUnion OriginalColor = GetPixel( inData, X, Y );
  28.  
  29.     for( int i = Y; i < Y + InputFactor; i++ )  {
  30.         for( int j = X; j < X + InputFactor; j++ )  {
  31.            
  32.             if( IsContain( j, i ) ) {
  33.                 ColorUnion ColorData = GetPixel( inData, j, i );
  34.  
  35.                 Red  += ColorData.ColorPixel.Red;
  36.                 Green   += ColorData.ColorPixel.Green;
  37.                 Blue    += ColorData.ColorPixel.Blue;
  38.             }
  39.             else    {
  40.                 Red  += OriginalColor.ColorPixel.Red;
  41.                 Green   += OriginalColor.ColorPixel.Green;
  42.                 Blue    += OriginalColor.ColorPixel.Blue;
  43.             }
  44.         }
  45.     }
  46.  
  47.     int DividerNumber = static_cast< int >( std::pow( InputFactor, 2.0 ) );
  48.  
  49.     Red  /= DividerNumber;
  50.     Green   /= DividerNumber;
  51.     Blue    /= DividerNumber;
  52.  
  53.     return MakePixel( 0xFF, Red, Green, Blue );
  54. }
  뭔가 복잡한 것 같지만 이러한 이미지 처리를 하는 것으로 다양한 결과물을 만들어 낼 수 있습니다. 게임 같은 경우 텍스쳐 또한 각도에 따라서 이미지 크기를 변경시키고 회전시켜 좌표에 맵핑을 하는 것이죠. 그래서 실제 게임 플레이어같은 경우엔 어떠한 형태를 가진 물체로 인식하게 하는 것입니다.
  이 글을 보신분 이미지 크기를 변경시키는 Resizing 기능을 구현해보시는 것은 어떻습니까?^^
=뱀다리=
std::pow를 사용하는 것을 생성자에 집어넣고 하여 최적화를 시켜야 할 여지가 존재합니다. 다만 당시 빠르게 작성하느라 못했기 때문에 최적화는 필요하신 분이 하셔서 사용해보세요^^
크리에이티브 커먼즈 라이센스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

"Program" 분류의 다른 글

재귀적 합성이랄지.. (0)2008/10/13
\r\n 과 \n 차이 때문에 생기는 문제 (0)2008/04/15
PangCal - 팡야계산기 (0)2008/02/16
War 3 Axis - 워크래프트3 후킹 프로그램 (0)2008/02/16
2008/04/04 23:01 2008/04/04 23:01
TAG C++, Filtering, Image, Image Processing, 이미지 프로세싱
받은 트랙백이 없고, 댓글이 없습니다.

트랙백 주소 :: http://www.filewiki.net/tc/trackback/44

댓글을 달아 주세요

◀ 이전페이지 1 ... 64 65 66 67 68 69 70 71 72 ... 110 다음페이지 ▶

블로그 이미지
First Sensation 귀차니스트
rss
  • 관리자
  • 글쓰기

카테고리

  • 전체 (110)
    • Computer (3)
    • Language (14)
    • Reverse Engineering (1)
    • Algorithm (9)
    • TopCoder (3)
    • Library (2)
    • Programming (19)
    • Programming Tip (9)
    • PSP-Programming (10)
    • Program (5)
    • Small Talk (31)
    • Document (4)

최근에 올라온 글

  • Gradient 작성중에 있습.... (3)
  • 게임&인터랙티브 애플리....
  • 한게임 자동테트리스 Ve.... (24)
  • Intel 64 And IA32 Arch.... (2)
  • 한게임 자동테트리스 Ve.... (24)

최근에 달린 댓글

  • 다운어덯게 받아요. difl 2008
  • 멋있네요 ㅎㅎ. 준호씨 2008
  • ^^; 그러셨군요.. 사실 동영.... 귀차니스트 2008
  • ㅋㅋ 속도 튜닝의 무서움 ㅜ.... 귀차니스트 2008
  • 관리자만 볼 수 있는 댓글입.... 비밀방문자 2008

달력

«   2009/01   »
일 월 화 수 목 금 토
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

링크

  • kkamagui 프로그래밍 세상.
  • 류광의 번역 이야기.
  • 서광열의 프로그래밍 언....
  • 준호씨의 블로그.
  • 최익필의 이름없는 블로그.
  • 위키는 귀차니즘.

최근에 받은 트랙백

  • 궁극의 예외처리. 이름없는 블로그 2008
  • Maximum sum. 티스토리 지점 2008

글 보관함

  • 2008/12 (1)
  • 2008/11 (4)
  • 2008/10 (2)
  • 2008/09 (3)
  • 2008/08 (5)

태그목록

  • FTP
  • 분양
  • GDI+
  • Chaos
  • GUI
  • 버퍼 오버플로우
  • System.Xml
  • \r\n
  • boost::random
  • 디아블로3
  • TTF
  • Filtering
  • 홈브류
  • 6GB
  • 개발
  • Logitech
  • 병렬처리
  • High Precision Event Timer
  • Warcraft3
  • Reference
  • i++
  • 책
  • 타이틀
  • 뻘글
  • 공백
  • Return
  • Array
  • RLE8
  • 준비
  • 파이널 데이터

지역로그 : 태그 : 방명록 : 관리자 : 글쓰기
귀차니스트’s Blog is powered by Textcube 1.7.5 : Risoluto / Designed by DesignNia.net