1

我有一个 python 函数,它接受一个字符串 s 表达式,如“(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)
4

2 回答 2

2

分析可以告诉您程序大部分时间都花在了哪里。

其次,是str(sList[index-1])将anImage转换为字符串吗?是否ip.token(...)返回图像?如果是这样,您将多次在字符串和图像之间进行转换。那可能会很慢。

可能有助于改变

rawImage = eval("ip." + token + "(" + "\"" + str(sList[index-1]) +
                                    "\"" + ")")

类似于

getattr(ip,token)(sList[index-1])

但这当然取决于ip.token期望的论点类型。我在谷歌上找不到任何信息ImgProcessing。这是一个自定义类吗?如果是这样,它可能有助于更多地解释它是如何工作的。如果ip.token可以从获取字符串更改为获取图像,那可能是一个很大的改进。

于 2010-07-27T00:04:02.760 回答
0

以我的经验,你在纯 Python 或 PIL 中对大图像逐个像素所做的任何事情都会在一月份像糖蜜一样缓慢。考虑将低级的东西移动到用 C 编写的 Python 扩展中。我使用过 OpenCV,但需要一些学习。

于 2010-07-27T00:33:55.830 回答