├── .gitignore ├── README.md ├── figure2 ├── brick-multi-linear.jpg ├── brick-multiscale.jpg ├── brick-single-11.jpg ├── brick-single-23.jpg ├── brick-single-3.jpg ├── brick-single-37.jpg ├── brick-single-55.jpg ├── brick-single-7.jpg ├── brick_wall.jpg ├── figure2.pdf ├── make_figure2.py ├── pebbles-multi-linear.jpg ├── pebbles-multiscale.jpg ├── pebbles-single-11.jpg ├── pebbles-single-23.jpg ├── pebbles-single-3.jpg ├── pebbles-single-37.jpg ├── pebbles-single-55.jpg ├── pebbles-single-7.jpg ├── pebbles.jpg ├── synthesise_figure2.sh ├── trees-multi-linear.jpg ├── trees-multiscale.jpg ├── trees-single-11.jpg ├── trees-single-23.jpg ├── trees-single-3.jpg ├── trees-single-37.jpg ├── trees-single-55.jpg ├── trees-single-7.jpg └── trees.jpg ├── figure3 ├── brick-sample-1.jpg ├── brick-sample-2.jpg ├── brick-sample-3.jpg ├── brick_wall.jpg ├── figure3.pdf ├── make_figure3.py ├── pebbles-sample-1.jpg ├── pebbles-sample-2.jpg ├── pebbles-sample-3.jpg ├── pebbles.jpg ├── synthesise_figure3.sh ├── trees-sample-1.jpg ├── trees-sample-2.jpg ├── trees-sample-3.jpg └── trees.jpg ├── figure4 ├── evaluate_quality.py ├── figure4.pdf ├── make_figure4.py ├── synthesise_figure4.sh ├── textures │ ├── barbara.jpg │ ├── barbara.jpg-11.jpg │ ├── barbara.jpg-multiscale.jpg │ ├── barbara.jpg-vgg19.jpg │ ├── brick_wall.jpg │ ├── brick_wall.jpg-11.jpg │ ├── brick_wall.jpg-multiscale.jpg │ ├── brick_wall.jpg-vgg19.jpg │ ├── bubbly_0067.jpg │ ├── bubbly_0067.jpg-11.jpg │ ├── bubbly_0067.jpg-multiscale.jpg │ ├── bubbly_0067.jpg-vgg19.jpg │ ├── bubbly_0111.jpg │ ├── bubbly_0111.jpg-11.jpg │ ├── bubbly_0111.jpg-multiscale.jpg │ ├── bubbly_0111.jpg-vgg19.jpg │ ├── bumpy_0121.jpg │ ├── bumpy_0121.jpg-11.jpg │ ├── bumpy_0121.jpg-multiscale.jpg │ ├── bumpy_0121.jpg-vgg19.jpg │ ├── cobwebbed_0132.jpg │ ├── cobwebbed_0132.jpg-11.jpg │ ├── cobwebbed_0132.jpg-multiscale.jpg │ ├── cobwebbed_0132.jpg-vgg19.jpg │ ├── frilly_0103.jpg │ ├── frilly_0103.jpg-11.jpg │ ├── frilly_0103.jpg-multiscale.jpg │ ├── frilly_0103.jpg-vgg19.jpg │ ├── gauzy_0126.jpg │ ├── gauzy_0126.jpg-11.jpg │ ├── gauzy_0126.jpg-multiscale.jpg │ ├── gauzy_0126.jpg-vgg19.jpg │ ├── grid_0053.jpg │ ├── grid_0053.jpg-11.jpg │ ├── grid_0053.jpg-multiscale.jpg │ ├── grid_0053.jpg-vgg19.jpg │ ├── lacelike_0004.jpg │ ├── lacelike_0004.jpg-11.jpg │ ├── lacelike_0004.jpg-multiscale.jpg │ ├── lacelike_0004.jpg-vgg19.jpg │ ├── lacelike_0069.jpg │ ├── lacelike_0069.jpg-11.jpg │ ├── lacelike_0069.jpg-multiscale.jpg │ ├── lacelike_0069.jpg-vgg19.jpg │ ├── lacelike_0073.jpg │ ├── lacelike_0073.jpg-11.jpg │ ├── lacelike_0073.jpg-multiscale.jpg │ ├── lacelike_0073.jpg-vgg19.jpg │ ├── lena.jpg │ ├── lena.jpg-11.jpg │ ├── lena.jpg-multiscale.jpg │ ├── lena.jpg-vgg19.jpg │ ├── meshed_0164.jpg │ ├── meshed_0164.jpg-11.jpg │ ├── meshed_0164.jpg-multiscale.jpg │ ├── meshed_0164.jpg-vgg19.jpg │ ├── pebble_texture.jpg │ ├── pebble_texture.jpg-11.jpg │ ├── pebble_texture.jpg-multiscale.jpg │ ├── pebble_texture.jpg-vgg19.jpg │ ├── pebbles.jpg │ ├── pebbles.jpg-11.jpg │ ├── pebbles.jpg-multiscale.jpg │ ├── pebbles.jpg-vgg19.jpg │ ├── porous_0137.jpg │ ├── porous_0137.jpg-11.jpg │ ├── porous_0137.jpg-multiscale.jpg │ ├── porous_0137.jpg-vgg19.jpg │ ├── radish.jpg │ ├── radish.jpg-11.jpg │ ├── radish.jpg-multiscale.jpg │ ├── radish.jpg-vgg19.jpg │ ├── scaly_0127.jpg │ ├── scaly_0127.jpg-11.jpg │ ├── scaly_0127.jpg-multiscale.jpg │ ├── scaly_0127.jpg-vgg19.jpg │ ├── trees.jpg │ ├── trees.jpg-11.jpg │ ├── trees.jpg-multiscale.jpg │ └── trees.jpg-vgg19.jpg └── vgg_loss.py ├── synthesise.py ├── vgg19_normalized.pkl └── vgg_loss.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | 91 | # Vim 92 | *.swp 93 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # random-texture-synthesis 2 | Code for the ICLR 2017 paper [“What does it take to generate natural textures?”](https://openreview.net/forum?id=BJhZeLsxx) 3 | 4 | # How to run 5 | ## Synthesising textures 6 | The main function is `synthesise.py`, which allows to synthesise textures using random shallow models described in the paper. 7 | 8 | Running 9 | 10 | `python3 synthesise.py -t texture.jpg -s 200` 11 | 12 | will synthesise a new texture of size 200x200 using the multi-scale model described in the paper and save it as `texture_synthesised.jpg`. You can change the sizes of convolutional filters for different scales using the “--scales” keyword. For example, 13 | 14 | `python3 synthesise.py -t texture.jpg -s 200 --scales 11` 15 | 16 | will synthesise a new texture using a single-scale model with 11x11 filters. 17 | 18 | Additional arguments to `synthesise.py` are as follows: 19 | 20 | ``` 21 | $ python3 synthesise.py -h 22 | 23 | usage: synthesise.py [-h] -t TEXTURE -s SIZE [-f TARGET_FILE] [-n N_ITER] 24 | [-c N_FEATURES] [--scales [SCALES [SCALES ...]]] [-l] 25 | 26 | optional arguments: 27 | -h, --help show this help message and exit 28 | -t TEXTURE, --texture TEXTURE 29 | Path to the reference texture 30 | -s SIZE, --size SIZE Size of a synthesised texture in pixels 31 | -f TARGET_FILE, --target-file TARGET_FILE 32 | File name of a syntesised texture 33 | -n N_ITER, --n-iter N_ITER 34 | Number of L-BFGS optinisation iterations 35 | -c N_FEATURES, --n-features N_FEATURES 36 | Number of feature maps per each scale 37 | --scales [SCALES [SCALES ...]] 38 | Sizes of convolutional filters 39 | -l, --linear Use linear model (conv layer without non-linearity) 40 | ``` 41 | 42 | * `-t` is a path to a reference textures, 43 | * `-s` is a size (in pixels) of a synthesised textures, 44 | * `-f` is a filename of a synthesised texture (if not provided, by default `_synthesised.jpg` is added to the filename of the reference texture), 45 | * `-n` is a number of L-BFGS optimisation steps (default 4000), 46 | * `-c` is a number of feature maps per scale (i.e. for each filter size), 47 | * `--scales` are the sizes of convolutional filters (if not provided the multi-scale model is used by default with filters sizes 3, 5, 7, 11, 15, 23, 37, 55, 48 | * `-l` makes the model linear (no non-linearity after the conv layer is used). 49 | 50 | ## Evaluating VGG-loss 51 | `vgg_loss.py` allows to evaluate the VGG-loss of a synthesised texture. Function `main` in this file takes two arguments (path to the reference texture and path to the synthesised texture) and returns the value of the VGG-loss: 52 | 53 | ```python 54 | import vgg_loss 55 | 56 | loss = vgg_loss.main('reference_texture.jpg', 'synthesised_texture.jpg') 57 | ``` 58 | 59 | # Figures 60 | Folders for respective figures contain code to generate these figures (e.g. `make_figure2.py`) using the provided synthesised textures as well as the shell scripts (e.g. `synthesise_figure2.sh`) to generate new textures. 61 | -------------------------------------------------------------------------------- /figure2/brick-multi-linear.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/brick-multi-linear.jpg -------------------------------------------------------------------------------- /figure2/brick-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/brick-multiscale.jpg -------------------------------------------------------------------------------- /figure2/brick-single-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/brick-single-11.jpg -------------------------------------------------------------------------------- /figure2/brick-single-23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/brick-single-23.jpg -------------------------------------------------------------------------------- /figure2/brick-single-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/brick-single-3.jpg -------------------------------------------------------------------------------- /figure2/brick-single-37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/brick-single-37.jpg -------------------------------------------------------------------------------- /figure2/brick-single-55.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/brick-single-55.jpg -------------------------------------------------------------------------------- /figure2/brick-single-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/brick-single-7.jpg -------------------------------------------------------------------------------- /figure2/brick_wall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/brick_wall.jpg -------------------------------------------------------------------------------- /figure2/figure2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/figure2.pdf -------------------------------------------------------------------------------- /figure2/make_figure2.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | import matplotlib 4 | matplotlib.use('Agg') 5 | 6 | import matplotlib.pyplot as plt 7 | from matplotlib import gridspec 8 | from matplotlib import rc 9 | import matplotlib.patches as patches 10 | 11 | rc('text', usetex=True) 12 | 13 | gs = gridspec.GridSpec(4, 8, width_ratios=[3]*8, height_ratios=[0.5, 3, 3, 3], 14 | wspace=0, hspace=0, left=0, right=1, top=1, bottom=0) 15 | 16 | fontsize = 25 17 | 18 | plt.figure(figsize=(24, 9.5)) 19 | 20 | for row in range(4): 21 | for col in range(8): 22 | if row == 0 and col > 0: continue 23 | if col == 0: 24 | plt.subplot(gs[row, col], frameon=False) 25 | plt.gca().add_patch(patches.Rectangle((0, 0), 1.0, 1.0, color='0.8', alpha=1, zorder=0)) 26 | if row == 1: 27 | img = plt.imread('pebbles-multiscale.jpg') 28 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 29 | plt.title(r'\textbf{Multi-scale}', fontsize=fontsize, y=0.98) 30 | if row == 2: 31 | img = plt.imread('trees-multiscale.jpg') 32 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 33 | if row == 3: 34 | img = plt.imread('brick-multiscale.jpg') 35 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 36 | plt.xlim([0, 1]) 37 | plt.ylim([0, 1]) 38 | plt.gca().xaxis.set_visible(False) 39 | plt.gca().yaxis.set_visible(False) 40 | 41 | if col == 1: 42 | plt.subplot(gs[row, col], frameon=False) 43 | if row == 1: 44 | img = plt.imread('pebbles-single-3.jpg') 45 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 46 | plt.title(r'\textbf{3x3}', fontsize=fontsize, y=0.98) 47 | if row == 2: 48 | img = plt.imread('trees-single-3.jpg') 49 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 50 | if row == 3: 51 | img = plt.imread('brick-single-3.jpg') 52 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 53 | plt.xlim([0, 1]) 54 | plt.ylim([0, 1]) 55 | plt.gca().xaxis.set_visible(False) 56 | plt.gca().yaxis.set_visible(False) 57 | 58 | if col == 2: 59 | plt.subplot(gs[row, col], frameon=False) 60 | if row == 1: 61 | img = plt.imread('pebbles-single-7.jpg') 62 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 63 | plt.title(r'\textbf{7x7}', fontsize=fontsize, y=0.98) 64 | if row == 2: 65 | img = plt.imread('trees-single-7.jpg') 66 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 67 | if row == 3: 68 | img = plt.imread('brick-single-7.jpg') 69 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 70 | plt.xlim([0, 1]) 71 | plt.ylim([0, 1]) 72 | plt.gca().xaxis.set_visible(False) 73 | plt.gca().yaxis.set_visible(False) 74 | 75 | if col == 3: 76 | plt.subplot(gs[row, col], frameon=False) 77 | if row == 1: 78 | img = plt.imread('pebbles-single-11.jpg') 79 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 80 | plt.title(r'\textbf{11x11}', fontsize=fontsize, y=0.98) 81 | if row == 2: 82 | img = plt.imread('trees-single-11.jpg') 83 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 84 | if row == 3: 85 | img = plt.imread('brick-single-11.jpg') 86 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 87 | plt.xlim([0, 1]) 88 | plt.ylim([0, 1]) 89 | plt.gca().xaxis.set_visible(False) 90 | plt.gca().yaxis.set_visible(False) 91 | 92 | if col == 4: 93 | plt.subplot(gs[row, col], frameon=False) 94 | if row == 1: 95 | img = plt.imread('pebbles-single-23.jpg') 96 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 97 | plt.title(r'\textbf{23x23}', fontsize=fontsize, y=0.98) 98 | if row == 2: 99 | img = plt.imread('trees-single-23.jpg') 100 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 101 | if row == 3: 102 | img = plt.imread('brick-single-23.jpg') 103 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 104 | plt.xlim([0, 1]) 105 | plt.ylim([0, 1]) 106 | plt.gca().xaxis.set_visible(False) 107 | plt.gca().yaxis.set_visible(False) 108 | 109 | if col == 5: 110 | plt.subplot(gs[row, col], frameon=False) 111 | if row == 1: 112 | img = plt.imread('pebbles-single-37.jpg') 113 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 114 | plt.title(r'\textbf{37x37}', fontsize=fontsize, y=0.98) 115 | if row == 2: 116 | img = plt.imread('trees-single-37.jpg') 117 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 118 | if row == 3: 119 | img = plt.imread('brick-single-37.jpg') 120 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 121 | plt.xlim([0, 1]) 122 | plt.ylim([0, 1]) 123 | plt.gca().xaxis.set_visible(False) 124 | plt.gca().yaxis.set_visible(False) 125 | 126 | if col == 6: 127 | plt.subplot(gs[row, col], frameon=False) 128 | if row == 1: 129 | img = plt.imread('pebbles-single-55.jpg') 130 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 131 | plt.title(r'\textbf{55x55}', fontsize=fontsize, y=0.98) 132 | if row == 2: 133 | img = plt.imread('trees-single-55.jpg') 134 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 135 | if row == 3: 136 | img = plt.imread('brick-single-55.jpg') 137 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 138 | plt.xlim([0, 1]) 139 | plt.ylim([0, 1]) 140 | plt.gca().xaxis.set_visible(False) 141 | plt.gca().yaxis.set_visible(False) 142 | 143 | if col == 7: 144 | plt.subplot(gs[row, col], frameon=False) 145 | if row == 1: 146 | img = plt.imread('pebbles-multi-linear.jpg') 147 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 148 | plt.title(r"""\textbf{Multi-scale} 149 | \textbf{(linear)}""", fontsize=fontsize, y=0.98) 150 | if row == 2: 151 | img = plt.imread('trees-multi-linear.jpg') 152 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 153 | if row == 3: 154 | img = plt.imread('brick-multi-linear.jpg') 155 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 156 | plt.xlim([0, 1]) 157 | plt.ylim([0, 1]) 158 | plt.gca().xaxis.set_visible(False) 159 | plt.gca().yaxis.set_visible(False) 160 | 161 | plt.savefig('figure2.pdf', bbox_inches='tight') 162 | -------------------------------------------------------------------------------- /figure2/pebbles-multi-linear.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/pebbles-multi-linear.jpg -------------------------------------------------------------------------------- /figure2/pebbles-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/pebbles-multiscale.jpg -------------------------------------------------------------------------------- /figure2/pebbles-single-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/pebbles-single-11.jpg -------------------------------------------------------------------------------- /figure2/pebbles-single-23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/pebbles-single-23.jpg -------------------------------------------------------------------------------- /figure2/pebbles-single-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/pebbles-single-3.jpg -------------------------------------------------------------------------------- /figure2/pebbles-single-37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/pebbles-single-37.jpg -------------------------------------------------------------------------------- /figure2/pebbles-single-55.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/pebbles-single-55.jpg -------------------------------------------------------------------------------- /figure2/pebbles-single-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/pebbles-single-7.jpg -------------------------------------------------------------------------------- /figure2/pebbles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/pebbles.jpg -------------------------------------------------------------------------------- /figure2/synthesise_figure2.sh: -------------------------------------------------------------------------------- 1 | # Individual scales 2 | scales=(3 7 11 23 37 55); 3 | 4 | for scale in ${scales[@]}; do 5 | python3 ../synthesise.py -t pebbles.jpg -s 256 -n 1 -f pebbles-single-$scale.jpg -c 1024 --scales $scale 6 | python3 ../synthesise.py -t trees.jpg -s 256 -n 1 -f trees-single-$scale.jpg -c 1024 --scales $scale 7 | python3 ../synthesise.py -t brick_wall.jpg -s 256 -n 1 -f brick-single-$scale.jpg -c 1024 --scales $scale 8 | done 9 | 10 | 11 | # Linear multi-scale 12 | python3 ../synthesise.py -t pebbles.jpg -s 256 -n 1 -f pebbles-multiscale.jpg 13 | python3 ../synthesise.py -t trees.jpg -s 256 -n 1 -f trees-multiscale.jpg 14 | python3 ../synthesise.py -t brick_wall.jpg -s 256 -n 1 -f brick-multiscale.jpg 15 | 16 | # Linear multi-scale 17 | python3 ../synthesise.py -t pebbles.jpg -s 256 -n 1 -f pebbles-multi-linear.jpg --linear 18 | python3 ../synthesise.py -t trees.jpg -s 256 -n 1 -f trees-multi-linear.jpg --linear 19 | python3 ../synthesise.py -t brick_wall.jpg -s 256 -n 1 -f brick-multi-linear.jpg --linear 20 | -------------------------------------------------------------------------------- /figure2/trees-multi-linear.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/trees-multi-linear.jpg -------------------------------------------------------------------------------- /figure2/trees-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/trees-multiscale.jpg -------------------------------------------------------------------------------- /figure2/trees-single-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/trees-single-11.jpg -------------------------------------------------------------------------------- /figure2/trees-single-23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/trees-single-23.jpg -------------------------------------------------------------------------------- /figure2/trees-single-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/trees-single-3.jpg -------------------------------------------------------------------------------- /figure2/trees-single-37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/trees-single-37.jpg -------------------------------------------------------------------------------- /figure2/trees-single-55.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/trees-single-55.jpg -------------------------------------------------------------------------------- /figure2/trees-single-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/trees-single-7.jpg -------------------------------------------------------------------------------- /figure2/trees.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure2/trees.jpg -------------------------------------------------------------------------------- /figure3/brick-sample-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure3/brick-sample-1.jpg -------------------------------------------------------------------------------- /figure3/brick-sample-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure3/brick-sample-2.jpg -------------------------------------------------------------------------------- /figure3/brick-sample-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure3/brick-sample-3.jpg -------------------------------------------------------------------------------- /figure3/brick_wall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure3/brick_wall.jpg -------------------------------------------------------------------------------- /figure3/figure3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure3/figure3.pdf -------------------------------------------------------------------------------- /figure3/make_figure3.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | import matplotlib 4 | matplotlib.use('Agg') 5 | 6 | import matplotlib.pyplot as plt 7 | from matplotlib import gridspec 8 | from matplotlib import rc 9 | import matplotlib.patches as patches 10 | 11 | rc('text', usetex=True) 12 | 13 | gs = gridspec.GridSpec(4, 4, width_ratios=[3]*4, height_ratios=[0.5, 3, 3, 3], 14 | wspace=0, hspace=0, left=0, right=1, top=1, bottom=0) 15 | 16 | fontsize = 25 17 | 18 | plt.figure(figsize=(12, 9.5)) 19 | 20 | for row in range(4): 21 | for col in range(4): 22 | if row == 0 and col > 0: continue 23 | if col == 0: 24 | plt.subplot(gs[row, col], frameon=False) 25 | plt.gca().add_patch(patches.Rectangle((0, 0), 1.0, 1.0, color='0.8', alpha=1, zorder=0)) 26 | if row == 1: 27 | img = plt.imread('pebbles.jpg') 28 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 29 | plt.title(r'\textbf{Original}', fontsize=fontsize, y=0.98) 30 | if row == 2: 31 | img = plt.imread('trees.jpg') 32 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 33 | if row == 3: 34 | img = plt.imread('brick_wall.jpg') 35 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 36 | plt.xlim([0, 1]) 37 | plt.ylim([0, 1]) 38 | plt.gca().xaxis.set_visible(False) 39 | plt.gca().yaxis.set_visible(False) 40 | 41 | if col == 1: 42 | plt.subplot(gs[row, col], frameon=False) 43 | if row == 1: 44 | img = plt.imread('pebbles-sample-1.jpg') 45 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 46 | plt.title(r'\textbf{Sample 1}', fontsize=fontsize, y=0.98) 47 | if row == 2: 48 | img = plt.imread('trees-sample-1.jpg') 49 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 50 | if row == 3: 51 | img = plt.imread('brick-sample-1.jpg') 52 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 53 | plt.xlim([0, 1]) 54 | plt.ylim([0, 1]) 55 | plt.gca().xaxis.set_visible(False) 56 | plt.gca().yaxis.set_visible(False) 57 | 58 | if col == 2: 59 | plt.subplot(gs[row, col], frameon=False) 60 | if row == 1: 61 | img = plt.imread('pebbles-sample-2.jpg') 62 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 63 | plt.title(r'\textbf{Sample 2}', fontsize=fontsize, y=0.98) 64 | if row == 2: 65 | img = plt.imread('trees-sample-2.jpg') 66 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 67 | if row == 3: 68 | img = plt.imread('brick-sample-2.jpg') 69 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 70 | plt.xlim([0, 1]) 71 | plt.ylim([0, 1]) 72 | plt.gca().xaxis.set_visible(False) 73 | plt.gca().yaxis.set_visible(False) 74 | 75 | if col == 3: 76 | plt.subplot(gs[row, col], frameon=False) 77 | if row == 1: 78 | img = plt.imread('pebbles-sample-3.jpg') 79 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 80 | plt.title(r'\textbf{Sample 3}', fontsize=fontsize, y=0.98) 81 | if row == 2: 82 | img = plt.imread('trees-sample-3.jpg') 83 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 84 | if row == 3: 85 | img = plt.imread('brick-sample-3.jpg') 86 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 87 | plt.xlim([0, 1]) 88 | plt.ylim([0, 1]) 89 | plt.gca().xaxis.set_visible(False) 90 | plt.gca().yaxis.set_visible(False) 91 | 92 | plt.savefig('figure3.pdf', bbox_inches='tight') 93 | -------------------------------------------------------------------------------- /figure3/pebbles-sample-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure3/pebbles-sample-1.jpg -------------------------------------------------------------------------------- /figure3/pebbles-sample-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure3/pebbles-sample-2.jpg -------------------------------------------------------------------------------- /figure3/pebbles-sample-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure3/pebbles-sample-3.jpg -------------------------------------------------------------------------------- /figure3/pebbles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure3/pebbles.jpg -------------------------------------------------------------------------------- /figure3/synthesise_figure3.sh: -------------------------------------------------------------------------------- 1 | # Individual scales 2 | samples=(1 2 3); 3 | 4 | for sample in ${samples[@]}; do 5 | python3 ../synthesise.py -t pebbles.jpg -s 256 -f pebbles-sample-$sample.jpg 6 | python3 ../synthesise.py -t trees.jpg -s 256 -f trees-sample-$sample.jpg 7 | python3 ../synthesise.py -t brick_wall.jpg -s 256 -f brick-sample-$sample.jpg 8 | done 9 | -------------------------------------------------------------------------------- /figure3/trees-sample-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure3/trees-sample-1.jpg -------------------------------------------------------------------------------- /figure3/trees-sample-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure3/trees-sample-2.jpg -------------------------------------------------------------------------------- /figure3/trees-sample-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure3/trees-sample-3.jpg -------------------------------------------------------------------------------- /figure3/trees.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure3/trees.jpg -------------------------------------------------------------------------------- /figure4/evaluate_quality.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pickle 3 | import scipy 4 | import sys 5 | import os 6 | import matplotlib.pyplot as plt 7 | import skimage.transform 8 | 9 | sys.path.append('/master/') 10 | 11 | import theano 12 | import theano.tensor as T 13 | import lasagne 14 | 15 | from lasagne.utils import floatX 16 | from lasagne.layers import InputLayer, ConcatLayer 17 | from lasagne.layers import Conv2DLayer as ConvLayer 18 | from lasagne.layers import Pool2DLayer as PoolLayer 19 | 20 | def prep_image(im): 21 | MEAN_VALUES = np.array([104, 117, 123]).reshape((3,1,1)) 22 | 23 | if len(im.shape) == 2: 24 | im = im[:, :, np.newaxis] 25 | im = np.repeat(im, 3, axis=2) 26 | if im.shape[2] == 4: 27 | im = im[:,:,:3] 28 | h, w, _ = im.shape 29 | 30 | if h < w: 31 | im = skimage.transform.resize(im, (IMAGE_W, int(w*IMAGE_W/h)), preserve_range=True) 32 | else: 33 | im = skimage.transform.resize(im, (int(h*IMAGE_W/w), IMAGE_W), preserve_range=True) 34 | 35 | # Central crop 36 | h, w, _ = im.shape 37 | im = im[h//2-IMAGE_W//2:h//2+IMAGE_W//2, w//2-IMAGE_W//2:w//2+IMAGE_W//2] 38 | 39 | rawim = np.copy(im).astype('uint8') 40 | 41 | # Shuffle axes to c01 42 | im = np.swapaxes(np.swapaxes(im, 1, 2), 0, 1) 43 | 44 | # Convert RGB to BGR 45 | im = im[::-1, :, :] 46 | 47 | im = im - MEAN_VALUES 48 | return rawim, floatX(im[np.newaxis]) 49 | 50 | def gram_matrix(x): 51 | x = x.flatten(ndim=3) 52 | g = T.tensordot(x, x, axes=([2], [2])) 53 | return g 54 | 55 | def style_loss(A, X, layer): 56 | a = A[layer] 57 | x = X[layer] 58 | 59 | A = gram_matrix(a) 60 | G = gram_matrix(x) 61 | 62 | N = a.shape[1] 63 | M = a.shape[2] * a.shape[3] 64 | 65 | loss = 1./(4 * N**2 * M**2) * ((G - A)**2).sum() 66 | return loss 67 | 68 | def deprocess(x): 69 | MEAN_VALUES = np.array([104, 117, 123]).reshape((3,1,1)) 70 | x = np.copy(x[0]) 71 | x += MEAN_VALUES 72 | 73 | x = x[::-1] 74 | x = np.swapaxes(np.swapaxes(x, 0, 1), 1, 2) 75 | 76 | x = np.clip(x, 0, 255).astype('uint8') 77 | return x 78 | 79 | def style_loss_relative(A, X, layer, layers): 80 | a = A[layer] 81 | x = X[layer] 82 | 83 | G_all = [] 84 | for l in layers: 85 | G_layer = gram_matrix(A[l]) 86 | G_all.append((G_layer**2).mean()) 87 | G_all = T.sum(G_all) 88 | 89 | A = gram_matrix(a) 90 | G = gram_matrix(x) 91 | 92 | # loss = ((G - A)**2).mean() / (A**2).mean() 93 | loss = ((G - A)**2).mean() / G_all 94 | return loss 95 | 96 | def build_model(): 97 | net = {} 98 | net['input'] = InputLayer((1, 3, IMAGE_W, IMAGE_W)) 99 | net['conv1_1'] = ConvLayer(net['input'], 64, 3, pad=1, flip_filters=False) 100 | net['conv1_2'] = ConvLayer(net['conv1_1'], 64, 3, pad=1, flip_filters=False) 101 | net['pool1'] = PoolLayer(net['conv1_2'], 2, mode='average_exc_pad') 102 | net['conv2_1'] = ConvLayer(net['pool1'], 128, 3, pad=1, flip_filters=False) 103 | net['conv2_2'] = ConvLayer(net['conv2_1'], 128, 3, pad=1, flip_filters=False) 104 | net['pool2'] = PoolLayer(net['conv2_2'], 2, mode='average_exc_pad') 105 | net['conv3_1'] = ConvLayer(net['pool2'], 256, 3, pad=1, flip_filters=False) 106 | net['conv3_2'] = ConvLayer(net['conv3_1'], 256, 3, pad=1, flip_filters=False) 107 | net['conv3_3'] = ConvLayer(net['conv3_2'], 256, 3, pad=1, flip_filters=False) 108 | net['conv3_4'] = ConvLayer(net['conv3_3'], 256, 3, pad=1, flip_filters=False) 109 | net['pool3'] = PoolLayer(net['conv3_4'], 2, mode='average_exc_pad') 110 | net['conv4_1'] = ConvLayer(net['pool3'], 512, 3, pad=1, flip_filters=False) 111 | net['conv4_2'] = ConvLayer(net['conv4_1'], 512, 3, pad=1, flip_filters=False) 112 | net['conv4_3'] = ConvLayer(net['conv4_2'], 512, 3, pad=1, flip_filters=False) 113 | net['conv4_4'] = ConvLayer(net['conv4_3'], 512, 3, pad=1, flip_filters=False) 114 | net['pool4'] = PoolLayer(net['conv4_4'], 2, mode='average_exc_pad') 115 | net['conv5_1'] = ConvLayer(net['pool4'], 512, 3, pad=1, flip_filters=False) 116 | net['conv5_2'] = ConvLayer(net['conv5_1'], 512, 3, pad=1, flip_filters=False) 117 | net['conv5_3'] = ConvLayer(net['conv5_2'], 512, 3, pad=1, flip_filters=False) 118 | net['conv5_4'] = ConvLayer(net['conv5_3'], 512, 3, pad=1, flip_filters=False) 119 | net['pool5'] = PoolLayer(net['conv5_4'], 2, mode='average_exc_pad') 120 | return net 121 | 122 | def evaluate(texture_file, texture_file_synthesized, net): 123 | texture = plt.imread(texture_file) 124 | rawim, texture = prep_image(texture) 125 | 126 | texture_synt = plt.imread(texture_file_synthesized) 127 | rawim_synt, texture_synt = prep_image(texture_synt) 128 | 129 | layers = ['conv1_1', 'conv2_1', 'conv3_1', 'conv4_1', 'conv5_1'] 130 | layers = {k: net[k] for k in layers} 131 | 132 | input_im_theano = T.tensor4() 133 | outputs = lasagne.layers.get_output(layers.values(), input_im_theano) 134 | texture_features = {k: theano.shared(output.eval({input_im_theano: texture})) 135 | for k, output in zip(layers.keys(), outputs)} 136 | 137 | generated_image = theano.shared(floatX(texture_synt)) 138 | gen_features = lasagne.layers.get_output(layers.values(), generated_image) 139 | gen_features = {k: v for k, v in zip(layers.keys(), gen_features)} 140 | 141 | losses = [] 142 | losses_test = [] 143 | layers_all = ['conv1_1', 'conv2_1', 'conv3_1', 'conv4_1', 'conv5_1'] 144 | losses.append(1 * style_loss(texture_features, gen_features, 'conv1_1')) 145 | losses.append(1 * style_loss(texture_features, gen_features, 'conv2_1')) 146 | losses.append(1 * style_loss(texture_features, gen_features, 'conv3_1')) 147 | losses.append(1 * style_loss(texture_features, gen_features, 'conv4_1')) 148 | losses.append(1 * style_loss(texture_features, gen_features, 'conv5_1')) 149 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv1_1', layers_all)) 150 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv2_1', layers_all)) 151 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv3_1', layers_all)) 152 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv4_1', layers_all)) 153 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv5_1', layers_all)) 154 | total_loss = sum(losses) 155 | total_loss_test = sum(losses_test) 156 | 157 | grad = T.grad(total_loss, generated_image) 158 | f_loss = theano.function([], total_loss) 159 | f_test_loss = theano.function([], total_loss_test) 160 | f_grad = theano.function([], grad) 161 | 162 | def eval_loss(x0): 163 | x0 = floatX(x0.reshape((1, 3, IMAGE_W, IMAGE_W))) 164 | generated_image.set_value(x0) 165 | return f_loss().astype('float64') 166 | 167 | def test_loss(x0): 168 | x0 = floatX(x0.reshape((1, 3, IMAGE_W, IMAGE_W))) 169 | generated_image.set_value(x0) 170 | return f_test_loss().astype('float64') 171 | 172 | def eval_grad(x0): 173 | x0 = floatX(x0.reshape((1, 3, IMAGE_W, IMAGE_W))) 174 | generated_image.set_value(x0) 175 | return np.array(f_grad()).flatten().astype('float64') 176 | 177 | generated_image.set_value(floatX(texture_synt)) 178 | x0 = generated_image.get_value().astype('float64') 179 | xs = [] 180 | xs.append(x0) 181 | losses = [] 182 | test_losses = [] 183 | losses.append(eval_loss(x0)) 184 | test_losses.append(test_loss(x0)) 185 | 186 | return (losses[-1], test_losses[-1]) 187 | 188 | def main(argv): 189 | texture_file = argv[0] 190 | texture_file_synthesized = argv[1] 191 | 192 | global IMAGE_W 193 | IMAGE_W = int(argv[2]) 194 | 195 | net = build_model() 196 | values = pickle.load(open('/master/parameters/vgg19_normalized.pkl', 'rb'), encoding='latin1')['param values'] 197 | lasagne.layers.set_all_param_values(net['pool5'], values) 198 | 199 | loss, relative_loss = evaluate(texture_file, texture_file_synthesized, net) 200 | return (float(loss), float(relative_loss)) 201 | 202 | if __name__ == '__main__': 203 | main(sys.argv[1:]) 204 | -------------------------------------------------------------------------------- /figure4/figure4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/figure4.pdf -------------------------------------------------------------------------------- /figure4/make_figure4.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import os 3 | import ..vgg_loss 4 | import evaluate_quality as eq 5 | 6 | import matplotlib 7 | matplotlib.use('Agg') 8 | 9 | import matplotlib.pyplot as plt 10 | from matplotlib import gridspec 11 | from matplotlib import rc 12 | import matplotlib.patches as patches 13 | 14 | rc('text', usetex=True) 15 | 16 | def make_10_notation(x): 17 | x2 = x / 1e-3 18 | x2str = r'${:.3f}'.format(x2) 19 | return x2str + r' \cdot 10^{-3}$' 20 | 21 | texture_files1 = ['lena.jpg', 'barbara.jpg', 'trees.jpg', 'pebbles.jpg', 'radish.jpg', 'brick_wall.jpg', 'bubbly_0067.jpg', 'bubbly_0111.jpg', 'bumpy_0121.jpg', 'cobwebbed_0132.jpg'] 22 | texture_files2 = ['frilly_0103.jpg', 'gauzy_0126.jpg', 'grid_0053.jpg', 'lacelike_0004.jpg', 'lacelike_0069.jpg', 'lacelike_0073.jpg', 'meshed_0164.jpg', 'pebble_texture.jpg', 'porous_0137.jpg', 'scaly_0127.jpg'] 23 | 24 | width_ratios = [3,3,3,3,2,3,3,3,3] 25 | height_ratios = [1.0, 3] + [0.4, 3]*9 26 | gs = gridspec.GridSpec(20, 9, width_ratios=width_ratios, height_ratios=height_ratios, 27 | wspace=0, hspace=0, left=0, right=1, top=1, bottom=0) 28 | 29 | fontsize = 25 30 | 31 | plt.figure(figsize=(sum(width_ratios), sum(height_ratios))) 32 | 33 | for row in range(20): 34 | for col in range(9): 35 | if col == 0: 36 | plt.subplot(gs[row, col], frameon=False) 37 | plt.gca().add_patch(patches.Rectangle((0, 0), 1.0, 1.0, color='0.8', alpha=1, zorder=0)) 38 | if row > 0 and row % 2 == 1: 39 | img = plt.imread(os.path.join('textures', texture_files1[row//2])) 40 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 41 | if row == 1: 42 | plt.title(r'\textbf{Original}', fontsize=fontsize, y=1.1) 43 | plt.xlim([0, 1]) 44 | plt.ylim([0, 1]) 45 | plt.gca().xaxis.set_visible(False) 46 | plt.gca().yaxis.set_visible(False) 47 | 48 | if col == 1: 49 | plt.subplot(gs[row, col], frameon=False) 50 | if row > 0 and row % 2 == 1: 51 | img = plt.imread(os.path.join('textures', texture_files1[row//2] + '-11.jpg')) 52 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 53 | loss = vgg_loss.main(os.path.join('textures', texture_files1[row//2]), 54 | os.path.join('textures', texture_files1[row//2] + '-11.jpg')) 55 | if row == 1: 56 | title = r'\textbf{signle-scale}' + '\n' + make_10_notation(loss) 57 | else: 58 | title = make_10_notation(loss) 59 | plt.title(title, fontsize=fontsize, y=0.98) 60 | plt.xlim([0, 1]) 61 | plt.ylim([0, 1]) 62 | plt.gca().xaxis.set_visible(False) 63 | plt.gca().yaxis.set_visible(False) 64 | 65 | if col == 2: 66 | plt.subplot(gs[row, col], frameon=False) 67 | if row > 0 and row % 2 == 1: 68 | img = plt.imread(os.path.join('textures', texture_files1[row//2] + '-multiscale.jpg')) 69 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 70 | loss = vgg_loss.main(os.path.join('textures', texture_files1[row//2]), 71 | os.path.join('textures', texture_files1[row//2] + '-multiscale.jpg')) 72 | if row == 1: 73 | title = r'\textbf{multi-scale}' + '\n' + make_10_notation(loss) 74 | else: 75 | title = make_10_notation(loss) 76 | plt.title(title, fontsize=fontsize, y=0.98) 77 | plt.xlim([0, 1]) 78 | plt.ylim([0, 1]) 79 | plt.gca().xaxis.set_visible(False) 80 | plt.gca().yaxis.set_visible(False) 81 | 82 | if col == 3: 83 | plt.subplot(gs[row, col], frameon=False) 84 | if row > 0 and row % 2 == 1: 85 | img = plt.imread(os.path.join('textures', texture_files1[row//2] + '-vgg19.jpg')) 86 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 87 | loss = vgg_loss.main(os.path.join('textures', texture_files1[row//2]), 88 | os.path.join('textures', texture_files1[row//2] + '-vgg19.jpg')) 89 | if row == 1: 90 | title = r'\textbf{Gatys et al. [1]}' + '\n' + make_10_notation(loss) 91 | else: 92 | title = make_10_notation(loss) 93 | plt.title(title, fontsize=fontsize, y=0.98) 94 | plt.xlim([0, 1]) 95 | plt.ylim([0, 1]) 96 | plt.gca().xaxis.set_visible(False) 97 | plt.gca().yaxis.set_visible(False) 98 | 99 | if col == 5: 100 | plt.subplot(gs[row, col], frameon=False) 101 | plt.gca().add_patch(patches.Rectangle((0, 0), 1.0, 1.0, color='0.8', alpha=1, zorder=0)) 102 | if row > 0 and row % 2 == 1: 103 | img = plt.imread(os.path.join('textures', texture_files2[row//2])) 104 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 105 | if row == 1: 106 | plt.title(r'\textbf{Original}', fontsize=fontsize, y=1.1) 107 | plt.xlim([0, 1]) 108 | plt.ylim([0, 1]) 109 | plt.gca().xaxis.set_visible(False) 110 | plt.gca().yaxis.set_visible(False) 111 | 112 | if col == 6: 113 | plt.subplot(gs[row, col], frameon=False) 114 | if row > 0 and row % 2 == 1: 115 | img = plt.imread(os.path.join('textures', texture_files2[row//2] + '-11.jpg')) 116 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 117 | loss = vgg_loss.main(os.path.join('textures', texture_files2[row//2]), 118 | os.path.join('textures', texture_files2[row//2] + '-11.jpg')) 119 | if row == 1: 120 | title = r'\textbf{signle-scale}' + '\n' + make_10_notation(loss) 121 | else: 122 | title = make_10_notation(loss) 123 | plt.title(title, fontsize=fontsize, y=0.98) 124 | plt.xlim([0, 1]) 125 | plt.ylim([0, 1]) 126 | plt.gca().xaxis.set_visible(False) 127 | plt.gca().yaxis.set_visible(False) 128 | 129 | if col == 7: 130 | plt.subplot(gs[row, col], frameon=False) 131 | if row > 0 and row % 2 == 1: 132 | img = plt.imread(os.path.join('textures', texture_files2[row//2] + '-multiscale.jpg')) 133 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 134 | loss = vgg_loss.main(os.path.join('textures', texture_files2[row//2]), 135 | os.path.join('textures', texture_files2[row//2] + '-multiscale.jpg')) 136 | if row == 1: 137 | title = r'\textbf{multi-scale}' + '\n' + make_10_notation(loss) 138 | else: 139 | title = make_10_notation(loss) 140 | plt.title(title, fontsize=fontsize, y=0.98) 141 | plt.xlim([0, 1]) 142 | plt.ylim([0, 1]) 143 | plt.gca().xaxis.set_visible(False) 144 | plt.gca().yaxis.set_visible(False) 145 | 146 | if col == 8: 147 | plt.subplot(gs[row, col], frameon=False) 148 | if row > 0 and row % 2 == 1: 149 | img = plt.imread(os.path.join('textures', texture_files2[row//2] + '-vgg19.jpg')) 150 | plt.imshow(img, extent=[0.06, 0.94, 0.06, 0.94]) 151 | loss = vgg_loss.main(os.path.join('textures', texture_files2[row//2]), 152 | os.path.join('textures', texture_files2[row//2] + '-vgg19.jpg')) 153 | if row == 1: 154 | title = r'\textbf{Gatys et al. [1]}' + '\n' + make_10_notation(loss) 155 | else: 156 | title = make_10_notation(loss) 157 | plt.title(title, fontsize=fontsize, y=0.98) 158 | plt.xlim([0, 1]) 159 | plt.ylim([0, 1]) 160 | plt.gca().xaxis.set_visible(False) 161 | plt.gca().yaxis.set_visible(False) 162 | 163 | plt.savefig('figure4.pdf', bbox_inches='tight') 164 | -------------------------------------------------------------------------------- /figure4/synthesise_figure4.sh: -------------------------------------------------------------------------------- 1 | python3 ../synthesise.py -t textures/barbara.jpg -s 256 -f textures/barbara.jpg-multiscale.jpg 2 | python3 ../synthesise.py -t textures/barbara.jpg -s 256 -f textures/barbara.jpg-11.jpg --scales 11 3 | 4 | python3 ../synthesise.py -t textures/brick_wall.jpg -s 256 -f textures/brick_wall.jpg-multiscale.jpg 5 | python3 ../synthesise.py -t textures/brick_wall.jpg -s 256 -f textures/brick_wall.jpg-11.jpg --scales 11 6 | 7 | python3 ../synthesise.py -t textures/bubbly_0067.jpg -s 256 -f textures/bubbly_0067.jpg-multiscale.jpg 8 | python3 ../synthesise.py -t textures/bubbly_0067.jpg -s 256 -f textures/bubbly_0067.jpg-11.jpg --scales 11 9 | 10 | python3 ../synthesise.py -t textures/bubbly_0111.jpg -s 256 -f textures/bubbly_0111.jpg-multiscale.jpg 11 | python3 ../synthesise.py -t textures/bubbly_0111.jpg -s 256 -f textures/bubbly_0111.jpg-11.jpg --scales 11 12 | 13 | python3 ../synthesise.py -t textures/bumpy_0121.jpg -s 256 -f textures/bumpy_0121.jpg-multiscale.jpg 14 | python3 ../synthesise.py -t textures/bumpy_0121.jpg -s 256 -f textures/bumpy_0121.jpg-11.jpg --scales 11 15 | 16 | python3 ../synthesise.py -t textures/cobwebbed_0132.jpg -s 256 -f textures/cobwebbed_0132.jpg-multiscale.jpg 17 | python3 ../synthesise.py -t textures/cobwebbed_0132.jpg -s 256 -f textures/cobwebbed_0132.jpg-11.jpg --scales 11 18 | 19 | python3 ../synthesise.py -t textures/frilly_0103.jpg -s 256 -f textures/frilly_0103.jpg-multiscale.jpg 20 | python3 ../synthesise.py -t textures/frilly_0103.jpg -s 256 -f textures/frilly_0103.jpg-11.jpg --scales 11 21 | 22 | python3 ../synthesise.py -t textures/gauzy_0126.jpg -s 256 -f textures/gauzy_0126.jpg-multiscale.jpg 23 | python3 ../synthesise.py -t textures/gauzy_0126.jpg -s 256 -f textures/gauzy_0126.jpg-11.jpg --scales 11 24 | 25 | python3 ../synthesise.py -t textures/grid_0053.jpg -s 256 -f textures/grid_0053.jpg-multiscale.jpg 26 | python3 ../synthesise.py -t textures/grid_0053.jpg -s 256 -f textures/grid_0053.jpg-11.jpg --scales 11 27 | 28 | python3 ../synthesise.py -t textures/lacelike_0004.jpg -s 256 -f textures/lacelike_0004.jpg-multiscale.jpg 29 | python3 ../synthesise.py -t textures/lacelike_0004.jpg -s 256 -f textures/lacelike_0004.jpg-11.jpg --scales 11 30 | 31 | python3 ../synthesise.py -t textures/lacelike_0069.jpg -s 256 -f textures/lacelike_0069.jpg-multiscale.jpg 32 | python3 ../synthesise.py -t textures/lacelike_0069.jpg -s 256 -f textures/lacelike_0069.jpg-11.jpg --scales 11 33 | 34 | python3 ../synthesise.py -t textures/lacelike_0073.jpg -s 256 -f textures/lacelike_0073.jpg-multiscale.jpg 35 | python3 ../synthesise.py -t textures/lacelike_0073.jpg -s 256 -f textures/lacelike_0073.jpg-11.jpg --scales 11 36 | 37 | python3 ../synthesise.py -t textures/lena.jpg -s 256 -f textures/lena.jpg-multiscale.jpg 38 | python3 ../synthesise.py -t textures/lena.jpg -s 256 -f textures/lena.jpg-11.jpg --scales 11 39 | 40 | python3 ../synthesise.py -t textures/meshed_0164.jpg -s 256 -f textures/meshed_0164.jpg-multiscale.jpg 41 | python3 ../synthesise.py -t textures/meshed_0164.jpg -s 256 -f textures/meshed_0164.jpg-11.jpg --scales 11 42 | 43 | python3 ../synthesise.py -t textures/pebble_texture.jpg -s 256 -f textures/pebble_texture.jpg-multiscale.jpg 44 | python3 ../synthesise.py -t textures/pebble_texture.jpg -s 256 -f textures/pebble_texture.jpg-11.jpg --scales 11 45 | 46 | python3 ../synthesise.py -t textures/pebbles.jpg -s 256 -f textures/pebbles.jpg-multiscale.jpg 47 | python3 ../synthesise.py -t textures/pebbles.jpg -s 256 -f textures/pebbles.jpg-11.jpg --scales 11 48 | 49 | python3 ../synthesise.py -t textures/porous_0137.jpg -s 256 -f textures/porous_0137.jpg-multiscale.jpg 50 | python3 ../synthesise.py -t textures/porous_0137.jpg -s 256 -f textures/porous_0137.jpg-11.jpg --scales 11 51 | 52 | python3 ../synthesise.py -t textures/radish.jpg -s 256 -f textures/radish.jpg-multiscale.jpg 53 | python3 ../synthesise.py -t textures/radish.jpg -s 256 -f textures/radish.jpg-11.jpg --scales 11 54 | 55 | python3 ../synthesise.py -t textures/scaly_0127.jpg -s 256 -f textures/scaly_0127.jpg-multiscale.jpg 56 | python3 ../synthesise.py -t textures/scaly_0127.jpg -s 256 -f textures/scaly_0127.jpg-11.jpg --scales 11 57 | 58 | python3 ../synthesise.py -t textures/trees.jpg -s 256 -f textures/trees.jpg-multiscale.jpg 59 | python3 ../synthesise.py -t textures/trees.jpg -s 256 -f textures/trees.jpg-11.jpg --scales 11 60 | 61 | -------------------------------------------------------------------------------- /figure4/textures/barbara.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/barbara.jpg -------------------------------------------------------------------------------- /figure4/textures/barbara.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/barbara.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/barbara.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/barbara.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/barbara.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/barbara.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/brick_wall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/brick_wall.jpg -------------------------------------------------------------------------------- /figure4/textures/brick_wall.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/brick_wall.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/brick_wall.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/brick_wall.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/brick_wall.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/brick_wall.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/bubbly_0067.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/bubbly_0067.jpg -------------------------------------------------------------------------------- /figure4/textures/bubbly_0067.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/bubbly_0067.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/bubbly_0067.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/bubbly_0067.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/bubbly_0067.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/bubbly_0067.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/bubbly_0111.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/bubbly_0111.jpg -------------------------------------------------------------------------------- /figure4/textures/bubbly_0111.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/bubbly_0111.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/bubbly_0111.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/bubbly_0111.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/bubbly_0111.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/bubbly_0111.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/bumpy_0121.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/bumpy_0121.jpg -------------------------------------------------------------------------------- /figure4/textures/bumpy_0121.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/bumpy_0121.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/bumpy_0121.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/bumpy_0121.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/bumpy_0121.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/bumpy_0121.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/cobwebbed_0132.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/cobwebbed_0132.jpg -------------------------------------------------------------------------------- /figure4/textures/cobwebbed_0132.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/cobwebbed_0132.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/cobwebbed_0132.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/cobwebbed_0132.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/cobwebbed_0132.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/cobwebbed_0132.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/frilly_0103.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/frilly_0103.jpg -------------------------------------------------------------------------------- /figure4/textures/frilly_0103.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/frilly_0103.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/frilly_0103.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/frilly_0103.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/frilly_0103.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/frilly_0103.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/gauzy_0126.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/gauzy_0126.jpg -------------------------------------------------------------------------------- /figure4/textures/gauzy_0126.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/gauzy_0126.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/gauzy_0126.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/gauzy_0126.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/gauzy_0126.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/gauzy_0126.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/grid_0053.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/grid_0053.jpg -------------------------------------------------------------------------------- /figure4/textures/grid_0053.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/grid_0053.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/grid_0053.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/grid_0053.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/grid_0053.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/grid_0053.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/lacelike_0004.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lacelike_0004.jpg -------------------------------------------------------------------------------- /figure4/textures/lacelike_0004.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lacelike_0004.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/lacelike_0004.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lacelike_0004.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/lacelike_0004.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lacelike_0004.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/lacelike_0069.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lacelike_0069.jpg -------------------------------------------------------------------------------- /figure4/textures/lacelike_0069.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lacelike_0069.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/lacelike_0069.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lacelike_0069.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/lacelike_0069.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lacelike_0069.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/lacelike_0073.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lacelike_0073.jpg -------------------------------------------------------------------------------- /figure4/textures/lacelike_0073.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lacelike_0073.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/lacelike_0073.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lacelike_0073.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/lacelike_0073.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lacelike_0073.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/lena.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lena.jpg -------------------------------------------------------------------------------- /figure4/textures/lena.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lena.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/lena.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lena.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/lena.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/lena.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/meshed_0164.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/meshed_0164.jpg -------------------------------------------------------------------------------- /figure4/textures/meshed_0164.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/meshed_0164.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/meshed_0164.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/meshed_0164.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/meshed_0164.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/meshed_0164.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/pebble_texture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/pebble_texture.jpg -------------------------------------------------------------------------------- /figure4/textures/pebble_texture.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/pebble_texture.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/pebble_texture.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/pebble_texture.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/pebble_texture.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/pebble_texture.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/pebbles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/pebbles.jpg -------------------------------------------------------------------------------- /figure4/textures/pebbles.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/pebbles.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/pebbles.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/pebbles.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/pebbles.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/pebbles.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/porous_0137.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/porous_0137.jpg -------------------------------------------------------------------------------- /figure4/textures/porous_0137.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/porous_0137.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/porous_0137.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/porous_0137.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/porous_0137.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/porous_0137.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/radish.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/radish.jpg -------------------------------------------------------------------------------- /figure4/textures/radish.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/radish.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/radish.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/radish.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/radish.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/radish.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/scaly_0127.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/scaly_0127.jpg -------------------------------------------------------------------------------- /figure4/textures/scaly_0127.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/scaly_0127.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/scaly_0127.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/scaly_0127.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/scaly_0127.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/scaly_0127.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/textures/trees.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/trees.jpg -------------------------------------------------------------------------------- /figure4/textures/trees.jpg-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/trees.jpg-11.jpg -------------------------------------------------------------------------------- /figure4/textures/trees.jpg-multiscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/trees.jpg-multiscale.jpg -------------------------------------------------------------------------------- /figure4/textures/trees.jpg-vgg19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/figure4/textures/trees.jpg-vgg19.jpg -------------------------------------------------------------------------------- /figure4/vgg_loss.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import sys 3 | import pickle 4 | 5 | import matplotlib 6 | matplotlib.use('Agg') 7 | 8 | import matplotlib.pyplot as plt 9 | import skimage.transform 10 | 11 | import theano 12 | import theano.tensor as T 13 | import lasagne 14 | 15 | from lasagne.utils import floatX 16 | from lasagne.layers import InputLayer, ConcatLayer 17 | from lasagne.layers import Conv2DLayer as ConvLayer 18 | from lasagne.layers import Pool2DLayer as PoolLayer 19 | 20 | def prep_image(im): 21 | MEAN_VALUES = np.array([104, 117, 123]).reshape((3,1,1)) 22 | 23 | if len(im.shape) == 2: 24 | im = im[:, :, np.newaxis] 25 | im = np.repeat(im, 3, axis=2) 26 | h, w, _ = im.shape 27 | 28 | if h < w: 29 | im = skimage.transform.resize(im, (IMAGE_W, int(w*IMAGE_W/h)), preserve_range=True) 30 | else: 31 | im = skimage.transform.resize(im, (int(h*IMAGE_W/w), IMAGE_W), preserve_range=True) 32 | 33 | # Central crop 34 | h, w, _ = im.shape 35 | im = im[h//2-IMAGE_W//2:h//2+IMAGE_W//2, w//2-IMAGE_W//2:w//2+IMAGE_W//2] 36 | 37 | rawim = np.copy(im).astype('uint8') 38 | 39 | # Shuffle axes to c01 40 | im = np.swapaxes(np.swapaxes(im, 1, 2), 0, 1) 41 | 42 | # Convert RGB to BGR 43 | im = im[::-1, :, :] 44 | 45 | im = im - MEAN_VALUES 46 | return rawim, floatX(im[np.newaxis]) 47 | 48 | def deprocess(x): 49 | MEAN_VALUES = np.array([104, 117, 123]).reshape((3,1,1)) 50 | x = np.copy(x[0]) 51 | x += MEAN_VALUES 52 | 53 | x = x[::-1] 54 | x = np.swapaxes(np.swapaxes(x, 0, 1), 1, 2) 55 | 56 | x = np.clip(x, 0, 255).astype('uint8') 57 | return x 58 | 59 | def gram_matrix(x): 60 | x = x.flatten(ndim=3) 61 | g = T.tensordot(x, x, axes=([2], [2])) 62 | return g 63 | 64 | def style_loss_relative(A, X, layer, layers): 65 | a = A[layer] 66 | x = X[layer] 67 | 68 | G_all = [] 69 | for l in layers: 70 | G_layer = gram_matrix(A[l]) 71 | G_all.append((G_layer**2).mean()) 72 | G_all = T.sum(G_all) 73 | 74 | A = gram_matrix(a) 75 | G = gram_matrix(x) 76 | 77 | loss = ((G - A)**2).mean() / G_all 78 | return loss 79 | 80 | def build_vgg_model(): 81 | net = {} 82 | net['input'] = InputLayer((1, 3, IMAGE_W, IMAGE_W)) 83 | net['conv1_1'] = ConvLayer(net['input'], 64, 3, pad=1, flip_filters=False) 84 | net['conv1_2'] = ConvLayer(net['conv1_1'], 64, 3, pad=1, flip_filters=False) 85 | net['pool1'] = PoolLayer(net['conv1_2'], 2, mode='average_exc_pad') 86 | net['conv2_1'] = ConvLayer(net['pool1'], 128, 3, pad=1, flip_filters=False) 87 | net['conv2_2'] = ConvLayer(net['conv2_1'], 128, 3, pad=1, flip_filters=False) 88 | net['pool2'] = PoolLayer(net['conv2_2'], 2, mode='average_exc_pad') 89 | net['conv3_1'] = ConvLayer(net['pool2'], 256, 3, pad=1, flip_filters=False) 90 | net['conv3_2'] = ConvLayer(net['conv3_1'], 256, 3, pad=1, flip_filters=False) 91 | net['conv3_3'] = ConvLayer(net['conv3_2'], 256, 3, pad=1, flip_filters=False) 92 | net['conv3_4'] = ConvLayer(net['conv3_3'], 256, 3, pad=1, flip_filters=False) 93 | net['pool3'] = PoolLayer(net['conv3_4'], 2, mode='average_exc_pad') 94 | net['conv4_1'] = ConvLayer(net['pool3'], 512, 3, pad=1, flip_filters=False) 95 | net['conv4_2'] = ConvLayer(net['conv4_1'], 512, 3, pad=1, flip_filters=False) 96 | net['conv4_3'] = ConvLayer(net['conv4_2'], 512, 3, pad=1, flip_filters=False) 97 | net['conv4_4'] = ConvLayer(net['conv4_3'], 512, 3, pad=1, flip_filters=False) 98 | net['pool4'] = PoolLayer(net['conv4_4'], 2, mode='average_exc_pad') 99 | net['conv5_1'] = ConvLayer(net['pool4'], 512, 3, pad=1, flip_filters=False) 100 | net['conv5_2'] = ConvLayer(net['conv5_1'], 512, 3, pad=1, flip_filters=False) 101 | net['conv5_3'] = ConvLayer(net['conv5_2'], 512, 3, pad=1, flip_filters=False) 102 | net['conv5_4'] = ConvLayer(net['conv5_3'], 512, 3, pad=1, flip_filters=False) 103 | net['pool5'] = PoolLayer(net['conv5_4'], 2, mode='average_exc_pad') 104 | return net 105 | 106 | def vgg_loss(texture_file, texture_file_synthesized, net): 107 | texture = plt.imread(texture_file) 108 | rawim, texture = prep_image(texture) 109 | 110 | texture_synt = plt.imread(texture_file_synthesized) 111 | rawim_synt, texture_synt = prep_image(texture_synt) 112 | 113 | layers = ['conv1_1', 'conv2_1', 'conv3_1', 'conv4_1', 'conv5_1'] 114 | layers = {k: net[k] for k in layers} 115 | 116 | input_im_theano = T.tensor4() 117 | outputs = lasagne.layers.get_output(layers.values(), input_im_theano) 118 | texture_features = {k: theano.shared(output.eval({input_im_theano: texture})) 119 | for k, output in zip(layers.keys(), outputs)} 120 | 121 | generated_image = theano.shared(floatX(texture_synt)) 122 | gen_features = lasagne.layers.get_output(layers.values(), generated_image) 123 | gen_features = {k: v for k, v in zip(layers.keys(), gen_features)} 124 | 125 | losses_test = [] 126 | layers_all = ['conv1_1', 'conv2_1', 'conv3_1', 'conv4_1', 'conv5_1'] 127 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv1_1', layers_all)) 128 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv2_1', layers_all)) 129 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv3_1', layers_all)) 130 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv4_1', layers_all)) 131 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv5_1', layers_all)) 132 | total_loss_test = sum(losses_test) 133 | 134 | f_test_loss = theano.function([], total_loss_test) 135 | 136 | def test_loss(x0): 137 | x0 = floatX(x0.reshape((1, 3, IMAGE_W, IMAGE_W))) 138 | generated_image.set_value(x0) 139 | return f_test_loss().astype('float64') 140 | 141 | generated_image.set_value(floatX(texture_synt)) 142 | loss = test_loss(generated_image.get_value().astype('float64')) 143 | 144 | return loss 145 | 146 | def main(texture_file, texture_file_synthesised): 147 | global IMAGE_W 148 | IMAGE_W = 200 149 | 150 | net = build_vgg_model() 151 | values = pickle.load(open('../vgg19_normalized.pkl', 'rb'), encoding='latin1')['param values'] 152 | lasagne.layers.set_all_param_values(net['pool5'], values) 153 | 154 | loss = vgg_loss(texture_file, texture_file_synthesised, net) 155 | 156 | return loss 157 | -------------------------------------------------------------------------------- /synthesise.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import scipy 3 | import sys 4 | import argparse 5 | import matplotlib.pyplot as plt 6 | import skimage.transform 7 | 8 | import theano 9 | import theano.tensor as T 10 | import lasagne 11 | 12 | from lasagne.utils import floatX 13 | from lasagne.layers import InputLayer, ConcatLayer 14 | from lasagne.layers import Conv2DLayer as ConvLayer 15 | 16 | def prep_image(im): 17 | MEAN_VALUES = np.array([104, 117, 123]).reshape((3,1,1)) 18 | 19 | if len(im.shape) == 2: 20 | im = im[:, :, np.newaxis] 21 | im = np.repeat(im, 3, axis=2) 22 | h, w, _ = im.shape 23 | 24 | if h < w: 25 | im = skimage.transform.resize(im, (IMAGE_W, int(w*IMAGE_W/h)), preserve_range=True) 26 | else: 27 | im = skimage.transform.resize(im, (int(h*IMAGE_W/w), IMAGE_W), preserve_range=True) 28 | 29 | # Central crop 30 | h, w, _ = im.shape 31 | im = im[h//2-IMAGE_W//2:h//2+IMAGE_W//2, w//2-IMAGE_W//2:w//2+IMAGE_W//2] 32 | 33 | rawim = np.copy(im).astype('uint8') 34 | 35 | # Shuffle axes to c01 36 | im = np.swapaxes(np.swapaxes(im, 1, 2), 0, 1) 37 | 38 | # Convert RGB to BGR 39 | im = im[::-1, :, :] 40 | 41 | im = im - MEAN_VALUES 42 | return rawim, floatX(im[np.newaxis]) 43 | 44 | def deprocess(x): 45 | MEAN_VALUES = np.array([104, 117, 123]).reshape((3,1,1)) 46 | x = np.copy(x[0]) 47 | x += MEAN_VALUES 48 | 49 | x = x[::-1] 50 | x = np.swapaxes(np.swapaxes(x, 0, 1), 1, 2) 51 | 52 | x = np.clip(x, 0, 255).astype('uint8') 53 | return x 54 | 55 | def gram_matrix(x): 56 | x = x.flatten(ndim=3) 57 | g = T.tensordot(x, x, axes=([2], [2])) 58 | return g 59 | 60 | def style_loss(A, X, layer): 61 | a = A[layer] 62 | x = X[layer] 63 | 64 | A = gram_matrix(a) 65 | G = gram_matrix(x) 66 | 67 | N = a.shape[1] 68 | M = a.shape[2] * a.shape[3] 69 | 70 | loss = 1./(4 * N**2 * M**2) * ((G - A)**2).sum() 71 | return loss 72 | 73 | def style_loss_relative(A, X, layer): 74 | a = A[layer] 75 | x = X[layer] 76 | 77 | A = gram_matrix(a) 78 | G = gram_matrix(x) 79 | 80 | loss = ((G - A)**2).sum() / (G**2).sum() 81 | return loss 82 | 83 | def build_model_one_scale(n_feature_maps, filter_size): 84 | net = {} 85 | net['input'] = InputLayer((1, 3, IMAGE_W, IMAGE_W)) 86 | net['conv1_1'] = ConvLayer(net['input'], n_feature_maps, filter_size, pad=filter_size//2, flip_filters=False) 87 | return net 88 | 89 | def build_model_multiscale(n_feature_maps, scales, nonlinearity=lasagne.nonlinearities.rectify): 90 | net = {} 91 | net['input'] = InputLayer((1, 3, IMAGE_W, IMAGE_W)) 92 | 93 | multiple_scales = [ConvLayer(net['input'], n_feature_maps, filter_size, pad=filter_size//2, flip_filters=False, 94 | nonlinearity=nonlinearity) 95 | for filter_size in scales] 96 | net['conv1_1'] = ConcatLayer(multiple_scales) 97 | return net 98 | 99 | def optimize(texture_file, net, n_iter, scales): 100 | texture = plt.imread(texture_file) 101 | rawim, texture = prep_image(texture) 102 | 103 | layers = ['conv1_1'] 104 | layers = {k: net[k] for k in layers} 105 | 106 | input_im_theano = T.tensor4() 107 | outputs = lasagne.layers.get_output(layers.values(), input_im_theano) 108 | texture_features = {k: theano.shared(output.eval({input_im_theano: texture})) 109 | for k, output in zip(layers.keys(), outputs)} 110 | 111 | generated_image = theano.shared(floatX(np.random.uniform(-1, 1, (1, 3, IMAGE_W, IMAGE_W)))) 112 | gen_features = lasagne.layers.get_output(layers.values(), generated_image) 113 | gen_features = {k: v for k, v in zip(layers.keys(), gen_features)} 114 | 115 | losses = [] 116 | losses_test = [] 117 | losses.append(1e7 * style_loss(texture_features, gen_features, 'conv1_1')) 118 | losses_test.append(1 * style_loss_relative(texture_features, gen_features, 'conv1_1')) 119 | total_loss = sum(losses) 120 | total_loss_test = sum(losses_test) 121 | 122 | grad = T.grad(total_loss, generated_image) 123 | f_loss = theano.function([], total_loss) 124 | f_test_loss = theano.function([], total_loss_test) 125 | f_grad = theano.function([], grad) 126 | 127 | def eval_loss(x0): 128 | x0 = floatX(x0.reshape((1, 3, IMAGE_W, IMAGE_W))) 129 | generated_image.set_value(x0) 130 | return f_loss().astype('float64') 131 | 132 | def test_loss(x0): 133 | x0 = floatX(x0.reshape((1, 3, IMAGE_W, IMAGE_W))) 134 | generated_image.set_value(x0) 135 | return f_test_loss().astype('float64') 136 | 137 | def eval_grad(x0): 138 | x0 = floatX(x0.reshape((1, 3, IMAGE_W, IMAGE_W))) 139 | generated_image.set_value(x0) 140 | return np.array(f_grad()).flatten().astype('float64') 141 | 142 | texture_init = np.random.uniform(-1, 1, (1, 3, IMAGE_W, IMAGE_W)) 143 | 144 | generated_image.set_value(floatX(texture_init)) 145 | x0 = generated_image.get_value().astype('float64') 146 | xs = [] 147 | xs.append(x0) 148 | 149 | scipy.optimize.fmin_l_bfgs_b(eval_loss, x0.flatten(), fprime=eval_grad, maxfun=n_iter) 150 | x0 = generated_image.get_value().astype('float64') 151 | 152 | return x0 153 | 154 | def main(): 155 | parser = argparse.ArgumentParser() 156 | parser.add_argument('-t', '--texture', required=True, type=str, help='Path to the reference texture') 157 | parser.add_argument('-s', '--size', required=True, type=int, help='Size of a synthesised texture in pixels') 158 | parser.add_argument('-f', '--target-file', default=None, type=str, help='File name of a syntesised texture') 159 | parser.add_argument('-n', '--n-iter', default=4000, type=int, help='Number of L-BFGS optinisation iterations') 160 | parser.add_argument('-c', '--n-features', default=128, type=int, help='Number of feature maps per each scale') 161 | parser.add_argument('--scales', default=None, type=int, nargs='*', help='Sizes of convolutional filters') 162 | parser.add_argument('-l', '--linear', action='store_true', help='Use linear model (conv layer without non-linearity)') 163 | args = parser.parse_args() 164 | 165 | texture_file = args.texture 166 | 167 | global IMAGE_W 168 | IMAGE_W = args.size 169 | 170 | n_iter = args.n_iter 171 | n_feature_maps = args.n_features 172 | 173 | # if no scales provided, assume multiscale model 174 | if args.scales is None: 175 | scales = [3, 5, 7, 11, 15, 23, 37, 55] 176 | else: 177 | scales = args.scales 178 | 179 | if not args.linear: 180 | net = build_model_multiscale(n_feature_maps, scales) 181 | else: 182 | net = build_model_multiscale(n_feature_maps, scales, nonlinearity=None) 183 | 184 | synthesised = optimize(texture_file, net, n_iter, scales) 185 | 186 | if args.target_file is None: 187 | target_file = texture_file.split('.')[0] + '_synthesised.jpg' 188 | else: 189 | target_file = args.target_file 190 | plt.imsave(target_file, deprocess(synthesised)) 191 | 192 | return 0 193 | 194 | if __name__ == '__main__': 195 | main() 196 | -------------------------------------------------------------------------------- /vgg19_normalized.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivust/random-texture-synthesis/11077363be8eebed1c933b38eb4e93b2facea8e5/vgg19_normalized.pkl -------------------------------------------------------------------------------- /vgg_loss.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import sys 3 | import pickle 4 | 5 | import matplotlib 6 | matplotlib.use('Agg') 7 | 8 | import matplotlib.pyplot as plt 9 | import skimage.transform 10 | 11 | import theano 12 | import theano.tensor as T 13 | import lasagne 14 | 15 | from lasagne.utils import floatX 16 | from lasagne.layers import InputLayer, ConcatLayer 17 | from lasagne.layers import Conv2DLayer as ConvLayer 18 | from lasagne.layers import Pool2DLayer as PoolLayer 19 | 20 | def prep_image(im): 21 | MEAN_VALUES = np.array([104, 117, 123]).reshape((3,1,1)) 22 | 23 | if len(im.shape) == 2: 24 | im = im[:, :, np.newaxis] 25 | im = np.repeat(im, 3, axis=2) 26 | h, w, _ = im.shape 27 | 28 | if h < w: 29 | im = skimage.transform.resize(im, (IMAGE_W, int(w*IMAGE_W/h)), preserve_range=True) 30 | else: 31 | im = skimage.transform.resize(im, (int(h*IMAGE_W/w), IMAGE_W), preserve_range=True) 32 | 33 | # Central crop 34 | h, w, _ = im.shape 35 | im = im[h//2-IMAGE_W//2:h//2+IMAGE_W//2, w//2-IMAGE_W//2:w//2+IMAGE_W//2] 36 | 37 | rawim = np.copy(im).astype('uint8') 38 | 39 | # Shuffle axes to c01 40 | im = np.swapaxes(np.swapaxes(im, 1, 2), 0, 1) 41 | 42 | # Convert RGB to BGR 43 | im = im[::-1, :, :] 44 | 45 | im = im - MEAN_VALUES 46 | return rawim, floatX(im[np.newaxis]) 47 | 48 | def deprocess(x): 49 | MEAN_VALUES = np.array([104, 117, 123]).reshape((3,1,1)) 50 | x = np.copy(x[0]) 51 | x += MEAN_VALUES 52 | 53 | x = x[::-1] 54 | x = np.swapaxes(np.swapaxes(x, 0, 1), 1, 2) 55 | 56 | x = np.clip(x, 0, 255).astype('uint8') 57 | return x 58 | 59 | def gram_matrix(x): 60 | x = x.flatten(ndim=3) 61 | g = T.tensordot(x, x, axes=([2], [2])) 62 | return g 63 | 64 | def style_loss_relative(A, X, layer, layers): 65 | a = A[layer] 66 | x = X[layer] 67 | 68 | G_all = [] 69 | for l in layers: 70 | G_layer = gram_matrix(A[l]) 71 | G_all.append((G_layer**2).mean()) 72 | G_all = T.sum(G_all) 73 | 74 | A = gram_matrix(a) 75 | G = gram_matrix(x) 76 | 77 | loss = ((G - A)**2).mean() / G_all 78 | return loss 79 | 80 | def build_vgg_model(): 81 | net = {} 82 | net['input'] = InputLayer((1, 3, IMAGE_W, IMAGE_W)) 83 | net['conv1_1'] = ConvLayer(net['input'], 64, 3, pad=1, flip_filters=False) 84 | net['conv1_2'] = ConvLayer(net['conv1_1'], 64, 3, pad=1, flip_filters=False) 85 | net['pool1'] = PoolLayer(net['conv1_2'], 2, mode='average_exc_pad') 86 | net['conv2_1'] = ConvLayer(net['pool1'], 128, 3, pad=1, flip_filters=False) 87 | net['conv2_2'] = ConvLayer(net['conv2_1'], 128, 3, pad=1, flip_filters=False) 88 | net['pool2'] = PoolLayer(net['conv2_2'], 2, mode='average_exc_pad') 89 | net['conv3_1'] = ConvLayer(net['pool2'], 256, 3, pad=1, flip_filters=False) 90 | net['conv3_2'] = ConvLayer(net['conv3_1'], 256, 3, pad=1, flip_filters=False) 91 | net['conv3_3'] = ConvLayer(net['conv3_2'], 256, 3, pad=1, flip_filters=False) 92 | net['conv3_4'] = ConvLayer(net['conv3_3'], 256, 3, pad=1, flip_filters=False) 93 | net['pool3'] = PoolLayer(net['conv3_4'], 2, mode='average_exc_pad') 94 | net['conv4_1'] = ConvLayer(net['pool3'], 512, 3, pad=1, flip_filters=False) 95 | net['conv4_2'] = ConvLayer(net['conv4_1'], 512, 3, pad=1, flip_filters=False) 96 | net['conv4_3'] = ConvLayer(net['conv4_2'], 512, 3, pad=1, flip_filters=False) 97 | net['conv4_4'] = ConvLayer(net['conv4_3'], 512, 3, pad=1, flip_filters=False) 98 | net['pool4'] = PoolLayer(net['conv4_4'], 2, mode='average_exc_pad') 99 | net['conv5_1'] = ConvLayer(net['pool4'], 512, 3, pad=1, flip_filters=False) 100 | net['conv5_2'] = ConvLayer(net['conv5_1'], 512, 3, pad=1, flip_filters=False) 101 | net['conv5_3'] = ConvLayer(net['conv5_2'], 512, 3, pad=1, flip_filters=False) 102 | net['conv5_4'] = ConvLayer(net['conv5_3'], 512, 3, pad=1, flip_filters=False) 103 | net['pool5'] = PoolLayer(net['conv5_4'], 2, mode='average_exc_pad') 104 | return net 105 | 106 | def vgg_loss(texture_file, texture_file_synthesized, net): 107 | texture = plt.imread(texture_file) 108 | rawim, texture = prep_image(texture) 109 | 110 | texture_synt = plt.imread(texture_file_synthesized) 111 | rawim_synt, texture_synt = prep_image(texture_synt) 112 | 113 | layers = ['conv1_1', 'conv2_1', 'conv3_1', 'conv4_1', 'conv5_1'] 114 | layers = {k: net[k] for k in layers} 115 | 116 | input_im_theano = T.tensor4() 117 | outputs = lasagne.layers.get_output(layers.values(), input_im_theano) 118 | texture_features = {k: theano.shared(output.eval({input_im_theano: texture})) 119 | for k, output in zip(layers.keys(), outputs)} 120 | 121 | generated_image = theano.shared(floatX(texture_synt)) 122 | gen_features = lasagne.layers.get_output(layers.values(), generated_image) 123 | gen_features = {k: v for k, v in zip(layers.keys(), gen_features)} 124 | 125 | losses_test = [] 126 | layers_all = ['conv1_1', 'conv2_1', 'conv3_1', 'conv4_1', 'conv5_1'] 127 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv1_1', layers_all)) 128 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv2_1', layers_all)) 129 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv3_1', layers_all)) 130 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv4_1', layers_all)) 131 | losses_test.append(0.2 * style_loss_relative(texture_features, gen_features, 'conv5_1', layers_all)) 132 | total_loss_test = sum(losses_test) 133 | 134 | f_test_loss = theano.function([], total_loss_test) 135 | 136 | def test_loss(x0): 137 | x0 = floatX(x0.reshape((1, 3, IMAGE_W, IMAGE_W))) 138 | generated_image.set_value(x0) 139 | return f_test_loss().astype('float64') 140 | 141 | generated_image.set_value(floatX(texture_synt)) 142 | loss = test_loss(generated_image.get_value().astype('float64')) 143 | 144 | return loss 145 | 146 | def main(texture_file, texture_file_synthesised): 147 | global IMAGE_W 148 | IMAGE_W = 200 149 | 150 | net = build_vgg_model() 151 | values = pickle.load(open('vgg19_normalized.pkl', 'rb'), encoding='latin1')['param values'] 152 | lasagne.layers.set_all_param_values(net['pool5'], values) 153 | 154 | loss = vgg_loss(texture_file, texture_file_synthesised, net) 155 | 156 | return loss 157 | --------------------------------------------------------------------------------