Python+OpenCV:图像去噪(Image Denoising)

深碍√TFBOYSˉ_ 2022-12-25 12:55 336阅读 0赞

Python+OpenCV:图像去噪(Image Denoising)

理论

We have seen many image smoothing techniques like Gaussian Blurring, Median Blurring etc and they were good to some extent in removing small quantities of noise.

In those techniques, we took a small neighbourhood around a pixel and did some operations like gaussian weighted average, median of the values etc to replace the central element.

In short, noise removal at a pixel was local to its neighbourhood.

There is a property of noise.

Noise is generally considered to be a random variable with zero mean.

Consider a noisy pixel, 20201201231920464.png where 20201201231932647.png is the true value of pixel and n is the noise in that pixel.

You can take large number of same pixels (say N) from different images and computes their average.

Ideally, you should get 2020120123203580.png since mean of noise is zero.

You can verify it yourself by a simple setup.

Hold a static camera to a certain location for a couple of seconds.

This will give you plenty of frames, or a lot of images of the same scene.

Then write a piece of code to find the average of all the frames in the video (This should be too simple for you now ).

Compare the final result and first frame. You can see reduction in noise.

Unfortunately this simple method is not robust to camera and scene motions. Also often there is only one noisy image available.

So idea is simple, we need a set of similar images to average out the noise.

Consider a small window (say 5x5 window) in the image.

Chance is large that the same patch may be somewhere else in the image.

Sometimes in a small neighbourhood around it.

What about using these similar patches together and find their average? For that particular window, that is fine.

See an example image below:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpdWJpbmc4NjA5_size_16_color_FFFFFF_t_70

The blue patches in the image looks the similar. Green patches looks similar.

So we take a pixel, take small window around it, search for similar windows in the image, average all the windows and replace the pixel with the result we got.

This method is Non-Local Means Denoising. It takes more time compared to blurring techniques we saw earlier, but its result is very good.

More details and online demo can be found at link: http://www.ipol.im/pub/art/2011/bcm_nlm/ (It has the details, online demo etc. Highly recommended to visit. Our test image is generated from this link).

For color images, image is converted to CIELAB colorspace and then it separately denoise L and AB components.

Image Denoising in OpenCV

OpenCV provides four variations of this technique.

  1. cv.fastNlMeansDenoising() - works with a single grayscale images.
  2. cv.fastNlMeansDenoisingColored() - works with a color image.
  3. cv.fastNlMeansDenoisingMulti() - works with image sequence captured in short period of time (grayscale images).
  4. cv.fastNlMeansDenoisingColoredMulti() - same as above, but for color images.

Common arguments are:

  • h : parameter deciding filter strength. Higher h value removes noise better, but removes details of image also. (10 is ok).
  • hForColorComponents : same as h, but for color images only. (normally same as h).
  • templateWindowSize : should be odd. (recommended 7).
  • searchWindowSize : should be odd. (recommended 21).

Please visit first link in additional resources for more details on these parameters.

We will demonstrate 2 and 3 here. Rest is left for you.

1. cv.fastNlMeansDenoisingColored()

As mentioned above it is used to remove noise from color images. (Noise is expected to be gaussian).

See the example below:

  1. ####################################################################################################
  2. # 图像去噪(Image Denoising)
  3. def lmc_cv_image_denoising(method):
  4. """
  5. 函数功能: 图像去噪(Image Denoising).
  6. """
  7. # 0: fastNlMeansDenoisingColored(): used to remove noise from color images.
  8. if 0 == method:
  9. image = lmc_cv.imread('D:/99-Research/TestData/image/cartoon6.jpg')
  10. image = lmc_cv.cvtColor(image, lmc_cv.COLOR_BGR2RGB)
  11. denoising_image = lmc_cv.fastNlMeansDenoisingColored(image, None, 10, 10, 7, 21)
  12. # 显示结果
  13. pyplot.subplot(121)
  14. pyplot.imshow(image)
  15. pyplot.xticks([])
  16. pyplot.yticks([])
  17. pyplot.subplot(122)
  18. pyplot.imshow(denoising_image)
  19. pyplot.xticks([])
  20. pyplot.yticks([])
  21. pyplot.show()

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpdWJpbmc4NjA5_size_16_color_FFFFFF_t_70 1

2. cv.fastNlMeansDenoisingMulti()

Now we will apply the same method to a video.

The first argument is the list of noisy frames.

Second argument imgToDenoiseIndex specifies which frame we need to denoise, for that we pass the index of frame in our input list.

Third is the temporalWindowSize which specifies the number of nearby frames to be used for denoising.

It should be odd. In that case, a total of temporalWindowSize frames are used where central frame is the frame to be denoised.

For example, you passed a list of 5 frames as input. Let imgToDenoiseIndex = 2 and temporalWindowSize = 3. Then frame-1, frame-2 and frame-3 are used to denoise frame-2.

Let’s see an example.

  1. ####################################################################################################
  2. # 图像去噪(Image Denoising)
  3. def lmc_cv_image_denoising(method):
  4. """
  5. 函数功能: 图像去噪(Image Denoising).
  6. """
  7. # 1: remove noise from color video.
  8. if 1 == method:
  9. # 读取视频
  10. parser = argparse.ArgumentParser(
  11. description='This sample demonstrates remove noise from color video.')
  12. parser.add_argument('--input', type=str, help='Path to a video or a sequence of image.',
  13. default='D:/99-Research/TestData/image/slow_traffic_small.mp4')
  14. args = parser.parse_args()
  15. cap = lmc_cv.VideoCapture(lmc_cv.samples.findFileOrKeep(args.input))
  16. # create a list of first 5 frames
  17. image = [cap.read()[1] for i in range(5)]
  18. # convert all to grayscale
  19. gray = [lmc_cv.cvtColor(i, lmc_cv.COLOR_BGR2GRAY) for i in image]
  20. # convert all to float64
  21. gray = [np.float64(i) for i in gray]
  22. # create a noise of variance 25
  23. noise = np.random.randn(*gray[1].shape) * 10
  24. # Add this noise to images
  25. noisy = [i + noise for i in gray]
  26. # Convert back to uint8
  27. noisy = [np.uint8(np.clip(i, 0, 255)) for i in noisy]
  28. # Denoise 3rd frame considering all the 5 frames
  29. denoising_image = lmc_cv.fastNlMeansDenoisingMulti(noisy, 2, 5, None, 4, 7, 35)
  30. # 显示结果
  31. pyplot.subplot(131)
  32. pyplot.imshow(gray[2], 'gray')
  33. pyplot.xticks([])
  34. pyplot.yticks([])
  35. pyplot.subplot(132)
  36. pyplot.imshow(noisy[2], 'gray')
  37. pyplot.xticks([])
  38. pyplot.yticks([])
  39. pyplot.subplot(133)
  40. pyplot.imshow(denoising_image, 'gray')
  41. pyplot.xticks([])
  42. pyplot.yticks([])
  43. pyplot.show()

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpdWJpbmc4NjA5_size_16_color_FFFFFF_t_70 2

It takes considerable amount of time for computation. In the result, first image is the original frame, second is the noisy one, third is the denoised image.

发表评论

表情:
评论列表 (有 0 条评论,336人围观)

还没有评论,来说两句吧...

相关阅读

    相关 多种滤波器实现图像

    多种滤波器实现图像去噪 图像去噪是数字图像处理中非常重要的一个问题,因为图像中噪声会影响到图像的质量和信息的提取。为了解决这个问题,研究人员提出了很多的去噪算法,其中最常用的

    相关 自编码器图像

    自编码器(AutoEncoder)是深度学习中的一类无监督学习模型,由 encoder 和 decoder 两部分组成。 • encoder 将原始表示编码成隐层表示;

    相关 数字图像MATLAB

    图像去噪是数字图像处理中的重要环节和步骤。去噪效果的好坏直接影响到后续的图像处理工作如图像分割、边缘检测等。图像信号在产生、传输过程中都可能会受到噪声的污染,一般数字图像系统中