Autor Beitrag
der_zaehe
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 317

WinXP SP2
D6 Pers, D2005 Prof, VS2005
BeitragVerfasst: Do 07.04.05 20:25 
Wie kann ich Unschärfe in einem Array, auf einem Canvas, wie auch immer berechnen?
Da jetzt wahrscheinlich noch keinem klar ist, was ich mit dieser diffusen Formulierung eigentlich meine hier die genauere Beschreibung, was ich unter Unschärfe verstehe:

    Ich zeichne beispielsweise in einem 700x700 großem Canvas an die Stelle [200,200] einen Punkt.
    Dann soll nach einem definierbaren Unschärferadius das Pixel 'verunschärft' werden, so dass dann so aussieht:
user defined image

in meinem beispiel hier wurde ein ca 40 pixel großer kreis mit einem unschärferadius von 20 "geunschärft"

schon mal danke für eure hilfe!

_________________
[inspirationslos]
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Do 07.04.05 22:49 
Du willst mit anderen Worten einfach ein Bild verunschärfen?
=> Falte das Bild mit einer 2D-Gausskurve. Oder lass ne Diffusionsgleichung drauf los (mit finiten Differenzen).

Wenn der "Radius" (bzw. die Standardabweichung der Gausskurve) nicht genau angegeben werden können muss, kannst du ja ne Binomialmaske nehmen. Die lässt sich separieren, sodass du zuerst in x und dann in y Richtung falten kannst (2x 1D-Maske ist weniger aufwändig als 1x 2D-Maske).

Wenn du das Bild mit einer Gausskurve falten willst, dann ist das etwas komplizierter. Ich beschreibe hier kurz eine einfachere Methode (Binomialfilter). Die ist geeignet für kleine "Unschärferadien". Die Zahlen für die Binomialmaske entnimmt man aus dem Pascaldreieck. Sie sind Annäherungen an die Gausssche Glockenkurve. Beispiel für 5x5-Unschärfemaske:
Pascaldreieck:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Die Maske lautet:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
[1 4 6 4 1]^T x [1 4 6 4 1]=
[1   4   6   4   1]
[4  16  24  16   4]
[6  24  36  24   6]
[4  16  24  16   4]
[1   4   6   4   1]

Das ist die Unschärfe-Matrix, die man aber noch normieren muss. Die Summe aller Zahlen der Matrix ist 256. Du musst also alle Zahlen in der Matrix noch durch 256 teilen. Im Prinzip gehst du dann durchs ganze Bild durch - Punkt für Punkt - und bildest bei jedem Punkt ein gewichtetes Mittel der umliegenden Punkte. Die Gewichte für die Mittelung entnimmst du aus der oberen Matrix (geteilt durch 256).

Wie gesagt lässt sich jetzt dieser Filter noch separieren: Du verunschärfst das Bild zuerst Zeilenweise mit dem "Kernel" [1 4 6 4 1]. Das resultierende Bild verunschärfst du dann mit derselben Maske, diesmal aber spaltenweise. Du erhältst genau dasselbe Resultat wie bei der Matrix, nur ist diese Methode wesentlich effizienter. Ungetesteter Code:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
for y := 0 to maxy do
 for x := 2 to maxX-2 do
  P[x,y] := (1*P[x-2,y]+4*P[x-1,y]+6*P[x,y]+4*P[x+1,y]+1*P[x+2,y])/16;

for x := 0 to maxX do
 for y := 2 to maxY-2 do
  P[x,y] := (1*P[x,y-2]+4*P[x,y-1]+6*P[x,y]+4*P[x,y+1]+1*P[x,y+2])/16;

// Die Punkte am Rand sind nicht verunschärft


Das war jetzt vielleicht etwas knapp aber ich hoff mit dem Code wird's einigermassen klar.
der_zaehe Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 317

WinXP SP2
D6 Pers, D2005 Prof, VS2005
BeitragVerfasst: Fr 08.04.05 22:16 
danke schon mal für deine antwort, das muss ich jetzt erst mal verdauen :shock: (mathekenntenisse 11., rechnen mit matrizen sagt mir gar nix), aber in deinem beispiel unten wird mir klarer, wie das geht.
ich denk mal, mit der hilfe von dir krieg ich das gut hin.

_________________
[inspirationslos]