椒鹽噪聲 Python實現


最近碰到一個過擬合問題(感覺在工程裏大部分時間都在解決過擬合,只要選正確模型~),想通過增加椒鹽噪聲來增加訓練樣本的多樣性,對椒鹽噪聲有了新的認識——原來 椒鹽噪聲 = 椒噪聲 + 鹽噪聲

椒鹽噪聲概念

椒鹽噪聲又稱爲脈衝噪聲,它是一種隨機出現的白點或者黑點,如下圖。在這裏插入圖片描述
在機器學習的圖像分類任務中,爲圖像增加椒鹽噪聲是一種常用的數據增強方法,這裏就介紹添加椒鹽噪聲的函數(基於python)。

椒鹽噪聲數學定義

信噪比
在噪聲的概念中,通常採用信噪比(Signal-Noise Rate, SNR)衡量圖像噪聲。通俗的講就是信號佔多少,噪聲佔多少,SNR越小,噪聲佔比越大。
在信號系統中,計量單位爲dB,爲10lg(PS/PN), PS和PN分別代表信號和噪聲的有效功率。

在這裏,採用信號像素點的佔比充當SNR,以衡量所添加噪聲的多少。
舉個例,假設一張圖像的寬x高 = 10x10 ,共計100個像素,想讓其中20個像素點變爲噪聲,其餘80個像素點保留原值,則這裏定義的SNR=80/100 = 0.8 。

一開始也說了,椒鹽噪聲 = 椒噪聲 + 鹽噪聲 ,椒鹽噪聲的值爲0(黑色)或者255(白色),這裏假設爲等概率的出現0或者255。

爲圖像添加椒鹽噪聲的的步驟如下:

  1. 依SNR製作mask,用於判斷像素點是原始信號,還是噪聲
  2. 依mask給原圖像賦噪聲值

椒鹽噪聲代碼實現

def addsalt_pepper(img, SNR):
    img_ = img.copy()
    c, h, w = img_.shape
    mask = np.random.choice((0, 1, 2), size=(1, h, w), p=[SNR, (1 - SNR) / 2., (1 - SNR) / 2.])
    mask = np.repeat(mask, c, axis=0)     # 按channel 複製到 與img具有相同的shape
    img_[mask == 1] = 255    # 鹽噪聲
    img_[mask == 2] = 0      # 椒噪聲
    return img_

注意事項,輸入的img的shape有規定,需要是 c,h,w。可自行修改

執行以下腳本,可以查看不同SNR下添加椒鹽噪聲的效果。

# coding: utf-8

import numpy as np
import cv2
from matplotlib import pyplot as plt

def addsalt_pepper(img, SNR):
    img_ = img.copy()
    c, h, w = img_.shape
    mask = np.random.choice((0, 1, 2), size=(1, h, w), p=[SNR, (1 - SNR) / 2., (1 - SNR) / 2.])
    mask = np.repeat(mask, c, axis=0)     # 按channel 複製到 與img具有相同的shape
    img_[mask == 1] = 255    # 鹽噪聲
    img_[mask == 2] = 0      # 椒噪聲

    return img_


img = cv2.imread('your_path.jpg')

SNR_list = [0.9, 0.7, 0.5, 0.3]
sub_plot = [221, 222, 223, 224]

plt.figure(1)
for i in range(len(SNR_list)):
    plt.subplot(sub_plot[i])
    img_s = addsalt_pepper(img.transpose(2, 1, 0), SNR_list[i])     # c,
    img_s = img_s.transpose(2, 1, 0)
    cv2.imshow('PepperandSalt', img_s)
    cv2.waitKey(0)
    plt.imshow(img_s[:,:,::-1])     # bgr --> rgb
    plt.title('add salt pepper noise(SNR={})'.format(SNR_list[i]))  

plt.show()

最終得到小貓圖像如下:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章