
하이브리드 이미지는 한 사진의 저주파 성분과 다른 사진의 고주파 성분을 합쳐, 가까이서 볼 때와 멀리서 볼 때 서로 다른 이미지가 드러나게 만든다. 이 글은 푸리에 변환을 이용해 마릴린 먼로와 알베르트 아인슈타인의 이미지를 결합하는 원리와 파이썬 코드를 소개한다.
2006년 오드 올리바(Aude Oliva), 안토니오 토랄바(Antonio Torralba), 필리프 G. 슈인스(Philippe G. Schyns)는 하이브리드 이미지라는 개념을 발표했다. 가까이서 보면 아인슈타인, 멀리서 보면 마릴린 먼로로 보이는 ‘Marilyn Einstein’이 대표 사례다. 글은 레오나르도 다빈치의 모나리자 미소와 살바도르 달리의 작품을 예로 들며, 보는 거리와 시선에 따라 이미지가 달라지는 효과를 설명한다. 2006년 논문
이미지에서 푸리에 계수는 주파수 성분을 나타낸다. 원점에 가까운 저주파 성분은 넓고 부드러운 변화를, 멀리 있는 고주파 성분은 선명한 경계와 세부를 담는다. 따라서 부드러운 얼굴 특징을 가진 먼로 사진에서는 저주파 성분을, 주름과 머리카락처럼 세부가 많은 아인슈타인 사진에서는 고주파 성분을 추출해 합칠 수 있다.
글은 가우시안 필터로 주파수 성분을 조절한다. 저역 통과 필터는 저주파 성분을 남기고 고주파 성분을 줄이며, 고역 통과 필터는 그 반대로 작동한다. 필터를 적용한 두 이미지를 결합하면 하이브리드 이미지가 된다. 결과를 보기 좋게 만들려면 필터 매개변수를 조정해야 하며, 글의 예시에서는 원본 이미지의 중앙 정렬이나 크기 조정을 거의 하지 않았다고 설명한다.
글은 파이썬 코드와 관련 자료를 GitHub 저장소에서 내려받을 수 있다고 안내한다. 푸리에 변환의 기초와 관련 구현은 네 편의 입문 글, 파이썬으로 구현하는 고속 푸리에 변환, 디지털 워터마킹에 사용하는 2차원 푸리에 변환에서 확인할 수 있다. 올리바 연구진의 다른 예시는 하이브리드 이미지 갤러리에 있다.
글은 이 기법을 동영상에 적용하거나, 다른 변환의 스펙트럼을 조작하거나, 음악 같은 1차원 신호에 적용하는 방안을 후속 탐구 주제로 제안한다.
부록: 원문 예시
import numpy from numpy.fft import fft2, ifft2, fftshift, ifftshift from scipy import misc from scipy import ndimage import math def makeGaussianFilter(numRows, numCols, sigma, highPass=True): centerI = int(numRows/2) + 1 if numRows % 2 == 1 else int(numRows/2) centerJ = int(numCols/2) + 1 if numCols % 2 == 1 else int(numCols/2) def gaussian(i,j): coefficient = math.exp(-1.0 * ((i - centerI)**2 + (j - centerJ)**2) / (2 * sigma**2)) return 1 - coefficient if highPass else coefficient return numpy.array([[gaussian(i,j) for j in range(numCols)] for i in range(numRows)]) def filterDFT(imageMatrix, filterMatrix): shiftedDFT = fftshift(fft2(imageMatrix)) filteredDFT = shiftedDFT * filterMatrix return ifft2(ifftshift(filteredDFT)) def lowPass(imageMatrix, sigma): n,m = imageMatrix.shape return filterDFT(imageMatrix, makeGaussianFilter(n, m, sigma, highPass=False)) def highPass(imageMatrix, sigma): n,m = imageMatrix.shape return filterDFT(imageMatrix, makeGaussianFilter(n, m, sigma, highPass=True)) if __name__ == "__main__": marilyn = ndimage.imread("marilyn.png", flatten=True) lowPassedMarilyn = lowPass(marilyn, 20) misc.imsave("low-passed-marilyn.png", numpy.real(lowPassedMarilyn))
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요