Я запускаю 2 Python 3.7.6 скриптов, которые полагаются на библиотеку PIL в записной книжке Jupyter и получают разные результаты, и я не могу определить, почему. Я считаю, что две части должны быть эквивалентны, а результат идентичен. Может кто-нибудь сказать мне, почему второй блок не генерирует тот же вывод, что и первый?
По сути, код должен делать то же самое, разбивать изображение на его цветовые каналы RGB, умножать каждый канал на один из 3 различных интенсивности, а затем объединить каналы обратно в составное изображение. Вот исходное изображение:
Единственная разница между двумя кодовыми блоками состоит в том, что в одном я делаю разбиение внутри самого внутреннего для l oop а в другом я делаю разбиение вне циклов for, копирую результат в переменную и затем присваиваю копию внутри самого l oop.
В первом разделе я вызываю функцию разбиения изображения в самом внутреннем l oop в первом сегменте и назначьте его переменной кортежа изображения:
img_tmp = image.split()
во втором, я называю это вне внешнего l oop и назначьте его переменной кортежа изображения, а затем назначьте эту переменную второй переменной внутри самой внутренней l oop, чтобы сбросить значение каждый раз до конца.
source = image.split()
...
for ...:
for ...:
img_tmp = source
1-й кодовый блок (работает правильно):
import PIL
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
# read image and convert to RGB
image=Image.open("readonly/msi_recruitment.gif")
image=image.convert('RGB')
# read True Type font
fnt=ImageFont.truetype("readonly/fanwood-webfont.ttf", size=50)
# source = image.split()
# initialize key constants and variables
R,G,B = 0,1,2
intensity = [0.1, 0.5, 0.9]
images = []
images_meta = []
banner_height = 70
banner_margin = 10
txt_color = 'rgb(255,255,255)' # white
# build a list of 9 images, 3 for each color channel with the appropriate color intensity
for channel in [R,G,B]:
# multiply each channel by appropriate color intensity factor
for i_factor in intensity:
# img_tmp = source # split the original image into 3 separate channels (images) with 1 for each color
img_tmp = image.split()
img_band = img_tmp[channel].point(lambda x: x*i_factor) # multiply the channel color by the intensity factor
img_tmp[channel].paste(img_band) # replace the selected channel image with its color corrected version
img_out = Image.merge(image.mode, img_tmp) # merge all 3 channels back into one image
images.append(img_out) # add the updated image to the list
images_meta.append('channel {} intensity {}'.format(channel, i_factor)) # update the metadata
# create a contact sheet of 3 rows with one row per color channel displaying
# an image with 3 different color intensities
first_image=images[0]
contact_sheet=PIL.Image.new(first_image.mode, (first_image.width*3,first_image.height*3 + banner_height*3))
x=0
y=0
# initialize the drawing context with the contact sheet as background
banner = ImageDraw.Draw(contact_sheet)
for i,img in enumerate(images):
# Lets paste the current image into the contact sheet
contact_sheet.paste(img, (x, y) )
# now draw the text and create a banner below the corresponding image
banner.text((x, y + first_image.height + banner_margin), images_meta[i], font=fnt, fill=txt_color)
# Now we update our X position. If it is going to be the width of the image, then we set it to 0
# and update Y as well to point to the next "line" of the contact sheet.
if x+first_image.width == contact_sheet.width:
x=0
y=y+first_image.height + banner_height
else:
x=x+first_image.width
# resize and display the contact sheet
contact_sheet = contact_sheet.resize((int(contact_sheet.width/2),int(contact_sheet.height/2) ))
display(contact_sheet)
contact_sheet.save('assignment_1.pdf')
результирующее изображение:
![image processed correctly](https://i.stack.imgur.com/o6tqs.jpg)
2-й кодовый блок (запускается, но не обрабатывает изображение правильно):
import PIL
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
# read image and convert to RGB
image=Image.open("readonly/msi_recruitment.gif")
image=image.convert('RGB')
# read True Type font
fnt=ImageFont.truetype("readonly/fanwood-webfont.ttf", size=50)
source = image.split()
# initialize key constants and variables
R,G,B = 0,1,2
intensity = [0.1, 0.5, 0.9]
images = []
images_meta = []
banner_height = 70
banner_margin = 10
txt_color = 'rgb(255,255,255)' # white
# build a list of 9 images, 3 for each color channel with the appropriate color intensity
for channel in [R,G,B]:
# multiply each channel by appropriate color intensity factor
for i_factor in intensity:
img_tmp = source # split the original image into 3 separate channels (images) with 1 for each color
img_band = img_tmp[channel].point(lambda x: x*i_factor) # multiply the channel color by the intensity factor
img_tmp[channel].paste(img_band) # replace the selected channel image with its color corrected version
img_out = Image.merge(image.mode, img_tmp) # merge all 3 channels back into one image
images.append(img_out) # add the updated image to the list
images_meta.append('channel {} intensity {}'.format(channel, i_factor)) # update the metadata
# create a contact sheet of 3 rows with one row per color channel displaying
# an image with 3 different color intensities
first_image=images[0]
contact_sheet=PIL.Image.new(first_image.mode, (first_image.width*3,first_image.height*3 + banner_height*3))
x=0
y=0
# initialize the drawing context with the contact sheet as background
banner = ImageDraw.Draw(contact_sheet)
for i,img in enumerate(images):
# Lets paste the current image into the contact sheet
contact_sheet.paste(img, (x, y) )
# now draw the text and create a banner below the corresponding image
banner.text((x, y + first_image.height + banner_margin), images_meta[i], font=fnt, fill=txt_color)
# Now we update our X position. If it is going to be the width of the image, then we set it to 0
# and update Y as well to point to the next "line" of the contact sheet.
if x+first_image.width == contact_sheet.width:
x=0
y=y+first_image.height + banner_height
else:
x=x+first_image.width
# resize and display the contact sheet
contact_sheet = contact_sheet.resize((int(contact_sheet.width/2),int(contact_sheet.height/2) ))
display(contact_sheet)
contact_sheet.save('assignment_1.pdf')```
![image not processing correctly](https://i.stack.imgur.com/HzaLk.jpg)