3

Python 2.7.4 でシンプルなグリーン スクリーン アプリを作成していますが、結果が非​​常に遅くなります。私は現在、PIL 1.1.7 を使用して画像の読み込みと反復処理を行っており、古い getpixel() から新しい load() とピクセル アクセス オブジェクトのインデックス作成に変更することで大幅なスピードアップが見られました。ただし、次のループは、約 720p の解像度の画像の実行に約 2.5 秒かかります。

def colorclose(Cb_p, Cr_p, Cb_key, Cr_key, tola, tolb):
    temp = math.sqrt((Cb_key-Cb_p)**2+(Cr_key-Cr_p)**2)
    if temp < tola:
        return 0.0
    else: 
        if temp < tolb:
            return (temp-tola)/(tolb-tola)
        else:
            return 1.0

....

for x in range(width):
    for y in range(height):
        Y, cb, cr = fg_cbcr_list[x, y]
        mask = colorclose(cb, cr, cb_key, cr_key, tola, tolb)
        mask = 1 - mask
        bgr, bgg, bgb = bg_list[x,y]
        fgr, fgg, fgb = fg_list[x,y]
        pixels[x,y] = (
            (int)(fgr - mask*key_color[0] + mask*bgr),
            (int)(fgg - mask*key_color[1] + mask*bgg),
            (int)(fgb - mask*key_color[2] + mask*bgb))

ここで実行が非常に遅くなる非常に非効率的なことをしていますか? たとえば、ループがブール行列に置き換えられた同様のより単純な例を見たことがありますが、この場合、ループを置き換える方法がわかりません。

ピクセル[x、y]の割り当てに最も時間がかかるようですが、Pythonをよく知らないので、これを行うためのより効率的な方法がわかりません。

どんな助けでも大歓迎です。

4

1 に答える 1

0

これはメモリで使用されるレイアウトであるため、ピクセルを行単位で反復処理することをお勧めします。

したがって、代わりに:

for x in range(width):
    for y in range(height):

使用する

for y in range(height):
    for x in range(width):

編集:たとえば、これが重要な理由については、配列の反復処理に関するnumpyドキュメントを読むことができます

この繰り返しで注意すべき重要なことは、標準の C または Fortran の順序付けを使用する代わりに、配列のメモリ レイアウトに一致するように順序が選択されることです。これは、アクセスの効率化のために行われます。これは、デフォルトでは、特定の順序を気にせずに各要素にアクセスしたいという考えを反映しています。これは、以前の配列の転置を繰り返し処理することで確認できます。C オーダーでその転置のコピーを取得するのと比較します。

于 2013-11-05T09:54:16.793 に答える