블로그는 귀차니즘

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 - 팡야계산기 (2)2008/02/16
War 3 Axis - 워크래프트3 후킹 프로그램 (1)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 다음페이지 ▶

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

카테고리

  • 전체 (118)
    • Computer (3)
    • Language (14)
    • Reverse Engineering (1)
    • Algorithm (9)
    • TopCoder (3)
    • Library (2)
    • Programming (21)
    • Programming Tip (9)
    • PSP-Programming (10)
    • Program (5)
    • Small Talk (33)
    • Document (4)
    • OS Develope (4)

최근에 올라온 글

  • Script Interpreter - b....
  • VirtualHttpServer - 가.... (2)
  • 음.. 여러가지 일이 있.... (2)
  • 어후.. 드디어 인터럽트....
  • Kernel Image에 어이없....

최근에 달린 댓글

  • 헠 ㅋ 다음에도 들러주세용 ㅋㅋ. 귀차니스트 03/09
  • ㅎㅎ RSS로 첨 온 글이네.ㅋ. 당구리 02/22
  • 음.. 한글화 파일 0.5 버젼은.... 귀차니스트 02/22
  • 관리자만 볼 수 있는 댓글입.... 비밀방문자 01/30
  • 어떤 의미이신지 잘 모르겠네.... 귀차니스트 01/23

달력

«   2010/03   »
일 월 화 수 목 금 토
  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 프로그래밍 세상.
  • runner님의 이글루.
  • 당구리의 마굿간.
  • 동우fly.
  • 류광의 번역 이야기.
  • 서광열의 프로그래밍 언....
  • 준호씨의 블로그.
  • 최익필의 이름없는 블로그.
  • 위키는 귀차니즘.

최근에 받은 트랙백

  • 한게임 테트리스 인공지.... 고니's Life 2009
  • ACM 706 (Uva ID) : LCD.... 알고리즘 트레이닝 : Oh... 2009
  • 문제 4 : LCD 디스플레.... 최익필의 이름없는 블로그 2009
  • 궁극의 예외처리. 이름없는 블로그 2008
  • Maximum sum. 티스토리 지점 2008

글 보관함

  • 2010/03 (1)
  • 2010/02 (1)
  • 2010/01 (1)
  • 2009/12 (3)
  • 2009/08 (1)

태그목록

  • Contest
  • 테트리스
  • Warcraft3
  • Kernel
  • 한글표현
  • 압축
  • Run Length
  • 홈브류
  • 한글화
  • tr1
  • Builder
  • 예외
  • AppWizard
  • 동방환상마작
  • Parent
  • 병렬
  • RLE
  • ACM
  • 입양
  • Codejock
  • 팡야계산기
  • Sector
  • Chaos
  • C++
  • 개발일지
  • 클라리넷
  • 파이널 데이터
  • 프로그래밍
  • ostream_iterator
  • QT4

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