1. 程式人生 > >python 影象增噪演算法

python 影象增噪演算法

matlab版本的有非常nb的庫函式,很適合工程開發

pyhton版本的適合學習基礎理論知識

使用python產生加性零均值高斯噪聲:是對每一個點的灰度值加上一個隨機數,使用Box-Muller演算法,該演算法用均勻分佈生成的兩組獨立的隨機數通過以下公式生成正態分佈隨機變數X、Y,具體公式如下:

Box-Muller 是產生隨機數的一種方法。Box-Muller 演算法隱含的原理非常深奧,但結果卻是相當簡單。它一般是要得到服從正態分佈的隨機數,基本思想是先得到服從均勻分佈的隨機數再將服從均勻分佈的隨機數轉變為服從正態分佈。

# -*- coding: utf-8 -*-
# 加性零均值高斯噪聲


import cv2
import numpy as np

fn = "64.png"
img_1 = cv2.imread(fn)
img = cv2.cvtColor(img_1, cv2.COLOR_BGR2GRAY)

param = 20
# 灰階範圍
grayscale = 256
w = img.shape[1]
h = img.shape[0]
newimg = np.zeros((h, w), np.uint8)

for x in range(0, h):
    for y in range(0, w, 2):
        r1 = np.random.random_sample()
        r2 = np.random.random_sample()
        z1 = param * np.cos(2 * np.pi * r2) * np.sqrt((-2) * np.log(r1))
        z2 = param * np.sin(2 * np.pi * r2) * np.sqrt((-2) * np.log(r1))


        fxy = int(img[x, y] + z1)#img畫素點的值
        fxy1 = int(img[x, y + 1] + z2)
        # f(x,y)
        if fxy < 0:
            fxy_val = 0
        elif fxy > grayscale - 1:
            fxy_val = grayscale - 1
        else:
            fxy_val = fxy
        # f(x,y+1)
        if fxy1 < 0:
            fxy1_val = 0
        elif fxy1 > grayscale - 1:
            fxy1_val = grayscale - 1
        else:
            fxy1_val = fxy1
        newimg[x, y] = fxy_val
        newimg[x, y + 1] = fxy1_val

cv2.imshow('preview', newimg)
cv2.imwrite("F:\\projec_tt\\create_noise\\pic_2\\test2.png",newimg)
cv2.waitKey()

效果圖涉及軍工機密,這裡就不放了!

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

在這裡,採用訊號畫素點的佔比充當SNR,以衡量所新增噪聲的多少。 舉個例,假設一張影象的寬x高 = 10x10 ,共計100個畫素,想讓其中20個畫素點變為噪聲,其餘80個畫素點保留原值,則這裡定義的SNR=80/100 = 0.8 。 椒鹽噪聲又稱為脈衝噪聲,它是一種隨機出現的白點或者黑點,如下圖。

1.     椒鹽噪聲(Salt And Pepper Noise)

椒鹽噪聲是一種因為訊號脈衝強度引起的噪聲,信噪比(Signal NoiseRate)是衡量影象噪聲的一個數字指標。

給一副數字影象加上椒鹽噪聲的處理順序應該如下:

1.指定信噪比 SNR 其取值範圍在[0, 1]之間 2.計算總畫素數目 SP, 得到要加噪的畫素數目 NP = SP * (1-SNR) 3.隨機獲取要加噪的每個畫素位置P(i, j) 4.指定畫素值為255或者0。 5.重複c, d兩個步驟完成所有畫素的NP個畫素

2.     高斯噪聲(Gaussian Noise)

高斯噪聲的密度取決於公式G(x, sigma) 其中X是代表平均值,sigma代表的標準方差,每個輸入畫素 Pin, 

一個正常的高斯取樣分佈公式G(d), 得到輸出畫素Pout.

       Pout = Pin + XMeans + sigma *G(d)

其中d為一個線性的隨機數,G(d)是隨機數的高斯分佈隨機值。

給一副數字影象加上高斯噪聲的處理順序如下:

a.      輸入引數sigam 和 X mean

b.      以系統時間為種子產生一個偽隨機數

c.      將偽隨機數帶入G(d)得到高斯隨機數

d.      根據輸入畫素計算出輸出畫素

e.      重新將畫素值防縮在[0 ~ 255]之間

f.       迴圈所有畫素

g.      輸出影象  

import cv2
import numpy as np
def saltpepper(img,n):
    m=int((img.shape[0]*img.shape[1])*n)
    for a in range(m):
        i=int(np.random.random()*img.shape[1])
        j=int(np.random.random()*img.shape[0])
        if img.ndim==2:
            img[j,i]=255
        elif img.ndim==3:
            img[j,i,0]=255
            img[j,i,1]=255
            img[j,i,2]=255
    for b in range(m):
        i=int(np.random.random()*img.shape[1])
        j=int(np.random.random()*img.shape[0])
        if img.ndim==2:
            img[j,i]=0
        elif img.ndim==3:
            img[j,i,0]=0
            img[j,i,1]=0
            img[j,i,2]=0
    return img



img=cv2.imread('F:\\projec_tt\\create_noise\\pic_3\\64.png')
saltImage=saltpepper(img,0.01)
cv2.imshow('F:\projec_tt\create_noise\pic_3\saltImage',saltImage)
cv2.waitKey(0)
cv2.destroyAllWindows()

輸出加噪以後的影象

致謝 :