Bildfilterung in Python

Haben Sie jemals ein lautes Bild gefunden? Ich meine ein Bild, das beim Betrachten nicht so klar war? Ich denke, dass wir solche Bilder sehr oft finden, besonders wenn heutzutage viele Bilder von unseren Handykameras oder Digitalkameras mit niedriger Auflösung aufgenommen werden.

Wenn Sie nur dieses verrauschte Bild hätten, das Ihnen etwas bedeutet, aber das Problem ist, dass es nicht richtig angezeigt werden kann, gibt es eine Lösung, um sich von diesem Rauschen zu erholen?

Hier kommt die Bildfilterung ins Spiel, und ich werde sie in diesem Tutorial beschreiben. Lass uns anfangen!

Bildfilterung

Die Bildfilterung ist ein beliebtes Werkzeug für die Bildverarbeitung. Am Ende des Tages verwenden wir eine Bildfilterung, um Rauschen und unerwünschte Merkmale aus einem Bild zu entfernen, wodurch eine bessere und verbesserte Version dieses Bildes entsteht. Es gibt zwei Arten von Filtern: linear und nicht linear. Beispiele für lineare Filter sind Mittelwert- und Laplace-Filter. Nichtlineare Filter bilden Filter wie Median-, Minimum-, Maximum- und Sobel-Filter.

Jeder dieser Filter hat einen bestimmten Zweck und dient dazu, entweder Rauschen zu entfernen oder einige Aspekte im Bild zu verbessern. Wie wird aber gefiltert? Dies werden wir im nächsten Abschnitt sehen.

Wie führen wir die Bildfilterung durch??

Um eine Bildfilterung durchzuführen, benötigen wir eine Filter, auch a genannt Maske. Bei diesem Filter handelt es sich in der Regel um ein zweidimensionales quadratisches Fenster, dh um ein Fenster mit gleichen Abmessungen (Breite und Höhe).. 

Der Filter enthält Zahlen. Diese Nummern werden angerufen Koeffizienten, und sie bestimmen tatsächlich die Wirkung des Filters und wie das Ausgabebild aussehen wird. Die folgende Abbildung zeigt ein Beispiel von a 3x3 Filter mit neun Werten (Koeffizienten).

Um den Filter anzuwenden, die 3x3 Fenster wird über das Bild geschoben. Dieser Vorgang des Verschiebens eines Filterfensters über ein Bild wird aufgerufen Faltung im räumlichen Bereich. Das Fenster wird auf jedem Pixel im Bild platziert (d. H. Als eine Zelle in einer Matrix betrachtet), wobei die Mitte des Filters das Pixel überlappen sollte. 

Sobald diese Überlappung auftritt, werden die Pixel in dem Unterbild, auf dem sich der Filter befindet, mit den entsprechenden Koeffizienten des Filters multipliziert. In diesem Fall haben wir eine neue Matrix mit neuen Werten, die der Größe des Filters ähnlich sind (d. H. 3x3). Schließlich wird der zentrale Pixelwert durch einen neuen Wert ersetzt, wobei eine spezifische mathematische Gleichung in Abhängigkeit von der Art des verwendeten Filters verwendet wird (d. H. Medianfilter)..

Ich weiß, dass der obige Absatz etwas wortreich ist. Nehmen wir ein Beispiel, um zu zeigen, wie ein Bildfilter in Aktion angewendet wird. Angenommen, wir haben das folgende Unterbild, bei dem sich unser Filter überlappte (ich und j beziehen sich auf die Pixelposition im Unterbild und ich verweist auf das Bild):

Die Faltung unseres Filters, die in der ersten Abbildung mit dem obigen Unterbild dargestellt ist, sieht wie folgt aus I_neu (i, j) repräsentiert das Ergebnis am Ort (i, j).

I_Neu (i, j) = v1 x I (i-1, j-1) + v2 x I (i-1, j) + v3 x I (i-1, j + 1) + v4 x I (i, j-1) + v5 x I (i, j) + v6 x I (i, j + 1) + v7 x I (i + 1, j-1) + v8 x I (i + 1, j) + v9 x I (i + 1, j + 1) 

Der Vorgang wird für jedes Pixel im Bild einschließlich der Pixel an der Bildgrenze wiederholt. Wie Sie sich vorstellen können, befindet sich ein Teil des Filters außerhalb des Bildes, wenn Sie den Filter an den Randpixeln platzieren. In diesem Fall führen wir aus Polsterung

Dieser Prozess bedeutet einfach, dass wir neue Pixelwerte in das Unterbild unter dem Teil des Filters einfügen, der vor dem Faltungsprozess außerhalb des Bildes kommt, da dieser Teil anscheinend keine Pixelwerte enthält. Es ist außerhalb des Bildes! Diese aufgefüllten Pixel können Nullen oder ein konstanter Wert sein. Es gibt andere Methoden zum Festlegen der Auffüllwerte, die jedoch nicht in diesem Tutorial enthalten sind.

Ich denke, das ist genug Theorie für jetzt, also machen wir uns die Hände mit dem Kodieren schmutzig! In diesem Tutorial erkläre ich den Medianfilter (d. H. Nichtlinear) und den Mittelfilter (d. H. Linear) und wie wir sie in Python implementieren können. 

Medianfilter

Im Medianfilter wählen wir ein Schiebefenster, das sich über alle Bildpixel bewegt. Was wir hier tun, ist, dass wir die Pixelwerte sammeln, die unter den Filter fallen, und den Median dieser Werte verwenden. Das Ergebnis wird dem mittleren Pixel zugewiesen. 

Sag unser 3x3 filter hatte die folgenden Werte, nachdem es auf einem Unterbild platziert wurde:

Mal sehen, wie man den Median berechnet. Der Median ist im Wesentlichen der Mitte Nummer einer sortierten Liste von Nummern. Um den Median für den obigen Filter zu finden, sortieren wir einfach die Zahlen von niedrig nach hoch und die Mitte dieser Zahlen wird unser Medianwert sein. Die Werte in unserem sortieren 3x3 Fenster wird uns folgendes geben:

17 29 43 57 59 63 65 84 98

Um die mittlere Zahl (Median) zu ermitteln, zählen wir einfach die Anzahl der Werte, die wir haben, addieren 1 zu dieser Zahl und dividieren durch 2. Dies gibt uns die Position des mittleren Werts im Fenster an, der unser Medianwert ist. Der Medianwert wird also am Ort sein 9 + 1/2 = 5, welches ist 59. Dieser Wert ist der neue Wert des Pixels unter dem Mittelpunkt von 3x3 Fenster.

Diese Art von Filter wird zum Entfernen von Rauschen verwendet und funktioniert am besten bei Bildern, die darunter leiden Salz und Pfeffer Lärm. Das Bild unten zeigt ein Beispiel eines Bildes, das unter solchen Geräuschen leidet:

Nun schreiben wir ein Python-Skript, das den Medianfilter auf das obige Bild anwendet. In diesem Beispiel verwenden wir die OpenCV-Bibliothek. Überprüfen Sie bitte Install OpenCV-Python unter Windows und installieren Sie OpenCV 3.0 und Python 2.7+ unter Ubuntu, um OpenCV zu installieren.

Um den Medianfilter anzuwenden, verwenden wir einfach OpenCVs cv2.medianBlur () Funktion. Unser Skript kann also wie folgt aussehen:

import cv2 import argparse # erstellt den Argument-Parser und parst die Argumente ap = argparse.ArgumentParser () ap.add_argument ('- i', '--image', required = True, help = 'Pfad zum Eingabebild') args = vars (ap.parse_args ()) # lese das Bild image = cv2.imread (args ['image']) # wende den 3x3-Medianfilter auf das Bild processing_image = cv2.medianBlur (image, 3) # display image cv2 an. imshow ('Median Filter Processing', processing_image) # Bild auf Platte cv2.imwrite speichern ('processing_image.png', processing_image) # die Ausführung des Skripts anhalten, bis eine Taste auf der Tastatur gedrückt wird cv2.waitKey (0)

Beachten Sie, dass ich verwendet habe argparse, Es ist eine gute Praxis, hier flexibel zu sein und das Image, auf das der Medianfilter angewendet werden soll, als Argument an unser Programm zu übergeben. 

Nachdem wir unser Bild als Befehlszeilenargument übergeben haben, lesen wir dieses Bild mit der cv2.imread () Funktion. Dann wenden wir den Medianfilter mit der medianBlur () Funktion, übergeben Sie unsere Bild- und Filtergröße als Parameter. Das Bild wird mit angezeigt cv2.imshow () Funktion und wird mit gespeichert cv2.imwrite ().

Das Ergebnis des obigen Skripts lautet wie folgt:

Naja, was denkst du? Sehr schön - ein schönes und sauberes Bild ohne Rauschen.

Sie können den obigen Code von meinem Median-Filter-Repository auf GitHub herunterladen.

Mittlerer Filter

Der mittlere Filter ist ein Beispiel eines linearen Filters. Es ersetzt grundsätzlich jedes Pixel im Ausgabebild durch den Mittelwert (Durchschnitt) der Nachbarschaft. Dies hat die Wirkung, dass das Bild geglättet wird (der Betrag der Intensitätsschwankungen zwischen einem Pixel und dem nächsten wird verringert), Rauschen aus dem Bild entfernt und das Bild aufgehellt wird.

Bei der Mittelwertfilterung wird daher jedes Pixel des Bildes durch den Mittelwert seiner Nachbarn einschließlich des Pixels selbst ersetzt. Das 3x3 Der für die mittlere Filterung verwendete Kern ist wie in der folgenden Abbildung dargestellt, obwohl auch andere Kerngrößen verwendet werden könnten (d. h. 5 x 5):

Was der obige Kernel tatsächlich zu sagen versucht, ist, dass wir alle Elemente unter dem Kernel summieren und den Mittelwert (Durchschnitt) der Summe nehmen.

Ein wichtiger Punkt, der hier erwähnt werden muss, ist, dass alle Elemente des gemeinen Kernels

  • Summe zu 1
  • gleich sein

Nehmen wir ein Beispiel, um die Dinge klarer zu machen. Angenommen, wir haben das folgende Unterbild:

Beim Anwenden des Mittelwertfilters würden wir Folgendes tun:

(7 + 9 + 23 + 76 + 91 + 7 + 64 + 90 + 32) / 9 = 44

Das genaue Ergebnis ist 44.3, aber ich habe das Ergebnis gerundet 44. Der neue Wert für das mittlere Pixel ist also 44 anstatt 91.

Nun zum Coding-Teil. Nehmen wir an, wir haben folgendes Bild:

An dieser Stelle möchten wir den Mittelwertfilter auf das obige Bild anwenden und die Auswirkungen eines solchen Filters sehen.

Der Code für diesen Vorgang lautet wie folgt:

import cv2 import numpy as np import argparse # erstellt den Argument-Parser und parst die Argumente ap = argparse.ArgumentParser () ap.add_argument ('- i', '--image', required = True, help = 'Pfad zur Eingabe image ') args = vars (ap.parse_args ()) # lese das Image image = cv2.imread (args [' image ']) # wende den Mittelwertfilter 3x3 auf den Image-Kernel = np.ones ((3,3) an verarbeitete_image = cv2.filter2D (image, -1, kernel) # display image cv2.imshow ('Mean Filter Processing', verarbeitete_image) # Bild auf Festplatte speichern cv2.imwrite ('verarbeitete_image.png', processing_image) # pausiert die Ausführung des Skripts, bis eine Taste auf der Tastatur gedrückt wird cv2.waitKey (0)

Beachten Sie aus dem Code, dass wir a verwendet haben 3x3 Kernel für unseren mittleren Filter. Wir haben auch die verwendet filter2D () Funktion zum Anwenden des Mittelwertfilters. Der erste Parameter dieser Funktion ist unser Eingabebild, der zweite ist die gewünschte Tiefe des Ausgabebildes ddepth, und der dritte Parameter ist unser Kernel. Zuweisung -1 für die ddepth Parameter bedeutet, dass das Ausgabebild die gleich Tiefe als Eingabebild.

Nachdem ich den Code auf unserem Bild mit Geräuschen ausgeführt hatte, erhielt ich folgendes Ergebnis:

Wenn Sie das Ausgabebild beobachten, können wir feststellen, dass es weicher ist als das verrauschte Bild. Mission erledigt!

Sie können den obigen Code aus meinem mittleren Filter-Repository auf GitHub herunterladen.

Fazit

Wie wir in diesem Tutorial gesehen haben, können Sie mit Python auf einfache Art und Weise erweiterte Aufgaben wie die Bildfilterung durchführen, insbesondere durch die OpenCV-Bibliothek.

Zögern Sie nicht, zu sehen, was wir auf dem Markt zum Verkauf und zum Lernen zur Verfügung haben, und zögern Sie nicht, Fragen zu stellen und mit dem untenstehenden Feed wertvolles Feedback zu geben.