Images.zip


영상처리를 공부하다보면 자주 보게 되는 이미지 모음입니다.
출처는 아래와 같구요...

http://www.dip.ee.uct.ac.za/imageproc/

참고로, 폴더에 USC 라 함은 아래 사이트를 참고하세요.
이곳에 가면 더 많은 표준 영상을 구할 수 있습니다.

http://sipi.usc.edu/database/



Posted by kkokkal
:


RGB로 표현되는 트루칼라를 그레이스케일로 변환하는 식은 다음과 같다.

L = 0.299R + 0.587G + 0.114B

CxImage 라이브러리( http://www.xdp.it/cximage.htm )에는 위의 변환식을 define 문과 shift 연산자를 사용하여 속도 향상을 꾀하였다는 특색이 있다. CxImage 소스에 적혀있는 변환 코드는 다음과 같다.

// color to grey mapping <H. Muelner> <jurgene>
// Same as #define RGB2GRAY(r, g, b) (((b)*114 + (g)*587 + (r)*299)/1000)
#define RGB2GRAY(r, g, b) (((b)*117 + (g)*601 + (r)*306) >> 10)

이와는 달리, 매우 간단하게 grayscale 형태로 바꾸는 다음과 같은 식도 존재한다.

grayscale = (R + G + B) / 3

그러나, 이 방법은 말 그대로 매우 단순하게 grayscale 과 비슷한 값으로 바꾸는 것이고, 정확한 변환식은 아닌 것으로 생각된다.

(2005년 12월 28일 추가)

Matlab에서도 rgb2gray() 라는 함수가 있는데 이 함수에서는 다음과 같은 행렬을 이용하여 grayscale 로 변환을 한다.

T = inv([1.0 0.956 0.621; 1.0 -0.272 -0.647; 1.0 -1.106 1.703]);

이 행렬 T의 첫 번째 행이 위에서 제시한 변환식과 일치한다.

>> T

T =

     0.2989 0.5870 0.1140
     0.5959 -0.2744 -0.3216
     0.2115 -0.5229 0.3114


Posted by kkokkal
:
영상 처리 프로그래밍에 있어서 가장 많이 접하는 타입이 바로 2차원 배열이다. C/C++ 에서는 모든 자료형에 대하여 다차원 배열을 지원하고 있다. 그러나, 기본적인 2차원 배열을 사용하려면 그 크기를 미리 지정해야한다는 단점이 있다. 그러나, 다양한 크기의 영상을 배열에 넣기 위해서는 배열의 크기가 프로그램 동작 시간에 결정되게 마련이고, 그 때문에 new 연산자를 이용한 동적 배열 할당이 필요하다.

가장 일반적인 형태의 2차원 배열 동적 할당 방법은 다음과 같다.


위의 코드를 그림으로 설명하면 다음과 같다.


위의 코드에서 주의해야 할 점은 할당한 메모리 공간을 해제할 때, 그림상 하늘색으로 표현된 공간을 모두 해제해주어야 한다는 점이다. 즉, 가로로 그려진 하늘색 메모리 공간 w개와 세로로 그려진 메모리 공간 1개를 delete [] <변수이름> 형태로 삭제해주어야 한다는 점이다.

이제 이것과 동일한 역할을 하는, 새로운 2차원 배열 동적 할당 방법을 알아보자. 코드는 다음과 같다.


마찬가지로 이 코드에 대한 그림 설명을 보면 이해가 더 쉽게 되리라 믿는다.


이 새로운 방법에서는 new 연산을 2번만 수행한다는 장점이 있다. 그러므로, for 문을 돌면서 메모리를 할당하거나 해제하는 작업이 없다. pixels[1]~pixels[h-1] 까지는 모두 새로운 메모리를 할당하여 그 위치를 가리키는 것이 아니라, pixels[0] 이 할당한 큰 메모리 공간의 중간을 각각 가리키는 방식을 취한다.

이러한 Alloc2 방법은 배열의 크기가 아주 크지 않을 때에는 Alloc1 보다 어느정도의 속도 향상의 성능을 보여준다. 예를 들어, 256x256 크기의 배열을 10번 할당&해제할 때의 속도를 VC++ 6.0의 Profile 기능을 이용하여 그 시간을 체크해보았다. 실험에 사용한 컴퓨터 환경은 Pentium IV 2.8GHz(3.3GHz로 overclocking), 1GByte RAM, Windows XP sp2 이다.

Func Func+Child Hit
Time % Time % Count Function
---------------------------------------------------------
20.624 58.9 20.624 58.9 10 Alloc1(void) (dyna2d.obj)
14.391 41.1 14.391 41.1 10 Alloc2(void) (dyna2d.obj)
0.007 0.0 35.023 100.0 1 _main (dyna2d.obj)

그러나, 배열의 크기를 키우면 그다지 속도 차이가 나지 않음을 발견하였다. 1024x1024 배열을 10번 할당하고 해제할 때의 속도를 보자.

Func Func+Child Hit
Time % Time % Count Function
---------------------------------------------------------
297.449 54.1 297.449 54.1 10 Alloc1(void) (dyna2d.obj)
252.632 45.9 252.632 45.9 10 Alloc2(void) (dyna2d.obj)
0.007 0.0 550.087 100.0 1 _main (dyna2d.obj)

사실, 2003년도에 이 Alloc2 방법이 Alloc1 방법보다 매우 빠르다고 생각했었는데, 이번 실험에서 이렇게 결과가 나온 것은 상당히 당혹스러웠다. 그러나, 이번 실험의 하나하나를 다 따져보았으나 잘못된 부분은 발견할 수 없었다. 결국, 속도상에서의 merit 는 그다지 없는 것이 아닌가 하는 결론을 내려야만 했다.

첨부파일은 VC++ 6.0 에서 profile 을 보기 위해 만든 프로젝트와 VC .NET에서 GetTickCount 함수를 이용하여 배열을 할당 & 해제하는데 걸리는 시간을 재는 윈도우용 프로그램의 프로젝트 압축파일이다. 참고하시길...


ps. VC .NET 으로 만든 프로그램으로 256x256 배열을 1000번 할당 & 해제할 경우, 은근히 속도 차이를 나타내는 것을 발견하였다. 흠... 작은 배열일 때는 과연 Alloc2 가 유리한 것인가? ㅡㅡ;

012345
Posted by kkokkal
: