python检测图片噪声(噪点噪声、雪花噪声、条纹噪声)

首先是噪声的大体分类:

噪点噪声:又称脉冲噪声、椒盐噪声

雪花噪声:又称高斯噪声

条纹噪声:

细节图如下所示(图像来源,论文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)+"%")

原图是视频组播电视图,噪声图是网上找的···

可能会有用吧···

 以上。

博客记录,从我做起。我是会武术之白猫,转载请注明。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注