이번 포스팅은 Image Pyramid에 대해 알아보고 OpenCV에서 어떻게 사용되는지 알아보겠습니다.
포스팅 관련 내용은 아래에서 출처를 얻어 사용하였습니다.
https://docs.opencv.org/4.5.1/d4/d1f/tutorial_pyramids.html
GOAL
- Image Pyramid?
- OpenCV에서 Image Pyramid 사용 방법
Theory
- 이미지 피라미드(Image Pyramid)
- 위 그림처럼 이미지 피라미드란 이미지의 크기를 피라미드처럼 확대하거나 축소하는 작업을 말합니다.
가우시안 피라미드 ( Gaussian Pyramid )
- 가우시안 필터를 적용한 뒤 이미지 피라미드를 구성하는 것을 말합니다.
downsampling 경우 이미지를 가우시안 블러 처리한 후 짝수 행과 열을 제거 함으로써 만들어집니다.
M x N의 이미지에서 downsampling 처리를 하면 M/2 x N/2 가 되어 전체적으로 이미지가 1/4 줄어들게 됩니다.
블러 처리를 하는 이유는 블러 처리를 하지 않고 downsampling을 하게 되면 aliasing이 나타나기 때문입니다.
- upsampling의 경우 상위 단계(해상도는 작지만 스케일이 높음)의 이미지에서 짝수 열과 행에 픽셀을 추가한 후 이미지를 블러 처리하여 하위 단계(해상도는 높지만 스케일이 낮음)의 이미지를 만듭니다.
하지만 생성된 하위 단계 이미지는 블러링 한 효과를 낸 것처럼 나타나게 되는데 이는 해상도를 높이게 되면 이미지 정보가 제대로 복원되지 않기 때문입니다. 이를 해결하기 위한 방법으로 Super Resolution 기법을 많이 사용합니다.
Using Gaussian Pyramid With OpenCV
- 이제 OpenCV에서 가우시안 피라미드를 어떻게 사용하는지 알아봅시다.
OpenCV에서는 가우시안 피라미드 함수를 제공합니다.
- cv2.pyrDown(src, dst, dstsize, borderType)
입력 매개변수
- src : 입력 영상
- dst : 결과 영상
- dstsize : 결과 영상 크기
- borderTyrpe : 외곽 보정 방식
- cv2.pyrUp(src, dst, dstsize, borderType)
입력 매개변수
- src : 입력 영상
- dst : 결과 영상
- dstsize : 결과 영상 크기
- borderTyrpe : 외곽 보정 방식
코드)
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('./images/lena.jpg')
Upimg = cv2.pyrUp(img)
Downimg = cv2.pyrDown(img)
plt.subplot(1,3,1)
plt.imshow(img)
plt.title('Original Img')
plt.subplot(1,3,2)
plt.imshow(Upimg)
plt.title('Upsampling Img')
plt.subplot(1,3,3)
plt.imshow(Downimg)
plt.title('Downsampling Img')
plt.show()
결과)
- Upsampling과 Downsampling을 각각 보시면 사이즈가 커지고 줄어든 것을 볼 수 있고
이미지가 블러 처리된 것을 확인할 수 있습니다.
라플라시안 피라미드 (Laplacian Pyramids)
- 앞서 가우시안 피라미드로 나온 결과를 보시면 pyUp()으로 이미지를 확대하면 화질이 떨어지는 것을 볼 수 있습니다. 이런 문제점을 해결하기 위해 라플라시안 피라미드를 사용합니다.
- 라플라시안 피라미드는 가우시안 피라미드의 이미지와 상위 단계(해상도는 낮지만 스케일은 높음)의 이미지를 확장시킨 이미지의 차이로 구성됩니다. 즉, 가우시안 피라미드로 만들어진 이미지들을 가지고 라플라시안 피라미드를 만든다는 의미입니다.
- 코드를 보면 한 번에 이해를 하실 수 있습니다.
import cv2
import numpy as np
img = cv2.imread('./images/lena.jpg')
Down_img = cv2.pyrDown(img)
Down_to_Upimg = cv2.pyrUp(Down_img)
laplacian = cv2.subtract(img, Down_to_Upimg)
restored = laplacian + Down_to_Upimg
images = [img, Down_to_Upimg, laplacian, restored]
merged = np.hstack(images)
cv2.imshow('Laplacian Pyramid', merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
1. 원본 이미지를 가우시안 피라미드로 축소
2. 축소한 이미지를 가우시안 피라미드로 확대 = Down_to_Upimg
3. 원본 이미지와 2번으로 처리한 이미지를 뺌 = Laplacian
4. 2번과 3번 이미지를 더해서 이미지 복구 = Restored
결과)
- 라플라시안 피라미드를 적용하여 구한 4번째 이미지는 원본 이미지와 가장 비슷하게 복구된 것을 볼 수 있었습니다.
OpenCV에서 사용하는 이미지 피라미드 함수에 대해서 알아보았습니다.
질문이나 잘못된 점이 있으면 댓글로 남겨주세요
감사합니다 :)
'영상처리' 카테고리의 다른 글
Python - OpenCV (16) : Meanshift (0) | 2021.08.06 |
---|---|
Python - OpenCV (15) : Face Detection (0) | 2021.08.03 |
Python - OpenCV (13) : SVM(Support Vector Machines) (0) | 2021.07.20 |
Python - OpenCV (12) : Segmentation with Watershed (0) | 2021.07.19 |
Python - OpenCV (11) : Grayscale 함수 비교 (2) | 2021.07.16 |