AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Sobel Normalisierungsschritt

Ein Thema von Atlunch · begonnen am 8. Mai 2017 · letzter Beitrag vom 13. Mai 2017
 
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
778 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Sobel Normalisierungsschritt

  Alt 8. Mai 2017, 22:03
Hallo Atlunch,

da der von mir verlinkte Code auf DP bei mir nicht funktioniert und zudem etwas langsam ist, habe ich hier rasch einen "Sobelcode" geschrieben. [Man könnte den Code - auch ohne asm - noch optimieren. Siehe Link "Sperarierbarkeit" https://de.wikipedia.org/wiki/Sobel-Operator Für ein 1150x1150 Bild werden auf meiner langsamen Kiste nur 65ms benötigt.]

Dieses Beispiel funktioniert für Graustufenbilder. Den Vorprozess für "Farbbilder als Quelle", hast du ja sicher bereits.

Im Beispiel unten nutze ich für jedes Bild den ganzen Graustufenraum [0..255], indem ich mir den maximalen Gradient merke und diesem 255 zuweise (für den minimalen Wert nehme ich 0 an, da es praktisch in jedem Bild einen Punkt mit 8 Umgebungspixel mit Ableitung 0 gibt). Falls dein Grafiksystem mehr Grauwerte hergibt, dann kannst du den Code (siehe //normieren) leicht anpassen.

Wenn du mehrere "Sobelbilder" miteinander vergleichen möchtest, dann willst du pro Bild eventuell nicht den gesamten Graustufenraum ausnutzen [damit du Unterschiede erkennen kannst]. In diesem Fall müsstest du berechnen wie gross g^2 = gx^2+gy^2 werden kann. Ich glaube du kannst dir überlegen, dass zum Beispiel folgendes Umgebungspixel-Muster maximales g liefert:

Delphi-Quellcode:
Für gx:
S - W
S - W
S - W

Für gy:
S S S
- - -
W W W
Für den Punkt unten links könnte a=W oder a=S oder ein Zwischenwert gut sein, für den Punkt oben rechts könnte b=S oder b=W oder ein Zwischenwert optimal sein.

Du hast also eine Funktion g(a,b), welche du maximieren musst. Zwei Lösungen: 1. a=W und b=S und 2. a=S und b=W

Wenn ich richtig gerechnet habe ist max(g^2) = 1300500 oder max(g) = 1140.4.
Du müsstest als g normieren mittels norm(g) = g*256 div 1141, um Werte zwischen 0 und 255 zu erhalten.

Falls ich mich verrechnet habe, dann möge man diese Meldung für immer löschen .


Hier der Sobelcode mit Ausnutzung des ganzen Graustufenbereichs
(Wie erwähnt könntest du auch gnorm := (grauwerte[x,y] shl 8) div 1141 verwenden.)

Delphi-Quellcode:
type
  TRGB32 = packed record
    B, G, R, A: Byte;
  end;
  TRGB32Array = packed array[0..0] of TRGB32;
  PRGB32Array = ^TRGB32Array;

procedure SobelSL_GRAU( graubit , sobelbit : TBitMap );
var gnorm, ming, maxg, gw, g, gx, gy, x, y : integer;
    Line_m1, line, line_p1 : PRGB32Array;
    grauwerte : array of array of integer;

begin
  ming := maxint;
  maxg := 0;

  setlength( grauwerte, graubit.Width, graubit.Height );

  for y := 1 to graubit.height-2 do
  begin
      line_m1 := graubit.ScanLine[y-1];
      line := graubit.ScanLine[y];
      line_p1 := graubit.ScanLine[y+1];

      for x := 1 to graubit.Width-2 do
      begin
          gx := -line_m1[x-1].R - 2*line[x-1].R - line_p1[x-1].R
                +line_m1[x+1].R + 2*line[x+1].R + line_p1[x+1].R;

          gy := -line_m1[x-1].R - 2*line_m1[x].R - line_m1[x+1].R
                +line_p1[x-1].R + 2*line_p1[x].R + line_p1[x+1].R;

          g := round(sqrt( gx*gx + gy*gy ));

          if g > maxg then maxg := g;
          if g < ming then ming := g;
          grauwerte[x,y] := g;
      end;
  end;

  // normieren:
  for y := 1 to graubit.height-2 do
  begin
      line := sobelbit.ScanLine[y];
      for x := 1 to graubit.Width-2 do
      begin
        gnorm := (grauwerte[x,y] shl 8) div maxg;
        if gnorm=256 then gnorm := 255;
        line[x].R := gnorm;
        line[x].G := gnorm;
        line[x].B := gnorm;
      end;
  end;
end;


procedure SobelFromFile( const fileQuelle, fileZiel : string );
var quelle, ziel : TBitMap;
begin
      quelle := TBitMap.Create;
      ziel := TBitMap.Create;
    try
      quelle.LoadFromFile( fileQuelle );
      quelle.PixelFormat := pf32bit;

      ziel.PixelFormat := pf32bit;
      ziel.SetSize( quelle.Width, quelle.Height );

      SobelSL_GRAU( quelle, ziel );
      ziel.SaveToFile( fileZiel );
    finally
      quelle.Free;
      ziel.Free;
    end;
end;
Michael Gasser

Geändert von Michael II ( 9. Mai 2017 um 00:10 Uhr)
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz