Frequency Domain Hybrid Images
import numpy as np
import cv2
import scipy.linalg as la
import matplotlib.pyplot as plt
import sys
import tqdm
from numpy.fft import fft, fft2, ifft, ifft2, fftshift, ifftshift
from scipy import misc
from scipy import ndimage
import math
# Resources:
# https://jeremykun.com/tag/marilyn-monroe/
def normalize(A): # Spectrum spans many orders of magnitude -- need to show on log scale
amag = np.real(np.log10(np.absolute(A) + np.ones(A.shape)))
amag = amag-np.min(amag)
return amag / np.max(amag)
# The famouse Einstein Monroe Image
einstein_monroe = cv2.cvtColor(cv2.imread("/work/images/einstein-monroe.png"), cv2.COLOR_BGR2RGB)
plt.figure(figsize=(10,10))
plt.imshow(einstein_monroe)
plt.figure(figsize=(2,2))
plt.imshow(einstein_monroe)
# Code from https://jeremykun.com/tag/marilyn-monroe/
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 np.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))
# Doing this with arbitrary images
# Images gotten from: https://this-person-does-not-exist.com/en
# Flip this first image so that the images are better aligned
img1 = cv2.cvtColor(cv2.imread("/work/images/test1.jpg")[:,::-1], cv2.COLOR_BGR2GRAY).astype(np.float32)/255
img2 = cv2.cvtColor(cv2.imread("/work/images/test2.jpg"), cv2.COLOR_BGR2GRAY).astype(np.float32)/255
img1_low_freq = np.real(lowPass(img1, 20)) # Need to only take real part
img2_high_freq = np.real(highPass(img2, 18)) # Need to only take real part
img1_spectrum = fftshift(fft2(img1))
img2_spectrum = fftshift(fft2(img2))
img1_low_freq_spectrum = fftshift(fft2(img1_low_freq))
img2_high_freq_spectrum = fftshift(fft2(img2_high_freq))
hybrid = img1_low_freq + img2_high_freq
fig, ax = plt.subplots(2, 4, figsize=(4*6, 2*6))
ax[0,0].imshow(img1, cmap='gray')
ax[0,1].imshow(img1_low_freq, cmap='gray')
ax[0,2].imshow(img2, cmap='gray')
ax[0,3].imshow(img2_high_freq, cmap='gray')
ax[1,0].imshow(normalize(img1_spectrum), cmap='gray')
ax[1,1].imshow(normalize(img1_low_freq_spectrum), cmap='gray')
ax[1,2].imshow(normalize(img2_spectrum), cmap='gray')
ax[1,3].imshow(normalize(img2_high_freq_spectrum), cmap='gray')
plt.figure(figsize=(10,10))
plt.imshow(hybrid, cmap='gray')
plt.figure(figsize=(2,2))
plt.imshow(hybrid, cmap='gray')