Есть много способов сделать синие пиксели красными - и использование for
l oop далеко внизу списка с точки зрения производительности, удобочитаемости и удобства обслуживания.
Вот пример использования «Цветовой матрицы» для переключения красного и синего каналов:
from PIL import Image
# Open image
im = Image.open('lines.png')
# Define color matrix to swap the red and blue channels
# This says:
# New red = 0*old red + 0*old green + 1*old blue + 0offset
# New green = 0*old red + 1*old green + 0*old blue + 0offset
# New blue = 1*old red + 0*old green + 0*old blue + 0offset
Matrix = ( 0, 0, 1, 0,
0, 1, 0, 0,
1, 0, 0, 0)
# Apply matrix
result = im.convert("RGB", Matrix)
Это примерно в 40 раз быстрее, чем for
. На моем аппарате требуется 1,07 мс против 40 мс с использованием циклов for
.
Вот пример использования Numpy для поиска синих пикселей и их красного цвета:
import numpy as np
from PIL import image
# Open image and make Numpy version
im = Image.open('lines.png')
na = np.array(im)
# Make all blue pixels red
na[ np.all(na[:,:]==[0,0,255], axis=2) ] = [255,0,0]
# Convert back to PIL Image
result = Image.fromarray(na)
Это примерно в 8 раз быстрее при 5 мс.
Вот один из них, использующий Numpy для изменения порядка RGB в BGR:
import numpy as np
from PIL import image
# Open image and make Numpy version
im = Image.open('lines.png')
na = np.array(im)
# Reverse channel ordering i.e. RGB -> BGR
BGR = na[...,::-1]
# Convert back to PIL Image
result = Image.fromarray(BGR)
Это примерно в 9 раз быстрее при 4,4 мс.
Здесь мы используем PIL, чтобы разделить изображение на составляющие его каналы RGB и затем объединить их в обратном порядке:
from PIL import Image
# Open image
im = Image.open('lines.png')
# Split into R, G, B channels
R, G, B = im.split()
# Recombine in B, G, R order
result = Image.merge('RGB',(B,G,R))
Это примерно в 100 раз быстрее при 371 микросекунде.