OpenCV implements basic methods of image noise and denoising

1. Noise classification

1. Gaussian noise

Refers to a type of noise that obeys Gaussian distribution (normal distribution). The main reason for its generation is that the camera has a dark field of view and uneven brightness when shooting. At the same time, the camera works for a long time and the temperature is too high, which can also 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:

Initial image:

Note that when adding noise, you cannot directly add noise+img, otherwise the final result will be a blank and a few scattered noise points. The reason is that the input requirement of cv2.imshow is 0-1 float or 0-255 int.

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   

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 a weighted average of itself and other pixel values ​​in the neighborhood.

Two-dimensional Gaussian function:

Specific process:

Code: Using cv2.GaussianBlur() function

Note that the Gaussian blur radius cannot be an even number.

Filter results:

2. Poisson noise

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

Use the **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)

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

3. Salt and pepper noise

Salt and pepper noise, also known as impulse noise, is a random appearance of black and white pixels on the image. As the name suggests, salt and pepper noise = pepper noise (value is 0, black) + salt noise (value is 255, white)

Go directly to 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)

The smaller the SNR, the greater the noise.

4. Rayleigh noise

It is generally caused by the imperfection of the channel. Its relationship with the signal is multiplication. When the signal is there, it is not there. When the signal is not there, it is not there.

Rayleigh density is useful for modeling skewed shaped histograms.

When generating Rayleigh noise, the **np.random.rayleigh()** method is actually used, and this method is based on the second formula, so you only need to specify one parameter, and the resulting distribution is The first formula is essentially the same.

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)

5. Irish (gamma) noise

The probability density function (PDF) is as follows: (b is a positive integer)

The exponential distribution and the chi-square distribution can actually be regarded as special forms of the gamma distribution.

When b = 1: exponential distribution;

b =n/2, a = 1/2: Chi-square distribution.

Code:

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

6. Uniform noise

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

2. Denoising method

1. Mean filtering

1.1 Arithmetic mean filtering

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 help of the following figure

Denoising effect:

1.2 Geometric mean filtering

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:

Geometric mean filtering is very sensitive to 0 values, and its flaw is also obvious, that is, when one pixel in the window has a value of 0, the calculated value is 0.

1.3 Harmonic average filtering

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

This method can handle both salt noise and other noise similar to Gaussian noise, but it cannot handle pepper noise.

2. Statistical sorting and filtering

2.1 Median filtering

A denoising method that we are very familiar with is to replace the value of a pixel with the grayscale median value in the pixel neighborhood.

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:

Or use the cv2.medianBlur() function directly

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 value filtering

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:

2.4 Modified Alpha Mean Filter

Processing method: Delete d / 2 d/2 d/2 lowest gray values ​​and d / 2 d/2 d/2 highest gray values ​​in the neighborhood S x y S_{xy} Sxy​. g R ( r , c ) g_{R}(r,c) gR​(r,c) represents the remaining m n − d mn-d mn−d pixels in S x y S_{xy} Sxy​.

d = 0 d=0 d=0: becomes arithmetic mean filtering

d = m n − 1 d=mn-1 d=mn−1: median filtering

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:

Supongo que te gusta

Origin blog.csdn.net/qq_53545309/article/details/134586016
Recomendado
Clasificación