如何在python上减少图像的噪声?

如何在python上减少图像的噪声?,python,python-3.x,list,python-2.7,Python,Python 3.x,List,Python 2.7,这是到目前为止我的代码。我完全迷路了,不知道该怎么办。它的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

这是到目前为止我的代码。我完全迷路了,不知道该怎么办。它的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)
第1部分(另见下文第2部分)

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

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

在下一个算法中,中值滤波器的强度由
n
参数控制,在我的例子中,该参数等于7。值
n
意味着我们通过
n
在大小为
n
的平方像素之间取中值

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

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

输入:

输出:

彩色示例:

输入:

输出:


第二部分

我的同位语,我错读了你的问题,而不是“我不能使用cv2”,我读了“我可以使用cv2”,因此实现了下一个OpenCV算法,作为我第一次尝试解决你的任务(第一部分算法后来实现)

根据OpenCV去噪教程,您可以像下面的代码一样去噪图像。它使用函数,如果你有灰度图像,这个函数也有灰度变化

去噪程度由我的代码中的
20,20,14,42
参数控制,去噪非常强,您可以使用默认值(不提供这些数字),它将给出较小的去噪程度。对于您的图像,从默认值
3,3,7,21
开始,也许它们足够了,不需要进行非常强的去噪,然后用这些值进行实验

输入:

输出:

第1部分(另见下文第2部分)

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

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

在下一个算法中,中值滤波器的强度由
n
参数控制,在我的例子中,该参数等于7。值
n
意味着我们通过
n
在大小为
n
的平方像素之间取中值

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

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

输入:

输出:

彩色示例:

输入:

输出:


第二部分

我的同位语,我错读了你的问题,而不是“我不能使用cv2”,我读了“我可以使用cv2”,因此实现了下一个OpenCV算法,作为我第一次尝试解决你的任务(第一部分算法后来实现)

根据OpenCV去噪教程,您可以像下面的代码一样去噪图像。它使用函数,如果你有灰度图像,这个函数也有灰度变化

去噪程度由我的代码中的
20,20,14,42
参数控制,去噪非常强,您可以使用默认值(不提供这些数字),它将给出较小的去噪程度。对于您的图像,从默认值
3,3,7,21
开始,也许它们足够了,不需要进行非常强的去噪,然后用这些值进行实验

输入:

输出:


减少噪声的一个最简单的方法是通过计算每个像素的值来进行模糊,该值等于周围3x3或5x5像素的平均值。正如我在你的代码中看到的,你试图(尽管有编码错误)计算它周围一些像素的中值,这也是一种方法。这看起来像是中值滤波器的开始,它在一定程度上可以有效地对抗噪声。但它根本不完整,你没有定义
r1
-
r4
g1
-
g4
,或者
b1
-
b4
@alex我使用了你实现中值滤波器的想法,并将其改进为使用纯Numpy,如下所示。减少噪声的一个最简单的方法是通过计算每个像素的值来实现模糊,该值等于周围3x3或5x5像素的平均值。正如我在你的代码中看到的,你试图(尽管有编码错误)计算它周围一些像素的中值,这也是一种方法。这看起来像是中值滤波器的开始,它在一定程度上可以有效地对抗噪声。但它一点也不完整,您没有定义
r1
-
r4
g1
-
g4
,或者
b1
-
b4
@alex我使用了您实现中值滤波器的想法,并将其改进为使用纯Numpy,见下文。我不能使用matplotlib。此外,我只允许使用一个参数,它需要是一个图像。你能告诉我如何将你的代码转换成that@alex请看一下我问题的第二部分,第一句话,我在那里说我只是错误地实现了第二部分。所以真正正确的解决方案是我答案开头的第一部分。该算法只使用Numpy。使用该算法。第一部分
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')
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()