5

ヒートマップを作成するためにpygame(1.9.0rc3、ただしこれは1.8.1でも発生します)を使用しています。ヒートマップを作成するために、白い背景と非常に不透明度の低い灰色のドットが端で正確に停止する、小さな24ビットの11x11pxドットPNG画像を使用します。

ドット画像http://img442.imageshack.us/img442/465/dot.png

ドットの周りの領域は、本来あるべき完全な白、#ffffffです。ただし、pygameを使用して、BLEND_MULTを使用して画像を新しいサーフェスに複数回ブリットすると、ドットの背景が完全な白ではないかのように灰色の正方形が表示されます。これは意味がありません。

次のコードと含まれている画像は、これを再現できます。

import os
import numpy
import pygame

os.environ['SDL_VIDEODRIVER'] = 'dummy'
pygame.display.init()
pygame.display.set_mode((1,1), 0, 32)

dot_image = pygame.image.load('dot.png').convert_alpha()

surf = pygame.Surface((100, 100), 0, 32)
surf.fill((255, 255, 255))
surf = surf.convert_alpha()

for i in range(50):
    surf.blit(dot_image, (20, 40), None, pygame.BLEND_MULT)    

for i in range(100):
    surf.blit(dot_image, (60, 40), None, pygame.BLEND_MULT)      

pygame.image.save(surf, 'result.png')

コードを実行すると、次の画像が表示されます。

ブレンド後の結果の画像http://img263.imageshack.us/img263/4568/result.png

これが起こる理由はありますか?どうすれば回避できますか?

4

2 に答える 2

6

いろいろ試してみた結果、100% 正しいということがわかりました。255 を掛けると、毎回 1 が減算されます。最後に、pygame のソース コードをダウンロードしました。答えは次の場所にありsurface.hます。

#define BLEND_MULT(sR, sG, sB, sA, dR, dG, dB, dA) \
    dR = (dR && sR) ? (dR * sR) >> 8 : 0;          \
    dG = (dG && sG) ? (dG * sG) >> 8 : 0;          \
    dB = (dB && sB) ? (dB * sB) >> 8 : 0;

Pygame は乗算ブレンディングを次のように実装します。

new_val = old_dest * old_source / 256

そうではなく、これが正しい方法です。

new_val = old_dest * old_source / 255

これはおそらく最適化の目的で行われます。ビット シフトは除算よりもはるかに高速です。比率255 / 256が 1 に非常に近いため、これがもたらす唯一の違いは「1 ずつずれている」ことです。得られる値は、期待値から 1 を引いた値になります。ゼロを期待していた場合を除き、結果は正しいです。

したがって、次の可能性があります。

  1. オフバイワンはほとんどの目的にとって重要ではないため、無視してください。
  2. 1すべての結果値に加算します。ゼロを失うことを除いて、期待される結果に最も近い。
  3. 全体的な正確性は重要ではないが必要な場合255 * 255 == 255(私の言いたいことはわかります)、1足し合わせる代わりに ORing を使用する方が高速です。

回答 1 を選択しない場合、パフォーマンス上の理由から、Python を直接使用する代わりに C 拡張機能を作成する必要があることに注意してください。

于 2009-07-21T07:37:34.490 に答える
1

また、ヒートマップを実行しているときにこの問題が発生し、balpha の回答を読んだ後、「正しい」(遅い場合) 方法で修正することを選択しました。色々変えて

(s * d) >> 8

(s * d) / 255 

これには、乗算関数にパッチを適用する必要がありましたalphablit.c(ただし、パッチも適用surface.hしました)。これがパフォーマンスにどの程度影響するかはわかりませんが、特定の (ヒートマップ) アプリケーションでは、はるかにきれいな画像が生成されます。

于 2009-11-10T19:38:30.110 に答える