编辑:由于Mark和Zephyr,代码现在正在运行。西风还有以下两种替代工作方案。
我想用PIL分割混合两个图像。我找到ImageChops.multiply(image1, image2)
但我找不到类似的divide(image, image2)
函数。
Divide Blend Mode Explained(我在这里使用前两张图片作为我的测试来源。)
是否存在我错过的内置分割混合功能(PIL或其他)?
我的测试代码在下面运行,并且正在接近我正在寻找的内容。生成的图像输出类似于此处的除法混合示例图像:Divide Blend Mode Explained。
是否有更有效的方法来进行此分割混合操作(更少步骤和更快)?起初,我尝试在Image.eval
和ImageMath.eval
中使用lambda函数来检查黑色像素,并在分割过程中将它们翻转为白色,但我无法获得正确的结果。
编辑:修正代码并缩短了感谢Mark和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')
答案 0 :(得分: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')
答案 1 :(得分:1)
你遇到的问题是当你的图像B为零时 - 它会导致除以零。如果您将所有这些值转换为1,我认为您将获得所需的结果。这样就不需要检查零并在结果中修复它们。
答案 2 :(得分:1)
你在问:
是否有更有效的方法来进行此分割混合操作(更少步骤和更快)?
您也可以使用python包blend modes。它是用矢量化的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)
。