2013-03-23 9 views
5

Ich habe eine Matrix X, die ein Bild darstellt, das von Rauschen betroffen war. Ich habe auch eine boolesche Matrix M, die darstellt, welche Pixel von Rauschen betroffen waren. Was ich tun möchte, ist, jedes "verdorbene" Pixel auf den Mittelwert seiner acht benachbarten Pixel zu setzen.Wie wird das Matrixelement auf Umgebungselemente gesetzt?

Beschädigte Pixel sind garantiert immer von unverfälschten Pixeln umgeben, und auch keines der Pixel an den Rändern des Bildes ist beschädigt. Mit welcher Funktion kann ich eine vektorisierte Version davon schreiben?

+0

Vielleicht brauchen Sie Median, nicht gemein? Verwende "medfilt2". –

+0

Die Antworten auf diese Fragen - http://stackoverflow.com/questions/1637000/how-to-divide-an-image-into-blocks-in-matlab- werden Sie interessieren. –

+0

@Eddy_Em Es sieht so aus als ob "medfilt2" das tut, was ich will, mit der Ausnahme, dass ich diesen Vorgang nur für bestimmte Pixel machen möchte, nicht für das ganze Bild. –

Antwort

2

Dies ist wahrscheinlich nicht die effektivste Lösung, aber es sollte funktionieren.

N = size(M, 1); 
target_ind = find(M); 
offset = [-N-1, -N, -N+1, -1, 0, 1, N-1, N, N+1]; 

area_ind = bsxfun(@plus, offset, target_ind); 
X(target_ind) = median(X(area_ind), 2); 

Da alle beschädigten Pixel garantiert werden von Pixeln umgeben sein, können wir eher berechnen leicht die lineare Indizes von jedem Nachbarn beschädigt Pixel. Hier habe ich angenommen, dass X ein Graustufenbild ist.

Wenn I mehr als einen Kanal hat, dann könnten wir über jeden Kanal Schleife und fügen Sie ein target_ind und area_ind jedes Mal Offset:

for i = 1:size(X, 3) 
    chan_offset = (i - 1)*size(X, 1)*size(X, 2) % Add the number of elements in previous channels to get indices in the current channel 
    X(target_ind + chan_offset) = median(X(area_ind + chan_offset), 2); 
end 
+0

Ich verstehe, wie das funktioniert, aber ich habe ein kleines Problem, es an RGB-Bilder anzupassen. Offensichtlich muss ich dieses Verfahren dreimal anwenden, einmal für jeden Kanal. Ich habe versucht, 'X (:,:, 1) (target_ind) = ...' zu machen, aber das gibt mir einen Fehler: '() muss gefolgt werden. oder schließe die Indexkette. Wie kann ich das beheben? –

+0

@PaulManta Ich habe meine Antwort bearbeitet, um eine Möglichkeit für die Bearbeitung eines Bildes mit mehreren Kanälen hinzuzufügen. – BjoernH

4

Für Ihre Situation sollte dies durchführen recht schnell

fixed = conv2 (image, [1 1 1; 1 0 1; 1 1 1]/8, "same") 
# mask is a logical matrix for the corrupted pixels 
image(mask) = fixed(mask) 

Erklärung: ein Mittelwertfilter ist mit der conv2 Funktion gemacht. Um den Durchschnitt eines Pixels und seiner Nachbarn zu berechnen, ist der verwendete Kernel ones (3)/9, was bedeutet, dass 1/9 jedes Pixelwerts verwendet wird, um den neuen Wert zu berechnen. Da Sie das mittlere Pixel im Durchschnitt nicht zählen möchten, nehmen Sie seinen Wert 0 (im Kernel) und die anderen auf 1/8.

+0

+1 Sehr schöne Lösung. –

+1

@PaulManta da es scheint, dass Sie mit RGB-Bildern zu tun haben, können Sie 'convn' anstelle von' conv2' verwenden. Sie müssen den Kernel anpassen, aber das Prinzip ist das gleiche. 'Kernel = Nullen (3,3,3); Kernel (:,:, 2) = 1/8; kernel (2,2,2) = 0' – carandraug

+0

Nur ein kleiner typ: 'same' statt 'same': D nur sagend, da könnte es ppl nicht bekommen :) – tim

Verwandte Themen