Python PIL-функция для разделения смешивания двух изображений?
EDIT: код работает сейчас, благодаря Марку и зефиру. zephyr также имеет два альтернативных рабочих решения ниже.
Я хочу разделить смесь двух изображений с PIL. Я нашел ImageChops.multiply(image1, image2)
но я не мог найти подобное
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-это вызывает деление на ноль. Если вы конвертируете все эти значения в один, я думаю, вы получите желаемый результат. Это устранит необходимость проверять нули и фиксировать их в результате.
ты спрашиваешь:
есть ли более эффективный способ сделать эту операцию разделения смеси (меньше шагов и быстрее)?
вы также можете использовать пакет 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)
.