在 python 上叠加图像

Overlaying images on python

提问人:Giovanni Pignatelli 提问时间:11/14/2023 最后编辑:Christoph RackwitzGiovanni Pignatelli 更新时间:11/14/2023 访问量:110

问:

我有这三张来自SEM显微镜的照片。一个是实际图片,而另外两个只是表明样品上存在特定元素(铝和硅)。

我想使用 Numpy 和 matplotlib 覆盖它们,以便我可以看到元素的确切位置,但是不确定如何在 python 上解决这个问题,到目前为止,我只将图片文件读取为 np 数组:

image_SEM = np.asarray(Image.open('Project_SEI.JPG'))
image_Al = np.asarray(Image.open('Project_Al K.JPG'))
image_Si = np.asarray(Image.open('Project_Si K.JPG'))

谢谢!

enter image description here enter image description here enter image description here

python numpy 图像处理 python 成像库

评论

1赞 Woodford 11/14/2023
你可以采取几种方式。使用 alpha 使 Al/Si 图像中的黑色像素透明并叠加它们。或者,当元素图像像素不是黑色时,逐个像素地平均颜色。尝试一些事情,如果它不起作用,请回来询问它。

答:

3赞 jacob 11/14/2023 #1

你根本不需要 Numpy 数组来进行简单的覆盖。

from PIL import Image

# Change to your file names, this is what mine downloaded as from your post
image_sem = Image.open('aZ8ED.jpg')
image_si = Image.open('HeiA7.jpg')
image_al = Image.open('HlcOR.jpg')

si_k = Image.blend(image_sem, image_si, 0.5)
si_k.show()

al_k = Image.blend(image_sem, image_al, 0.5)
al_k.show()

您必须根据需要裁剪或使用右下角的图片标签,也许还有左侧的色阶,但这应该可以让您入门。它对我有用。

enter image description here enter image description here

根据 OP 评论进行编辑:

blend 方法输出 .要将它们放在一起,只需依次将元素图像组合在一起,然后将该结果与主图像混合,如下所示:out = image1 * (1.0 - alpha) + image2 * alpha

elements = Image.blend(image_si, image_al, 0.5)

elements_overlay = Image.blend(image_sem, elements, 0.5)
elements_overlay.show()

enter image description here

对于许多图像来说,混合方法可能不是最好的。颜色将褪色,因为随着更多元素图像的组合,alpha 使第一个元素图像的权重小于最终图像的权重。请参阅文档,了解合并图像的所有方法。对于更复杂的组合,您可能希望毕竟使用 Numpy 数组,并对实际像素进行一些归一化或调整,然后重新组合或类似。fromarray

评论

0赞 Giovanni Pignatelli 11/14/2023
谢谢!这行得通,对于进一步的工作,有没有一种好方法可以将这两个元素叠加在同一张图片上?如果我再次使用 Image.blend,它会慢慢降低基础图像的清晰度,不是吗?
0赞 jacob 11/14/2023
@GiovanniPignatelli看到我的答案的更新。
2赞 Mark Setchell 11/14/2023 #2

我倾向于使用掩模粘贴 Si 和 Al 图像,以便它们只影响着色的 SEM 图像,而不会影响它们为黑色/灰色的 SEM 图像 - 否则您将倾向于降低基础图像的对比度:

from PIL import Image

# Load images
sei = Image.open('sei.jpg')
si = Image.open('si.jpg')
al = Image.open('al.jpg')

# Make mask which only allows coloured areas to show
siMask = si.convert('L')
siMask.save('DEBUG-siMask.jpg')

# Paste Si image over SEM image with transparency mask
sei.paste(si, siMask)

# Make mask which only allows coloured areas to show
alMask = al.convert('L')
alMask.save('DEBUG-alMask.jpg')

# Paste Al image over SEM image with transparency mask
sei.paste(al, alMask)
sei.save('result.png')

调试-siMask.jpg

enter image description here

调试-alMask.jpg

enter image description here

结果.jpg

enter image description here


请注意,您可以在使用前增强蒙版——例如,您可以中值滤镜以去除小斑点,或者您可以对比拉伸以使洋红色/黄色阴影或多或少地出现。例如,你可以看到黄色比洋红色更纯色,这是因为黄色蒙版更亮,所以你可以将洋红色蒙版设置为纯黑色和白色,这将使洋红色变成纯白色。

因此,我中值过滤掉了斑点并更改了遮罩,使彩色区域具有 50% 的透明度,如下所示:

#!/usr/bin/env python3

from PIL import Image, ImageFilter

# Load images
sei = Image.open('sei.jpg')
si = Image.open('si.jpg')
al = Image.open('al.jpg')

# Make mask which only allows coloured areas to show
siMask = si.convert('L')
# Median filter mask to remove small speckles
siMask = siMask.filter(ImageFilter.MedianFilter(5))
# Threshold mask and set opacity to 50% for coloured areas
siMask = siMask.point(lambda p: 128 if p > 50 else 0)
siMask.save('DEBUG-siMask.jpg')

# Paste Si image over SEM image with transparency mask
sei.paste(si, siMask)

# Make mask which only allows coloured areas to show
alMask = al.convert('L')
# Median filter mask to remove small speckles
alMask = alMask.filter(ImageFilter.MedianFilter(5))
# Threshold mask and set opacity to 50% for coloured areas
alMask = alMask.point(lambda p: 128 if p > 50 else 0)
alMask.save('DEBUG-alMask.jpg')

# Paste Al image over SEM image with transparency mask
sei.paste(al, alMask)
sei.save('result.jpg')

这给出了这些掩码和结果:

enter image description here

enter image description here

enter image description here