Colección de métodos básicos para ruido de imagen y eliminación de ruido (implementación de Python)


prefacio

Este artículo se refiere principalmente al Procesamiento de imágenes digitales de González (4.ª edición), presenta algunas formas comunes de ruido en imágenes y métodos de eliminación de ruido de uso común, y brinda el código de implementación de los métodos de filtrado correspondientes.

如果要使用本文代码,建议在Jupyter Notebook环境下运行。

1. Clasificación de ruido

1. Ruido gaussiano

Se refiere a un tipo de ruido que obedece a una distribución gaussiana (distribución normal). La razón principal de su generación es que el campo de visión de la cámara es oscuro y el brillo es desigual al disparar. Al mismo tiempo, la cámara funciona para mucho tiempo y la temperatura es demasiado alta para causar ruido gaussiano .
La función de densidad de probabilidad (PDF) es la siguiente:
inserte la descripción de la imagen aquí
Imagen inicial:
inserte la descripción de la imagen aquí
tenga en cuenta que al agregar ruido, no puede agregar directamente ruido+img, de lo contrario, el resultado final será un espacio en blanco y algunos puntos de ruido esporádicos. La razón es que el requisito de entrada de cv2.imshow es 0-1 float o 0 -255 int .

(1) Visualización de errores:
inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí
(2) Visualización correcta:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')

# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   

cv2.imshow('Gauss noise',img)
cv2.waitKey(0)


(3) Filtro gaussiano
El filtro gaussiano es un filtro de suavizado lineal , generalmente utilizado para eliminar el ruido gaussiano. El valor de cada píxel se obtiene por el promedio ponderado de sí mismo y otros valores de píxel en el vecindario .
Función gaussiana bidimensional:
inserte la descripción de la imagen aquí
Proceso específico:
inserte la descripción de la imagen aquí
Código: Usar cv2.GaussianBlur()la función
inserte la descripción de la imagen aquí
Tenga en cuenta que el radio de desenfoque gaussiano no puede ser un número par
Resultado del filtro:
inserte la descripción de la imagen aquí

2. Ruido venenoso

En definitiva, es un modelo de ruido que se ajusta a la distribución de Poisson, también conocida como ruido de disparo.
inserte la descripción de la imagen aquí

Utilice la función **np.random.poisson()**

import cv2
import random
import numpy as np
img = cv2.imread('A.png')

# 产生泊松噪声
noise = np.random.poisson(lam=20,size=img.shape).astype('uint8')

# 加上噪声
img = img + noise
np.clip(img,0,255)
img = img/255

cv2.imshow('Poisson noise',img)
cv2.waitKey(0)

inserte la descripción de la imagen aquí

Cuanto mayor sea el valor de λ, más profundo será el nivel de ruido.

3. Ruido de sal y pimienta

El ruido de sal y pimienta, también conocido como ruido de impulso, son píxeles en blanco y negro que aparecen aleatoriamente en la imagen. Como su nombre lo indica, ruido de sal y pimienta = ruido de pimienta (valor 0, negro) + ruido de sal (valor 255, blanco)
directamente en el código:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')

# 转化成向量
x = img.reshape(1,-1)  
# 设置信噪比
SNR = 0.85
# 得到要加噪的像素数目
noise_num = x.size * (1-SNR)
# 得到需要加噪的像素值的位置
list = random.sample(range(0,x.size),int(noise_num))

for i in list:
    if random.random() >= 0.5:
        x[0][i] = 0
    else:
        x[0][i] = 255
img1 = x.reshape(img.shape)

cv2.imshow('salt&pepper noise',img1)
cv2.waitKey(0)

inserte la descripción de la imagen aquí
Cuanto menor sea la SNR, mayor será el ruido.

4. Ruido de Rayleigh

Generalmente, es causado por un canal insatisfactorio.La relación entre este y la señal se multiplica.Si la señal está presente, no existirá si la señal no está presente.
La densidad de Rayleigh es útil para modelar histogramas con formas sesgadas.

La función de densidad de probabilidad (PDF) es la siguiente:
inserte la descripción de la imagen aquí
La distribución de Rayleigh dada en muchos lugares es la siguiente fórmula:
inserte la descripción de la imagen aquí
estas dos fórmulas son en realidad la misma fórmula, y solo es necesario realizar la siguiente sustitución de variables para obtener la misma forma que la primera fórmula .
inserte la descripción de la imagen aquí

Cuando se genera ruido de Rayleigh, **np.random.rayleigh()**en realidad se utiliza el método para generarlo, y este método se basa en la segunda fórmula, por lo que solo se necesita especificar un parámetro , y la distribución obtenida es esencialmente la misma que la de la primera fórmula.

código:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')

# 产生瑞利噪声
sigma = 70.0
noise = np.random.rayleigh(sigma, size=img.shape)
# 可以试试下面这个效果
# noise = np.random.rayleigh(img, size=img.shape)

# 加上噪声
img = img + noise
np.clip(img,0,255)
img = img/255

cv2.imshow('Rayleigh noise',img)
cv2.waitKey(0)
print(img.shape)

inserte la descripción de la imagen aquí

5. Ruido irlandés (gamma)

La función de densidad de probabilidad (PDF) es la siguiente: (b es un número entero positivo) La
inserte la descripción de la imagen aquí
distribución exponencial y la distribución chi-cuadrado en realidad se pueden considerar como formas especiales de la distribución gamma.

Cuando b = 1: distribución exponencial,
cuando b = n/2, a = 1/2: distribución chi-cuadrado.
código:

noise = np.random.gamma(shape=10.0,scale=10.0,size=img.shape)
#其他部分同上

inserte la descripción de la imagen aquí

6. Ruido uniforme

La función de densidad de probabilidad (PDF) es la siguiente:
inserte la descripción de la imagen aquí
Código:

noise = np.random.uniform(50,100,img.shape)
#其他部分同上

inserte la descripción de la imagen aquí

2. Método de eliminación de ruido

1. Filtrado medio

1.1 Filtrado de media aritmética

inserte la descripción de la imagen aquí

import cv2
import random
import numpy as np
img = cv2.imread('A.png')

# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   

# 算术平均滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3   #定义滤波核大小
n = 3
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):
    for i in range(rec_img[channel].shape[0]):
        for j in range(rec_img[channel].shape[1]):
            rec_img[channel][i,j] = img1[channel][i:i+m,j:j+n].sum()/(m*n)
rec_img = np.transpose(rec_img,(1,2,0))

cv2.imshow('average',rec_img)
cv2.waitKey(0)

El proceso específico se puede entender con la siguiente figura para comprender
inserte la descripción de la imagen aquí
el efecto de eliminación de ruido:

inserte la descripción de la imagen aquí

1.2 Filtrado de media geométrica

inserte la descripción de la imagen aquí

import cv2
import random
import numpy as np
img = cv2.imread('A.png')

# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   

# 几何均值滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3   #定义滤波核大小
n = 3
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):
    for i in range(rec_img[channel].shape[0]):
        for j in range(rec_img[channel].shape[1]):
            rec_img[channel][i,j] = np.power(np.prod(img1[channel][i:i+m,j:j+n]),1/(m*n))
rec_img = np.transpose(rec_img,(1,2,0))

cv2.imshow('average',rec_img)
cv2.waitKey(0)

Efecto de eliminación de ruido:

inserte la descripción de la imagen aquí
El filtrado de media geométrica es muy sensible a los valores 0 , y el defecto también es obvio, es decir, siempre que un píxel en la ventana tenga un valor de 0, el valor calculado es 0.

1.3 Filtrado de promedio de armónicos

inserte la descripción de la imagen aquí

rec_img[channel][i,j] = 1/(np.power(img1[channel][i:i+m,j:j+n],-1).sum())*(m*n)
# 其余部分同上

inserte la descripción de la imagen aquí

Este método puede manejar tanto el ruido de sal como otros ruidos similares al ruido de Gauss, pero no puede manejar el ruido de pimienta .
### 1.4
inserte la descripción de la imagen aquí
P: El orden del filtro. Útil para reducir o eliminar el ruido de sal y pimienta.

Nota: Cuando Q=0. Filtrado simplificado a media aritmética; Q=1, filtrado simplificado a media armónica.

código:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')

#---------椒盐噪声----------
# 转化成向量
x = img.reshape(1,-1)  
# 设置信噪比
SNR = 0.85
# 得到要加噪的像素数目
noise_num = x.size * (1-SNR)
# 得到需要加噪的像素值的位置
list = random.sample(range(0,x.size),int(noise_num))

for i in list:
    if random.random() >= 0.5:
        x[0][i] = 0
    else:
        x[0][i] = 255
img = x.reshape(img.shape)
img = img/255
#--------------------------

# 反谐波平均滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3   #定义滤波核大小
n = 3
Q = 0.1
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):
    for i in range(rec_img[channel].shape[0]):
        for j in range(rec_img[channel].shape[1]):
            rec_img[channel][i,j] = ((np.power(img1[channel][i:i+m,j:j+n],Q+1)).sum())/((np.power(img1[channel][i:i+m,j:j+n],Q)).sum())
rec_img = np.transpose(rec_img,(1,2,0))

cv2.imshow('average',rec_img)
cv2.waitKey(0)

Mapa de ruido:

inserte la descripción de la imagen aquí
Efecto de eliminación de ruido:

inserte la descripción de la imagen aquí

Nota: El valor de Q no debe ser demasiado grande, de lo contrario, se convertirá en la siguiente imagen (cuando Q=2):

inserte la descripción de la imagen aquí

2. Clasificación y filtrado estadístico

2.1 Filtrado mediano

Un método de eliminación de ruido con el que estamos muy familiarizados es reemplazar el valor del píxel con el valor de la mediana gris en la vecindad del píxel.
inserte la descripción de la imagen aquí
código:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')

# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   

# 中值滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3   #定义滤波核大小
n = 3
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):
    for i in range(rec_img[channel].shape[0]):
        for j in range(rec_img[channel].shape[1]):
            rec_img[channel][i,j] = np.median(img1[channel][i:i+m,j:j+n])
rec_img = np.transpose(rec_img,(1,2,0))

cv2.imshow('median',rec_img)
cv2.waitKey(0)

Efecto de eliminación de ruido:

inserte la descripción de la imagen aquí
o usar directamentecv2.medianBlur()函数

import cv2
import random
import numpy as np
img = cv2.imread('A.png')

# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = np.uint8(img)

# 中值滤波
rec_img = cv2.medianBlur(img,3)

cv2.imshow('median',rec_img)
cv2.waitKey(0)

2.2 Filtrado máximo y mínimo

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
Se utiliza principalmente para:np.amax() 和 np.amin()两个函数

2.3 Filtrado de punto medio

inserte la descripción de la imagen aquí
código:

rec_img[channel][i,j] = (np.amax(img1[channel][i:i+m,j:j+n]) + np.amin(img1[channel][i:i+m,j:j+n]))/2

Efecto de filtrado en el procesamiento de ruido gaussiano :

inserte la descripción de la imagen aquí

2.4 Filtrado de la media alfa modificada

Método de procesamiento: en la vecindad S xy S_{xy}Sx yeliminar dentro de d/2 d/2d /2 valores de gris más bajos yd/2 d/2d /2 valor de gris más alto. g R ( r , c ) g_{R}(r,c)gramoR( R ,c ) significaS xy S_{xy}Sx yEl resto mn − d mn-d enMinnesotad píxeles.

re = 0 re = 0d=0 : se convierte en filtro de media aritmética
d = mn − 1 d=mn-1d=Minnesota1 : Filtrado mediano

inserte la descripción de la imagen aquí
código:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')

# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   

# 修正阿尔法均值滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3  #定义滤波核大小
n = 3
d = 4    #d取偶数
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):
    for i in range(rec_img[channel].shape[0]):
        for j in range(rec_img[channel].shape[1]):
            img2 = np.sort(np.ravel(img1[channel][i:i+m,j:j+n]))  #np.ravel():多维数组变成一维数组
            rec_img[channel][i,j] = (img2[int(d/2):-int(d/2)].sum())*(1/(m*n-d))
rec_img = np.transpose(rec_img,(1,2,0))

cv2.imshow('alpha average',rec_img)
cv2.waitKey(0)

Efecto de eliminación de ruido:

inserte la descripción de la imagen aquí

Resumir

La introducción trata principalmente sobre algunos filtros muy básicos. La función de filtrado solo puede ser efectiva para cierto tipo de ruido, y su efecto de filtrado generalmente no es muy bueno. Para los tipos de ruido complicados en el entorno real, es necesario usar más adecuados, mejores métodos de filtrado, pero estos métodos se basan más o menos en estos métodos básicos para optimizar y mejorar continuamente. Habrá tiempo para actualizar algunos métodos de eliminación de ruido más fuertes más adelante.
Puede haber problemas y deficiencias en algunos lugares, ¡bienvenido a comunicarse con nosotros!

referencias:

[1] Ruan Qiuqi, traducido por Ruan Yuzhi; (EE. UU.) Raphael C. Gonzalez, Richard E. Woods. Digital Image Processing 4th Edition of Foreign E-books and Communication Textbook Series [M]. Beijing: Electronic Industry Press, 2020

Supongo que te gusta

Origin blog.csdn.net/m0_46366547/article/details/129371491
Recomendado
Clasificación