Registriert seit: 23. Jan 2008
3.686 Beiträge
Delphi 2007 Enterprise
|
AW: Canny edge algorithmus und Sobel Matrix
28. Jul 2014, 02:38
Zwar sehen deine "gesobelten" Bilder in der Tat etwas komisch aus (eher wie kontrastverminderte und teilinvertierte Versionen des Originals), aber ich sehe ein großes Problem bei deiner Vorgehensweise: Du nutzt als Zwischenspeicher für deine Schritte immer ein TBitmap. Du brauchst aber auch die negativen Werte der Sobel-Komponenten um nachher die korrekten Magnituden und Richtungen zu berechnen, da kommst du nicht drum rum!
Ich hatte für mein Programm damals eine eigenen FloatBitmap Klasse gemacht, und habe diese für sämtliche Operationen genutzt - ausser Laden und Speichern, dafür konnte diese Klasse ein .CreateFromBitmap() und ein .ToBitmap() durchführen. Ich habe die Bilder darin, also zumindest die, die zur Darstellung genutzt wurden, auf die Range 0..1 skaliert, und alle Farbkomponenten als Single hinterlegt. (Hatte auch den Hintergrund, dass ich das nachher so umgebaut habe, dass Gauss und Sobel in einem Shader von der Graka gemacht wurden, wo man das eh so braucht.)
Für die Farben hatte ich eine eigene FloatColor Klasse, die Methoden wie .ToYCC() und .ToRGB() oder .ToColor() gleich mit gebracht hat. Das FloatBitmap hat davon einfach ein 2D Array verwaltet, und ein paar Methoden zum Umwandeln eben.
Nutzt man sowas als "Mittler" zwischen den Schritten, sind Negative Farben und denormalisierte "Bilder" kein Problem mehr (streng genommen sind es ja schon fast keine Bilder mehr dann). Das würde ich als aller erstes machen, und dann mal schauen wie es danach aussieht.
Sowohl die Normaierung auf 0..1, als auch die deutlich erhöhte Genauigkeit durch Floats sind gerade bei den Zwischenschritten zum einen eine Vereinfachung, und das Zweite je nach Anwendungsfall schon fast eine Notwendigkeit finde ich. Wenn die Geschwindigkeit nicht hin haut, könnte man auch noch mit auf Integer-Range skalierten Farben arbeiten, muss dann aber aufpassen mit Ausreissern in den Zwischenschritten die wie beim Sobel dann auch mal über "1" (bzw. MaxInt) liegen können. Und es ist eine ziemliche Rumrechnerei. Wenn wirklich sehr schnelle Verarbeitung sein soll, würde ich letztlich wieder zum Shader greifen. Da das aber eine ganze Ecke Infrastruktur und potenziell Anpassungen im gesamten Programm braucht wenn man es nicht von Anfang an darauf ausgelegt hat, will ich das nicht uneingeschränkt als Heiland preisen.
Aber deine negativen Werte brauchst du. Definitiv. Wenn du die Zwischenschritte anzeigen willst, würde ich dafür das FloatBitmap von (-1..1) auf (0..255) mappen, und Werte unter/über -1/1 clampen. Dann bleibt genügend "Kontrast" um vernünftig was sehen zu können. (Diese Bilder taugen dann aber nicht mehr wirklich zum weiter damit arbeiten, nur zur Kontrollanzeige.)
"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)
|