2

How can I use something like below line to save images on a grid of 4x4 of heterogenous images? Imagine that images are identified by sample[i] and i takes 16 different values.

scipy.misc.imsave(str(img_index) + '.png', sample[1])

Similar to this answer but for 16 different images https://stackoverflow.com/a/42041135/2414957

I am not biased towards the used method as long as it does the deed. Also, I am interested in saving images rather than showing them using plt.show() as I am using a remote server and dealing with CelebA image dataset which is a giant dataset. I just want to randomly select 16 images from my batch and save the results of DCGAN and see if it makes any sense or if it converges.

*Currently, I am saving images like below:

batch_no = random.randint(0, 63)


scipy.misc.imsave('sample_gan_images/iter_%d_epoch_%d_sample_%d.png' %(itr, epoch, batch_no), sample[batch_no])

and here, I have 25 epochs and 2000 iterations and batch size is 64.

Mona Jalal
  • 34,860
  • 64
  • 239
  • 408
  • 1
    @Panlantic82 What on earth was that???, That's not an answer, that's saying some bad stuff, don't ever do that again, that's very nasty, Your violating the site, see the [Code of Conduct](https://stackoverflow.com/conduct) (formerly called "Be nice policy") – U13-Forward Nov 12 '18 at 03:07
  • 1
    Wait, so what's wrong with the answer you linked to? It seems to do everything you want. To save instead of show, just use `plt.savefig` in place of `plt.show` – tel Nov 12 '18 at 03:53
  • 2
    @U9-Forward That's a lot of commas. It's a lot simpler to just flag for moderator attention and explain the situation. They'll determine the best way to discipline the user. I've done so. – cs95 Nov 12 '18 at 04:06
  • @coldspeed thanks for letting me know, but where to flag? – U13-Forward Nov 12 '18 at 04:50
  • 1
    @U9-Forward If the answer has already been deleted, you will need to wait till you have 10k rep to see deleted content. – cs95 Nov 12 '18 at 04:54
  • @coldspeed Got it, get moderation privilege – U13-Forward Nov 12 '18 at 04:55

2 Answers2

4

Personally, I tend to use matplotlib.pyplot.subplots for these kinds of situations. If your images are really heterogenous it might be a better choice than the image concatenation based approach in the answer you linked to.

import matplotlib.pyplot as plt
from scipy.misc import face

x = 4
y = 4

fig,axarr = plt.subplots(x,y)
ims = [face() for i in range(x*y)]

for ax,im in zip(axarr.ravel(), ims):
    ax.imshow(im)

fig.savefig('faces.png')

default plt.subplots behavior

My big complaint about subplots is the quantity of whitespace in the resulting figure. As well, for your application you may not want the axes ticks/frames. Here's a wrapper function that deals with those issues:

import matplotlib.pyplot as plt

def savegrid(ims, rows=None, cols=None, fill=True, showax=False):
    if rows is None != cols is None:
        raise ValueError("Set either both rows and cols or neither.")

    if rows is None:
        rows = len(ims)
        cols = 1

    gridspec_kw = {'wspace': 0, 'hspace': 0} if fill else {}
    fig,axarr = plt.subplots(rows, cols, gridspec_kw=gridspec_kw)

    if fill:
        bleed = 0
        fig.subplots_adjust(left=bleed, bottom=bleed, right=(1 - bleed), top=(1 - bleed))

    for ax,im in zip(axarr.ravel(), ims):
        ax.imshow(im)
        if not showax:
            ax.set_axis_off()

    kwargs = {'pad_inches': .01} if fill else {}
    fig.savefig('faces.png', **kwargs)

Running savegrid(ims, 4, 4) on the same set of images as used earlier yields:

output of savegrid wrapper

If you use savegrid, if you want each individual image to take up less space, pass the fill=False keyword arg. If you want to show the axes ticks/frames, pass showax=True.

tel
  • 13,005
  • 2
  • 44
  • 62
1

I found this on github, also sharing it:

import matplotlib.pyplot as plt

def merge_images(image_batch, size):
    h,w = image_batch.shape[1], image_batch.shape[2]
    c = image_batch.shape[3]
    img = np.zeros((int(h*size[0]), w*size[1], c))
    for idx, im in enumerate(image_batch):
        i = idx % size[1]
        j = idx // size[1]
        img[j*h:j*h+h, i*w:i*w+w,:] = im
    return img

im_merged = merge_images(sample, [8,8])
plt.imsave('sample_gan_images/im_merged.png', im_merged )

enter image description here

Mona Jalal
  • 34,860
  • 64
  • 239
  • 408