Python中的图像位操作

3 投票
2 回答
2788 浏览
提问于 2025-04-16 03:21

我有一个应用程序,它从一个相机的API那里获取JPEG数据的指针,这个API是用ctypes封装的,然后把这些数据转换成wx.Image格式,并把图像显示成电影。

这个应用程序需要一个功能,就是把每个像素的两个颜色值设置成第三个颜色值。比如说,我的像素是RGB格式的(100,200,255),我想把R和B的值都改成G的值,也就是变成(200,200,200)。我需要对图像中的每个像素都做这个操作,同时还要保持一个不错的帧率。

我可以通过调用Image.GetData来获取wx.Image中的RGB值,这个方法返回一个字符串,里面包含像素值,格式是:RGBRGBRGB……我最开始是通过简单地遍历这个RGBRGBRGB字符串来实现这个功能的。

但是,这种简单的方法速度太慢,无法达到理想的帧率,因为我觉得:

a) 我在遍历图像中的每一个像素。

b) 我在进行太多的数据复制。

我考虑过把我的RGB数据转换成numpy格式,进行操作(我认为numpy会有更快的方法来处理这种事情),然后再转换回wx.Image。不过,遗憾的是,我不能直接把原始数据转换成numpy,因为数据是JPEG格式的,而不是RGB位图。所以我需要经过这个过程:数据 -> wx.Image -> numpy数组 -> wx.Image。

我还考虑过自己实现一个python缓冲区,这样在读取时可以返回G的像素值,而不是R和B的值。我觉得这可能是最理想的解决方案,因为这样不需要数据复制或过多的遍历,但我不知道该怎么做。我需要用C语言来写这个缓冲区吗?在纯python中实现缓冲区并且操作原始内存是可能的吗?

所以,大家觉得我应该怎么做才能提高性能?我应该尝试numpy或者缓冲区的方案,还是有更简单的解决办法我没想到?

我主要是在寻找一些想法、相关文档或示例链接,不过如果有人愿意写点代码,那也没问题 :)

谢谢

2 个回答

1

如果你需要非常快速地处理图像,我建议你写一个 GLSL 像素着色器,然后通过 OpenGL 和 PyGame 来连接它。像素着色器的处理速度是无与伦比的,因为每个像素都是由显卡上的 GPU 并行处理的。

如果你想测试像素着色器的代码(这些代码是用 C 的一个子集写的),最好使用 RenderMonkey,这是一个不错的着色器开发工具!

祝你好运!

1

你可以试试使用 Python图像库(PIL)——这是一个用来处理图像的库。

关于如何在wxPython图像和PIL图像之间转换的信息,你可以在这里找到,或者你也可以直接把jpeg图像加载到PIL图像中。

一旦你把wx图像转换成PIL图像,我觉得这样做应该能满足你的需求(不过我没有测试过):

r, g, b = im.split()              # split the image into separate color planes
im = Image.merge("RGB", (g, g, g))  # merge them back, using the green plane for each

然后再把它转换回wxPython图像。

这样做的速度应该比在Python中处理快很多,因为PIL是用C语言实现的,并且经过了图像处理的优化。

撰写回答