기본적으로 bilinear interpolation = interpolation을 3번 한 것이다.
// interpolation
// su,ev su,eu
// c----------d
// | |
// | p(x,y) |
// | |
// a----------b
// su,sv su,ev
이라면, pixel과 바로 옆 한 픽셀사이를 그 범위로 한다. 따라서 0~1 위치값으로 대변된다.
interpolation의 기본식은(찾아보기 바람)
식(1) (1-p)*a+p*b
이때 a와 b는 pixel값이다. 예를 들어, 위의 그림에서 a(x, y)이면 b(x+1, y)란걸 인식해야한다.
그러면,
식(2) (1-p)a+pb = (1-p)* I(x,y)+p*I(x,y)
p는 무엇인가 interpolation의 weight인데 헷갈린다. 어떻게 0~1사이에 값을 weight를 주는가?
보통 회전을 하거나 확대를 할때 변환된다.
x1, y1 ----- Rotation ------ x2,y2
이때 변환되는 x2, y2의 실제값은 float형이고 실제 집넣어야하는 값은 int형이다. 이때의 distance값이 생성되는데 이값이다 바로 P이다.
식(3) p = x2-(int)x2;
을 해주면 된다.
위에서 bilinear interpolation = interpolation*3번이니
// 1. Q = a-b interploation
// 2. P = c-d interploation
// 3. Q-P interpoloation
이런 순서로 해주면 된다.
Not interpolation
bilinear interpolation
소스 코드 (Source code)
for(int i=0; i<h; ++i){ //v
for(int j=0; j<w; ++j){ //u
int x = j;
int y = i;
// rotation
float _u = x*cos(radian)-y*sin(radian); // x -> rx
float _v = x*sin(radian)+y*cos(radian); // y -> ry
if((_u<0) | (_v<0) | (_u>=w-1) | (_v>=h-1)){
gImage[i][j] = 0;
continue;
}
int su, sv, eu, ev;
su = _u; sv = _v;
eu = _u+1; ev = _v+1;
//bilinear interpolation
// interpolation = (1-p)a+pb
// 1. Q = a-b interploation
// 2. P = c-d interploation
// 3. Q-P interpoloation
int a = gImage[sv][su];
int b = gImage[sv][eu];
int c = gImage[ev][su];
int d = gImage[ev][eu];
// 1. a-b interploation
// p value compute = dx, dy
float dx = _u-(int)_u; // eu-su;
float dy = _v-(int)_v; //ev-sv;;
int Q = (1-dx)*a+dx*b; // Q = a-b interploation
int P = (1-dx)*c+dx*d; // P = c-d interploation
int Q_P =(1-dy)*Q+dy*P; // Q-P interpoloation
gImage[i][j] = Q_P;
//gImage[i][j] = gImage[sv][su]; // not interpolation
}
}
'Lab > Basic Algorithms' 카테고리의 다른 글
Gaussian Blur - 1 (0) | 2013.01.25 |
---|---|
Edge Detection - Sobel (2) | 2013.01.11 |