Generierung von Zone Plate Texturen in C/C++

Letztes Update: Dienstag, 16. August 2016 - 16:41 Uhr

Auf dieser Seite findest du Beispiele und kurze Erläuterungen zur Generierung von Zone Plate Texturen.
Diese Bilder eignen sich sehr gut um spezielle Rasterisierungsprobleme zu untersuchen (s. dazu auch den entsprechenden Artikel auf Wikipedia).

Dabei wird kurz auf den mathematischen Hintergrund der Kreisfunktionen eingegangen, um dann mit wenigen Zeilen Quellcode die eigentliche Generierung verständlich zu machen.

Wenn du Anmerkungen, Verbesserungen oder sonstiges Feedback hast, würde ich mich über einen Kommentar am Ende der Seite sehr freuen!


 

Zone Plate Texturen

Um Anti-Aliasing Probleme oder Moiré-Effekte zu untersuchen, eignen sich Zone Plate Texturen besonders gut. Die immer kleiner werdenden Kreise erzeugen ein sehr feines Raster, so dass sich bei Überlagerungen scheinbar grobe Kreise bemerkbar machen, wenn z.B. eine zu kleine Abtastung (sample rate / Auflösung) eingesetzt wird.
Die Bilder weiter unten verdeutlichen das Phänomen: In dem linken Bild mit hoher Auflösung erscheint genau ein Kreis in der Mitte mit Ringen umgeben,  im rechten Bild wurde der selbe Wertebereich mit geringerer Auflösung abgetastet, so das um den Hauptkreis in der Mitte auch zusätzliche Kreise an den Rändern erscheinen.

Beispiel für zwei Zone Plate Texturen mit gleichem Wertebereich aber unterschiedlicher Abtastung:
Linkes Bild: 300x300, rechtes Bild: 128x128, Wertebereich: [-10, 10], Offset: 0/0
Zone plate texture
Zone Plate Textur mit Versatz (X-Offset: -8, Y-Offset: -8):

Zone Plate Textur mit Versatz

Mathematischer Hintergrund:

Funktion zur Berechnung des Grauwerts:

f(x, y) = sin(x2 + y2)

bzw. mit Verschiebung des Zentrums um einen Offset:

f(x, y) = sin( (x - offsetX)2 + (y - offsetY)2 )

Simpler Quelltext zur Generierung von Zone Plate Texturen:

// ptr points to a memory buffer of size width * height * sizeof(unsigned int)
// offsetX, offsetY can be used to move the center of the inner circle
static void genZonePlate(unsigned int *ptr, int width, int height, float offsetX, float offsetY)
{
float xx, yy, s;
int x, y, c;
for (y = 0; y < height; ++y)
{
for (x = 0; x < width; ++x)
{
xx = -10.0f + ((float)x / width * 20.0f) - offsetX; // scale x to range [-10, 10]
yy = -10.0f + ((float)y / height * 20.0f) - offsetY; // scale y to range [-10, 10]
s = sinf(xx * xx + yy * yy); // s = sin(x² + y²)
c = (unsigned int)(((s + 1) / 2) * 255); // scale [-1, 1] to [0, 255]
*ptr++ = (c<<24) | (c<<16) | (c<<8) | 0xff; // set grayscale pixel
}
}
} ... genZonePlate(buf, 300, 300, 0.0f, 0.0f); // upper left texture genZonePlate(buf, 762, 256, -8.0f, -8.0f); // wide texture

 

Frequenzbesen Testbild

Neben den beschriebenen Zone Plate Texturen werden in der Computergrafik und Bildverarbeitung außerdem häufig Frequenzbesen (horizontal und vertikal) verwendet, die zur Beurteilung der Auflösung oder Filtertechniken dienen.

Das Bild enthält Übergänge die von grob bis sehr fein die Problemschwellen, Abtastprobleme oder Moiré Effekte aufzeigen und für verschiedene Winkel herangezogen werden können. Mehr Details sind auf Wikipedia zu finden.


 

Findest du diesen Beitrag hilfreich oder interessant? Hast du weitere Code-Beispiele oder zusätzliche Informationen, die hier noch fehlen? Hast du Fehler gefunden? Schreibe doch einen Kommentar...

 

Neuen Kommentar abgeben

efbk2