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

Schwellwertbasierte Teilmatrix

 

Buhmann
Forum-Anfänger

Forum-Anfänger



Beiträge: 30
Anmeldedatum: 25.05.11
Wohnort: ---
Version: R2012b
     Beitrag Verfasst am: 25.01.2012, 11:22     Titel: Schwellwertbasierte Teilmatrix
  Antworten mit Zitat      
Hallo zusammen!

(ja, ich habe schon gegoogelt Wink)

Eigentlich bezieht sich die Frage auf die Bildverarbeitung, da es sich aber um eine normale Matrixoperation handelt, hab ichs mal hierrein gepostet:

Ich habe eine Matrix A und möchte möglichst effizient alle Werte größer (oder kleiner) als Schwellwert t in (der gleichdimensionalen) Matrix B speichern. Ich möchte dies nicht so stumpf lösen, wie es das folgende Beispiel zeigt:

Code:

A = magic(5);
B = zeros(5);
t = 10;
for i=1:size(A,1)
    for j=1:size(A,2)
        if A(i,j) > t
            B(i,j) = A(i,j);
        end
    end
end
 

sondern möchte möglichst elegant mit Matlab-Funktionen lösen. Schließlich ist Matlab auf Matrixoperationen optimiert Smile
Ich habe schon mit logischen Operationen rumgespielt, aber fand es dann doch umständlich, auch noch eine Boolean-Matrix mit einzubeziehen...

Kann mir da jemand etwas zu sagen?
Oder sind die in Matlab eingebauten Matrixfunktionen in sich auch nur schleifenbasiert?

LG
Buhmann
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden


denny
Supporter

Supporter



Beiträge: 3.853
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2012b
     Beitrag Verfasst am: 25.01.2012, 12:40     Titel:
  Antworten mit Zitat      
Hallo

hier geht es über Logische Operationen:
Code:


A = magic(5);
B = zeros(size(A));
t  = 10;
B(A>t)=A(A>t)
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Buhmann
Themenstarter

Forum-Anfänger

Forum-Anfänger



Beiträge: 30
Anmeldedatum: 25.05.11
Wohnort: ---
Version: R2012b
     Beitrag Verfasst am: 26.01.2012, 08:38     Titel:
  Antworten mit Zitat      
Hui, das ging ja schnell, vielen Dank.
Ich hatte die binären Operatoren so verwendet, dass ich nur eine boolesche Matrix rausbekam, die ich so nur sehr umständlich verwenden konnte. Gut zu wissen, dass man den Ausdruck auch ins "Argument" der Matrix schreiben kann.

Vielleicht kannst du mir dann auch ganz schnell bei einem anderen Problem helfen, das damit zusammenhängt:

Ich habe nämlich ein Image (640x480 px² 8-bit), das ich filtern möchte. Ich schaue mir für jedes Pixel die neighborhood an (5x5 oder 7x7) und möchte, dass entsprechend eines structuring elements (z.B. disk) alle Pixel den geringsten Grauwert innerhalb des SE bekommen. Ich habe dazu kein Filter in der Image Procession TB gefunden, dass das Problem lösen könnte, deshalb hab ich's (wohl sehr umständlich) mit Schleifen gelöst.
Ich multipliziere hier die neighborhood mit einem selbstgebauten SE, so dass die unerwünschten "eckenpixel" durch einen hohen Wert in der min()-Funktion nicht zum Tragen kommen.

Code:

function imgOut = floorfilter(imgIn,n)
    side = (n-1)/2;
    imgOut = zeros(size(imgIn));
    senhood = uint8(254.*~getnhood(strel('disk',side,0))+ones(n));
    for x = 1+side:size(imgIn,1)-side
        for y = 1+side:size(imgIn,2)-side
            tileIn = imgIn(x-side:x+side,y-side:y+side);
            imgOut(x,y) = min(min(senhood .* tileIn));
            %imgOut(x,y) = min(min(tileIn));    % "square"
        end
    end
    imgOut = uint8(imgOut);
end
 


Kann man das so machen oder geht das prinzipiell auch einfacher? (Die Laufzeit dieses Konstrukts ist nicht die beste...)
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
denny
Supporter

Supporter



Beiträge: 3.853
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2012b
     Beitrag Verfasst am: 26.01.2012, 13:24     Titel:
  Antworten mit Zitat      
Hallo

hallo, weiß ich nicht ob es noch verbessern kann

aber so:

Code:

function imgOut = floorfilter(imgIn,n)
    side = (n-1)/2;
    imgOut  = zeros(size(imgIn),'uint8');
    senhood = getnhood(strel('disk',side,0));
    for x = side+1 : size(imgIn,1)-side
        for y = side+1 : size(imgIn,2)-side
            tileIn      = imgIn(x-side:x+side,y-side:y+side);
            imgOut(x,y) = min(tileIn(senhood));
            % imgOut(x,y) = min(min(tileIn));    % "square"
        end
    end
%     imgOut = uint8(imgOut);
end
 
 
Private Nachricht senden Benutzer-Profile anzeigen
 
denny
Supporter

Supporter



Beiträge: 3.853
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2012b
     Beitrag Verfasst am: 27.01.2012, 16:47     Titel:
  Antworten mit Zitat      
Hallo

Hast du dir COLFILT und NLFILTER schon mal angeschaut?

Code:

 I = imread('cameraman.tif');
figure; imshow(I); title('Blurred Image');
I2 = colfilt(I,[5 5],'sliding',@min);
figure; imshow(I2); title('Blurred Image');
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Buhmann
Themenstarter

Forum-Anfänger

Forum-Anfänger



Beiträge: 30
Anmeldedatum: 25.05.11
Wohnort: ---
Version: R2012b
     Beitrag Verfasst am: 28.01.2012, 12:42     Titel:
  Antworten mit Zitat      
Hm, hab mir die Funktionen mal angesehen. Die könnten mir zwar beide die FOR-Schleifen ersparen, nicht aber die Multiplikation mit dem modifizierten SE. Das müsste ich dann in der Funktion fun machen:
Code:

B = nlfilter(A, [m n], fun)
 

Ich werde mal beide Funktionen ausprobieren, und statt COLFILT auch mal die manuelle Kombination von IM2COL, meiner funktion, COL2IM ausprobieren (dann ohne padding des Randes).

Danke für die Denkanstöße!

Es gibt so viele Funktionen, die man nicht kennt, und auf die man bei der Recherche auch nicht direkt stößt...
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
Buhmann
Themenstarter

Forum-Anfänger

Forum-Anfänger



Beiträge: 30
Anmeldedatum: 25.05.11
Wohnort: ---
Version: R2012b
     Beitrag Verfasst am: 28.01.2012, 13:53     Titel:
  Antworten mit Zitat      
OK, siehe Ergebnis:

ursprüngliche Funktion:
Code:

>> tic;floorfilter(imread('g2.png'),3);toc
Elapsed time is 1.458285 seconds.
 

mit NLFILTER:
Code:

>> tic;floorfilterNL(imread('g2.png'));toc
Elapsed time is 17.304658 seconds.
 

mit
Code:

function imOut = floorfilterNL(imgIN)
    SE = uint8(254.*~getnhood(strel('disk',1,0))+ones(3,3));
    SEmin = @(inpuTile) min(min(inpuTile.*SE));
    imOut = nlfilter(uint8(imgIN),[3 3],SEmin);
end
 


Die "Applying neighborhood operation" dauert sehr lange...

COLFILT bringt mir in meinem Falle nichts, da ja die Matrix in Blöcke unterteilt wird und diese Blöcke dann (reshaped into columns) die Spalten der neuen temporären Matrix bilden, auf die ich FUN anwende. Daher gibt es für mich keine Möglichkeit, das Aussehen der Blöcke zu verändern, es sei denn, ich patche im2col.m, so dass die Funktion auf meine Bedürfnisse passt...
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
denny
Supporter

Supporter



Beiträge: 3.853
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2012b
     Beitrag Verfasst am: 29.01.2012, 09:22     Titel:
  Antworten mit Zitat      
Hallo

oben habe, ich dir bereits gezeigt wie du deine Funktion verbessern kannst

Du hast recht man kann IM2COL für deine Bedürfnisse gut anpassen, und zwar so:
Code:

function imOut = floorfilterIM2COL(imIN,n)
side   = (n-1)/2;
SE     =    getnhood(strel('disk',side,0));
[j,k]  = size(imIN);
imOut  = im2col(imIN,[3 3],'sliding');
imOut  = reshape(min(imOut(SE(:),:)),j-n+1,k-n+1);
end
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Buhmann
Themenstarter

Forum-Anfänger

Forum-Anfänger



Beiträge: 30
Anmeldedatum: 25.05.11
Wohnort: ---
Version: R2012b
     Beitrag Verfasst am: 29.01.2012, 21:53     Titel:
  Antworten mit Zitat      
Supi, die Lösung mit IM2COL ist wesentlich flotter.

Versteh ich das richtig, dass IM2COL in deiner Lösung aus imIN eine Matrix mit [Blöcke] Spalten und [SE-Elemente] Zeilen erstellt, und dass durch die SE(Smile-Maskenspalte die nicht interessierenden Eckelemente unterdrückt werden?
Das heißt also, dass die Informationen, die ich haben will, letztendlich nach dem Aufruf von IM2COL in den Zeilen 2, 4, 5, 6, 8 stecken. D.h. Zeilen 1, 3, 7, 9 werden aus der Matrix rausgelöscht und anschließen wird diese dann reshaped, richtig?
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
denny
Supporter

Supporter



Beiträge: 3.853
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2012b
     Beitrag Verfasst am: 30.01.2012, 11:03     Titel:
  Antworten mit Zitat      
Ja, das ist fast richtig, sie werden nicht rausgelöscht, sondern ich extrahiere nur die Zeilen, an der Stellen von SE ungleich Null ist. Und dann wird MIN gebildet
Private Nachricht senden Benutzer-Profile anzeigen
 
Buhmann
Themenstarter

Forum-Anfänger

Forum-Anfänger



Beiträge: 30
Anmeldedatum: 25.05.11
Wohnort: ---
Version: R2012b
     Beitrag Verfasst am: 30.01.2012, 19:17     Titel:
  Antworten mit Zitat      
Ja, natürlich werden sie nicht gelöscht. Hab mich dumm ausgedrückt Smile
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
Neues Thema eröffnen Neue Antwort erstellen



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 - 2025 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.