Thema: Delphi Gaußsches Weichzeichen

Einzelnen Beitrag anzeigen

Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#7

Re: Gaußsches Weichzeichen

  Alt 7. Mai 2010, 11:00
Ich vermute da einen Fehler in deiner Berechnung. Bei wachsendem Sigma flacht die Glockenkurve ab, d.h. weiter von 0 entfernten X-Werten sollte ein größerer Y-Wert zugeteilt werden als bei kleineren Sigmas. Bei Sigma>1 spätestens darf niemals ein Wert > 1 für ein Element raus kommen. Der Sinn des ganzen ist ja, dass das Integral unter der gesamten Kurve 1 ist, was ja kleinere Y-Werte bedeutet, je größer die Streuung ist. (Weniger Kugeln treffen die Wand auf gleich bleibender Fläche )

Wenn nach aussen zu kleine Werte auftreten, ist das ein Zeichen für einen zu großen Kernel.

Üblicherweise bewegen sich die einzelnen Werte im Kernel so grob zwischen 0,05 und 0,4. Wirklich sehr grob, da ja stark vom Sigma abhängig, aber das ist in etwa die Größenordnung. Keinesfalls 10^30, und schon garnicht 10^-80

Edit: Hier mal ein Gauss aus einem aktuellen Projekt. Ist nun zwar ein HLSL-Shader, aber die Mathematik bleibt ja gleich.
Code:
void ps_Gauss3_Y(in v2p IN, out p2f OUT)
{
   IN.tex.xy += rcpXY*0.5;
   float k = 0.39894228; // = 1 / (phi*sqrt(2*PI)); phi=1 (radius=3)
   
   OUT.color.agb = (float3)0;
   
   OUT.color.r =
      tex2D(sBase, IN.tex.xy-SY*3).r * k * exp(-4.5) +
      tex2D(sBase, IN.tex.xy-SY*2).r * k * exp(-2.0) +
      tex2D(sBase, IN.tex.xy-SY*1).r * k * exp(-0.5) +
      tex2D(sBase, IN.tex.xy    ).r * k            +
      tex2D(sBase, IN.tex.xy+SY*1).r * k * exp(-0.5) +
      tex2D(sBase, IN.tex.xy+SY*2).r * k * exp(-2.0) +
      tex2D(sBase, IN.tex.xy+SY*3).r * k * exp(-4.5);
}

void ps_Gauss3_X(in v2p IN, out p2f OUT)
{
   IN.tex.xy += rcpXY*0.5;
   float k = 0.39894228; // = 1 / (phi*sqrt(2*PI)); phi=1 (radius=3)
   
   OUT.color.agb = (float3)0;
   
   OUT.color.r =
      tex2D(sBase, IN.tex.xy-SX*3).r * k * exp(-4.5) +
      tex2D(sBase, IN.tex.xy-SX*2).r * k * exp(-2.0) +
      tex2D(sBase, IN.tex.xy-SX*1).r * k * exp(-0.5) +
      tex2D(sBase, IN.tex.xy    ).r * k            +
      tex2D(sBase, IN.tex.xy+SX*1).r * k * exp(-0.5) +
      tex2D(sBase, IN.tex.xy+SX*2).r * k * exp(-2.0) +
      tex2D(sBase, IN.tex.xy+SX*3).r * k * exp(-4.5);
}
Das ist nun auch noch etwas optimiert, da es in zwei Passes läuft. Erst wird das Bild in Y-Richtung "gegausst", dann in X-Richtung. Spart nen Haufen Zeit. Zudem ist hier Sigma=1 fix (und heisst komischerweise phi, oops). Die Formel für einen Pass wäre hier also:
Pixel[x, y] = Summe(n=-3; n<4; Pixel[x, y+n] * 1/(phi * sqrt(2*PI)) * exp(-(0.5*n²/phi)))
Das ganze läuft dann über komplett x und y (das ganze Bild), und dann der ganze Spaß auf dem Ergebnis davon noch ein mal, aber diesmal mit:
Pixel[x, y] = Summe(n=-3; n<4; Pixel[x+n, y] * 1/(phi * sqrt(2*PI)) * exp(-(0.5*n²/phi)))
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat