Antworten:
Ein allgemeines Verfahren ist im Wikipedia-Artikel zur unscharfen Maskierung beschrieben :
Sie verwenden einen Gaußschen Glättungsfilter und subtrahieren die geglättete Version vom Originalbild (gewichtet, damit die Werte eines konstanten Bereichs konstant bleiben).
So erhalten Sie eine geschärfte Version von frame
in image
: (beide cv::Mat
)
cv::GaussianBlur(frame, image, cv::Size(0, 0), 3);
cv::addWeighted(frame, 1.5, image, -0.5, 0, image);
Die Parameter dort müssen Sie selbst anpassen.
Es gibt auch Laplace-Schärfen, Sie sollten etwas darauf finden, wenn Sie googeln.
Sie können einen einfachen Kernel und die Funktion filter2D ausprobieren , z. B. in Python:
kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
im = cv2.filter2D(im, -1, kernel)
Wikipedia hat einen guten Überblick über Kernel mit einigen weiteren Beispielen hier - https://en.wikipedia.org/wiki/Kernel_(image_processing)
Bei der Bildverarbeitung ist ein Kernel, eine Faltungsmatrix oder eine Maske eine kleine Matrix. Es wird zum Verwischen, Schärfen, Prägen, Kantenerkennen und mehr verwendet. Dies wird erreicht, indem eine Faltung zwischen einem Kernel und einem Image durchgeführt wird.
Einen Beispielcode zum Schärfen von Bildern mit dem Algorithmus "Unscharfe Maske" finden Sie in der OpenCV-Dokumentation .
Ändern von Werten von sigma
, threshold
, amount
werden unterschiedliche Ergebnisse.
// sharpen image using "unsharp mask" algorithm
Mat blurred; double sigma = 1, threshold = 5, amount = 1;
GaussianBlur(img, blurred, Size(), sigma, sigma);
Mat lowContrastMask = abs(img - blurred) < threshold;
Mat sharpened = img*(1+amount) + blurred*(-amount);
img.copyTo(sharpened, lowContrastMask);
Sie können ein Bild mit einer unscharfen Maske schärfen . Weitere Informationen zur unscharfen Maskierung finden Sie hier . Und hier ist eine Python-Implementierung mit OpenCV:
import cv2 as cv
import numpy as np
def unsharp_mask(image, kernel_size=(5, 5), sigma=1.0, amount=1.0, threshold=0):
"""Return a sharpened version of the image, using an unsharp mask."""
blurred = cv.GaussianBlur(image, kernel_size, sigma)
sharpened = float(amount + 1) * image - float(amount) * blurred
sharpened = np.maximum(sharpened, np.zeros(sharpened.shape))
sharpened = np.minimum(sharpened, 255 * np.ones(sharpened.shape))
sharpened = sharpened.round().astype(np.uint8)
if threshold > 0:
low_contrast_mask = np.absolute(image - blurred) < threshold
np.copyto(sharpened, image, where=low_contrast_mask)
return sharpened
def example():
image = cv.imread('my-image.jpg')
sharpened_image = unsharp_mask(image)
cv.imwrite('my-sharpened-image.jpg', sharpened_image)
amount
ist einfach das Ausmaß des Schärfens. Beispielsweise amount
ergibt ein Wert von 2,0 ein schärferes Bild im Vergleich zum Standardwert von 1,0. threshold
ist der Schwellenwert für die kontrastarme Maske. Mit anderen Worten, die Pixel, bei denen der Unterschied zwischen den eingegebenen und den unscharfen Bildern geringer ist als threshold
, bleiben unverändert.
Jedes Bild ist eine Sammlung von Signalen mit verschiedenen Frequenzen. Die höheren Frequenzen steuern die Kanten und die niedrigeren Frequenzen steuern den Bildinhalt. Kanten werden gebildet, wenn es einen scharfen Übergang von einem Pixelwert zu dem anderen Pixelwert wie 0 und 255 in der benachbarten Zelle gibt. Offensichtlich gibt es eine scharfe Änderung und damit die Kante und die Hochfrequenz. Zum Schärfen eines Bildes können diese Übergänge weiter verbessert werden.
Eine Möglichkeit besteht darin, einen selbst erstellten Filterkern mit dem Bild zu falten.
import cv2
import numpy as np
image = cv2.imread('images/input.jpg')
kernel = np.array([[-1,-1,-1],
[-1, 9,-1],
[-1,-1,-1]])
sharpened = cv2.filter2D(image, -1, kernel) # applying the sharpening kernel to the input image & displaying it.
cv2.imshow('Image Sharpening', sharpened)
cv2.waitKey(0)
cv2.destroyAllWindows()
Es gibt eine andere Methode, um eine unscharfe Version des Bildes von der hellen Version zu subtrahieren. Dies hilft beim Schärfen des Bildes. Dies sollte jedoch mit Vorsicht erfolgen, da wir nur die Pixelwerte erhöhen. Stellen Sie sich einen Graustufenpixelwert 190 vor, der, wenn er mit einem Gewicht von 2 multipliziert wird, 380 ergibt, aber aufgrund des maximal zulässigen Pixelbereichs auf 255 gekürzt wird. Dies ist ein Informationsverlust und führt zu einem verwaschenen Bild.
addWeighted(frame, 1.5, image, -0.5, 0, image);
Aus Gründen der Klarheit in diesem Thema sollten einige Punkte hervorgehoben werden:
Das Schärfen von Bildern ist ein schlechtes Problem. Mit anderen Worten, Unschärfe ist eine verlustbehaftete Operation, und ein Zurückkehren ist im Allgemeinen nicht möglich.
Um einzelne Bilder zu schärfen, müssen Sie Einschränkungen (Annahmen) hinzufügen, welche Art von Bild Sie möchten und wie es unscharf geworden ist. Dies ist der Bereich der natürlichen Bildstatistik. Ansätze zum Schärfen halten diese Statistiken explizit oder implizit in ihren Algorithmen (Deep Learning ist das implizit codierteste). Der übliche Ansatz, einige Ebenen einer DOG- oder Laplace-Pyramiden-Zerlegung hochzuwichten , der die Verallgemeinerung der Antwort von Brian Burns darstellt, geht davon aus, dass eine Gaußsche Unschärfe das Bild verfälscht und wie die Gewichtung erfolgt, hängt mit Annahmen darüber zusammen, was war im Bild zu Beginn.
Andere Informationsquellen können das Problem beim Schärfen gut aufwerfen. Häufig sind solche Informationsquellen Videos eines sich bewegenden Objekts oder Einstellungen mit mehreren Ansichten. Das Schärfen in dieser Einstellung wird normalerweise als Superauflösung bezeichnet (was ein sehr schlechter Name dafür ist, aber in akademischen Kreisen stecken geblieben ist). Es hat in OpenCV Super-Resolution - Verfahren seit langer Zeit .... obwohl sie in der Regel arbeiten nicht so gut für reale Probleme dauern ich sie ausgecheckt. Ich gehe davon aus, dass Deep Learning auch hier einige wundervolle Ergebnisse hervorgebracht hat. Vielleicht schreibt jemand eine Bemerkung darüber, was sich da draußen lohnt.
Um ein Bild zu schärfen, können wir den Filter verwenden (wie in vielen vorherigen Antworten).
kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32)
kernel /= denominator * kernel
Es wird am meisten sein, wenn der Nenner 1 ist und mit zunehmendem Wert abnimmt (2.3 ..)
Am häufigsten wird verwendet, wenn der Nenner 3 ist.
Unten ist die Implementierung.
kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32)
kernel = 1/3 * kernel
dst = cv2.filter2D(image, -1, kernel)
Versuchen Sie es damit:
cv::bilateralFilter(img, 9, 75, 75);
Weitere Informationen finden Sie hier .