Respostas:
Um procedimento geral é apresentado no artigo da Wikipedia sobre mascaramento sem nitidez :
Você usa um filtro de suavização gaussiano e subtrai a versão suavizada da imagem original (de maneira ponderada, para que os valores de uma área constante permaneçam constantes).
Para obter uma versão mais nítida do frame
into image
: (ambos cv::Mat
)
cv::GaussianBlur(frame, image, cv::Size(0, 0), 3);
cv::addWeighted(frame, 1.5, image, -0.5, 0, image);
Os parâmetros existem algo que você precisa ajustar para si mesmo.
Há também a nitidez da Lapônia, você deve encontrar algo sobre isso quando pesquisar no Google.
Você pode tentar um kernel simples e a função filter2D , por exemplo, em Python:
kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
im = cv2.filter2D(im, -1, kernel)
A Wikipedia tem uma boa visão geral dos kernels, com mais alguns exemplos aqui - https://en.wikipedia.org/wiki/Kernel_(image_processing)
No processamento de imagens, um núcleo, matriz de convolução ou máscara é uma matriz pequena. É usado para desfoque, nitidez, gravação, detecção de bordas e muito mais. Isso é realizado fazendo uma convolução entre um kernel e uma imagem.
Você pode encontrar um exemplo de código sobre nitidez da imagem usando o algoritmo "máscara de nitidez" na documentação do OpenCV .
Alterar valores de sigma
, threshold
, amount
vai dar resultados diferentes.
// 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);
Você pode afiar uma imagem usando uma máscara de nitidez . Você pode encontrar mais informações sobre máscara de nitidez aqui . E aqui está uma implementação Python usando 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
é simplesmente a quantidade de nitidez. Por exemplo, um amount
de 2.0 fornece uma imagem mais nítida em comparação com o valor padrão de 1.0. threshold
é o limite para a máscara de baixo contraste. Em outras palavras, os pixels cuja diferença entre a entrada e as imagens desfocadas são menores que threshold
permanecerão inalterados.
Qualquer imagem é uma coleção de sinais de várias frequências. As frequências mais altas controlam as bordas e as frequências mais baixas controlam o conteúdo da imagem. As arestas são formadas quando há uma transição nítida de um valor de pixel para outro, como 0 e 255 na célula adjacente. Obviamente, há uma mudança acentuada e, portanto, a borda e a alta frequência. Para aprimorar a imagem, essas transições podem ser aprimoradas ainda mais.
Uma maneira é envolver um kernel de filtro auto-criado com a imagem.
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()
Existe outro método para subtrair uma versão borrada da imagem da versão brilhante. Isso ajuda a aprimorar a imagem. Mas isso deve ser feito com cautela, pois estamos apenas aumentando os valores de pixel. Imagine um valor de pixel em escala de cinza 190, que se multiplicado por um peso de 2 produz se 380, mas é aparado em 255 devido ao alcance máximo permitido de pixels. Isso é perda de informações e leva à imagem desbotada.
addWeighted(frame, 1.5, image, -0.5, 0, image);
Para maior clareza neste tópico, alguns pontos realmente devem ser feitos:
Nitidez de imagens é um problema incorreto. Em outras palavras, o desfoque é uma operação com perdas, e voltar a partir dela geralmente não é possível.
Para aprimorar as imagens únicas, é necessário adicionar restrições (suposições) sobre o tipo de imagem que você deseja e como ficou borrada. Esta é a área de estatísticas de imagem natural. As abordagens para aprimorar a nitidez mantêm essas estatísticas explícita ou implicitamente em seus algoritmos (o aprendizado profundo é o mais implicitamente codificado). A abordagem comum de ponderar alguns dos níveis de uma decomposição da pirâmide do DOG ou do Laplaciano , que é a generalização da resposta de Brian Burns, pressupõe que um desfoque gaussiano corrompeu a imagem, e como a ponderação é feita está conectada a suposições sobre o que era na imagem para começar.
Outras fontes de informação podem tornar o problema mais aguçado. Essas fontes comuns de informação são o vídeo de um objeto em movimento ou a configuração de várias visualizações. A nitidez nesse cenário geralmente é chamada de super-resolução (que é um nome muito ruim para ele, mas ficou nos círculos acadêmicos). Existem métodos de super-resolução no OpenCV desde há muito tempo ... embora eles geralmente não funcionem tão bem para problemas reais, da última vez que os verifiquei. Espero que o aprendizado profundo tenha produzido alguns resultados maravilhosos aqui também. Talvez alguém publique comentários sobre o que vale a pena por aí.
Para afiar uma imagem, podemos usar o filtro (como em muitas respostas anteriores)
kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32)
kernel /= denominator * kernel
Será o máximo quando o denominador for 1 e diminuirá conforme aumentado (2,3 ..)
O mais usado é quando o denominador é 3.
Abaixo está a implementação.
kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32)
kernel = 1/3 * kernel
dst = cv2.filter2D(image, -1, kernel)