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
Antwort Antwort
BrightAngel

Registriert seit: 13. Mär 2007
130 Beiträge
 
#1

AW: Sobel Normalisierungsschritt

  Alt 13. Mai 2017, 11:48
Hallo zusammen

Tut mir leid, wenn ich jetzt auch noch Unruhe stifte und mitmischen möchte
Kann mir einer erklären wie ich von einem bestimmten G Wert in den Wertebereich 0 - 255 komme?
Kurz: Da beide Wertebereiche als Untergrenze 0 haben, musst du nur durch die Obergrenze des bestimmten G-Wertebereich teilen und mit der Obergrenze gewünschten Wertebereichs (255) multiplizieren.

Falls das Folgende für mehr Verwirrung sorgt, als dass es hilft, dann bitte ich darum diesen Post einfach zu ignorieren Ich fange nochmal an jeden einzelnen Schritt zu beleuchten, um ganz explizit die Wertebereiche zu nennen. Danach gehe ich auf die Normierung ein. Ich nehme vereinfachend an, dass Quell- und Zielvariablen immer 8 Bit Auflösung halten und die tatsächlichen Wertebereiche dazwischen, also im Intervall [0, 255] variieren. Auch wenn ich nur auf den 3x3 Bildkernel eingehe, so lässt sich das Prinzip auf andere (größere) Kernel anwenden.

Stichwort Bildkernel: Bei vielen Bildkerneln werden die Summe der Einträge (sprich die Faktoren mit denen die einzelnen Pixel multipliziert werden) im Bildkernel normalerweise so skaliert, dass die Zielintervalle wieder voll abgedeckt werden. (Beispiel: 3x3 Einheitsmatrix würde durch 3 geteilt, da das Maximum Spur(I) = 3*255 auf das Zielinterval [0, 255] gebracht werden sollen).
Beim (separierten) Sobelfilter fällt auf, dass die Kernel (hier nur der X-Achsenkernel)
Code:
[[ +1, 0, -1],
 [ +2, 0, -2],
 [ +1, 0, -1]]
so gebaut sind, dass sich die "Seiten" gegenseitig aufheben, wenn beide Spalten identisch sind (also die "übliche" Skalierung auf Eins nicht erfolgt!). Das ist bewusst so gewählt (weil das eben grade den Gradienten im Diskreten darstellt). Das impliziert nun aber Folgendes für den 3x3 Kernel in Anwendung:
Max(SobelX(P)) = 4*255 = 1020 & Min(SobelX(P)) = -4 * 255 = -1020 , wobei SobelX(P) die Anwendung des Sobelfilters um die Pixelumgebung des Punktes P bedeutet (SobelY analog).

Würden wir auf den entstandenen Wertebereich [-1020, 1020] jetzt in ein 8 Bit Graustufenbild schreiben wollen (hypothetisch), müssten wir also auf 0 verschieben und skalieren: Pixel[P] = round((SobelX(P) + 1020) / 2040 * 255) . Jetzt haben wir den Wertebereich auf das Intervall [0, 255] gebracht.

Da wir die Ergebnisse von X und Y Achse aber richtungsunabhängig kombinieren und dabei quadrieren, entfallen die negativen Intervallabschnitte und es bildet sich das Zielintervall wie folgt: Sobel(P) = sqrt(SobelX(P) * SobelX(P) + SobelY(P) * SobelY(P)) , wobei das Maximum wieder Max(Sobel(P)) = sqrt(1020^2 + 1020^2) = sqrt(2080800) ≈ 1442.497833620557 ergibt (Genauigkeit wurde so gewählt, dass IEEE754 Double Präzision am Besten ausgereizt wird). Das Minimum ist trivialerweise immer 0. Wir befinden uns jetzt also im Interval [0, 144.497833620557].
Daraus folgt die allgemeine Skalierung für Pixel P: Pixel[P] = round(Sobel(P) / 1442.497833620557 * 255) . Ich runde erst jetzt für maximale Genauigkeit. Somit ist das gewünschte Zielinterval [0, 255] erreicht.

[Edit]
Michael II: Bin jetzt auch bei dir angekommen. Hatte vergessen, dass das Bild ja den beiden Kerneln Abhängigkeiten "aufzwingt". Michael II hat also korrekt gerechnet. Meine Formel oben stimmt trotzdem von der Herleitung, allerdings kann man die Skalierung am Ende besser wählen:
Pixel[P] = round(Sobel(P) / 1140.4 * 255) .
[/Edit]

Das war jetzt mal meine Herleitung zur normalen naiven Berechnung. Korrekturen gerne willkommen.
Jetzt kann man noch das völlig unabhängig betrachtbare Problem der Vorverarbeitung/heuristischen Betrachtung dazuziehen;
Ob du das machen kannst hängt aber komplett von deinem Einsatzzweck ab.
Wenn du weitere Schritte einfügst, die sich auf das ganze Bild beziehen, so wirst du auf jeden Fall einmal mehr durch das Bild durchgehen. Entweder einmal am Anfang, um zu Detektieren oder am Ende beim Schreiben. Ich neige bei zum Beispiel Skalierung auf Maxiumum/Minimum zu ersterem, weil ich mir die Schreibzugriffe auf den Hauptspeicher sparen kann und dann auch auf ein Array mit den Zwischenergebnissen verzichten kann: Anfangs einmal alle Pixel anschauen und Maximum und Minimum in lokaler Variable merken. Die jeweilige Skalierung kann man dann oben in die Formel integrieren (wenn dich das genauer interessiert, kann ich gerne weiterhelfen ). (alternativ würde man beim Lesen schonmal bis zum letzten Schritt berechnen und dann in ein Zwischenzielarray speichern; muss dann aber danach nochmal über alle Werte darüber. Mir fällt grade spontan kein Anwendungsfall ein, bei dem ich das mal präferiert hatte...)

Man kann das Bild auch anderweitig "vorverarbeiten": Es gibt zum Beispiel die Histogrammnormalisierung. Mir hat für meine Anwendungszwecke bisher immer die Maximum/Minimumbetrachtung ausgereicht. Vor allem weil nicht lineares Verzerren manchmal zusätzlich Information auslöscht (wie "stark" war die Kante), wenn sie nicht geschickt angewendet wird.

Gruß, Brighty


Disclaimer: Ich musste leider grade ohne meine Codebasis das aus dem Kopf heraus rekonstruieren. Ganz besonders möchte ich anmerken, dass ich mich zugunsten des Verständnisses dafür entschieden hatte Werte innerhalb der Berechnungen implizit von Flieskomma- und Ganzzahlen zu konvertieren. Obwohl ich die Zahlen nachgerechnet habe, kann es sein, dass ich irgendwo noch etwas vergessen/nicht ganz deutlich in diesem Text herausgearbeitet habe.
Do you have the email of god??? --- I have to tell him that I'm happy to be born!

Geändert von BrightAngel (13. Mai 2017 um 14:03 Uhr)
  Mit Zitat antworten Zitat
Michael II

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

AW: Sobel Normalisierungsschritt

  Alt 13. Mai 2017, 14:11
Hallo Brighty

deine Berechnung ist nicht korrekt.

Du hast übersehen, was ich weiter oben gepostet habe: Gx^2 und Gy^2 können nicht beide gleichzeitig maximal sein.


Noch einmal:

Zitat:
In den folgenden beiden 3x3 Pixelbildern ist S=schwarz=0 und w=weiss=255.

gx wird (wie du korrekt schreibst) maximal, wenn es um Pixel P so aussieht:
S - W
S P W
S - W

gy wird maximal, wenn es um Pixel P so aussieht:
S S S
- P -
W W W
Wie du korrekt feststellst gilt max(gx) = 1020 und für max(gy)=1020. [bzw. min(gx)=-1020, min(gy)=-1020]

Wenn du die beiden 3x3 Pixelbilder oben betrachtest, dann siehst du, dass das Pixel unten links S sein muss für gx maximal und weiss sein muss für gy. Das kann nicht gleichzeitig der Fall sein.
Ebenso für das Pixel oben rechts: Für gx maximal müsste es weiss sein, für gy maximal aber schwarz. Auch das kann nicht gleichzeitig der Fall sein.

(Du nimmst aber in deiner Berechnung an, dass Pixel unten links gleichzeitig schwarz und weiss sein kann. Dito für das Pixel oben rechts: Es kann nicht schwarz und gleichzeitig auch weiss sein. )


=> Du musst also herausfinden für welche Wahl von a und b, der Gradient g^2(a,b) = gx^2(a,b) + gy^2(a,b) maximal wird. (siehe oben)

Zitat:
S S b
S P W
a W W
Wegen deinen Nachkommastellen. Wenn du letztendlich Resultate mit 3 Stellen ermittelst (du ermittelst ja Grauwerte von 0..255), reicht es, wenn deine Zahlen auf insgesamt 4-5 (Vor- und Nachkomma) Stellen genau sind.
Michael Gasser
  Mit Zitat antworten Zitat
BrightAngel

Registriert seit: 13. Mär 2007
130 Beiträge
 
#3

AW: Sobel Normalisierungsschritt

  Alt 13. Mai 2017, 14:50
deine Berechnung ist nicht korrekt.
korrekt!
Du hast übersehen, was ich weiter oben gepostet habe: Gx^2 und Gy^2 können nicht beide gleichzeitig maximal sein.
Wahr. Mir war das kurz vor deinem Post auch aufgefallen. Kennst du das Gefühl was vergessen zu haben? Deswegen saß ich auch so lange in dem Thread Habe es dann noch gekennzeichnet und auf dich verwiesen
[...]
=> Du musst also herausfinden für welche Wahl von a und b, der Gradient g^2(a,b) = gx^2(a,b) + gy^2(a,b) maximal wird. (siehe oben)

Zitat:
S S b
S P W
a W W
Genau und für a = 0 und b = 255 oder umgekehrt ist der Wert eben maximal (=1300500)
Wegen deinen Nachkommastellen. Wenn du letztendlich Resultate mit 3 Stellen ermittelst (du ermittelst ja Grauwerte von 0..255), reicht es, wenn deine Zahlen auf insgesamt 4-5 (Vor- und Nachkomma) Stellen genau sind.
Das ist ein Tick von mir: Für den Rechner macht es keinen Unterschied und ich mag exakte Ergebnisse. Ich weiß nie, ob die Skalierung sich nicht doch mal ändert (weil man vielleicht gar nicht mehr auf 255 skaliert, sondern direkt z.B. in nem Integerarray damit zaubert)

Ich hatte mich vorhin eingemischt, weil ich eigentlich dich nur dazwischen noch durch Erklärungen stützen wollte, und dann kam ich auf ein anderes Ergebnis

Brighty
Do you have the email of god??? --- I have to tell him that I'm happy to be born!
  Mit Zitat antworten Zitat
Michael II

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

AW: Sobel Normalisierungsschritt

  Alt 13. Mai 2017, 15:58
Zitat:
Kennst du das Gefühl was vergessen zu haben? Deswegen saß ich auch so lange in dem Thread Habe es dann noch gekennzeichnet und auf dich verwiesen
Ja dieses Gefühl kenne ich nur allzu gut. Nach meiner Antwort auf deine, dachte ich (als ich draussen die Katze suchte, welche wieder einmal partout nicht reinkommen will, obschon ich für 72h weg müsste und ein Katzentüre fehlt), ich hätte Mist geantwortet und habe gleich noch einmal gerechnet.

Aber es stimmt. Kurz, was man tun muss:

G(a,b) = 2a^2 + 2b^2 - 4ab + 2*765^2 maximieren.

Nun sieht man entweder, dass G(a,b) = 2(a-b)^2 + 2*765^2 und somit (a-b)^2 maximal, wenn a=255, b=0 bzw. a=0, b=255 oder man rechnet:

G abgleitet nach a:
dG(a,b)/da = 4a-4b = 0
und nach b:
dG(a,b)/db = 4b-4a = 0

Also a=b. Nun muss man noch untersuchen, ob man ein Minimum oder ein Maximum getroffen hat. Es ist ein Minimum. Die maximalen Werte für G(a,b) müssen also am Rand von [0..255]x[0..255] liegen. Und man findet leicht nach kurzer Rechnung (oder indem man G(a,b) betrachtet auch ohne ), dass a=255 und b=0 oder umgekehrt maximale Werte für G(a,b) liefert.

Gruss
M
Michael Gasser

Geändert von Michael II (13. Mai 2017 um 19:40 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


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 19:43 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