这个图像处理代码可以优化以使用更少的内存吗?

发布于 2024-09-12 01:31:28 字数 1877 浏览 9 评论 0原文

我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一指流沙 2024-09-19 01:31:28

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

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

更改

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

为类似的内容

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

可能会有所帮助,但这当然取决于 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 an Image into a string? Does ip.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

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

to something like

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

but of course this depends on what type of argument ip.token expects. I couldn't find any information on ImgProcessing 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.

很快妥协 2024-09-19 01:31:28

根据我的经验,您在纯 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文