• 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_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)+"%")

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

    可能会有用吧···

     以上。

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

  • 相关阅读:
    Python----定义
    [转载]Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)
    彻底明白IP地址——计算相关地址
    [转载] 教你如何迅速秒杀掉:99%的海量数据处理面试题
    [转载]从B 树、B+ 树、B* 树谈到R 树
    [转载]Java抽象类和接口的学习
    [转载]字符串匹配的Boyer-Moore算法
    [转载]字符串匹配的KMP算法
    [转载]孤儿进程与僵尸进程[总结]
    [转载]Huffman编码压缩算法
  • 原文地址:https://www.cnblogs.com/ljy1227476113/p/12171379.html
Copyright © 2020-2023  润新知