我有一个python函数,它接受一个字符串s-expression,如“(add(sub 10 5)5)”,其中“add”和“sub”实际上是图像处理函数,并评估和创建表示的图像字符串。图像处理功能采用常数,变量或其他图像(表示为矢量列表),并以相同的方式返回图像。 PIL用于将表示为矢量列表的图像转换为图像文件。
为了评估前缀表示法s-expressions,我将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)
答案 0 :(得分:2)
Profiling可以告诉您该计划在大部分时间内花费的时间。
其次,str(sList[index-1])
是否将Image
转换为字符串? ip.token(...)
会返回图片吗?如果是这样,您将在字符串和图像之间进行多次转换。那可能会很慢。
可能有助于改变
rawImage = eval("ip." + token + "(" + "\"" + str(sList[index-1]) +
"\"" + ")")
类似
getattr(ip,token)(sList[index-1])
但当然这取决于ip.token
期望的参数类型。我在谷歌搜索中找不到关于ImgProcessing
的任何信息。这是一个自定义类吗?如果是这样,它可能有助于更多地解释它是如何工作的。
如果ip.token
可以从拍摄字符串更改为拍摄图像,那么这可能是一个很大的改进。
答案 1 :(得分:0)
根据我的经验,在大型图像上以纯Python或PIL逐像素进行的任何事情都会像1月份的糖蜜一样慢。考虑将低级别的东西移动到用C编写的Python扩展中。我使用过OpenCV,但需要一些学习。