Pc Imaginative and prescient ist ein umfangreiches Gebiet zur Analyse von Bildern und Movies. Während viele Menschen bei Pc Imaginative and prescient hauptsächlich an Modelle des maschinellen Lernens denken, gibt es in Wirklichkeit viel mehr Algorithmen, die in manchen Fällen eine bessere Leistung als KI erbringen!
In der Pc Imaginative and prescient ist der Bereich von Merkmalserkennung Dabei geht es darum, bestimmte Bereiche von Interesse in einem Bild zu identifizieren. Diese Ergebnisse können dann zur Erstellung genutzt werden Characteristic-Deskriptoren – numerische Vektoren, die lokale Bildregionen darstellen. Anschließend können die Merkmalsdeskriptoren mehrerer Fotos derselben Szene kombiniert werden, um einen Bildabgleich durchzuführen oder sogar eine Szene zu rekonstruieren.
In diesem Artikel werden wir eine Analogie aus der Infinitesimalrechnung einführen BildableitungenUnd Farbverläufe . Es wird notwendig sein, dass wir die Logik hinter dem Faltungskern und dem verstehen Sobel-Operatorinsbesondere – ein Pc-Imaginative and prescient-Filter, der zur Erkennung von Kanten im Bild verwendet wird.
Bildintensität
ist eines der Hauptmerkmale eines Bildes. Jedes Pixel des Bildes besteht aus drei Komponenten: R (Rot), G (Grün) und B (Blau), die Werte zwischen 0 und 255 annehmen. Je höher der Wert, desto heller ist das Pixel. Die Intensität eines Pixels ist lediglich ein gewichteter Durchschnitt seiner R-, G- und B-Komponenten.
Tatsächlich gibt es mehrere Requirements, die unterschiedliche Gewichte definieren. Da wir uns auf OpenCV konzentrieren werden, verwenden wir deren Formel, die unten angegeben ist:

picture = cv2.imread('picture.png')
B, G, R = cv2.cut up(picture)
grayscale_image = 0.299 * R + 0.587 * G + 0.114 * B
grayscale_image = np.clip(grayscale_image, 0, 255).astype('uint8')
depth = grayscale_image.imply()
print(f"Picture depth: {depth:2f}")
Graustufenbilder
Bilder können mit unterschiedlichen Farbkanälen dargestellt werden. Wenn RGB-Kanäle ein Originalbild darstellen, wird es durch Anwendung der oben genannten Intensitätsformel in ein Graustufenformat umgewandelt, das nur aus einem Kanal besteht.
Da die Summe der Gewichte in der Formel gleich 1 ist, enthält das Graustufenbild genau wie die RGB-Kanäle Intensitätswerte zwischen 0 und 255.

In OpenCV können RGB-Kanäle mithilfe der Funktion cv2.cvtColor() in das Graustufenformat konvertiert werden. Dies ist eine einfachere Methode als die Methode, die wir oben gesehen haben.
picture = cv2.imread('picture.png')
grayscale_image = cv2.cvtColor(picture, cv2.COLOR_BGR2GRAY)
depth = grayscale_image.imply()
print(f"Picture depth: {depth:2f}")
Anstelle der Customary-RGB-Palette verwendet OpenCV die BGR-Palette. Sie sind beide gleich, außer dass die R- und B-Elemente nur vertauscht sind. Der Einfachheit halber werden wir in diesem und den folgenden Artikeln dieser Serie die Begriffe RGB und BGR synonym verwenden.
Wenn wir die Bildintensität mit beiden Methoden in OpenCV berechnen, können wir leicht unterschiedliche Ergebnisse erhalten. Das ist völlig regular, da OpenCV bei Verwendung der Funktion cv2.cvtColor transformierte Pixel auf die nächsten ganzen Zahlen rundet. Bei der Berechnung des Mittelwerts ergibt sich ein kleiner Unterschied.
Bildableitung
Bildableitungen werden verwendet, um zu messen, wie schnell sich die Pixelintensität im Bild ändert. Bilder können als Funktion zweier Argumente betrachtet werden, I(x, y), wobei x und y die Pixelposition angeben und I die Intensität dieses Pixels darstellt.
Wir könnten formal schreiben:

Da Bilder jedoch im diskreten Raum existieren, werden ihre Ableitungen normalerweise durch Faltungskerne angenähert:
- Für die horizontale X-Achse: (-1, 0, 1)
- Für die vertikale Y-Achse: (-1, 0, 1)ᵀ
Mit anderen Worten, wir können die obigen Gleichungen in der folgenden Kind umschreiben:

Um die Logik hinter den Kerneln besser zu verstehen, schauen wir uns das folgende Beispiel an.
Beispiel
Angenommen, wir haben eine Matrix bestehend aus 5×5 Pixeln, die einen Graustufenbildbereich darstellt. Die Elemente dieser Matrix zeigen die Intensität von Pixeln.

Zur Berechnung der Bildableitung können wir Faltungskerne verwenden. Die Idee ist einfach: Indem wir ein Pixel im Bild und mehrere Pixel in seiner Nachbarschaft nehmen, ermitteln wir die Summe einer elementweisen Multiplikation mit einem gegebenen Kernel, der eine feste Matrix (oder einen festen Vektor) darstellt.
In unserem Fall verwenden wir einen Vektor mit drei Elementen (-1, 0, 1). Nehmen wir aus dem obigen Beispiel ein Pixel an Place (1, 1), dessen Wert beispielsweise -3 ist.
Da die Kernelgröße (in Gelb) 3×1 beträgt, benötigen wir die linken und rechten Elemente von -3, um der Größe zu entsprechen. Als Ergebnis nehmen wir den Vektor (4, -3, 2). Indem wir dann die Summe des Elementprodukts ermitteln, erhalten wir den Wert -2:

Der Wert -2 stellt eine Ableitung für das Anfangspixel dar. Wenn wir genau hinschauen, können wir feststellen, dass die Ableitung von Pixel -3 einfach die Differenz zwischen dem Pixel ganz rechts (2) von -3 und seinem Pixel ganz hyperlinks (4) ist.
Warum komplexe Formeln verwenden, wenn wir die Differenz zwischen zwei Elementen ermitteln können? Tatsächlich hätten wir in diesem Beispiel einfach den Intensitätsunterschied zwischen den Elementen I(x, y + 1) und I(x, y – 1) berechnen können. Aber in Wirklichkeit können wir komplexere Szenarien bewältigen, wenn wir anspruchsvollere und weniger offensichtliche Merkmale erkennen müssen. Aus diesem Grund ist es praktisch, die Verallgemeinerung von Kerneln zu verwenden, deren Matrizen bereits bekannt sind, um vordefinierte Merkmalstypen zu erkennen.
Basierend auf dem Ableitungswert können wir einige Beobachtungen machen:
- Wenn der Ableitungswert in einem bestimmten Bildbereich signifikant ist, bedeutet dies, dass sich die Intensität dort drastisch ändert. Ansonsten gibt es hinsichtlich der Helligkeit keine spürbaren Veränderungen.
- Wenn der Wert der Ableitung positiv ist, bedeutet dies, dass der Bildbereich von hyperlinks nach rechts heller wird; ist es negativ, wird der Bildbereich von hyperlinks nach rechts dunkler.
Durch die Analogie zur linearen Algebra können Kernel als lineare Operatoren für Bilder betrachtet werden, die lokale Bildbereiche transformieren.
Analog können wir die Faltung mit dem vertikalen Kernel berechnen. Die Vorgehensweise bleibt die gleiche, außer dass wir jetzt unser Fenster (Kernel) vertikal über die Bildmatrix verschieben.

Sie können feststellen, dass nach der Anwendung eines Faltungsfilters auf das ursprüngliche 5×5-Bild ein 3×3-Bild entstand. Das ist regular, da wir die Faltung nicht auf die gleiche Weise auf Kantenpixel anwenden können (andernfalls geraten wir ins Aus).
Um die Bilddimensionalität zu bewahren, wird üblicherweise die Padding-Technik verwendet, die darin besteht, Bildränder vorübergehend zu verlängern/interpolieren oder mit Nullen zu füllen, sodass die Faltung auch für Kantenpixel berechnet werden kann.
Standardmäßig füllen Bibliotheken wie OpenCV die Ränder automatisch auf, um die gleiche Dimensionalität für Eingabe- und Ausgabebilder zu gewährleisten.
Bildverlauf
Ein Bildverlauf zeigt, wie schnell sich die Intensität (Helligkeit) an einem bestimmten Pixel in beide Richtungen (X und Y) ändert.

Formal kann der Bildgradient als Vektor von Bildableitungen in Bezug auf die X- und Y-Achse geschrieben werden.
Gradientengröße
Die Gradientengröße stellt eine Norm des Gradientenvektors dar und kann mithilfe der folgenden Formel ermittelt werden:

Gradientenorientierung
Mit den gefundenen Gx und Gy lässt sich auch der Winkel des Gradientenvektors berechnen:

Beispiel
Sehen wir uns anhand des obigen Beispiels an, wie wir Farbverläufe manuell berechnen können. Dazu benötigen wir die berechneten 3×3-Matrizen, nachdem der Faltungskern angewendet wurde.
Wenn wir das Pixel oben hyperlinks nehmen, hat es die Werte Gₓ = -2 Und Gᵧ = 11. Wir können die Größe und Ausrichtung des Gradienten leicht berechnen:

Für die gesamte 3×3-Matrix erhalten wir die folgende Visualisierung von Gradienten:

In der Praxis wird empfohlen, Kernel zu normalisieren, bevor sie auf Matrizen angewendet werden. Der Einfachheit halber haben wir darauf verzichtet.
Sobel-Operator
Nachdem Sie die Grundlagen von Bildableitungen und -verläufen kennengelernt haben, ist es nun an der Zeit, sich mit dem Sobel-Operator auseinanderzusetzen, der zur Approximation dieser Ableitungen verwendet wird. Im Vergleich zu früheren Kerneln der Größen 3×1 und 1×3 ist der Sobel-Operator durch ein Paar von 3×3-Kerneln (für beide Achsen) definiert:

Dies verschafft dem Sobel-Operator einen Vorteil, da die Kernel zuvor nur 1D-Änderungen gemessen haben und andere Zeilen und Spalten in der Nachbarschaft ignoriert haben. Der Sobel-Operator berücksichtigt weitere Informationen über lokale Regionen.
Ein weiterer Vorteil besteht darin, dass Sobel robuster gegenüber Lärm ist. Schauen wir uns den Bildpatch unten an. Wenn wir die Ableitung um das rote Component in der Mitte berechnen, das an der Grenze zwischen dunklen (2) und hellen (7) Pixeln liegt, sollten wir 5 erhalten. Das Drawback besteht darin, dass es ein verrauschtes Pixel mit dem Wert 10 gibt.

Wenn wir den horizontalen 1D-Kernel in der Nähe des roten Parts anwenden, erhält der Pixelwert 10, der ein klarer Ausreißer ist, erhebliche Bedeutung. Gleichzeitig ist der Sobel-Operator robuster: Er berücksichtigt 10 sowie die Pixel mit einem Wert von 7 um ihn herum. In gewisser Weise wendet der Sobel-Operator eine Glättung an.
Beim gleichzeitigen Vergleich mehrerer Kernel empfiehlt es sich, die Matrixkerne zu normalisieren, um sicherzustellen, dass sie alle im gleichen Maßstab liegen. Eine der häufigsten Anwendungen von Operatoren im Allgemeinen in der Bildanalyse ist die Merkmalserkennung.
Im Fall der Sobel- und Scharr-Operatoren werden sie üblicherweise zur Erkennung von Kanten verwendet – Zonen, in denen sich die Pixelintensität (und ihr Gradient) drastisch ändern.
OpenCV
Um Sobel-Operatoren anzuwenden, reicht es aus, die OpenCV-Funktion cv2.Sobel zu verwenden. Schauen wir uns seine Parameter an:
derivative_x = cv2.Sobel(picture, cv2.CV_64F, 1, 0)
derivative_y = cv2.Sobel(picture, cv2.CV_64F, 0, 1)
- Der erste Parameter ist ein eingegebenes NumPy-Bild.
- Der zweite Parameter (cv2.CV_64F) ist die Datentiefe des Ausgabebildes. Das Drawback besteht darin, dass Bediener im Allgemeinen Ausgabebilder erzeugen können, die Werte außerhalb des Intervalls 0–255 enthalten. Aus diesem Grund müssen wir die Artwork der Pixel angeben, die das Ausgabebild haben soll.
- Der dritte und vierte Parameter stellen die Reihenfolge der Ableitung in x-Richtung bzw. y-Richtung dar. In unserem Fall möchten wir nur die erste Ableitung in x- und y-Richtung, additionally übergeben wir die Werte (1, 0) und (0, 1).
Schauen wir uns das folgende Beispiel an, in dem wir ein Sudoku-Eingabebild erhalten:

Wenden wir den Sobel-Filter an:
import cv2
import matplotlib.pyplot as plt
picture = cv2.imread("knowledge/enter/sudoku.png")
picture = cv2.cvtColor(picture, cv2.COLOR_BGR2GRAY)
derivative_x = cv2.Scharr(picture, cv2.CV_64F, 1, 0)
derivative_y = cv2.Scharr(picture, cv2.CV_64F, 0, 1)
derivative_combined = cv2.addWeighted(derivative_x, 0.5, derivative_y, 0.5, 0)
min_value = min(derivative_x.min(), derivative_y.min(), derivative_combined.min())
max_value = max(derivative_x.max(), derivative_y.max(), derivative_combined.max())
print(f"Worth vary: ({min_value:.2f}, {max_value:.2f})")
fig, axes = plt.subplots(1, 3, figsize=(16, 6), constrained_layout=True)
axes(0).imshow(derivative_x, cmap='grey', vmin=min_value, vmax=max_value)
axes(0).set_title("Horizontal by-product")
axes(0).axis('off')
image_1 = axes(1).imshow(derivative_y, cmap='grey', vmin=min_value, vmax=max_value)
axes(1).set_title("Vertical by-product")
axes(1).axis('off')
image_2 = axes(2).imshow(derivative_combined, cmap='grey', vmin=min_value, vmax=max_value)
axes(2).set_title("Mixed by-product")
axes(2).axis('off')
color_bar = fig.colorbar(image_2, ax=axes.ravel().tolist(), orientation='vertical', fraction=0.025, pad=0.04)
plt.savefig("knowledge/output/sudoku.png")
plt.present()
Als Ergebnis können wir sehen, dass horizontale und vertikale Ableitungen die Linien sehr intestine erkennen! Darüber hinaus ermöglicht uns die Kombination dieser Linien, beide Arten von Merkmalen zu erkennen:

Scharr-Operator
Eine weitere beliebte Different zum Sober-Kernel ist der Scharr-Operator:

Trotz seiner wesentlichen Ähnlichkeit mit der Struktur des Sobel-Operators erreicht der Scharr-Kernel eine höhere Genauigkeit bei Kantenerkennungsaufgaben. Es verfügt über mehrere entscheidende mathematische Eigenschaften, die wir in diesem Artikel nicht berücksichtigen werden.
OpenCV
Die Verwendung des Scharr-Filters in OpenCV ist dem, was wir oben beim Sobel-Filter gesehen haben, sehr ähnlich. Der einzige Unterschied besteht in einem anderen Methodennamen (andere Parameter sind gleich):
derivative_x = cv2.Scharr(picture, cv2.CV_64F, 1, 0)
derivative_y = cv2.Scharr(picture, cv2.CV_64F, 0, 1)
Hier ist das Ergebnis, das wir mit dem Scharr-Filter erhalten:

In diesem Fall ist es schwierig, die Unterschiede in den Ergebnissen beider Operatoren zu erkennen. Wenn wir uns jedoch die Farbkarte ansehen, können wir erkennen, dass der Bereich möglicher Werte, der vom Scharr-Operator erzeugt wird, viel größer ist (-800, +800) als bei Sobel (-200, +200). Das ist regular, da der Scharr-Kernel größere Konstanten hat.
Es ist auch ein gutes Beispiel dafür, warum wir einen speziellen Typ cv2.CV_64F verwenden müssen. Andernfalls wären die Werte auf den Standardbereich zwischen 0 und 255 beschränkt worden und wir hätten wertvolle Informationen über die Verläufe verloren.
Notiz. Das direkte Anwenden von Speichermethoden auf cv2.CV_64F-Bilder würde einen Fehler verursachen. Um solche Bilder auf einer Festplatte zu speichern, müssen sie in ein anderes Format konvertiert werden und enthalten nur Werte zwischen 0 und 255.
Abschluss
Durch die Anwendung der Grundlagen der Evaluation auf Pc Imaginative and prescient haben wir wesentliche Bildeigenschaften untersucht, die es uns ermöglichen, Intensitätsspitzen in Bildern zu erkennen. Dieses Wissen ist hilfreich, da die Merkmalserkennung eine häufige Aufgabe bei der Bildanalyse ist, insbesondere wenn Einschränkungen bei der Bildverarbeitung bestehen oder keine Algorithmen für maschinelles Lernen verwendet werden.
Wir haben uns auch ein Beispiel mit OpenCV angesehen, um zu sehen, wie die Kantenerkennung mit Sobel- und Scharr-Operatoren funktioniert. In den folgenden Artikeln werden wir fortgeschrittenere Algorithmen zur Merkmalserkennung untersuchen und OpenCV-Beispiele untersuchen.
Ressourcen
Sofern nicht anders angegeben, stammen alle Bilder vom Autor.
