繁体   English   中英

Python PIL - 用于划分混合两个图像的函数?

[英]Python PIL - function to divide blend two images?

编辑:多亏了 Mark 和 zephyr,代码现在可以运行了。 zephyr 在下面还有两个替代的工作解决方案。

我想用 PIL 划分混合两个图像。 我找到了ImageChops.multiply(image1, image2)但我找不到类似的ImageChops.multiply(image1, image2) divide(image, image2)函数。

划分混合模式解释(我在这里使用前两个图像作为我的测试源。)

是否有我错过的内置除法混合功能(PIL 或其他)?

我下面的测试代码正在运行并且越来越接近我正在寻找的内容。 生成的图像输出类似于此处的划分混合示例图像: 划分混合模式解释

是否有更有效的方法来执行此除法混合操作(步骤更少且速度更快)? 起初,我尝试在Image.evalImageMath.eval使用 lambda 函数来检查黑色像素并将它们在除法过程中翻转为白色,但我无法得到正确的结果。

编辑:由于 Mark 和 zephyr,修复了代码并缩短了代码 生成的图像输出与下面 zephyr 的 numpy 和 scipy 解决方案的输出相匹配。

# PIL Divide Blend test

import Image, os, ImageMath

imgA = Image.open('01background.jpg')
imgA.load()
imgB = Image.open('02testgray.jpg')
imgB.load()

# split RGB images into 3 channels
rA, gA, bA = imgA.split()
rB, gB, bB = imgB.split()

# divide each channel (image1/image2)
rTmp = ImageMath.eval("int(a/((float(b)+1)/256))", a=rA, b=rB).convert('L')
gTmp = ImageMath.eval("int(a/((float(b)+1)/256))", a=gA, b=gB).convert('L')
bTmp = ImageMath.eval("int(a/((float(b)+1)/256))", a=bA, b=bB).convert('L')

# merge channels into RGB image
imgOut = Image.merge("RGB", (rTmp, gTmp, bTmp))

imgOut.save('PILdiv0.png', 'PNG')

os.system('start PILdiv0.png')

你在问:

是否有更有效的方法来执行此除法混合操作(步骤更少且速度更快)?

您还可以使用 python 包混合模式 它是用矢量化的 Numpy 数学编写的,通常速度很快。 通过pip install blend_modes安装它。 我以更详细的方式编写了命令以提高可读性,链接它们会更短。 使用像这样的blend_modes来分割你的图像:

from PIL import Image
import numpy
import os
from blend_modes import blend_modes

# Load images
imgA = Image.open('01background.jpg')
imgA = numpy.array(imgA)
# append alpha channel
imgA = numpy.dstack((imgA, numpy.ones((imgA.shape[0], imgA.shape[1], 1))*255))
imgA = imgA.astype(float)

imgB = Image.open('02testgray.jpg')
imgB = numpy.array(imgB)
# append alpha channel
imgB = numpy.dstack((imgB, numpy.ones((imgB.shape[0], imgB.shape[1], 1))*255))
imgB = imgB.astype(float)

# Divide images
imgOut = blend_modes.divide(imgA, imgB, 1.0)

# Save images
imgOut = numpy.uint8(imgOut)
imgOut = Image.fromarray(imgOut)
imgOut.save('PILdiv0.png', 'PNG')

os.system('start PILdiv0.png')

请注意,要使其工作,两个图像需要具有相同的尺寸,例如imgA.shape == (240,320,3)imgB.shape == (240,320,3)

这里有一个除法函数的数学定义: http : //www.linuxtopia.org/online_books/graphics_tools/gimp_advanced_guide/gimp_guide_node55_002.html

这是 scipy/matplotlib 的实现:

import numpy as np
import scipy.misc as mpl

a = mpl.imread('01background.jpg')
b = mpl.imread('02testgray.jpg')

c = a/((b.astype('float')+1)/256)
d = c*(c < 255)+255*np.ones(np.shape(c))*(c > 255)

e = d.astype('uint8')

mpl.imshow(e)
mpl.imsave('output.png', e)

如果你不想使用 matplotlib,你可以这样做(我假设你有 numpy):

imgA = Image.open('01background.jpg')
imgA.load()
imgB = Image.open('02testgray.jpg')
imgB.load()

a = asarray(imgA)
b = asarray(imgB)
c = a/((b.astype('float')+1)/256)
d = c*(c < 255)+255*ones(shape(c))*(c > 255)
e = d.astype('uint8')

imgOut = Image.fromarray(e)
imgOut.save('PILdiv0.png', 'PNG')

您遇到的问题是当图像 B 中有一个零时 - 它会导致除以零。 如果您将所有这些值都转换为一个,我认为您会得到想要的结果。 这将消除检查零并在结果中修复它们的需要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM