Created
February 16, 2017 17:41
-
-
Save ProGamerGov/73e6c242abc00777e4e8cf05cf39dc70 to your computer and use it in GitHub Desktop.
This script performs the linear color transfer step that the Scale Control feature in leongatys/NeuralImageSynthesis performs.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#This script performs the linear color transfer step that | |
#leongatys/NeuralImageSynthesis' Scale Control code performs. | |
#https://github.com/leongatys/NeuralImageSynthesis/blob/master/ExampleNotebooks/ScaleControl.ipynb | |
import scipy | |
import h5py | |
import skimage | |
import os | |
from skimage import io,transform,img_as_float | |
from skimage.io import imread,imsave | |
from collections import OrderedDict | |
#from PIL import Image, ImageFilter | |
import numpy as np | |
from numpy import eye | |
import decimal | |
#import click | |
target_img = imread('fig4_style2.jpg').astype(float)/256 | |
source_img = imread('fig4_content.jpg').astype(float)/256 | |
def match_color(target_img, source_img, mode='pca', eps=1e-5): | |
''' | |
Matches the colour distribution of the target image to that of the source image | |
using a linear transform. | |
Images are expected to be of form (w,h,c) and float in [0,1]. | |
Modes are chol, pca or sym for different choices of basis. | |
''' | |
mu_t = target_img.mean(0).mean(0) | |
t = target_img - mu_t | |
t = t.transpose(2,0,1).reshape(3,-1) | |
Ct = t.dot(t.T) / t.shape[1] + eps * eye(t.shape[0]) | |
mu_s = source_img.mean(0).mean(0) | |
s = source_img - mu_s | |
s = s.transpose(2,0,1).reshape(3,-1) | |
Cs = s.dot(s.T) / s.shape[1] + eps * eye(s.shape[0]) | |
if mode == 'chol': | |
chol_t = np.linalg.cholesky(Ct) | |
chol_s = np.linalg.cholesky(Cs) | |
ts = chol_s.dot(np.linalg.inv(chol_t)).dot(t) | |
if mode == 'pca': | |
eva_t, eve_t = np.linalg.eigh(Ct) | |
Qt = eve_t.dot(np.sqrt(np.diag(eva_t))).dot(eve_t.T) | |
eva_s, eve_s = np.linalg.eigh(Cs) | |
Qs = eve_s.dot(np.sqrt(np.diag(eva_s))).dot(eve_s.T) | |
ts = Qs.dot(np.linalg.inv(Qt)).dot(t) | |
if mode == 'sym': | |
eva_t, eve_t = np.linalg.eigh(Ct) | |
Qt = eve_t.dot(np.sqrt(np.diag(eva_t))).dot(eve_t.T) | |
Qt_Cs_Qt = Qt.dot(Cs).dot(Qt) | |
eva_QtCsQt, eve_QtCsQt = np.linalg.eigh(Qt_Cs_Qt) | |
QtCsQt = eve_QtCsQt.dot(np.sqrt(np.diag(eva_QtCsQt))).dot(eve_QtCsQt.T) | |
ts = np.linalg.inv(Qt).dot(QtCsQt).dot(np.linalg.inv(Qt)).dot(t) | |
matched_img = ts.reshape(*target_img.transpose(2,0,1).shape).transpose(1,2,0) | |
matched_img += mu_s | |
matched_img[matched_img>1] = 1 | |
matched_img[matched_img<0] = 0 | |
return matched_img | |
output_img = match_color(target_img, source_img) | |
imsave('result_pca.png', output_img) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment