【问题标题】:How can I sharpen an image in OpenCV?如何在 OpenCV 中锐化图像?
【发布时间】:2011-06-26 22:58:46
【问题描述】:

如何使用OpenCV 锐化图像?

有很多平滑或模糊的方法,但我看不到锐化的方法。

【问题讨论】:

    标签: image-processing opencv


    【解决方案1】:

    the Wikipedia article on unsharp masking 中列出了一个通用程序:

    您使用高斯平滑滤波器并从原始图像中减去平滑版本(以加权方式,使恒定区域的值保持不变)。

    frame 的锐化版本转换为image:(cv::Mat

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

    这里的参数需要自己调整。

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

    【讨论】:

    • 有没有办法复制 Photoshop 的 Unsharp Mask 效果?
    • @Drazick 你问是因为它不能被复制吗?上面已经给出了维基百科的链接。 digital_unsharp_masking 具体
    • @tilaprimera,我问是因为 Photoshop 的 USM 与“经典”USM 不同。
    • 确保 frame 是 float32,而不是 int8。否则它会输出一个四舍五入的图像,这在视觉上不会很明显,但在每个通道的直方图上会很清晰。
    【解决方案2】:

    您可以尝试一个简单的 kernelfilter2D 函数,例如在 Python 中:

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

    维基百科对内核有很好的概述,这里有更多示例 - https://en.wikipedia.org/wiki/Kernel_(image_processing)

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

    【讨论】:

      【解决方案3】:

      您可以使用unsharp mask 锐化图像。您可以找到更多关于非锐化遮罩here 的信息。这是一个使用 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)
      

      【讨论】:

      • 这似乎是一个非常方便的版本。您能否添加一些有关参数的更多信息。内核大小和sigma可以在opencv中查到,但是数量和阈值呢?谢谢!
      • @choise amount 只是锐化量。例如,与默认值 1.0 相比,amount 为 2.0 会提供更清晰的图像。 threshold 是低对比度蒙版的阈值。换句话说,输入图像和模糊图像之间的差异小于threshold 的像素将保持不变。
      【解决方案4】:

      您可以在OpenCV Documentation 找到有关使用“反锐化蒙版”算法锐化图像的示例代码。

      改变sigma,threshold,amount的值会产生不同的结果。

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

      【讨论】:

        【解决方案5】:

        任何图像都是各种频率信号的集合。这 高频控制边缘,低频控制 图像内容。当有一个急剧的过渡时形成边缘 从一个像素值到另一个像素值,例如 0 和 255 in 相邻单元格。显然有一个急剧的变化,因此边缘 和高频。为了锐化图像,这些过渡可以是 进一步增强。

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

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

        【讨论】:

        • 对不起,内核不应该是8而不是9吗?
        【解决方案6】:

        为了清楚本主题,确实应该提出几点:

        1. 锐化图像是一个不适定问题。换句话说,模糊是一种有损操作,并且通常不可能从它返回。

        2. 要锐化单个图像,您需要以某种方式对您想要什么样的图像以及它如何变得模糊添加约束(假设)。这是自然图像统计的领域。进行锐化的方法在其算法中显式或隐式地保存这些统计数据(深度学习是最隐含的编码方法)。对DOG or Laplacian pyramid decomposition 的某些级别进行加权的常用方法是对 Brian Burns 答案的概括,它假设高斯模糊破坏了图像,并且加权的完成方式与对图像中内容的假设有关。图像开始。

        3. 其他信息来源可以使问题锐化变得恰当。常见的此类信息源是移动对象的视频或多视图设置。在该设置中锐化通常称为super-resolution(这是一个非常糟糕的名字,但它一直停留在学术界)。 super-resolution methods in OpenCV 已经有很长一段时间了......虽然它们通常不能很好地解决实际问题,但最后我检查了它们。我希望深度学习在这里也能产生一些美妙的结果。也许有人会在评论中发表评论。

        【讨论】:

          【解决方案7】:

          要锐化图像,我们可以使用过滤器(与之前的许多答案一样)

          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)
          

          【讨论】:

          • "It will the most" 附近似乎缺少某些东西。
          【解决方案8】:

          你也可以试试这个过滤器

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

          【讨论】:

            【解决方案9】:

            试试这个:

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

            您可能会发现更多信息here

            【讨论】:

            • 问题是关于图像锐化,而不是边缘保持平滑。
            猜你喜欢
            • 2013-11-22
            • 2023-03-06
            • 1970-01-01
            • 2011-10-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-12-25
            • 2011-04-09
            相关资源
            最近更新 更多