pil-对每个像素应用相同的操作



我创建图像并填充像素:

img = Image.new( 'RGB', (2000,2000), "black") # create a new black image
pixels = img.load() # create the pixel map
for i in range(img.size[0]):    # for every pixel:
    for j in range(img.size[1]):
      #do some stuff that requires i and j as parameter

这可以更优雅(并且可能更快,因为从理论上讲,循环是可行的)?

注意:我将首先回答问题,然后提出AN,我认为AN

回答问题

很难在不知道您打算应用的更改以及图像作为pil图像的加载是问题的一部分还是给定的。

  • 更优雅的python说话通常意味着使用列表综合
  • 对于并行化,您会查看类似多处理模块或Joblib
  • 之类的东西

取决于您在图像中创建/加载的方法,list_of_pixels = list(img.getdata())img.putdata(new_list_of_pixels)功能可能对您感兴趣。

这可能是什么样子:

from PIL import Image
from multiprocessing import Pool
img = Image.new( 'RGB', (2000,2000), "black")
# a function that fixes the green component of a pixel to the value 50
def update_pixel(p):
    return (p[0], 50, p[2])
list_of_pixels = list(img.getdata())
pool = Pool(4)
new_list_of_pixels = pool.map(update_pixel, list_of_pixels)
pool.close()
pool.join()
img.putdata(new_list_of_pixels)

但是,我认为这不是一个好主意...当您看到python中成千上万个元素的循环(并列出综合)时,您的脑海中表现出色时,您可以确定有一个库会使这个更快。

更好的替代

首先,快速指向通道操作模块,由于您没有指定您打算执行的像素操作的类型,并且显然已经知道PIL库,我会假设您知道它,并且它不做您想要的。

然后,python中的任何中等复杂的矩阵操纵都将受益于熊猫,numpy或scipy ...

纯numpy示例:

import numpy as np
import matplotlib.pyplot as plt
#black image
img = np.zeros([100,100,3],dtype=np.uint8)
#show
plt.imshow(img)
#make it green
img[:,:, 1] = 50
#show
plt.imshow(img)

由于您只是使用标准的numpy.ndarray,因此您可以使用任何可用功能,例如np.vectorize,applains,map等,以显示与上述update_pixel函数的类似解决方案:

import numpy as np
import matplotlib.pyplot as plt
#black image
img = np.zeros([100,100,3],dtype=np.uint8)
#show
plt.imshow(img)
#make it green
def update_pixel(p):
    return (p[0], 50, p[2])
green_img = np.apply_along_axis(update_pixel, 2, img)
#show
plt.imshow(green_img)

另外一个示例,这次是直接从索引中计算图像内容的,而不是从现有图像像素内容中计算(无需先创建一个空图像):

import numpy as np
import matplotlib.pyplot as plt
def calc_pixel(x,y):
    return np.array([100-x, x+y, 100-y])
img = np.frompyfunc(calc_pixel, 2, 1).outer(np.arange(100), np.arange(100))    
plt.imshow(np.array(img.tolist()))
#note: I don't know any other way to convert a 2D array of arrays to a 3D array...

,而scipy具有读写图像和介于两者之间的方法,您只能使用numpy将它们作为"经典"多维阵列操纵。(顺便说一句,scipy.misc.imread取决于PIL)

更多示例代码。

最新更新