WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Prewitt, Sobel, Kompass: händische Implementierung

 

strobl_erwin
Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 14.04.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 15.04.2009, 13:13     Titel: Prewitt, Sobel, Kompass: händische Implementierung
  Antworten mit Zitat      
Liebe Matlab-User!

Ich selbst bin kein guter Matlab-Programmierer und ich benötige Matlab zur Bildbearbeitung. Ich brauche dringend eure Hilfe, um ein Problem zu lösen.

Ich habe eine Grafik mit einer gewissen Größe. Und ich möchte für diese Grafik drei Kantendetektoren verwenden, zum einen den Sobel, zum anderen den Prewitt und zum dritten den Kompass-Kantendetektor, der eine Vereinigung von Prewitt und Sobel darstellt.

Ich will jetzt aber nicht die Kantendetektoren mithilfe des Befehles imfilter anwenden, sondern den Filter selbst Zeile für Zeile, bzw. Spalte für Spalte implementieren mithilfe eines Kantenkernes als Matrix. Leider darf ich die Befehle imfilter (zum Anwenden) und fspecial (zum Definieren) nicht verwenden.

Wie kann ich jetzt die Filter selbst implementieren? Wie kann ich den Filter über jedes Pixel legen, und zwar Zeile für Zeile, bzw. Spalte für Spalte?
Den relevanten Codeteil der Faltung habe ich, nur leider verstehe ich es überhaupt nicht, was genau damit gemeint ist. Jedoch habe ich einiges doch entziffern können. Vielleicht könnt ihr mir helfen, die gesamte Funktion zu verstehen.

for cols = 1 : sizeHor
for rows = 1: sizeVer
Ausgangsmatrix (rows + NachbarRangeS, cols + NachbarRangeS) = sum(sum(Eingangsmatrix(rows: (rows +(fZeilen-1)), cols: (cols + (fSpalten-1))), .* Kern));
end
end

Jetzt einige Erklärungen:
sizeHor ist die horizontale Größe des Bildes
sizeVer die vertikale
cols sind die Spalten, rows die Reihen
NachbarRangeS ist die Größe des Kantenkerns. Wenn man einen Kern mit Größe 3x3 hat, dann ist die NachbarRangeS immer der Abstand zwischen Kern und Rand des gesamten Filters, also in diesem Fall genau ist. Bei 5x5 wäre es genau 2.
In fSpalten, bzw. fZeilen stehen die Größe des Kernes, die sich folgendermaßen ergibt: [fZeilen,fSpalten]=size(Kern)
Der Kern ist eine Matrix, die man definieren kann wie man will.
Die Randbehandlung des Bildes darf beliebig sein, und man kann diese Schleife auf jedes Bild mit Kanten anwenden. Es soll als Ergebnis ein neues Bild entstehen, in dem die Kanten sichtbar werden, jedoch das eigentliche Bild verschwindet. Das Ergebnis müsste ungefähr gleich sein, wenn ihr es mittels fspecial und danach mit imfilter probiert. Aber das darf ich leider nicht machen.

Ich brauche dringend eure Hilfe und bitte euch, alles, was ihr versteht hier zu posten, ich schaffe sonst diese händische Implementierung nicht. Bitte dringend um eure Hilfe.
Wenn ihr zufällig m-Files habt oder gemacht habt über dieses Thema, hängt es hier an, ich bin über jede Unterstützung glücklich!

Danke im Vorraus.
Erwin
Private Nachricht senden Benutzer-Profile anzeigen


Maddy
Ehrenmitglied

Ehrenmitglied



Beiträge: 494
Anmeldedatum: 02.10.08
Wohnort: Greifswald
Version: ---
     Beitrag Verfasst am: 15.04.2009, 16:25     Titel:
  Antworten mit Zitat      
ich versteh zwar nicht warum ihr extra eine For-Schleife nutzen sollt, weil sich eigentlich der conv2 befehl anbietet, aber nun gut:
Code:

Eingangsmatrix(rows: (rows +(fZeilen-1)), cols: (cols + (fSpalten-1))), .* Kern
 


Dieser Abschnitt sagt nichts weiter, als das dabei ein Ausschnitt der Eingangsmatrix (also des Original-Bildes) genauso groß wie der Kern mit dem Kern selbst elementweise multipliziert wird.

Beispiel: Kern 5x5 Matrix Zeile 10 Spalte 12


Code:

Eingangsmatrix(10:14,12:16).*Kern
 


Die beiden sum's addieren dann einfach alle 25 Elemente auf und man erhält einen Wert, welcher an die entsprechende Stelle in der Ausgangsmatrix geschrieben wird.

Die beiden for-Schleifen machen dies dann quasi für jede Position.

Das Einzige was du jetzt noch tuen musst ist den Kern zu definieren, also eine Matrix, die zum beispiel dem Sobel-Operator entspricht .

Meine Prof. hat das damals in seiner Vorlesung schön erklärt:

http://www2.physik.uni-greifswald.d.....bbert/bildver/bildver.pdf
(Seite 98 findest du den Sobel)
_________________

>> why
The computer did it.
Private Nachricht senden Benutzer-Profile anzeigen
 
strobl_erwin
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 14.04.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 15.04.2009, 16:50     Titel:
  Antworten mit Zitat      
Danke für deine Antwort. Jetzt brauche ich nur noch eine Hilfe:

Kannst du mir die Kerne schreiben, wie ich sie als Matrix definiere? Ist es richtig, dass ich für die vertikale, bzw. horizontale Kantenextraktion verschiedene Kerne verwenden muss?

Wie wende ich den Kompass-Filter dann an? Wie kann ich z.B. den Kompass-Filter für 0°, 45°, 90° und 135° einsetzen? Bitte hierin noch um Unterstützung.

Vielen Dank nochmals! Habe die For-Schleife jetzt verstanden. Ich darf den Befehl conv2 nicht verwenden.

Danke, Erwin
Private Nachricht senden Benutzer-Profile anzeigen
 
strobl_erwin
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 14.04.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 15.04.2009, 16:58     Titel:
  Antworten mit Zitat      
Ach ja, und noch etwas: Wenn ich jetzt z.B. Zeile 1 habe, wie kann ich in Matlab die Anzahl der Grauwerte errechnen? Natürlich, ich kann natürlich auch sehen, dass das Bild z.B. eine Pixelbreite von 178 Pixel hat, aber gibt es in Matlab auch irgendeine Möglichkeit, die Anzahl von Werten in einer Zeile zu berechnen?
Private Nachricht senden Benutzer-Profile anzeigen
 
Maddy
Ehrenmitglied

Ehrenmitglied



Beiträge: 494
Anmeldedatum: 02.10.08
Wohnort: Greifswald
Version: ---
     Beitrag Verfasst am: 15.04.2009, 17:18     Titel:
  Antworten mit Zitat      
Um vertikale Kanten zu finden musst du horizontal ableiten und für horizontale Kanten vertikal, d.h. 2 unterschiedliche Kerne musst du verwenden. Die Grundform der Matrizen findest du ebenfalls im obigen Link.

z.B. Sobel 3x3

Code:

Kern=[1 0 -1; 2 0 -2; 1 0 -1]./4; % horizontaler Sobel-Filterkern


Die Kompass-Filterung ist etwas schwerer zu entwerfen, aber vom Prinzip zeichnest du im Kern eine Linie mit Nullen, die einen entsprechenden Winkel zur x-Achse hat und oberhalb und unterhalb der Linie schreibst du Einsen bzw. Minus Einsen (auch andere Werte als 1 möglich, einfach mal Googlen nach "Sobel, Kompass Filter")

Zur letzten Frage müsstest du nochmal präzise sagen was du meinst:
Die Größe einer Matrix bestimmst du mit size, ansonsten weiß ich nicht genau was du meinst.
_________________

>> why
The computer did it.
Private Nachricht senden Benutzer-Profile anzeigen
 
strobl_erwin
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 14.04.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 15.04.2009, 17:48     Titel:
  Antworten mit Zitat      
Ok, das mit dem Winkel habe ich jetzt verstanden. DAs wird dann halt zwar komplex, aber es ist richtig.

Bzgl. der Frage, die du nicht verstanden hast: Wenn ich eine Grafik habe, die eine Größe von 50 x 70 hat, dann hat diese Grafik 50 Zeilen und 70 Spalten, das heißt, in Zeile 1 gibt es 70 Pixel, somit hat die Zeile eine Anzahl von 70 Pixelwerten.

Wie kann ich jetzt in Matlab definieren, dass ich genau diese Anzahl der vertikalen Grauwerte bekomme? Mache ich das so:

A = Bild (1, Smile; % so stelle ich die 1. Zeile des Bildes dar %
S = size (A); % hier zeigt er mir in einer 1x2 Matrix, also (1, 70), wenn wir das oben genannte Bild als Beispiel nehmen %
sizeVer = S (1,2); % jetzt zeigt er mir genau diesen 2. Wert als die Zahl 70, und somit habe ich die horizontale Größe des Bildes %

Ist das zu umständlich oder gibt es auch eine bessere Variante?

Und jetzt noch abschließend: Wenn ich den Kern, die fZeilen und sizeHor und sizeVer definiert habe, wie kann ich die Matrix genau in Matlab eingeben, dass ich dann am Ende sagen kann

imshow (Ausgangsmatrix);

sodass ich genau das gefilterte Bild bekomme? Oder muss ich da noch irgendetwas ändern?
Könntest du es bei dir selbst ausprobieren? Würde mir wirklich immens helfen! Du tätest mir wirklich einen großen Gefallen!

Vielen Dank, Erwin
Private Nachricht senden Benutzer-Profile anzeigen
 
Maddy
Ehrenmitglied

Ehrenmitglied



Beiträge: 494
Anmeldedatum: 02.10.08
Wohnort: Greifswald
Version: ---
     Beitrag Verfasst am: 15.04.2009, 18:18     Titel:
  Antworten mit Zitat      
Du solltest die code-Umgebung des Forums nutzen, dann ärgern dich die smilies nicht.

Code:
[sizeVer sizeHor]=size(Eingangsmatrix);


Wenn du alles vordefiniert hast, musst du nur noch das Bild einlesen mit:

Code:
Eingangsmatrix=imread('test.jpg');
Eingangsmatrix=double(Eingangsmatrix); % um sicher zu gehen, dass die Zahlen als double in der Matrix gespeichert sind


und dann die Schleife drüber laufen lassen und mit

Code:
imshow(Ausgangsmatrix)


sollte das gefilterte Bild erscheinen
_________________

>> why
The computer did it.
Private Nachricht senden Benutzer-Profile anzeigen
 
strobl_erwin
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 14.04.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 15.04.2009, 21:14     Titel:
  Antworten mit Zitat      
Noch eine Frage: Wie kann ich sinnvoll die NachbarRangeS definieren, und wenn möglich allgemein, damit es für jeden Kern gelten kann? Ich weiß nämlich nicht, wie ich ich das allgemein anschreiben kann.

Danke für deine Hilfe!
Erwin
Private Nachricht senden Benutzer-Profile anzeigen
 
Maddy
Ehrenmitglied

Ehrenmitglied



Beiträge: 494
Anmeldedatum: 02.10.08
Wohnort: Greifswald
Version: ---
     Beitrag Verfasst am: 15.04.2009, 22:41     Titel:
  Antworten mit Zitat      
Die Hälfte von der Kantenlänge des Kerns nach oben runden, also:

Code:

_________________

>> why
The computer did it.
Private Nachricht senden Benutzer-Profile anzeigen
 
strobl_erwin
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 14.04.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 15.04.2009, 22:55     Titel:
  Antworten mit Zitat      
Jetzt kommt aber noch eine Fehlermeldung, wenn ich den Code jetzt eintippe:

Error: Unbalanced or unexpected parenthesis or bracket.

Und es schreibt die ganze Zeile mit der Ausgangsmatrix ab und macht einen geraden Strich genau unter der Klammer nach Kern.

Was soll ich tun?
Private Nachricht senden Benutzer-Profile anzeigen
 
Maddy
Ehrenmitglied

Ehrenmitglied



Beiträge: 494
Anmeldedatum: 02.10.08
Wohnort: Greifswald
Version: ---
     Beitrag Verfasst am: 15.04.2009, 22:58     Titel:
  Antworten mit Zitat      
Das was da steht: die Anzahl der geöffneten und geschlossenen Klammern überprüfen und auf die richtige Anzahl anpassen. Smile
_________________

>> why
The computer did it.
Private Nachricht senden Benutzer-Profile anzeigen
 
strobl_erwin
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 14.04.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 15.04.2009, 23:08     Titel:
  Antworten mit Zitat      
Gut, das mit den Klammern ist Geschichte.

Doch was tue ich, wenn da steht:
??? Index exceeds matrix dimensions.

Lg Erwin
Private Nachricht senden Benutzer-Profile anzeigen
 
Maddy
Ehrenmitglied

Ehrenmitglied



Beiträge: 494
Anmeldedatum: 02.10.08
Wohnort: Greifswald
Version: ---
     Beitrag Verfasst am: 15.04.2009, 23:31     Titel:
  Antworten mit Zitat      
Englisch ist nicht so deine Stärke oder? Wink

Das heißt, dass die verwendeten Indizes größer als die eigentliche Matrix sind.

ich vermute mal das kann man mit den Laufvariablen der Schleife hinbiegen:

Code:

for cols = 1 : sizeHor-length(Kern)
for rows = 1: sizeVer-length(Kern)
 


Hilfreich wäre es, wenn du mal den jetzt verwendeten Code hier postest. Smile
(Bitte an die Code-Umgebung denken! Oben mittig beim Erstellen eines Beitrages)
_________________

>> why
The computer did it.
Private Nachricht senden Benutzer-Profile anzeigen
 
strobl_erwin
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 14.04.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 15.04.2009, 23:46     Titel:
  Antworten mit Zitat      
Englisch kann ich schon, aber nicht so gut.

Mein Code lautet:
for cols = 1 : sizeHor-length (PrewittHor)
for rows = 1 : sizeVer-length (PrewittHor)
Ausgangsmatrix (rows + NachbarRangeS, cols + NachbarRangeS) = sum(sum(LWS(rows: (rows + (fzeilen - 1)), cols: (cols + (fspalten - 1)) .* PrewittHor)));
end
end

LWS ist die Eingangsmatrix, PrewittHor ist der Kern.

Leider kommt bei mir da ein völlig falsches Bild (ist im Anhang).

Was hast du da mit length gemacht?

Bild.jpg
 Beschreibung:

Download
 Dateiname:  Bild.jpg
 Dateigröße:  18.55 KB
 Heruntergeladen:  899 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
Maddy
Ehrenmitglied

Ehrenmitglied



Beiträge: 494
Anmeldedatum: 02.10.08
Wohnort: Greifswald
Version: ---
     Beitrag Verfasst am: 16.04.2009, 01:07     Titel:
  Antworten mit Zitat      
Bitte den vollständigen Code, also so dass man ihn ausführen kann und an die Code-Umgebung denken.
_________________

>> why
The computer did it.
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen

Gehe zu Seite 1, 2  Weiter

Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.