【问题标题】:how to reduce the noise of an image on python?如何减少python上图像的噪声?
【发布时间】:2021-02-27 04:04:46
【问题描述】:

到目前为止,这是我的代码。我完全迷失了,不知道该怎么办。它的python语言。我不能使用 cv2 或 matpolibic。我只被允许使用 cimpl 和 numpy

from Cimpl import*
import numpy as np 
def reduce_noise (image: Image) -> Image:
    new_image = copy(image)
    for pixel in image:
        X, Y, (r, g, b) = pixel

        r_list = [r, r1, r2, r3, r4]
        r_list.sort()
        new_r = r_list[2]
        
        g_list = [g, g1, g2, g3, g4]
        g_list.sort()
        new_g = g_list[2]
        
        b_list = [b, b1, b2, b3, b4]
        b_list.sort()
        new_b = b_list[2]
        reduce_noise = create_color(new_r, new_g, new_b)
        set_color(new_image, X, Y, reduce_noise)
        
    return new_image

image = load_image (choose_file())
show (image) 
new_image = reduce_noise(image)
show (new_image)

【问题讨论】:

  • 一种最简单的降噪方法是通过计算每个像素的平均值来进行模糊处理,该值等于其周围 3x3 或 5x5 像素的平均值。正如我在您的代码中看到的那样,您尝试(尽管有编码错误)计算它周围一些像素的中值,这也是一种方法。
  • 这看起来像是中值滤波器的开始,它对噪声有一定的效果。但它一点也不完整,你没有定义r1-r4g1-g4,或者b1-b4
  • @alex 我使用了你实现中值滤波器的想法并改进了它以使用纯 Numpy,请参阅下面的 my answer

标签: python python-3.x list python-2.7


【解决方案1】:

第 1 部分(另请参阅下面的第 2 部分)

我决定改进你的去噪算法尝试。正如我从您的代码中看到的那样,您尝试(有编码错误)实现中值滤波器,在每个像素周围取几个像素的中值。

我在纯 Numpy 中实现了下一个算法。但是要从/向我使用 PIL 库的文件读取和写入图像,只需将此 PIL 用法替换为您喜欢的任何读取和写入文件的 numpy 数组。我只在第一行和最后一行代码上使用了 PIL。仅供测试使用的PIL库可以pip install pillow安装,它是python中最流行的图像库之一。

在下一个算法中,中值滤波器的强度由n 参数控制,在我的情况下等于 7。值n 表示我们在大小为n 的正方形像素中取中值乘以n

我的代码适用于灰色和彩色图像,请参阅代码后的灰色示例和灰色示例后的彩色示例。

Try it online!

def reduce_noise(a, n = 7):
    import numpy as np
    am = np.zeros(
        (n, n) + (a.shape[0] - n + 1, a.shape[1] - n + 1) + a.shape[2:],
        dtype = a.dtype
    )
    for i in range(n):
        for j in range(n):
            am[i, j] = a[i:i + am.shape[2], j:j + am.shape[3]]
    am = np.moveaxis(am, (0, 1), (-2, -1)).reshape(*am.shape[2:], -1)
    am = np.median(am, axis = -1)
    if am.dtype != a.dtype:
        am = (am.astype(np.float64) + 10 ** -7).astype(a.dtype)
    return am
    
import PIL.Image, numpy as np
a = np.array(PIL.Image.open('noised.jpg'))
a = reduce_noise(a)
PIL.Image.fromarray(a).save('noised_out.png')

灰色示例(后面的彩色示例):

输入:

输出:

彩色示例:

输入:

输出:


第 2 部分

我的道歉,我误读了你的问题,而不是“我不能使用 cv2”,我读的是“我可以使用 cv2”,因此实施了下一个 OpenCV 算法作为我第一次尝试解决你的任务(第 1 部分算法是稍后实施)。

根据this OpenCV 去噪教程,您可以像下面的代码一样对图像进行去噪。它使用cv2.fastNlMeansDenoisingColored()函数,如果你有灰度图像,这个函数也有灰度变体。

去噪度在我的代码中由20, 20, 14, 42参数控制,去噪很强,你可以使用默认值(不提供这些数字),它会给出更小的去噪度。对于您的图像,从默认值3, 3, 7, 21 开始,也许它们就足够了,不需要非常强的去噪,并尝试使用这些值。

Try it online!

import numpy as np, cv2
from matplotlib import pyplot as plt
img = cv2.imread('birds.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
dst = cv2.fastNlMeansDenoisingColored(img, None, 20, 20, 14, 42)
cv2.imwrite('birds_out.png', cv2.cvtColor(dst, cv2.COLOR_RGB2BGR))
plt.subplot(121); plt.imshow(img)
plt.subplot(122); plt.imshow(dst)
plt.show()

输入:

输出:

【讨论】:

  • 我不能使用 matplotlib。另外,我只能使用一个需要是图像的参数。你能告诉我如何将你的代码转换成那个
  • @alex 请看一下我的问题的第 2 部分,第一句话,我告诉那里我只是错误地实施了第 2 部分。所以实际正确的解决方案是我的答案开始时的第 1 部分。那里的算法只使用 Numpy。使用该算法。 Part 1函数reduce_noise()只有一个参数,大家可以这样调用reduce_noise(img)。第二个参数是可选的,你不需要在调用中使用它。您实际上可以删除它,只需将其从函数中删除并将函数体的第一行添加为n = 7,即只需将此n 参数移动到代码体的第一行。
  • @alex 另外,参数n = 7 控制降噪强度。为了去除噪点更强,增加它,生成的图像将更加降噪但也更加模糊。为了减少噪点,减少它,然后图像会变得不那么模糊,但仍然会留下一些噪点。在现实生活中可能好的价值是n = 5,如果噪音不强你可以使用n = 3。只是一个小建议,如果可能的话,对n 使用奇数,即 1 3 5 7 9 11,最好不要使用 2 4 8 10 12(但仍然可能,不会有错误)。只需尝试不同的 n 值。
  • @alex 如果最终我的回答对您来说是正确的,请不要忘记接受它和/或支持它。 Accept/UpVote 可以在我的答案顶部从顶部向左进行。有 CheckMark 接受和上箭头 upvote。
  • 我将 (a) 定义为什么,因为我不使用它作为参数?就像代码 a.shape 中显示的那样,我不确定它到底是什么意思,也不知道如何使用或分配它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2017-04-30
  • 2014-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多