Python图像处理教程(Pillow)12 像素处理与nump
像素处理与numpy
像素处理简介
有时你可能想单独读取或设置图像像素。这可以用于。
- 创建特殊的填充物或梯度。
- 创建计算的图像,如分形图。
- 执行专门的像素计算。
- 在像素层面上应用特殊效果。
基于像素处理图像
下面是一个简单的例子,我们对图像中的每个像素进行处理。我们将把绿色和蓝色通道在X方向上移动几个像素,以模拟糟糕的注册图像的效果。这纯粹是作为例子来做的,除了作为一种稍微不寻常的艺术效果,它没有任何实际用途。下面是最终图像的模样。
以下是代码。
from PIL import Image
import math
image = Image.open('boat.jpg')
pixels = image.load()
for x in range(image.size[0]-20):
for y in range(image.size[1]):
r, _, _ = pixels[x, y]
_, g, _ = pixels[x+10, y]
_, _, b = pixels[x+20, y]
pixels[x, y] = (r, g, b)
image.save('deregister.jpg')
image.close()
load方法把图像加载PixelAccess对象,然后将其存储在像素中。这是一个像素颜色的二维数组。
这种效果可以用不同的方式完成。我们可以用Image.split将图像分割成3个独立的带子,然后从绿色平面的左边边缘裁剪10个像素(从蓝色边缘裁剪20个),然后用Image.merge将这些带子重新连接起来。这可能更有效,但这个例子只是为了说明像素访问。
基于像素创建图像
我们将创建一个新的图像,而不是修改图像。我们将用一个简单的数学图形填充图像,基于正弦函数的点。
图片.png以下是代码。
image = Image.new('L', (256, 256), 'black')
pixels = image.load()
for x in range(256):
for y in range(256):
pixels[x, y] = 128+int(63*math.sin(x/10) + 63*math.sin(y/10))
image.save('sine-pattern.jpg')
image.close()
这个图案产生了弥漫的黑白点。然而,这个函数产生的值是在-2.0到+2.0的范围内。我们将这些值乘以63,再加上128,以产生更接近于0到255范围的值。我们还将x和y除以10,以使圆点变大。这里的实际模式并不太重要,你可以很容易地用你自己的函数来替换它。
当然,我们也可以用RGB图像来做这个。在这种情况下,我们可能需要计算(r,g,b)元组来分配给循环中的像素[x,y],就像前面的例子一样。
访问像素性能
你应该知道,单独访问像素是比较慢的。如果你实现的算法涉及读取或写入大量的像素,预计会比调用Pillow的内置函数慢很多。这是因为Pillow的大多数底层函数是用C语言编写的,而C语言比Python快很多。
在现代PC上,写入一个中等大小的图像(600万像素)的每个像素需要不到一秒钟。在以下情况下,性能会成为一个更重要的问题。
- 处理非常大的图像。
- 批量处理大量的图像,例如对一个特定文件夹中的所有图像应用一种效果。
在GUI应用程序中交互式地处理图像,用户通常期望得到即时的响应。
一般来说。
- 如果可能的话,使用Pillow内置函数。
- 考虑将图像转换为NumPy数组来执行复杂的处理。
参考资料
- 本文涉及的python测试开发库 谢谢点赞!
- 本文相关海量书籍下载
NumPy集成简介
这可能是最重要的集成,因为。
- NumPy可以非常有效地存储和处理大量的数据。
- 许多其他的Python包都与NumPy兼容。
NumPy以数值的多维数组形式存储数据。这些数值可以有不同的类型和大小。例如,如果一个NumPy数组存储整数数据,你可以选择存储8位、16位、32位或64位数据,这些数据可以是有符号或无符号的。这与Python整数相比,后者是一个对象,可以存储任何大小的整数。
为了与Pillow集成,我们通常使用无符号的8位整数。
from PIL import Image
import numpy as np
image = Image.open('boat-small.jpg')
image_array = np.array(image) # 将图像转换为NumPy数组
print('shape', image_array.shape)
# 修改NumPy数组
image_array = 255 - image_array #
image_array[100:200, 150:350] = np.array([255, 128, 0])
out_image = Image.fromarray(image_array) # 将数组转换回Pillow图像。
out_image.save('numpy-image.jpg')
(280, 420, 3)表这个数组是三维,它的大小是280乘以420乘以3。
使用NumPy处理图像时,我们需要到处交换x和y。比如说
image_array(10, 20)将访问(x, y)位置(20, 10)的像素。
image_array = 255 - image_array,这段代码对数组中的每个值都执行了x=255-x的操作,这就产生了反转图像的效果。
image_array[100:200, 150:350] = np.array([255, 128, 0])