Python 中的不安全图像处理类似于 C# 中的 LockBits
Unsafe Image Processing in Python like LockBits in C#
是否可以在 Python 中进行不安全的图像处理?
与 C# 一样,我在 Python 中的像素处理遇到了困难,因为 Image 中的 getPixel 方法 运行 太慢了。
是否可以像 C# 中的 LockBits 那样直接访问内存中的图像?它将使我的程序 运行 更快。
谢谢,
马克
没有什么"unsafe"关于这个。
一旦您理解了 Python 的工作原理,就会发现调用方法来检索每个像素的信息会很慢。
首先,虽然您没有提供相关信息,但我假设您使用的是 "Pillow" - Python 图像库 (PIL),它是最著名的图像处理库,使用Python。由于它是第三方软件包,因此没有任何义务要求您使用它。 (PIL 在图像上确实有 getpixel
方法,但没有 getPixel
方法)
以可操作的方式获取所有数据的一种直接方法是创建图像数据的字节数组对象 - 在 img
变量中给定图像,您可以执行以下操作:
data = bytearray(img.tobytes())
就是这样,您可以线性访问图像上的所有数据。要获取其中的特定像素,您需要获取图像宽度、高度和每像素字节数。后一个不是 PIL 中的直接 Image 属性,因此您必须在给定 Image 的 mode
的情况下计算它。最常见的图像类型是 RGB、RGBA 和 L。
所以,如果你想在图像的 "x, y, width, size" 处写出一个矩形,你可以这样做:
def rectangle(img, x,y, width, height):
data = bytearray(img.tobytes())
blank_data = (255,) * witdh * bpp
bpp = 3 if data.mode == 'RGB' else 4 if data.mode == 'RGBA' else 1
stride = img.width * bpp
for i in range(y, y + height):
data[i * stride + x * bpp: i * stride + (x + width) * bpp)] = blank_data
return Image.frombytes(img.mode, (img.width, img.height), bytes(data))
那个用的不多,只是为了简单的操作。人们需要在 Python 的图像中应用过滤器和其他更复杂的算法通常使用 numpy - python 高性能数据处理包访问图像,它与许多其他具有东西的包紧密耦合特定于图像 - 通常安装为 scipy
.
因此,要将图像作为 ndarray,它已经为您完成了上述所有坐标 -> 字节转换,您可以使用:
import scipy.misc
data = scipy.misc.imread(<filename>)
是否可以在 Python 中进行不安全的图像处理?
与 C# 一样,我在 Python 中的像素处理遇到了困难,因为 Image 中的 getPixel 方法 运行 太慢了。
是否可以像 C# 中的 LockBits 那样直接访问内存中的图像?它将使我的程序 运行 更快。
谢谢,
马克
没有什么"unsafe"关于这个。
一旦您理解了 Python 的工作原理,就会发现调用方法来检索每个像素的信息会很慢。
首先,虽然您没有提供相关信息,但我假设您使用的是 "Pillow" - Python 图像库 (PIL),它是最著名的图像处理库,使用Python。由于它是第三方软件包,因此没有任何义务要求您使用它。 (PIL 在图像上确实有 getpixel
方法,但没有 getPixel
方法)
以可操作的方式获取所有数据的一种直接方法是创建图像数据的字节数组对象 - 在 img
变量中给定图像,您可以执行以下操作:
data = bytearray(img.tobytes())
就是这样,您可以线性访问图像上的所有数据。要获取其中的特定像素,您需要获取图像宽度、高度和每像素字节数。后一个不是 PIL 中的直接 Image 属性,因此您必须在给定 Image 的 mode
的情况下计算它。最常见的图像类型是 RGB、RGBA 和 L。
所以,如果你想在图像的 "x, y, width, size" 处写出一个矩形,你可以这样做:
def rectangle(img, x,y, width, height):
data = bytearray(img.tobytes())
blank_data = (255,) * witdh * bpp
bpp = 3 if data.mode == 'RGB' else 4 if data.mode == 'RGBA' else 1
stride = img.width * bpp
for i in range(y, y + height):
data[i * stride + x * bpp: i * stride + (x + width) * bpp)] = blank_data
return Image.frombytes(img.mode, (img.width, img.height), bytes(data))
那个用的不多,只是为了简单的操作。人们需要在 Python 的图像中应用过滤器和其他更复杂的算法通常使用 numpy - python 高性能数据处理包访问图像,它与许多其他具有东西的包紧密耦合特定于图像 - 通常安装为 scipy
.
因此,要将图像作为 ndarray,它已经为您完成了上述所有坐标 -> 字节转换,您可以使用:
import scipy.misc
data = scipy.misc.imread(<filename>)