首先是噪声的大体分类:
噪点噪声:又称脉冲噪声、椒盐噪声
雪花噪声:又称高斯噪声
条纹噪声:
细节图如下所示(图像来源,论文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_noiseimage,prob=0.05): ''' 添加椒盐噪声 prob:噪声比例 ''' output = np.zerosimage.shape,np.uint8) thres = 1 - prob for i in rangeimage.shape[0]): for j in rangeimage.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 #printoutput) cv2.imshow"img",output) cv2.waitKey0) cv2.imwrite"noise_check/img.jpg",output) def gasuss_noiseimage, mean=0.2, var=0.005): ''' 添加高斯噪声 mean : 均值 var : 方差 ''' image = np.arrayimage/255, dtype=float) noise = np.random.normalmean, var ** 0.5, image.shape) out = image + noise if out.min) < 0: low_clip = -1. else: low_clip = 0. out = np.clipout, low_clip, 1.0) out = np.uint8out*255) cv2.imshow"gasuss", out) #return out cv2.waitKey0) cv2.imwrite"noise_check/img.jpg",out) #sp_noisecv2.imread"noise_check/5.jpg",cv2.IMREAD_COLOR)) gasuss_noisecv2.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.arraydemo.convert'L'))#灰度化矩阵 printim.shape) printim.dtype) #printim) height=im.shape[0]#尺寸 width=im.shape[1] varlist=[] for i in rangeheight): for j in rangewidth): for k in range16): 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 range0,height-height%3,3): for j in range0,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=powim[i][j],2)+powim[i+1][j],2)+powim[i+2][j],2)+powim[i][j+1],2)+powim[i+1][j+1],2)+powim[i+2][j+1],2)+powim[i][j+2],2)+powim[i+1][j+2],2)+powim[i+2][j+2],2))/9 var=x2-powx,2) varlist.appendroundvar,3))#子窗口的方差值3x3 printim) #printvarlist) T=roundsumvarlist)/lenvarlist),3)#保留3位小数 printT)
检测噪点和雪花的方法如下(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_eecomplex0, 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_eecomplex0, complex1): complex_ret = complex) complex_ret.real = complex0.real + complex1.real complex_ret.image = complex0.image + complex1.image return complex_ret #复数减法 def sub_eecomplex0, complex1): complex_ret = complex) complex_ret.real = complex0.real - complex1.real complex_ret.image = complex0.image - complex1.image return complex_ret #对输入数据进行倒序排列 def forward_input_datainput_data, num): j = num //2 for i in range1, num - 2): ifi < 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_1din_data, num): PI = 3.1415926 forward_input_datain_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 range1, M + 1): B = intmath.pow2, L -1)) #B为指数函数返回值,为float,需要转换integer for J in range0, B): P = math.pow2, M - L) * J for K in rangeJ, num, intmath.pow2, L))): #print "L:%d B:%d, J:%d, K:%d, P:%f" % L, B, J, K, P) complex_ret.real = math.cos2 * PI / num) * P) complex_ret.image = -math.sin2 * PI / num) * P) complex_mul = mul_eecomplex_ret, in_data[K + B]) complex_add = add_eein_data[K], complex_mul) complex_sub = sub_eein_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_1din_data): #in_data = [2,3,4,5,7,9,10,11,100,12,14,11,56,12,67,12] #待测试的x点元素 k=1 while1): if lenin_data)>pow2,k) and lenin_data)<=pow2,k+1):#不足的补0 #fftlen=pow2,k+1) #in_data.extend[0 for i in rangepow2,k+1)-lenin_data))]) fftlen=pow2,k) break k+=1 #变量data为长度为x、元素为complex类实例的list,用于存储输入数据 data = [complex)) for i in rangelenin_data))] #将8个测试点转换为complex类的形式,存储在变量data中 for i in rangelenin_data)): data[i].real = in_data[i] data[i].image = 0.0 ##输出FFT需要处理的数据 #print"The input data:") #for i in rangelenin_data)): # print"x[%d] real: %f, image: %f" % i, data[i].real, data[i].image)) fft_1ddata, fftlen) ##输出经过FFT处理后的结果 #print"The output data:") #for i in rangelenin_data)): # print"X[%d] real: %f, image: %f" % i, data[i].real, data[i].image)) Tnum=0 for i in rangelenin_data)):#虚实值都大于T的才叫偏离 if absdata[i].real)>T and absdata[i].image)>T: Tnum+=1 printTnum) printstrroundTnum/lenin_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.arraydemo.convert'L'))#灰度化矩阵 in_data=[] for item in im: in_data.extenditem) test_fft_1din_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.arraydemo.convert'L'))#灰度化矩阵 printim.shape) printim.dtype) r,g,b=demo.split) #gm=demo.convert'L') #plt.subplot2,2,1) #plt.imshowgm,cmap='gray'),plt.axis'off') #plt.subplot2,2,2) #plt.imshowr,cmap='gray'),plt.axis'off') #plt.subplot2,2,3) #plt.imshowg,cmap='gray'),plt.axis'off') #plt.subplot2,2,4) #plt.imshowb,cmap='gray'),plt.axis'off') #plt.show) rm=np.arrayr) gm=np.arrayg) bm=np.arrayb) height=im.shape[0]#尺寸 width=im.shape[1] midimg=[im,rm,gm,bm] count=0 for i in range4): mid=midimg[i] n=0 while1): if n+3>=height:break for j in range6,width-6,1): grA=mid[n][j] grB=mid[n+3][j] if absgrA-grB)>T1: L1=0 L2=0 for k in rangej-6,j+6,1): L1+=absmid[n][k]-grA) L2+=absmid[n][k]-mid[n+3][k]) #printL1) #printL2) #print"-----") if L1<T2 and L2>T3: count+=1 n+=10 #printcount) sum=height-3)*4*width-12) #printcount/sum) res=roundcount/sum,5)#保留3位小数 printstrres*100)+"%")
原图是视频组播电视图,噪声图是网上找的···
可能会有用吧···
以上。
博客记录,从我做起。我是会武术之白猫,转载请注明。