[英]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.eval
和ImageMath.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.