matlab에서 rgb 컬러이미지를 gray 이미지로 바꿀 때, 호출하는 함수가 rgb2gray이다. 이 함수는 주어진 RGB값에 다음과 같은 weight를 주어서 명암값을 얻는다:

gray = 0.2989 * r + 0.5870 * g + 0.1140 * b ;

이 계산을 fixed-point 버전으로 바꾸어 보자. 정밀도를 유지하기 위해서는 소수점 이하 4자리까지 유지해야 하는데, 이것은 weight에 각각 10000을 곱한 값을 사용한 후에 다시 10000으로 나누면 된다 (10000을 곱하더라도 r, g, b가 0-255사이의 값이므로 최대로 255 * 10000 보다 작은 값이 나와서 32-비트 정수 범위 내에 있게 된다)

gray = (2989 * r + 5870 * g + 1140 * b) / 10000;

여기서 좀 더 개선을 할 수 있다. 10000으로 나누는 과정을 shift 연산으로 바꾸면 된다. 정밀도를 보존하기 위해서 10000보다 큰 2의 power의 수를 찾으면 2^14 = 16384 이 주어진다. 따라서 10000 대신에 2^14을 곱한 weight를 쓰고, 계산 결과를 오른쪽으로 14만큼 shift 연산을 하면 된다.

0.2989 * 2^14 = 4897.1776;
0.5870 * 2^14 = 9617.408;
0.1140 * 2^14 = 1867.776;

gray = (4897 * r + 9617 * g + 1868 * b) >> 14;

weight의 총 합 = 4897 + 9617 + 1868 < 2^14 이어서 gray 값은 255를 넘지 않고, 중간 계산은 32-비트 정수 범위 내에서만 이루어 진다.

정말 빠를까?
Posted by helloktk

댓글을 달아 주세요