vla*_*sch 6 python python-imaging-library
我创建一个图像并填充像素:
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
Run Code Online (Sandbox Code Playgroud)
这可以做得更优雅(并且可能更快,因为从理论上讲,循环可以并行化)?
注意:我会先回答这个问题,然后提出一个我认为更好的选择
在不知道您打算应用哪些更改以及将图像加载为 PIL 图像是问题的一部分还是给定的情况下,很难给出建议。
根据您创建/加载图像的方法,您可能会对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)
Run Code Online (Sandbox Code Playgroud)
但是,我认为这不是一个好主意……当您看到 Python 中数千个元素上的循环(和列表推导式)并且考虑到性能时,您可以确定有一个库可以实现这一点快点。
首先,一个指向Channel Operations 模块的快速指针,由于您没有指定您打算执行的像素操作类型,并且您已经清楚地了解 PIL 库,我假设您知道它并且它没有做你想做的事。
然后,Python 中任何中等复杂的矩阵操作都将受益于拉入Pandas、Numpy或Scipy ...
纯麻木的例子:
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)
Run Code Online (Sandbox Code Playgroud)
由于您只是使用标准的 numpy.ndarray,您可以使用任何可用的功能,例如 np.vectorize、apply、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)
Run Code Online (Sandbox Code Playgroud)
再举一个例子,这次直接从索引计算图像内容,而不是从现有的图像像素内容(不需要先创建一个空图像):
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...
Run Code Online (Sandbox Code Playgroud)
而且,瞧,scipy 有读取和写入图像的方法,您可以使用 numpy 将它们作为“经典”多维数组进行操作。(scipy.misc.imread顺便说一下,取决于 PIL)
| 归档时间: |
|
| 查看次数: |
2777 次 |
| 最近记录: |