Image Processing: Randomly add salt and pepper noise and Gaussian noise Python

Image Processing: Randomly add salt and pepper noise and Gaussian noise Python

Table of contents

Image Processing: Randomly add salt and pepper noise and Gaussian noise Python

1. Common Image Noise

(1) Gaussian noise

(2) Salt and pepper noise

2. Generate image noise

(1) Gaussian noise

(2) Salt and pepper noise (slow speed)

(3) Salt and pepper noise (fast version)

3. Demo test


        Image noise refers to unnecessary or redundant interfering information that exists in image data. In the concept of noise, the signal-to-noise ratio (SNR) is usually used to measure image noise. In layman's terms, it is how much the signal accounts for and how much the noise accounts for. The smaller the SNR, the greater the noise proportion.

[Respect the principle, please indicate the source for reprinting] https://panjinquan.blog.csdn.net/article/details/126542210


1. Common Image Noise

(1) Gaussian noise

        Gaussian noise Gaussian noise refers to a type of noise whose probability density function obeys Gaussian distribution (ie, normal distribution), usually due to sensor noise caused by poor lighting and high temperature.

(2) Salt and pepper noise

        Salt and pepper noise salt-and-pepper noise, also known as impulse noise, is a random white point (salt noise) or black point (pepper noise), usually generated by image sensors, transmission channels, decompression processing, etc. Black and white light and dark spot noise (pepper-black, salt-white). A common and effective means of removing this noise is to use a median filter .


2. Generate image noise

Image noise can be generated by adding noise components to the original image

(1) Gaussian noise

def gaussian_noise(image, mean=0.1, sigma=0.1):
    """
    添加高斯噪声
    :param image:原图
    :param mean:均值
    :param sigma:标准差 值越大,噪声越多
    :return:噪声处理后的图片
    """
    image = np.asarray(image / 255, dtype=np.float32)  # 图片灰度标准化
    noise = np.random.normal(mean, sigma, image.shape).astype(dtype=np.float32)  # 产生高斯噪声
    output = image + noise  # 将噪声和图片叠加
    output = np.clip(output, 0, 1)
    output = np.uint8(output * 255)
    return output

(2) Salt and pepper noise (slow speed)

The conventional method, which needs to traverse each pixel and add salt and pepper noise, is very slow. The Python language does not recommend image pixel traversal operations, after all, the performance is too poor and the speed is too slow (unless written in C/C++ version). We can use numpy's matrix processing to quickly add salt and pepper noise.

def salt_pepper_noise(image: np.ndarray, prob=0.01):
    """
    添加椒盐噪声,该方法需要遍历每个像素,十分缓慢
    :param image:
    :param prob: 噪声比例
    :return:
    """
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            if random.random() < prob:
                image[i][j] = 0 if random.random() < 0.5 else 255
            else:
                image[i][j] = image[i][j]
    return image

(3) Salt and pepper noise (fast version)

We can use numpy's matrix processing to quickly add salt and pepper noise. Basic idea: use np.random.uniform to generate uniform distribution noise of 0~1, and then set the pixel of noise > prob to 0 or 255, so that through the processing of the matrix, salt and pepper noise can be quickly added.

def fast_salt_pepper_noise(image: np.ndarray, prob=0.02):
    """
    随机生成一个0~1的mask,作为椒盐噪声
    :param image:图像
    :param prob: 椒盐噪声噪声比例
    :return:
    """
    image = add_uniform_noise(image, prob * 0.51, vaule=255)
    image = add_uniform_noise(image, prob * 0.5, vaule=0)
    return image


def add_uniform_noise(image: np.ndarray, prob=0.05, vaule=255):
    """
    随机生成一个0~1的mask,作为椒盐噪声
    :param image:图像
    :param prob: 噪声比例
    :param vaule: 噪声值
    :return:
    """
    h, w = image.shape[:2]
    noise = np.random.uniform(low=0.0, high=1.0, size=(h, w)).astype(dtype=np.float32)  # 产生高斯噪声
    mask = np.zeros(shape=(h, w), dtype=np.uint8) + vaule
    index = noise > prob
    mask = mask * (~index)
    output = image * index[:, :, np.newaxis] + mask[:, :, np.newaxis]
    output = np.clip(output, 0, 255)
    output = np.uint8(output)
    return output

3. Demo performance test

Need to use the pybaseutils tool, pip installation can be

# -*-coding: utf-8 -*-
"""
    @Author : panjq
    @E-mail : [email protected]
    @Date   : 2022-07-27 15:23:24
    @Brief  :
"""
import cv2
import random
import numpy as np
from pybaseutils import time_utils


@time_utils.performance("gaussian_noise")
def gaussian_noise(image, mean=0.1, sigma=0.1):
    """
    添加高斯噪声
    :param image:原图
    :param mean:均值
    :param sigma:标准差 值越大,噪声越多
    :return:噪声处理后的图片
    """
    image = np.asarray(image / 255, dtype=np.float32)  # 图片灰度标准化
    noise = np.random.normal(mean, sigma, image.shape).astype(dtype=np.float32)  # 产生高斯噪声
    output = image + noise  # 将噪声和图片叠加
    output = np.clip(output, 0, 1)
    output = np.uint8(output * 255)
    return output


@time_utils.performance("salt_pepper_noise")
def salt_pepper_noise(image: np.ndarray, prob=0.01):
    """
    添加椒盐噪声,该方法需要遍历每个像素,十分缓慢
    :param image:
    :param prob: 噪声比例
    :return:
    """
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            if random.random() < prob:
                image[i][j] = 0 if random.random() < 0.5 else 255
            else:
                image[i][j] = image[i][j]
    return image


@time_utils.performance("fast_salt_pepper_noise")
def fast_salt_pepper_noise(image: np.ndarray, prob=0.02):
    """
    随机生成一个0~1的mask,作为椒盐噪声
    :param image:图像
    :param prob: 椒盐噪声噪声比例
    :return:
    """
    image = add_uniform_noise(image, prob * 0.51, vaule=255)
    image = add_uniform_noise(image, prob * 0.5, vaule=0)
    return image


def add_uniform_noise(image: np.ndarray, prob=0.05, vaule=255):
    """
    随机生成一个0~1的mask,作为椒盐噪声
    :param image:图像
    :param prob: 噪声比例
    :param vaule: 噪声值
    :return:
    """
    h, w = image.shape[:2]
    noise = np.random.uniform(low=0.0, high=1.0, size=(h, w)).astype(dtype=np.float32)  # 产生高斯噪声
    mask = np.zeros(shape=(h, w), dtype=np.uint8) + vaule
    index = noise > prob
    mask = mask * (~index)
    output = image * index[:, :, np.newaxis] + mask[:, :, np.newaxis]
    output = np.clip(output, 0, 255)
    output = np.uint8(output)
    return output


def cv_show_image(title, image, use_rgb=True, delay=0):
    """
    调用OpenCV显示RGB图片
    :param title: 图像标题
    :param image: 输入是否是RGB图像
    :param use_rgb: True:输入image是RGB的图像, False:返输入image是BGR格式的图像
    :return:
    """
    img = image.copy()
    if img.shape[-1] == 3 and use_rgb:
        img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)  # 将BGR转为RGB
    # cv2.namedWindow(title, flags=cv2.WINDOW_AUTOSIZE)
    cv2.namedWindow(title, flags=cv2.WINDOW_NORMAL)
    cv2.imshow(title, img)
    cv2.waitKey(delay)
    return img


if __name__ == "__main__":
    test_file = "test.png"
    image = cv2.imread(test_file)
    prob = 0.02
    for i in range(10):
        out1 = gaussian_noise(image.copy())
        out2 = salt_pepper_noise(image.copy(), prob=prob)
        out3 = fast_salt_pepper_noise(image.copy(), prob=prob)
        print("----" * 10)
    cv_show_image("image", image, use_rgb=False, delay=1)
    cv_show_image("gaussian_noise", out1, use_rgb=False, delay=1)
    cv_show_image("salt_pepper_noise", out2, use_rgb=False, delay=1)
    cv_show_image("fast_salt_pepper_noise", out3, use_rgb=False, delay=0)

Cycle the machine 10 times, the salt_pepper_noise takes an average of 125.49021ms, while the fast_salt_pepper_noise takes an average of 6.12011ms, and the performance is improved by about 60 times, and the generated effect is basically the same

call gaussian_noise elapsed: avg:19.42925ms     total:194.29255ms     count:10
call salt_pepper_noise elapsed: avg:125.49021ms     total:1254.90212ms     count:10
call fast_salt_pepper_noise elapsed: avg:6.12011ms     total:61.20110ms     count:10 

original image Gaussian noise

salt_pepper_noise

fast_salt_pepper_noise

Guess you like

Origin blog.csdn.net/guyuealian/article/details/126542210