我的Speckle(Lee滤波器)为什么会增加噪音而不是减少噪音?

huangapple go评论100阅读模式
英文:

Why is my Speckle (Lee Filter) adding noise instead of reducing noise?

问题

I researched the lee filter according to this: https://pro.arcgis.com/en/pro-app/3.0/help/analysis/raster-functions/speckle-function.htm.

I want it to reduce noise, but it is adding instead.

I have this python function to apply the lee filter to an image:

  1. from scipy.ndimage.filters import uniform_filter
  2. from scipy.ndimage.measurements import variance
  3. def leeFilter(img, size):
  4. img_mean = uniform_filter(img, (size, size))
  5. img_sqr_mean = uniform_filter(img**2, (size, size))
  6. img_variance = img_sqr_mean - img_mean**2
  7. overall_variance = np.var(img)
  8. img_weights = img_variance / (img_variance + overall_variance)
  9. img_output = img_mean + img_weights * (img - img_mean)
  10. return img_output

Then, I'm applying it to my image as such:

  1. currImg = cv2.imread(os.path.join(currPath,f'{i}.png'))
  2. # Get red, green and blue channels
  3. red = currImg[:,:,0]
  4. green = currImg[:,:,1]
  5. blue = currImg[:,:,2]
  6. # Apply the filter
  7. red = lee_filter(red,15)
  8. green = lee_filter(green,15)
  9. blue = lee_filter(blue,15)
  10. # merge channels
  11. currImg[:,:,0] = red
  12. currImg[:,:,1] = green
  13. currImg[:,:,2] = blue
  14. cv2.imwrite(os.path.join(newPath,f'{i}.png'),currImg)

The problem is that using a window size of 15, it looks like it is adding and not lowering the noise of the images. Below is a comparison with the before and after images.

enter image description here

英文:

I researched the lee filter according to this:
https://pro.arcgis.com/en/pro-app/3.0/help/analysis/raster-functions/speckle-function.htm.

I want it to reduce noise, but it is adding instead.

I have this python function to apply the lee filter to an image:

  1. from scipy.ndimage.filters import uniform_filter
  2. from scipy.ndimage.measurements import variance
  3. def leeFilter(img, size):
  4. img_mean = uniform_filter(img, (size, size))
  5. img_sqr_mean = uniform_filter(img**2, (size, size))
  6. img_variance = img_sqr_mean - img_mean**2
  7. overall_variance = np.var(img)
  8. img_weights = img_variance / (img_variance + overall_variance)
  9. img_output = img_mean + img_weights * (img - img_mean)
  10. return img_output

Then, I'm applying it to my image as such:

  1. currImg = cv2.imread(os.path.join(currPath,f'{i}.png'))
  2. # Get red, green and blue channels
  3. red = currImg[:,:,0]
  4. green = currImg[:,:,1]
  5. blue = currImg[:,:,2]
  6. # Apply the filter
  7. red = lee_filter(red,15)
  8. green = lee_filter(green,15)
  9. blue = lee_filter(blue,15)
  10. # merge channels
  11. currImg[:,:,0] = red
  12. currImg[:,:,1] = green
  13. currImg[:,:,2] = blue
  14. cv2.imwrite(os.path.join(newPath,f'{i}.png'),currImg)

The problem is that using a window size of 15, it looks like it is adding and not lowering the noise of the images. Below is a comparison with the before and after images.

enter image description here

答案1

得分: 2

Cris关于估计噪音水平是正确的,但主要问题是算术溢出 - 将计算应用于uint8元素后的结果。

我们可以在lee_filter之前将输入转换为float32,并在lee_filter之后将输出转换回uint8


代码示例:

  1. import cv2
  2. import numpy as np
  3. from scipy.ndimage.filters import uniform_filter
  4. from scipy.ndimage.measurements import variance
  5. def lee_filter(img, size):
  6. img_mean = uniform_filter(img, (size, size))
  7. img_sqr_mean = uniform_filter(img**2, (size, size))
  8. img_variance = img_sqr_mean - img_mean**2
  9. overall_variance = np.var(img)
  10. img_weights = img_variance / (img_variance + overall_variance)
  11. img_output = img_mean + img_weights * (img - img_mean)
  12. return img_output
  13. currImg = cv2.imread('before.png')
  14. # 获取红色、绿色和蓝色通道
  15. red = currImg[:,:,0].astype(np.float32) # 将数据类型从np.uint8转换为np.float32
  16. green = currImg[:,:,1].astype(np.float32)
  17. blue = currImg[:,:,2].astype(np.float32)
  18. # 应用滤波器
  19. red = lee_filter(red, 15)
  20. green = lee_filter(green, 15)
  21. blue = lee_filter(blue, 15)
  22. # 合并通道
  23. currImg[:,:,0] = red
  24. currImg[:,:,1] = green
  25. currImg[:,:,2] = blue
  26. currImg = currImg.round().clip(0, 255).astype(np.uint8) # 将数据从np.float32转换为np.uint8,四舍五入并剪切至0到255
  27. cv2.imwrite('after.png', currImg)
英文:

Cris is right about the estimated noise level, but the main issue is arithmetic overflow - result of applying the computations to uint8 elements.

We may convert the input to float32 before lee_filter, and convert the output back to uint8 after lee_filter.


Code sample:

  1. import cv2
  2. import numpy as np
  3. from scipy.ndimage.filters import uniform_filter
  4. from scipy.ndimage.measurements import variance
  5. def lee_filter(img, size):
  6. img_mean = uniform_filter(img, (size, size))
  7. img_sqr_mean = uniform_filter(img**2, (size, size))
  8. img_variance = img_sqr_mean - img_mean**2
  9. overall_variance = np.var(img)
  10. img_weights = img_variance / (img_variance + overall_variance)
  11. img_output = img_mean + img_weights * (img - img_mean)
  12. return img_output
  13. currImg = cv2.imread('before.png')
  14. # Get red, green and blue channels
  15. red = currImg[:,:,0].astype(np.float32) # Convert dtype from np.uint8 to np.float32
  16. green = currImg[:,:,1].astype(np.float32)
  17. blue = currImg[:,:,2].astype(np.float32)
  18. # Apply the filter
  19. red = lee_filter(red, 15)
  20. green = lee_filter(green, 15)
  21. blue = lee_filter(blue, 15)
  22. # merge channels
  23. currImg[:,:,0] = red
  24. currImg[:,:,1] = green
  25. currImg[:,:,2] = blue
  26. currImg = currImg.round().clip(0, 255).astype(np.uint8) # Convert from np.float32 to np.uint8 with rounding and clipping
  27. cv2.imwrite('after.png', currImg)

Before (before.png):
我的Speckle(Lee滤波器)为什么会增加噪音而不是减少噪音?

After (after.png):
我的Speckle(Lee滤波器)为什么会增加噪音而不是减少噪音?

huangapple
  • 本文由 发表于 2023年5月25日 23:51:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76334174.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定