1

「(add (sub 10 5) 5)」のような文字列 s 式を受け取る python 関数があります。ここで、「add」と「sub」は実際には画像処理関数であり、文字列で表される画像を評価して作成します。画像処理関数は、定数、変数、またはその他の画像 (ベクトルのリストとして表される) を受け取り、同じ方法で表される画像を返します。PIL は、ベクトルのリストとして表されるイメージをイメージ ファイルに変換するために使用されます。

接頭表記の s-expressions を評価するには、s-expr をリストに変換し、それを逆にして、関数が見つかるまでトークンを繰り返します。関数が見つかると、画像処理関数が実行され、結果の画像が関数とそのリスト内の引数。これは、最終的なイメージであるリストに 1 つの要素だけが残るまで行われます。

画像処理関数は単純です。ほとんどの場合、画像内の各 (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])変換しImageていますか? ip.token(...)画像を返しますか? その場合、文字列と画像の間で何度も変換しています。それは非常に遅いかもしれません。

変更するのに役立つかもしれません

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

のようなものに

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

もちろん、これは引数のタイプによって異なりますip.tokenImgProcessingグーグルからの情報は見つかりませんでした。これはカスタムクラスですか?もしそうなら、それがどのように機能するかについてもっと説明するのに役立つかもしれません. ip.token文字列の取得から画像の取得に変更できれば、大きな改善になる可能性があります。

于 2010-07-27T00:04:02.760 に答える
0

私の経験では、純粋な Python または PIL でピクセルごとに大きな画像を処理すると、1 月の糖蜜のように遅くなります。低レベルのものを C で記述された Python 拡張機能に移行することを検討してください。私は OpenCV を使用しましたが、ある程度の学習が必要です。

于 2010-07-27T00:33:55.830 に答える