Reputation: 68
How can I stack multiple images and save the new output image using python (or matlab)? I need to set the alpha of each image and do i little translation, e.g.:
Upvotes: 2
Views: 6391
Reputation: 13459
You could make such a stack of translated (shifted) images with Python, using the numpy and matplotlib module. Pillow (another Python module) by itself could probably do it as well, but I would have to look up how to ensure values of overlapping pixels get added, rather than overwritten.
So, here's a numpy + matplotlib solution, that starts off with a test image:
import numpy as np
import matplotlib.pyplot as plt
img1 = plt.imread('img.png')
For those following along, a very simply test image is shown at the end of this post, which will also serve to show the different options available for stacking (overwriting or additive which is weighted opacity with equal weights).
layers = 5 # How many images should be stacked.
x_offset, y_offset = 40, 20 # Number of pixels to offset each image.
new_shape = ((layers - 1)*y_offset + img1.shape[0],
(layers - 1)*x_offset + img1.shape[1],
4) # the last number, i.e. 4, refers to the 4 different channels, being RGB + alpha
stacked = np.zeros(new_shape, dtype=np.float)
for layer in range(layers):
stacked[layer*y_offset:layer*y_offset + img1.shape[0],
layer*x_offset:layer*x_offset + img1.shape[1],
...] += img1*1./layers
plt.imsave('stacked.png', stacked, vmin=0, vmax=1)
It's very simple really: you precalculate the size of the output image, initialize it to have full transparency and then you "drop" the base image in that file, each time offset by a certain offset vector. The interesting part comes when parts overlap. You then have some choices:
+=
operator to simply =
. Also, don't scale by the number of layers.vmin
and vmax
in the call to imsave
.The test image shown here contains 4 transparent squares, but those are not easily distinguished from the 2 white ones in the top left row. They were added to illustrate the transparency addition and effect of rescaling (white becomes gray).
After running the above code, you end up with something like this (change your offsets though) ("add") or like this ("overwrite")
There are a few more ways you can think of that reflect what you want to do when pixels overlap. The 2 situations here are probably the most common ones though. In any case, the approach laid out here should give you a good start.
Upvotes: 1
Reputation: 26069
here's an example based on my comment:
mask=zeros(50,50,5);
for n=1:size(mask,3)
mask(randi(20):randi(20)+20,randi(20):randi(20)+20,n )=1;
mask(:,:,n)= bwperim( mask(:,:,n),8);
end
A=permute(mask,[3 2 1]);
% plottning
h=slice(A,[],1:5,[]);
set(h,'EdgeColor','none','FaceColor','interp');
alpha(0.3);
colormap(flipud(flag))
Upvotes: 4