139 votes

Comment rendre une image plus nette dans OpenCV ?

Comment puis-je accentuer une image en utilisant OpenCV ?

Il existe de nombreuses façons de lisser ou d'estomper, mais aucune, à ma connaissance, d'accentuer la netteté.

173voto

etarion Points 6822

Une procédure générale est décrite dans l'article de Wikipédia sur le masquage flou :

Vous utilisez un filtre de lissage gaussien et soustrayez la version lissée de l'image originale (de manière pondérée afin que les valeurs d'une zone constante restent constantes).

Pour obtenir une version affinée de frame en image : (les deux cv::Mat )

cv::GaussianBlur(frame, image, cv::Size(0, 0), 3);
cv::addWeighted(frame, 1.5, image, -0.5, 0, image);

Vous devez régler vous-même les paramètres.

Il y a aussi l'affûtage Laplacien, vous devriez trouver quelque chose à ce sujet en cherchant sur Google.

1 votes

Existe-t-il un moyen de reproduire le résultat du masque flou de Photoshop ?

0 votes

@Drazick Est-ce que vous demandez parce qu'il ne peut pas être répliqué ? Le lien vers le wikipedia a été donné ci-dessus. masquage_numérique pour être précis

0 votes

@tilaprimera, je demande parce que l'USM de Photoshop est différent de l'USM "classique".

59voto

Brian Burns Points 398

Vous pouvez essayer un simple Noyau et le filtre2D par exemple, en Python :

kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
im = cv2.filter2D(im, -1, kernel)

Wikipedia offre une bonne vue d'ensemble des noyaux, avec d'autres exemples ici. https://en.wikipedia.org/wiki/Kernel_(traitement_de_l'image)

En traitement d'images, un noyau, une matrice de convolution ou un masque est une petite matrice. Il est utilisé pour le floutage, l'accentuation, le gaufrage, la détection des bords, etc. Pour ce faire, on effectue une convolution entre un noyau et une image.

22voto

Soroush Points 805

Vous pouvez accentuer une image en utilisant un masque flou . Vous pouvez trouver plus d'informations sur le masquage flou. ici . Et voici une implémentation Python utilisant 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)

0 votes

Cela semble être une version assez pratique. pourriez-vous ajouter un peu plus d'informations sur les paramètres. la taille du noyau et le sigma peuvent être recherchés dans opencv, mais qu'en est-il de la quantité et du seuil ? Merci !

2 votes

@choise amount est simplement le degré d'accentuation. Par exemple, un amount de 2.0 donne une image plus nette par rapport à la valeur par défaut de 1.0. threshold est le seuil pour le masque de faible contraste. En d'autres termes, les pixels pour lesquels la différence entre les images d'entrée et les images floues est inférieure à threshold restera inchangé.

17voto

sturkmen Points 2588

Vous pouvez trouver un exemple de code sur Renforcement de la netteté de l'image à l'aide de l'algorithme "unsharp mask". sur Documentation OpenCV .

Modification des valeurs de sigma , threshold , amount donnera des résultats différents.

// 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);

14voto

Ujjwal Saxena Points 239

Toute image est une collection de signaux de différentes fréquences. Les fréquences les plus élevées contrôlent les bords et les fréquences les plus basses contrôlent le contenu de l'image. Les bords sont formés lorsqu'il y a une transition nette d'une valeur de pixel à l'autre, comme 0 et 255 dans une cellule adjacente. cellule adjacente. De toute évidence, il y a un changement brusque et donc un bord et à haute fréquence. Pour rendre une image plus nette, ces transitions peuvent être améliorées. être améliorées.

L'une des méthodes consiste à convoluer un noyau de filtre créé par soi-même avec l'image.

    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()

Il existe une autre méthode qui consiste à soustraire une version floue de l'image de la version claire de celle-ci. Cela permet de rendre l'image plus nette. Mais elle doit être effectuée avec précaution car nous ne faisons qu'augmenter la valeur des pixels. Imaginez une valeur de pixel en niveaux de gris de 190, qui, si elle est multipliée par un poids de 2, donne 380, mais qui est coupée à 255 en raison de la plage de pixels maximale autorisée. Il s'agit d'une perte d'information qui conduit à une image délavée.

    addWeighted(frame, 1.5, image, -0.5, 0, image);

0 votes

Je suis désolé mais le noyau ne devrait-il pas avoir 8 au centre et non 9 ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X