본문 바로가기
디지털영상처리기초/Matlab

[디지털 영상처리 기초] 9. Image Geometry

by CodingKwon 2021. 6. 28.

[디지털 영상처리 기초] 9. Image Geometry

 

1) cameraman의 머리 부분을 각 차원으로 4배로 확대하기 위해서 0 끼우기와 본문에서 주어진 3개의 공간필터를 사용하라. 영상을 확대하기 위해서 아래와 같은 명령어 순서를 사용하라.

>> head2 = zeroint(head);
>> head2n = filter2(flit, head2);
>> head4 = zeroint(head2n);
>> head4n = filter2(filt, head4);
>> imshow(head4n/255)

여기서, filt는 사용할 필터이다. 이 결과와 imresize를 사용해서 얻은 결과를 서로 비교하라. 서로 간에 관측할 수 있는 어떤 차이가 있는가?

 

먼저 사용할 zeroint를 정의했습니다.

 

function out = zeroint (a)

[m, n] = size(a); a2 = reshape([a;zeros(m,n)], m , 2*n);
out = reshape([a2'; zeros(2*n,m)], 2*n, 2*m)';

 

카메라맨 영상과 3개의 공간필터를 정의하였습니다.

 

c = imread('cameraman.tif');

 

% 머리부분 ROI (Region of Interest)
head = c(33:96, 90:153);

filt1 = [1 1 0; 1 1 0; 0 0 0]; % nearest
filt2 = (1/4)*[1 2 1; 2 4 2; 1 2 1]; % bilinear
filt3 = (1/64)*[1 4 6 4 1;
                4 16 24 16 4;
                6 24 36 24 6;
                4 16 24 16 4;
                1 4 6 4 1;
                ]; % bicubic

% filt1, nearest
head2 = zeroint(head);
head2n = filter2(filt1, head2);

head4 = zeroint(head2n);
head4n = filter2(filt1, head4);

subplot(2,2,1), imshow(head4n/255), title('nearest')

% filt2, bilnear
head2 = zeroint(head);
head2n = filter2(filt2, head2);

head4 = zeroint(head2n);
head4n = filter2(filt2, head4);

subplot(2,2,2), imshow(head4n/255), title('bilinear')

% filt3, bicubic
head2 = zeroint(head);
head2n = filter2(filt3, head2);

head4 = zeroint(head2n);
head4n = filter2(filt3, head4);

subplot(2,2,3), imshow(head4n/255), title('bicubic')

% imresize
c_resize = imresize(head, 4);

subplot(2,2,4), imshow(c_resize), title('imresize')

Image Geometry 방식에 따른 영상

결과를 확인해보면 nearest방식은 모자이크처럼 계단 현상이 생겼습니다. bilinear은 계단현상이 거의 사라지고 부드러워졌습니다. bicubic의 경우 bilinear보다 부드러워져서 블러링 된 거처럼 보입니다. imresize로 확대한 영상은 bilinear와 비슷한 결과를 보였습니다.

 

 

 

2) 한 영상을 임의의 K배로 확대하고, 그 결과를 같은 양만큼 축소한다고 가정하자. 이 결과는 원래 영상과 정확히 같게 되는가? 그렇지 않다면 왜 그런가?

 

% 원본 영상
c = imread('cameraman.tif');

% nearest
c_resize1_1 = imresize(c, 4, 'nearest');
c_resize1_2 = imresize(c_resize1_1, 1/4, 'nearest');

% bilinear
c_resize2_1 = imresize(c, 4, 'bilinear');
c_resize2_2 = imresize(c_resize2_1, 1/4, 'bilinear');

% bicubic
c_resize3_1 = imresize(c, 4, 'bicubic');
c_resize3_2 = imresize(c_resize3_1, 1/4, 'bicubic');

% 결과 확인
resize1 = psnr(c_resize1_2, c)
resize2 = psnr(c_resize2_2, c)
resize3 = psnr(c_resize3_2, c)

 

 

임의의 영상 cameraman을 nearest, bilinear, bicubic 방식으로 확대하고 다시 축소하였습니다.

다음은 3가지의 결과를 psnr로 확인해보겠습니다.

 

3가지 공간필터의 PSNR

nearest 방식은 원형과 같은 psnr이 나왔습니다. bilinear는 psnr이 30, bicubic은 psnr이 36이 나왔습니다. nearest방식은 근처에 있는 원소를 이용해서 보간을 수행하고 bilinear는 두 값 사이를 선으로 이어 그 사이에 값을 구하는 선형 방식, bicubic는 3차 곡선을 이용하는 방식입니다. 따라서 nearest방식은 이웃한 값을 그대로 사용했기 때문에 원래의 이미지로 다시 돌아올 수 있었고 bilinear와 bicubic은 계산을 통해서 확대 후 축소를 하였기 때문에 원래의 이미지로는 돌아올 수 없었습니다. 그리고 bicubic이 bilinear보다 좋은 psnr을 가졌는데 이는 값을 확대와 축소 시 값을 더 세분화하였기 때문이라고 생각합니다.

 

 

3) 만일 먼저 영상을 축소하고, 그 결과를 확대하면 어떻게 되는가?

 

% 원본 영상
c = imread('cameraman.tif');

% 축소 후 확대
c_re1 = imresize(c, 1/4);
c_re2 = imresize(c_re1, 4);

% 결과 확인
subplot(1,2,1), imshow(c), title('원본')
subplot(1,2,2), imshow(c_re2), title('축소 후 확대')

1/4로 축소 후 4배 확대한 영상과 비교

축소 후에 확대하였을 때 결과는 원본보다 안 좋은 품질의 영상으로 블러링 된 느낌을 받는 영상이 나왔습니다. 이유는 영상을 축소했을 때 일부 데이터들을 잃게 되는데 이를 확대한다고 해도 다시 소실된 데이터들이 돌아오지 않습니다. 그렇기 때문에 축소 후에 확대했을 때 영상이 원본 영상처럼 돌아오지 않습니다.

 

 

 

4) 흑색 배경에 흰색 사각형이 있는 영상을 만들어라. 이 영상을 30°와 45° 회전시켜라. 단 아래에 있는 a와 b에 명시된 것을 사용하고, 그 결과도 서로 비교하라.

a. nearest 옵션으로 imrotate 명령
b. bilinear 옵션으로 imrotate 명령

 

% 사각형 생성
quad = zeros(300,300);
quad(75:225, 75:225) = 1;

% 30도 회전
quad30_n = imrotate(quad, 30, 'nearest');
quad30_l = imrotate(quad, 30, 'bilinear');

% 45도 회전
quad45_n = imrotate(quad, 45, 'nearest');
quad45_l = imrotate(quad, 45, 'bilinear');

% 결과 확인
subplot(2,2,1), imshow(quad30_n), title('30도 nearest')
subplot(2,2,2), imshow(quad30_l), title('30도 bilinear')
subplot(2,2,3), imshow(quad45_n), title('45도 nearest')
subplot(2,2,4), imshow(quad45_l), title('45도 bilinear')

% 30도와 45도의 nearest방식과 bilinear방식의 합을 구해서 차이를 확인

r30 = sum(quad30_n(:)) - sum(quad30_l(:))
r45 = sum(quad45_n(:)) - sum(quad45_l(:))

30° 와  45° 회전 영상

nearest방식으로 rotate 한 결과는 계단 형식으로 나타나 있습니다. bilinear방식은 계단 형식보다는 흐릿한 형태로 나타나고 있습니다.

 

30도와 45도의 nearest방식과 bilinear방식의 합을 구해서 차이를 내보았습니다.

30° 와  45°의  nearest 방식과  bilinear 방식의 합을 구한 차이

30도일 때보다 45도일 때가 더 차이가 심하게 나왔습니다.

 

 

 

5) 문제 4에서 회전된 사각형에 대하여 반대로(원래의 위치로) 회전시켜라. 그 결과가 원래 사각형과 얼마나 비슷한가?

 

문제 4번에서 30도, 45도 회전한 nearest와 bilinear방식을 다시 같은 방식으로 –30도, -45도 회전시켰습니다.

 

% 사각형 생성
quad = zeros(300,300);
quad(75:225, 75:225) = 1;

% 30도 회전 후 -30도 회전
quad30_n = imrotate(quad, 30, 'nearest');
quad30_l = imrotate(quad, 30, 'bilinear');
quad30_n_r = imrotate(quad30_n, -30, 'nearest');
quad30_l_r = imrotate(quad30_l, -30, 'bilinear');

% 45도 회전 후 -45도 회전
quad45_n = imrotate(quad, 45, 'nearest');
quad45_l = imrotate(quad, 45, 'bilinear');
quad45_n_r = imrotate(quad45_n, -45, 'nearest');
quad45_l_r = imrotate(quad45_l, -45, 'bilinear');


% 결과 확인
subplot(2,2,1), imshow(quad30_n_r), title('30도 nearest_reverse')
subplot(2,2,2), imshow(quad30_l_r), title('30도 bilinear_reverse')
subplot(2,2,3), imshow(quad45_n_r), title('45도 nearest_reverse')
subplot(2,2,4), imshow(quad45_l_r), title('45도 bilinear_reverse')

 

% 30도와 45도의 nearest방식과 bilinear방식의 합을 구해서 원본과 차이 확인
r30_nearest = sum(quad30_n_r(:)) - sum(quad(:))
r30_bilinear = sum(quad30_l_r(:)) - sum(quad(:))
r45_nearest = sum(quad45_n_r(:)) - sum(quad(:))
r45_bilinear = sum(quad45_l_r(:)) - sum(quad(:))

 

30°, 45° 회전 후 – 30°, -45° 회전 영상

nearest 방식은 원본으로 되돌렸을 때 사다리 모양을 30도와 45도 모두 확인할 수 있었습니다. 하지만 bilinear 방식에서는 원본과 다른 흐릿한 모양을 가지고 있지만 nearest방식보다는 깔끔하게 나오는 것을 볼 수 있습니다.

 

30도와 45도의 nearest방식과 bilinear방식의 합을 구해서 원본과 차이를 내보았습니다.

30도와 45도의 nearest방식과 bilinear방식의 합을 구해서 원본과 차이 확인

nearest는 원본과 차이가 90, 68로 크게 나타나지만 bilinear방식은 1.46, -7.25로 상대적으로 작은 차이를 나타내고 있습니다.

댓글