首先是噪聲的大體分類:
噪點噪聲:又稱脈沖噪聲、椒鹽噪聲
雪花噪聲:又稱高斯噪聲
條紋噪聲:
細節圖如下所示(圖像來源,論文http://www.doc88.com/p-2572496212147.html)



分析完這些噪聲的大致分布情況之后
首先需要作出這些噪聲圖(原型來自https://www.jb51.net/article/162073.htm)
import cv2 from PIL import Image from PIL import ImageChops import numpy as np import time import pytesseract import warnings import math import random def sp_noise(image,prob=0.05): ''' 添加椒鹽噪聲 prob:噪聲比例 ''' output = np.zeros(image.shape,np.uint8) thres = 1 - prob for i in range(image.shape[0]): for j in range(image.shape[1]): rdn = random.random() if rdn < prob: output[i][j] = 0 elif rdn > thres: output[i][j] = 255 else: output[i][j] = image[i][j] #return output #print(output) cv2.imshow("img",output) cv2.waitKey(0) cv2.imwrite("noise_check/img.jpg",output) def gasuss_noise(image, mean=0.2, var=0.005): ''' 添加高斯噪聲 mean : 均值 var : 方差 ''' image = np.array(image/255, dtype=float) noise = np.random.normal(mean, var ** 0.5, image.shape) out = image + noise if out.min() < 0: low_clip = -1. else: low_clip = 0. out = np.clip(out, low_clip, 1.0) out = np.uint8(out*255) cv2.imshow("gasuss", out) #return out cv2.waitKey(0) cv2.imwrite("noise_check/img.jpg",out) #sp_noise(cv2.imread("noise_check/5.jpg",cv2.IMREAD_COLOR)) gasuss_noise(cv2.imread("noise_check/5.jpg",cv2.IMREAD_COLOR))
檢測噪點和雪花的代碼如下(均方誤差法,思路來源https://blog.csdn.net/twinkle_star1314/article/details/74858253)
import cv2 from PIL import Image from PIL import ImageChops import numpy as np import time import pytesseract import warnings warnings.filterwarnings("ignore") demo=Image.open("noise_check//1.jpg") im=np.array(demo.convert('L'))#灰度化矩陣 print(im.shape) print(im.dtype) #print(im) height=im.shape[0]#尺寸 width=im.shape[1] varlist=[] for i in range(height): for j in range(width): for k in range(16): if im[i][j]>=k*16 and im[i][j]<(k+1)*16:#16級量化 im[i][j]=8*(k*2+1) break for i in range(0,height-height%3,3): for j in range(0,width-width%3,3): x=(im[i][j]+im[i+1][j]+im[i+2][j]+im[i][j+1]+im[i+1][j+1]+im[i+2][j+1]+im[i][j+2]+im[i+1][j+2]+im[i+2][j+2])/9 x2=(pow(im[i][j],2)+pow(im[i+1][j],2)+pow(im[i+2][j],2)+pow(im[i][j+1],2)+pow(im[i+1][j+1],2)+pow(im[i+2][j+1],2)+pow(im[i][j+2],2)+pow(im[i+1][j+2],2)+pow(im[i+2][j+2],2))/9 var=x2-pow(x,2) varlist.append(round(var,3))#子窗口的方差值3x3 print(im) #print(varlist) T=round(sum(varlist)/len(varlist),3)#保留3位小數 print(T)
檢測噪點和雪花的方法如下(FFT法)
from PIL import Image import numpy as np import math T=50#閾值設定,大於T則判定偏離xy軸過多 #復數類 class complex: def __init__(self): self.real = 0.0 self.image = 0.0 #復數乘法 def mul_ee(complex0, complex1): complex_ret = complex() complex_ret.real = complex0.real * complex1.real - complex0.image * complex1.image complex_ret.image = complex0.real * complex1.image + complex0.image * complex1.real return complex_ret #復數加法 def add_ee(complex0, complex1): complex_ret = complex() complex_ret.real = complex0.real + complex1.real complex_ret.image = complex0.image + complex1.image return complex_ret #復數減法 def sub_ee(complex0, complex1): complex_ret = complex() complex_ret.real = complex0.real - complex1.real complex_ret.image = complex0.image - complex1.image return complex_ret #對輸入數據進行倒序排列 def forward_input_data(input_data, num): j = num //2 for i in range(1, num - 2): if(i < j): complex_tmp = input_data[i] input_data[i] = input_data[j] input_data[j] = complex_tmp #print "forward x[%d] <==> x[%d]" % (i, j) k = num // 2 while (j >= k): j = j - k k = k // 2 j = j + k #實現1D FFT def fft_1d(in_data, num): PI = 3.1415926 forward_input_data(in_data, num) #倒序輸入數據 #計算蝶形級數,也就是迭代次數 M = 1 #num = 2^m tmp = num // 2; while (tmp != 1): M = M + 1 tmp = tmp // 2 #print "FFT level:%d" % M complex_ret = complex() for L in range(1, M + 1): B = int(math.pow(2, L -1)) #B為指數函數返回值,為float,需要轉換integer for J in range(0, B): P = math.pow(2, M - L) * J for K in range(J, num, int(math.pow(2, L))): #print "L:%d B:%d, J:%d, K:%d, P:%f" % (L, B, J, K, P) complex_ret.real = math.cos((2 * PI / num) * P) complex_ret.image = -math.sin((2 * PI / num) * P) complex_mul = mul_ee(complex_ret, in_data[K + B]) complex_add = add_ee(in_data[K], complex_mul) complex_sub = sub_ee(in_data[K], complex_mul) in_data[K] = complex_add in_data[K + B] = complex_sub #print "A[%d] real: %f, image: %f" % (K, in_data[K].real, in_data[K].image) # print "A[%d] real: %f, image: %f" % (K + B, in_data[K + B].real, in_data[K + B].image) def test_fft_1d(in_data): #in_data = [2,3,4,5,7,9,10,11,100,12,14,11,56,12,67,12] #待測試的x點元素 k=1 while(1): if len(in_data)>pow(2,k) and len(in_data)<=pow(2,k+1):#不足的補0 #fftlen=pow(2,k+1) #in_data.extend([0 for i in range(pow(2,k+1)-len(in_data))]) fftlen=pow(2,k) break k+=1 #變量data為長度為x、元素為complex類實例的list,用於存儲輸入數據 data = [(complex()) for i in range(len(in_data))] #將8個測試點轉換為complex類的形式,存儲在變量data中 for i in range(len(in_data)): data[i].real = in_data[i] data[i].image = 0.0 ##輸出FFT需要處理的數據 #print("The input data:") #for i in range(len(in_data)): # print("x[%d] real: %f, image: %f" % (i, data[i].real, data[i].image)) fft_1d(data, fftlen) ##輸出經過FFT處理后的結果 #print("The output data:") #for i in range(len(in_data)): # print("X[%d] real: %f, image: %f" % (i, data[i].real, data[i].image)) Tnum=0 for i in range(len(in_data)):#虛實值都大於T的才叫偏離 if abs(data[i].real)>T and abs(data[i].image)>T: Tnum+=1 print(Tnum) print(str(round(Tnum/len(in_data),4)*100)+"%") #test the 1d fft #in_data=[2,3,4,5,7,9,10,11] demo=Image.open("noise_check//5.jpg") im=np.array(demo.convert('L'))#灰度化矩陣 in_data=[] for item in im: in_data.extend(item) test_fft_1d(in_data)
以下為原圖、均方誤差法結果、FFT法結果















可以看出FFT法比均方誤差法要准確,雖然時間上也更長···
對於正常圖片,這個FFT百分比一般不超過94%




對於噪聲較小的也能在這個數值上體現出來:










要是更小的噪聲的話···
可能准確率就不行了···
條紋噪聲的檢測和上述不同
不知道如何才能生成條紋噪聲···
按照上面那個論文的思路倒是將代碼寫了出來,還未經過測試所以正確率不能保證
from PIL import Image import numpy as np import warnings T1=100#閾值1,通道行差 T2=1000#閾值2,A通道差絕對和 T3=1000#閾值3,AB通道絕對和 #算法來源,論文http://www.doc88.com/p-2572496212147.html warnings.filterwarnings("ignore") demo=Image.open("noise_check//21.jpg") im=np.array(demo.convert('L'))#灰度化矩陣 print(im.shape) print(im.dtype) r,g,b=demo.split() #gm=demo.convert('L') #plt.subplot(2,2,1) #plt.imshow(gm,cmap='gray'),plt.axis('off') #plt.subplot(2,2,2) #plt.imshow(r,cmap='gray'),plt.axis('off') #plt.subplot(2,2,3) #plt.imshow(g,cmap='gray'),plt.axis('off') #plt.subplot(2,2,4) #plt.imshow(b,cmap='gray'),plt.axis('off') #plt.show() rm=np.array(r) gm=np.array(g) bm=np.array(b) height=im.shape[0]#尺寸 width=im.shape[1] midimg=[im,rm,gm,bm] count=0 for i in range(4): mid=midimg[i] n=0 while(1): if n+3>=height:break for j in range(6,width-6,1): grA=mid[n][j] grB=mid[n+3][j] if abs(grA-grB)>T1: L1=0 L2=0 for k in range(j-6,j+6,1): L1+=abs(mid[n][k]-grA) L2+=abs(mid[n][k]-mid[n+3][k]) #print(L1) #print(L2) #print("-----") if L1<T2 and L2>T3: count+=1 n+=10 #print(count) sum=(height-3)*4*(width-12) #print(count/sum) res=round(count/sum,5)#保留3位小數 print(str(res*100)+"%")
原圖是視頻組播電視圖,噪聲圖是網上找的···
可能會有用吧···




以上。
博客記錄,從我做起。我是會武術之白貓,轉載請注明。
