如何在 OpenCV 中锐化图像?

如何使用 OpenCV锐化图像?

有许多平滑或模糊的方法,但没有一种我能看到锐化。

245009 次浏览

维基百科上关于不锋利面具的文章中列出了一个一般程序:

你使用一个高斯平滑滤波器,并从原始图像中减去平滑后的版本(以加权的方式,使得一个常量区域的值保持不变)。

为了将 frame的锐化版本转换为 image: (两者都是 cv::Mat)

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

这些参数需要你自己调整。

还有拉普拉斯锐化,你应该找到一些东西,当你谷歌。

试试这个:

cv::bilateralFilter(img, 9, 75, 75);

您可以找到更多的信息 给你

您可以在 OpenCV 文档上找到关于 利用“非锐化掩模”算法进行图像锐化的示例代码。

改变 sigmathresholdamount的值会得到不同的结果。

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

您可以尝试使用一个简单的 内核< a href = “ http://docs.opencv.org/module/imgproc/doc/filtering.html # filter2D”rel = “ noReferrer”> filter2D 函数,例如在 Python 中:

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

Wikipedia 对内核有一个很好的概述,这里还有一些例子—— https://en.wikipedia.org/wiki/Kernel_(image_processing)

在图像处理中,核、卷积矩阵或掩模是一个小矩阵。它用于模糊,锐化,压花,边缘检测等。这是通过在内核和映像之间进行卷积来实现的。

为了使这个主题更加清晰,有几点必须明确:

  1. 锐化图像是一个不适定的问题。换句话说,模糊是一种有损操作,一般来说不可能从模糊中恢复过来。

  2. 要锐化单个图像,您需要以某种方式添加约束(假设) ,什么样的图像是您想要的,以及如何变得模糊。这是自然图像统计的领域。进行锐化的方法将这些统计数据显式或隐式地保存在算法中(深度学习是最隐式的编码方法)。通常的方法是增加 拉普拉斯金字塔分解的一些水平,这是布莱恩 · 伯恩斯答案的推广,假设高斯模糊损坏了图像,如何加权是连接到假设什么是在图像开始。

  3. 其他信息来源可以使问题尖锐化。这类信息的常见来源是运动物体的视频或多视角设置。在这种情况下磨尖通常被称为 超高分辨率(这是一个非常糟糕的名字,但它已经卡在学术界)。OpenCV 中的超分辨率方法已经存在很长时间了... ..。虽然他们通常不工作,以及真正的问题,上次我检查了他们。我希望深度学习在这里也产生了一些美妙的结果。也许有人会在那里发表评论,说什么是值得的。

任何图像都是各种频率信号的集合 高频率控制边缘,低频率控制边缘 图像内容。边缘形成时,有一个明显的过渡 从一个像素值到另一个像素值,比如0和255英寸 明显有一个急剧的变化,因此边缘 和高频率。为了锐化图像,这些转换可以 进一步加强。

一种方法是将自制的滤波器内核与图像进行卷积。

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

还有一种方法可以从明亮的图像中减去模糊的图像。这有助于提高图像的清晰度。但是应该谨慎做,因为我们只是增加像素值。设想一个灰度像素值为190,如果将其乘以2的权重,则为380,但由于最大允许像素范围而被修剪为255。这是信息丢失,导致图像冲刷。

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

可以使用 不锋利的面具锐化图像。你可以找到更多关于非锐化掩模 给你的信息。下面是一个使用 OpenCV 的 Python 实现:

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)

为了使图像锐化,我们可以使用滤镜(就像以前的许多答案一样)

kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32)


kernel /= denominator * kernel

当分母为1时,它将是最大的,并且随着增加而减少(2.3. .)

最常用的是分母为3的时候。

下面是实现。

kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32)


kernel = 1/3 * kernel


dst = cv2.filter2D(image, -1, kernel)

你也可以试试这个过滤器

sharpen_filter = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
sharped_img = cv2.filter2D(image, -1, sharpen_filter)