image palette's dimension reduction using matp

2019-04-17 02:58发布

问题:

I am using iPython notebook, I have a 512x512 image that I want to 'transform' into a 'blocky' image using 'nearest' interpolation of colors in the blocks, similar to the 'mosaic' filter in Photoshop, for some further manipulation of a batch of pictures.

In Photoshop, you load the image and you can set the filter to 'Mosaic', and set the 'block size' in pixels.

Here there is a partial explanation about how to do it using numpy, but since I am not a numpy expert, I found a 'shortcut' that is sort of working for me using PIL. I don't know how to properly adapt it to avoid some unnecessary steps.

img = Image.open(filename) 
h = img.size[0]
v = img.size[1]

blocksize = 100

rsize = img.resize((h/blocksize,v/blocksize))  # resize the image
rsizeArr = np.asarray(rsize)
lum_img = rsizeArr[:,:,0]

#plt.axes.get_xaxis().set_visible(False)
#plt.axes.get_yaxis().set_visible(False)

imgplot = plt.imshow(rsizeArr)
#imgplot = plt.imsave('test.jpg', rsizeArr)
imgplot.set_interpolation('nearest')

imgplot.axes.get_xaxis().set_visible(False)
imgplot.axes.get_yaxis().set_visible(False)

plt.savefig('testplot1.png', bbox_inches = 'tight')

Since I'm using iPython notebook, this produces an inline output in the notebook as soon as the line is executed. (I don't want to display the inline output for this particular step, since I'll be processing several pictures in the notebook).

The 'tesplot1.png' file is 1KB in size, however, for some reason, its dimension get's reduced to 264x264 pixels. Since I want the image in its orginal size of 512x512, I do the following:

img2 = Image.open('testplot1.png')
rsize = img2.resize((512,512))  # resize the image
rsize.save('testplot2.jpg') 

This generates the right image of 512x512 pixels.

My questions are: 1) Is there a way to produce the image w/o having to display it inline via imgplot = plt.imshow(rsizeArr)? I need pylab inline in my notebook, so I dont know if it can be 'temporarily' disabled. 2) Is there a way to ommit the resizing step (img2), by saving 'tesplot1.png' in the right size? 3) What would be the vector operation required to accomplish this using the explanation here?

回答1:

  1. Don't use pylab inline.
  2. If you still want to use pylab inline don't. It's deprecated.
  3. use %matplotlib inline
  4. learn the matplotlib OO way where you don't do things implicitely on current active axes.

You plotting problem will go away.

For your block things you want to process your image as a numpy array by block: How can I efficiently process a numpy array in blocks similar to Matlab's blkproc (blockproc) function for example.