Collection of basic methods for image noise and denoising (Python implementation)


foreword

This article mainly refers to Gonzalez's Digital Image Processing (4th Edition), introduces some common forms of noise in pictures and commonly used denoising methods, and gives the implementation code of the corresponding filtering methods.

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

1. Noise classification

1. Gaussian noise

Refers to a type of noise that obeys a Gaussian distribution (normal distribution). The main reason for its generation is that the field of view of the camera is dark and the brightness is uneven when shooting. At the same time, the camera works for a long time and the temperature is too high to cause Gaussian noise . , In addition, the white body noise and mutual influence of circuit components are also one of the important reasons for Gaussian noise.
The probability density function (PDF) is as follows:
insert image description here
Initial picture:
insert image description here
Note that when adding noise, you cannot directly add noise+img, otherwise the final result will be a blank and a few sporadic noise points. The reason is that the input requirement of cv2.imshow is 0-1 float or 0 -255 int .

(1) Error display:
insert image description here

insert image description here
(2) Correct display:

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) Gaussian filter
Gaussian filter is a linear smoothing filter , generally used to eliminate Gaussian noise. The value of each pixel is obtained by the weighted average of itself and other pixel values ​​in the neighborhood .
Two-dimensional Gaussian function:
insert image description here
Specific process:
insert image description here
Code: Use cv2.GaussianBlur()the function
insert image description here
Note that the Gaussian blur radius cannot be an even number
Filter result:
insert image description here

2. Poisson noise

In short, it is a noise model that conforms to the Poisson distribution, also known as shot noise.
insert image description here

Use **np.random.poisson()** function

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)

insert image description here

The larger the λ value, the deeper the noise level.

3. Salt and pepper noise

Salt and pepper noise, also known as impulse noise, is black and white pixels that randomly appear on the image. As the name implies, salt and pepper noise = pepper noise (value 0, black) + salt noise (value 255, white)
directly on the code:

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)

insert image description here
The smaller the SNR, the greater the noise.

4. Rayleigh noise

Generally, it is caused by an unsatisfactory channel. The relationship between it and the signal is multiplied. If the signal is present, it will not exist if the signal is not present.
Rayleigh density is useful for modeling histograms with skewed shapes.

The probability density function (PDF) is as follows:
insert image description here
The Rayleigh distribution given in many places is the following formula:
insert image description here
these two formulas are actually the same formula, and only need to do the following variable substitution to get the same form as the first formula.
insert image description here

When generating Rayleigh noise, **np.random.rayleigh()**the method is actually used to generate it, and this method is based on the second formula, so only one parameter needs to be specified , and the obtained distribution is essentially the same as that of the first formula.

code:

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)

insert image description here

5. Irish (gamma) noise

The probability density function (PDF) is as follows: (b is a positive integer) The
insert image description here
exponential distribution and the chi-square distribution can actually be regarded as special forms of the gamma distribution.

When b = 1: exponential distribution;
when b = n/2, a = 1/2: chi-square distribution.
code:

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

insert image description here

6. Uniform noise

The probability density function (PDF) is as follows:
insert image description here
Code:

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

insert image description here

2. Denoising method

1. Mean filtering

1.1 Arithmetic mean filtering

insert image description here

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)

The specific process can be understood with the following figure to understand
insert image description here
the denoising effect:

insert image description here

1.2 Geometric mean filtering

insert image description here

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)

Denoising effect:

insert image description here
Geometric mean filtering is very sensitive to 0 values , and the defect is also obvious, that is, as long as one pixel in the window has a value of 0, the calculated value is 0.

1.3 Harmonic Average Filtering

insert image description here

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

insert image description here

This method can handle both salt noise and other noises similar to Gaussian noise, but it cannot handle pepper noise .
### 1.4
insert image description here
Q: The order of the filter. Useful for reducing or eliminating salt and pepper noise.

Note: When Q=0. Simplified to arithmetic average filtering; Q=1, simplified to harmonic average filtering.

code:

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)

Noise map:

insert image description here
Denoising effect:

insert image description here

Note: The value of Q should not be too large, otherwise it will become the following picture (when Q=2):

insert image description here

2. Statistical sorting and filtering

2.1 Median filtering

A denoising method that we are very familiar with is to replace the pixel value with the gray median value in the pixel neighborhood.
insert image description here
code:

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)

Denoising effect:

insert image description here
or directly usecv2.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 Maximum and minimum filtering

insert image description here
insert image description here
Mainly used to:np.amax() 和 np.amin()两个函数

2.3 Midpoint filtering

insert image description here
code:

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

Filtering effect on Gaussian noise processing:

insert image description here

2.4 Modified Alpha Mean Filtering

Processing method: in the neighborhood S xy S_{xy}Sxydelete within d/2 d/2d /2 lowest gray values ​​andd/2 d/2d /2 highest gray value. g R ( r , c ) g_{R}(r,c)gR(r,c ) meansS xy S_{xy}SxyThe remaining mn − d mn-d inmnd pixels.

d = 0 d=0 d=0 : become arithmetic mean filter
d = mn − 1 d=mn-1d=mn1 : Median filtering

insert image description here
code:

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)

Denoising effect:

insert image description here

Summarize

The introduction is mainly about some very basic filters. The filtering function can only be effective for a certain type of noise, and its filtering effect is generally not very good. For the complicated noise types in the real environment, it is necessary to use more suitable, Better filtering methods, but these methods are more or less based on these basic methods to continuously optimize and improve. There will be time to update some stronger denoising methods later.
There may be problems and deficiencies in some places, welcome to communicate with us!

references:

[1] Ruan Qiuqi, translated by Ruan Yuzhi; (US) 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

Guess you like

Origin blog.csdn.net/m0_46366547/article/details/129371491