1

i have a 2 list of png images, list _c and list _v. I want to paste _v on _c using a code like:

from PIL import Image

background = [Image.open(path, 'r') for path in glob.glob(list_c_path)]
foreground = [Image.open(path, 'r') for path in glob.glob(list_v_path)]

for im in range(len(background)):
    pasted = background[im].paste(foreground[im], (0, 0), foreground[im])

This code won't work but it will give you and idea of what i want. I also need to have the images read in grayscale format before they are pasted.

Here's a sample of a background image:

enter image description here

Here's a sample of a foreground image:

enter image description here

And this is the desired result:

enter image description here

I pasted this images using this code:

background = Image.open('1000_c.png')
foreground = Image.open('1000_v.png')


background.paste(foreground, (0, 0), foreground)
background.save('example.png')

How can i achieve this??

Thanks in advance

Miguel 2488
  • 1,410
  • 1
  • 20
  • 41
  • 1
    How can you read the images in grayscale after they have been pasted? You have to read them before they are pasted. How does a foreground, background and result image look - please provide samples. – Mark Setchell Oct 20 '18 at 20:44
  • You are right, i'm going to edit my question. Give a minute please – Miguel 2488 Oct 20 '18 at 20:49
  • @MarkSetchell question edited – Miguel 2488 Oct 20 '18 at 20:59
  • I'm not at a computer to check, but your result looks identical to the image you paste on top of the background? – Mark Setchell Oct 20 '18 at 21:04
  • @MarkSetchell Yes, they look very similar or the same indeed, but i think that code works. I took it from [this](https://stackoverflow.com/questions/5324647/how-to-merge-a-transparent-png-image-with-another-image-using-pil) post. Unless i'm not adding or doing something else. – Miguel 2488 Oct 20 '18 at 21:10
  • 1
    Mmmm... your result images are identical to your foreground images because although the foreground images have an alpha/transparency layer, they are fully opaque and completely conceal your backgrounds. You need to have a rethink! – Mark Setchell Oct 21 '18 at 11:01
  • @Mark Setchell damn, do you have any suggestions in mind? I'm new to image processing and i do not know all the whatnots :/ – Miguel 2488 Oct 21 '18 at 11:04

1 Answers1

3

Mmmm... your result images are identical to your foreground images because although the foreground images have an alpha/transparency layer, they are fully opaque and completely conceal your backgrounds. You need to have a rethink!

You can use ImageMagick in the Terminal to inspect your images. So, let's look at your foreground image:

identify -verbose fg.png

Sample Output

Image: fg.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: DirectClass
  Geometry: 118x128+0+0
  Units: Undefined
  Colorspace: sRGB
  Type: PaletteAlpha             <--- Image does have alpha/transparency layer
  Base type: Undefined
  Endianess: Undefined
  Depth: 8-bit
  Channel depth:
    Red: 8-bit
    Green: 8-bit
    Blue: 8-bit
    Alpha: 1-bit
  Channel statistics:
    Pixels: 15104
    Red:
      min: 30  (0.117647)
      ...
      ...
    Alpha:
      min: 255  (1)              <--- ... but alpha layer is fully opaque
      max: 255 (1)
      mean: 255 (1)
      standard deviation: 0 (0)
      kurtosis: 8.192e+51
      skewness: 1e+36
      entropy: 0

So there is no point pasting a fully opaque image over a background as it will fully conceal it.

If we punch a transparent hole in your foreground image with ImageMagick:

convert fg.png -region 100x100+9+14 -alpha transparent fg.png

It now looks like this:

enter image description here

And if we then run your code:

#!/usr/local/bin/python3

from PIL import Image
background = Image.open('bg.png')
foreground = Image.open('fg.png')

background.paste(foreground, (0, 0), foreground)
background.save('result.png')

It works:

enter image description here

So the moral of the story is that your foreground image either needs some transparency to allow the background to show through, or you need to use some blending mode to choose one or the other of the foreground and background images at each location, or to choose some combination - e.g. the average of the two, or the brighter of the two.


If you want to average the two images, or in fact, do any other blending mode, you could consider using Pillow's ImageChops module - documentation here. So, an average would look like this:

#!/usr/local/bin/python3

from PIL import Image, ImageChops
bg = Image.open('bg.png')
fg = Image.open('fg.png')

# Average the two images, i.e. add and divide by 2
result = ImageChops.add(bg, fg, scale=2.0)
result.save('result.png')

enter image description here

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • hi Mark, thank you very much for your answer. Do you think a combination of the images using their averages could be the way to go?In fact i'm building a classification model using a CNN to classify these images, the reason i want to combine them is because i habe 2 images per observation, but if i leave the images as they are, i can only use of the 2 image kind the _c or the _v, This means 2 models working independently. But i was thinking about a combination of the 2 images kinds to build a model that works with the 2 of them, and improve accuracy. I tried `np.vstack` – Miguel 2488 Oct 21 '18 at 11:45
  • but this only concatenates the images along the vertical axis, and i don't think this will work for me, what i was thinking was to somehow dimensionally stack the images by layer, building a combination of the 2, maybe the average approach you suggested will work here. I found something similar on [this](https://stackoverflow.com/questions/44112358/opencv-python-merge-different-channel-images-into-one) post. Correct me if i'm wrong, combining these 2 kinds of images into one is just an idea i have, i don0t have any evidence to think that it will work for my purposes. – Miguel 2488 Oct 21 '18 at 11:47
  • If you have a better suggestion to achieve this goal, ot you think another approach could be more effective, please tell me, i'm open to any suggestions :) Thanks again – Miguel 2488 Oct 21 '18 at 11:48
  • Sorry, I have very little experience with CNNs and mainly answer questions on the nitty-gritty mechanics of processing images rather than theoretical questions about CNNs. I would suggest you ask a new question, which is free, and tag it with a *"neural network"* or *"tensor flow"* or *"machine learning"* and concentrate more on the theory rather than the mechanics of how to combine images. Sorry! – Mark Setchell Oct 21 '18 at 11:50
  • Yes, actually, i have my working models, i just need an efficient way to combine these images, sorry if i have confused you, i'm not asking about building a CNN or something similar, but how to efficiently combine these 2 kinds of images into one. Maybe you can help me with that? Thank you – Miguel 2488 Oct 21 '18 at 11:53
  • 1
    I really have no idea - there are hundreds of ways of combining images. You can place them side-by-side, top-to-bottom, you can choose the brighter or the darker of the two pixels at each location. You can average the two pixels at each location or use a different weighting to take more of one image than the other. You can multiply the pixels at each location. Or difference them. You can XOR them. You can take the hue of one and the saturation of the other. You can take the luminosity of one and the hue of the other.Or any combination... I know how to do them but not which one is best for you. – Mark Setchell Oct 21 '18 at 12:01
  • Allright Mark, thank you for your sincere answer. I would really to try averaging the 2. May i ask you to provide an example of how to this applying it to my 2 lists of images please? You can just edit your answer above. Thank you – Miguel 2488 Oct 21 '18 at 12:28
  • 1
    I have added an example of averaging at the end of my answer. There is also a link to Pillow's *"Channel Operations"* module which will allow you to implement other blend modes I mentioned. – Mark Setchell Oct 21 '18 at 16:36
  • Thank you very much @Mark Setchell. You really gave a usefull answer here. Documentation on this issue is also very helpful to me, since i really want to learn more about image processing. Thanks again :D – Miguel 2488 Oct 21 '18 at 20:54