这个图像处理代码可以优化以使用更少的内存吗?
我有一个 python 函数,它接受一个字符串 s 表达式,如“(add (sub 10 5) 5)”,其中“add”和“sub”实际上是图像处理函数,并评估和创建字符串中表示的图像。图像处理函数采用常量、变量或其他图像(表示为向量列表),并返回以相同方式表示的图像。 PIL 用于将表示为向量列表的图像转换为图像文件。
为了评估前缀符号 s-表达式,我将 s-expr 转换为列表,反转它,并迭代标记直到找到函数,此时执行图像处理函数,并且生成的图像替换该函数及其列表中的参数。这样做直到列表中只剩下一个元素,即最终图像。
图像处理函数很简单 - 大多数对图像中的每个 (r,g,b) 值执行一些数学运算。
问题是,如果我想为更复杂的表达式制作合适尺寸的图像,我的计算机就会停止运行。可以优化它以使用更少的内存吗?
def createImage(self, sexpr, filename, (picWidth, picHeight)):
"""Use the image processing functions in ImgProcessing
to create an image from the procedural information
contained in the s-expression."""
img = Image.new("RGB",(picWidth,picHeight),(255,255,255))
ip = ImgProcessing(picWidth,picHeight)
# Split s-expression into list of tokens and reverse
sList = sexpr.replace("(","").replace(")","").split()
sList.reverse()
while len(sList) > 1:
for index,token in enumerate(sList):
# If token is an image processing function
if type(token) == str and self.FuncSet.has_key(token):
# If this function takes one argument
if self.FuncSet[token] == 1:
rawImage = eval("ip." + token + "(" + "\"" + str(sList[index-1]) +
"\"" + ")")
sList = sList[:index-1] + [rawImage] + sList[index+1:]
break
# If this function takes two arguments
elif self.FuncSet[token] == 2:
rawImage = eval("ip." + token + "(" + "\"" + str(sList[index-1]) +
"\"" + "," + "\"" + str(sList[index-2]) + "\"" +
")")
sList = sList[:index-2] + [rawImage] + sList[index+1:]
break
img.putdata(sList[0])
img.save(filename)
I have a python function that takes a string s-expression like "(add (sub 10 5) 5)", where "add" and "sub" are actually image processing functions, and evaluates and creates the image represented in the string. The image processing functions take constants, variables, or other images (represented as lists of vectors), and return images represented the same way. PIL is used to convert the image represented as a list of vectors into an image file.
To evaluate the prefix notation s-expressions, I convert the s-expr to a list, reverse it, and iterate the tokens until a function is found, at which point the image processing function is performed and the resulting image replaces the function and its arguments in the list. This is done until only one element is left in the list, which is the final image.
The image processing functions are simple- most perform some mathematical operation to each of the (r,g,b) values in the image(s).
The problem is my computer comes to a standstill if I want to make decent sized images for more complex expressions. Can this be optimised to use less memory?
def createImage(self, sexpr, filename, (picWidth, picHeight)):
"""Use the image processing functions in ImgProcessing
to create an image from the procedural information
contained in the s-expression."""
img = Image.new("RGB",(picWidth,picHeight),(255,255,255))
ip = ImgProcessing(picWidth,picHeight)
# Split s-expression into list of tokens and reverse
sList = sexpr.replace("(","").replace(")","").split()
sList.reverse()
while len(sList) > 1:
for index,token in enumerate(sList):
# If token is an image processing function
if type(token) == str and self.FuncSet.has_key(token):
# If this function takes one argument
if self.FuncSet[token] == 1:
rawImage = eval("ip." + token + "(" + "\"" + str(sList[index-1]) +
"\"" + ")")
sList = sList[:index-1] + [rawImage] + sList[index+1:]
break
# If this function takes two arguments
elif self.FuncSet[token] == 2:
rawImage = eval("ip." + token + "(" + "\"" + str(sList[index-1]) +
"\"" + "," + "\"" + str(sList[index-2]) + "\"" +
")")
sList = sList[:index-2] + [rawImage] + sList[index+1:]
break
img.putdata(sList[0])
img.save(filename)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
分析可以告诉您程序大部分时间都花在哪里。
其次,str(sList[index-1])是否将
Image
转换为字符串?ip.token(...)
返回图像吗?如果是这样,您将在字符串和图像之间进行多次转换。这可能会非常慢。更改
为类似的内容
可能会有所帮助,但这当然取决于 ip.token 期望的参数类型。我在 Google 上找不到任何有关
ImgProcessing
的信息。这是自定义类吗?如果是这样,可能有助于更多地解释它是如何工作的。如果 ip.token 可以从获取字符串更改为获取图像,那可能是一个很大的改进。
Profiling can tell you where the program is spending most of its time.
Second, is
str(sList[index-1])
converting anImage
into a string? Doesip.token(...)
return an Image? If so, you are converting between string and Image a number of times. That might be very slow.It might help to change
to something like
but of course this depends on what type of argument
ip.token
expects. I couldn't find any information onImgProcessing
from Googling. Is this a custom class? If so, it might help to explain more about how it works.If
ip.token
can be changed from taking strings to taking Images, that might be a big improvement.根据我的经验,您在纯 Python 或 PIL 中对大图像逐像素执行的任何操作都会像一月份的糖蜜一样慢。考虑将低级内容转移到用 C 编写的 Python 扩展中。我使用过 OpenCV,但这需要一些学习。
In my experience, anything that you do in pure Python or PIL pixel-by-pixel on a large image is going to be slow as molasses in January. Consider moving the low-level stuff into a Python extension written in C. I have used OpenCV, but it takes some learning.