首先是噪声的大体分类:

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

雪花噪声:又称高斯噪声

条纹噪声:

细节图如下所示(图像来源,论文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 L1T3:

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

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

可能会有用吧···

以上。

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