내 머릿속 데이터베이스

이미지 처리 본문

Development Notes/Study

이미지 처리

파도소리 2009. 5. 24. 19:22

과제로 이미지 처리를 해보았다.
비트맵 구조를 파악하고 이것저것 해보다보니 오호 이거 상당히 재미있는데? ㅋㅋ


여기까지는 뭐 --;; 디자인을 전혀 신경쓰지 않았다...
내가 구현하는건 RAW데이터를 뿌려주는 일이었으므로 ㅋ


이미지 확대, 축소야 뭐.. StretchDIBits 함수 인자만 바꾸는 일이었으므로 별로 어렵지 않았다.

하지만 여기서부터 문제

이미지 품질을 다운 시키는 작업이다.
8개의 비트중 앞자리 6비트, 4비트, 2비트만 남기고 나머지는 0으로 클리어.

아무생각없이 가로폭 255, 세로폭 255사이즈라고 생각해서 전체 크기를 255x255로 생각하면 안된다
데이터 구조가 RGB로 이루어져있기때문에
픽셀하나가 1Byte가 아닌 R 8비트, G 8비트, B 8비트, 총 3바이트로 이루어져있다.

그래서 즉, 255x255x3

각 픽셀의 컬러마다 11000000 을 비트 연산자 AND 로 연산했다.

여기서 또 아무생각없이 R & 11000000 하면 안된다 -_-;
11000000은 보기엔 2진수처럼 보이지만 -_-; C언어에서는 2진수로 표현하는게 없다!!!
(8진수와 16진수는 바로 표기할 수 있지만)

11000000은 그저 -_- 십진수 천백만일뿐이다..
11000000을 10진수로 변화한 값, 192를 비트연산 해야한다.

즉 R & 192 가 올바른 방법이다.

뭐 지금 쉬프트 연산자로 하는게 더 직관적일수도 있을것 같다 ㅠㅠ


반전은 제일 쉬웠다.
각 픽셀의 RGB 비트를 NOT연산만 하면 되었다.

~(R)


세피아톤, 일종의 컬러밸런스를 조절하는 작업이라고 해야하나? ^^;
세피아톤은 약간 붉은 컬러가 나오는 느낌이라서
G(그린)과 B(블루)의 비율을 각각 80%, 60%정도 조절하면 비슷하게 나오는것 같았다.(포토샵에서 대충해봄 -_-;)

간단하게 G에다 0.8을 B에다 0.6을 곱해줬다.

위의 이미지는 워낙 애초부터 붉은 사진이라 세피아톤의 느낌이 덜 난다.. ㅋㅋ;;;


의외로 고민을 많이했다.
컬러를 어떻게 음영으로만 이루어진 흑백으로 변환시키지!?! 고민하다가..

RGB컬러에서 색을 표현하는건, 3가지 색상을 섞음으로써 다양한 컬러를 표현,
만약 이 3가지 색상의 수치가 같다면? 단지 밝고 어두움으로 표현할수 없지 않을까

해서

그린과 블루에 레드 비트를 넣어, 3가지 색상 데이터를 레드로 만들었더니 흑백이미지가 떴다.

만세. 하지만 뭔가 빠진것 같다.

그렇다.
사진에 적색이 많이 포함되어있어서, 다른 색상들을 다 적색으로 덮어버리면 사진이 그만큼 어둡게 나올수 밖에 없다.

음.. 무슨 레드컬러 마스크 같단 느낌일까?
하던 찰나에. 아하

R = (R+G+B)/3;

평균 -_- 값을 내면 되는구나


90도 회전. 교수님은 어려울거라 말씀하시고 과제로 내주지 않았지만.
여기까지 와버린이상 -_- ㅋㅋ 도전하고 싶었다.

이미지를 2차원배열로 생각하고, 배열을 회전시키면 되지않을까 라는 생각이 들어서.
뭔가 규칙이 있겠구나 싶어 고민을 해보았다.

[0][1][2]          [6][3][0]
[3][4][5]   = >   [7][4][1]
[6][7][8]          [8][5][2]


[0][0] -> [0][2]
[0][1] -> [1][2]
[0][2] -> [2][2]

[1][0] -> [0][1]
[1][1] -> [1][1]
[1][2] -> [2][1]

오호라. 찾았다.
해서, 똑같은 사이즈의 버퍼를 만들어 이미지 배열을 회전시켜 저장한뒤 불러왔더니..
정상적으로 회전되었다.

만세!


90도 회전을 한번 더 누르면 90도가 더 회전되어 총 180도가 회전되게끔도 해보고 싶었다.

imgbuf는 전역변수고, buf2는 지역변수다.

imgbuf에 이미지가 들어가있고
imgbuf2를 만들어

imgbuf2 = 90도회전(imgbuf); 을 한뒤
imgbuf2를 화면에 뿌렸다.
그다음 함수가 종료되면 imgbuf2는 메모리를 해제한다.

가 기본 처리과정이었다.

하지만 90도 회전이 계속 유지되려면, 원본 imgbuf의 데이터를 바꿔줘야한다.

아무생각없이

BYTE *imgbuf, *imgbuf2;

*imgbuf = *imgbuf2;

라고 했다 -_-; 역시 안된다.
메모리를 직접 덮어버리는 함수로 덮어야겠단 생각이 들어,
memcpy 함수를 이용해 보기로 하고

memcpy(imgbuf, imgbuf2, sizeof(imgbuf));

라고 했지만 안됬다.
이때까지도 중요한 기본적인 핵심을 놓치고 있었다. ㅋㅋ


sizeof( 포인터 변수 );

이놈이었다.

int *p;
p = (int)malloc(sizeof(int)*50);

sizeof(p);

멍청하게 당연히 출력되는 sizeof는 int형 사이즈x50 이라고 생각했다.
하지만 sizeof(p)는 단순히 포인터 변수의 크기만 나온다. -_-;

p가 참조되는 영역을 알수가 없단 소리다.
string데이터는 뭐 끝에 널문자가 있으니 알수도 있겠지만.

malloc로 선언한 메모리 크기는 다시 알 수 없다.

그래서 이런 간단한걸 놓치고 멍청하게 삽질했다.

memcpy(imgbuf, imgbuf2, sizeof(이미지가로사이즈*이미지세로사이즈*3));

했더니 잘된다. 후후후후후



반전기능도 이와같이 적용해서, 90도 회전 3번과, 반전까지 먹인사례 -_-V


어쨋거나 재밌었다. ^^
Comments