2012-08-06 5 views
7

写真測量アプリケーション用の一連のテスト画像を生成する必要があります。 これらは、非常に正確に既知の位置を持つ単純なオブジェクト(ディスク、長方形など)を含む必要があります。OpenGLでのサブピクセルレンダリング - 精度の問題

白い背景上の黒い矩形の8ビットグレースケール画像を考えると、各ピクセルの256の可能な輝度レベルがあるので、最小の観察可能な変位(補間後)は1/256ピクセルでなければならない。

は、私は後で私が

は残念ながら、最高の精度は、私が達成したより複雑な(3Dシーン、ステレオ画像対)をレンダリングする必要があります、そのような画像をレンダリングする(のpython + pygletで)OpenGLを使用することにしましたピクセル/ 10の周囲にある場合、最大強度の深度は使用されません。

完全に1/256pixelの精度を達成するのが理想的です。それをどうするかについてのヒントはありますか?

サンプルコードは、部分的なディスクの画像を生成する、各フレームでより

#-*- coding: utf-8 -*- 
import pyglet 
from pyglet.gl import * 
from PIL import Image, ImageGrab 

config = pyglet.gl.Config(width = 800, height = 600, sample_buffers=1, samples=16) 
window = pyglet.window.Window(config=config, resizable=True) 
window.set_size(800, 600) 

printScreenNr = 0 

@window.event 
def on_draw(): 
    global printScreenNr 
    window.clear() 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glLoadIdentity() 
    glEnable(GL_LINE_SMOOTH) 
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); 

    glTranslated(200, 200,0) 

    circleQuad = gluNewQuadric() 
    glTranslated(200+(printScreenNr*0.01), 0, 0) 
    gluPartialDisk(circleQuad, 0, 50, 500, 500, 0, 180) 

@window.event 
def on_resize(width, height): 
    glViewport(0, 0, width, height) 
    glMatrixMode(GL_PROJECTION) 
    glLoadIdentity() 
    glOrtho (0, width, height, 0, 0, 1); 
    glMatrixMode(GL_MODELVIEW) 
    return pyglet.event.EVENT_HANDLED 

@window.event 
def on_text(text): 
    global printScreenNr 
    if(text == "p"): 
     pyglet.image.get_buffer_manager().get_color_buffer().save('photo'+str(printScreenNr)+'.tiff') 
     printScreenNr += 1 

pyglet.app.run() 

を0.01ピクセルだけ移動(上記のコードはgluPartialDiskを使用して、私は四角形を使用しても問題をテストして、その結果精度がなかったです違いはありません)

+0

32ビットの色深度を試しましたか?私がこれを言うのは、グラフィックドライバでは、32ビットのパスが最も使用されているため、現在最も管理されているコードパスであるということです。これが機能する場合は、その後、高品質の色深度を再スケールすることができます。 – Ani

+0

それを試しましたが、結果を変更していませんでした... まだ、ありがとうございます – Pietro

答えて

4

これを行う簡単な方法は、画像を係数でスケールすることです。イメージを4.0でスケーリングすると、16個の元のピクセルが1つのターゲットピクセルにマージされ、純粋なB & Wイメージをスケーリングすると16個のグレースケールが得られます。

しかし、おそらくあなたの問題を説明するキャッチがあります。

...##### 
    ...##### 
    ...##### 
    ...##### 

(左:ホワイト、右:ブラック充填矩形)あなたがこれを持っている場合は、単一の出力画素に寄与する12個の白と黒の4つの画素を有します。黒のピクセルを1つ取得するには、入力は次のようにする必要があります。

....#### 
    ....#### 
    ....#### 
    ...##### 

参照してください。ブラックボックスは空白に1ピクセルしか漏れませんが、それは4回です。したがって、サブピクセルレンダリングコードが機能するようにするには、エッジではなく単一のピクセルまたはコーナーを見る必要があります。

+0

レンダリングする(方法)大きな画像は解決ですが、画面のサイズは制限だと思いますか? 画像が4倍(各方向)に拡大されている場合、画像を観察すると4つの可能なシェードが表示されます。エッジ(とポイントを観察すると16) しかし、それは何らかの方法で完全深度の精度で配置されたエッジを生成することができる – Pietro

+0

どのように?エッジには4つの異なる位置しかないので、16のシェードのうち4つしか得られません。 –

+0

私はまだ間違っている場合私を修正してください 画像は256倍に拡大縮小されているとしましょう。 エッジには256の位置があり、ポイントは256^2(これは丸くなります) OpenGLでこのようなことが可能な場合(この場合はパフォーマンスは問題ありません)、 しかし私は知りませんこれらの要件を満たす画像は一般的に生成することができると考えています。私の質問はちょうどです:それを行う方法.. – Pietro

1

正射影を使用していても、GL_PERSPECTIVE_CORRECTION_HINTはレンダリングの精度に影響を与える可能性があります。少なくとも私はぼんやりとglHint(GL_PERSPECTIVE_CORRECTION_HINT、GL_NICEST)を覚えています。何年も前に私の直角に投影された場面にいくつかのギャップを固定する。

+0

ありがとうございました。加えて、現時点で結果を変更していませんでしたが、将来の3Dモードではおそらく必要になるでしょう – Pietro