python基于3西格玛准则和拉普拉斯变换实现图片质量检测(模糊检测、遮挡检测)
目录
程序简介
程序调用Python的opencv模块,根据拉普拉斯变换计算像素方差来作为图片的模糊程度和遮挡程度的指标值,然后根据参考值构建正态分布,根据3西格玛准则,判断图片是否异常,最终实现了模糊检测和遮挡检测功能。但是本程序使用的数据集为从VOC2007随机选择的图片,对于固定场景,最好选择对应场景的图片集,以及调整正确的参数。
拉普拉斯变换是工程数学中常用的一种积分变换,也可以用作边缘检测。
3西格玛准则又称为拉依达准则,它是先假设一组检测数据只含有随机误差,对其进行计算处理得到标准偏差,按一定概率确定一个区间,认为凡超过这个区间的误差,就不属于随机误差而是粗大误差,含有该误差的数据应予以剔除。
程序/数据集下载
代码分析
导入模块、路径
# -*- coding: utf-8 -*- from tqdm import tqdm import numpy as np import cv2
构建calLaplacianVar函数,用来对图片进行进行拉普拉斯变换和计算方差
def calLaplacianVar(img,size=None): ''' 计算拉普拉斯方差,图片越模糊,其边缘就越少 所以该方法可用于模糊检测、遮挡检测,衡量图片信息量 img:opencv图像矩阵 size:重定尺寸(宽,高) ''' #灰度化图片 if len(img.shape) == 3: grayImg = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) else: grayImg = img.copy() #重定尺寸,转矩阵为张量 if size is not None: grayImg = cv2.resize(grayImg,size) #经过拉普拉斯变换的图片 transeImg = cv2.Laplacian(grayImg, cv2.CV_64F) #拉普拉斯方差 imgVar = transeImg.var() return imgVar
构建ViewEvaluate类,其中evalDist函数用来读取特定文件夹下所有图片,计算出所有指标值,并形成分布,judgeOutlie作为接口,判断一张图片是否异常,此处使用1.5倍标准差作为异常判断标准
class ViewEvaluate(): def __init__(self,imgDir,size,sigmaTimes=1.5): ''' 利用拉普拉斯方差和均方差假设检验的方法进行视野评估 imgDir:用于计算分布的图片目录 size:重定图片(宽,高) sigmaTimes:标准差倍数内认为是正常值 ''' self.imgDir = imgDir self.size = tuple(size) self.sigmaTimes = sigmaTimes self.evalDist() def evalDist(self): ''' 计算图片目录下所有图片的指标,形成分布 ''' imgNames = tqdm(os.listdir(imgDir))#图片名列表 values = []#指标列表 #计算所有图片的指标 for index,name in enumerate(imgNames): imgNames.set_description("计算图片分布") path = imgDir + '/' + name img = cv2.imdecode(np.fromfile(path,dtype = np.uint8),-1) value = calLaplacianVar(img,size=self.size) values.append(value) values = np.array(values) #假设正常图片指标值近似正太分布,计算正常值范围 sigma = values.std()#标准差 u = values.mean()#均值 self.photoArea = [u-self.sigmaTimes*sigma,u+self.sigmaTimes*sigma] print("当前分布均值%d,标准差%d 正常区间[%d , %d]"%(u,sigma,self.photoArea[0],self.photoArea[1])) def judgeOutlier(self,img): ''' 判断该图片是否异常(0正常 1异常)以及指标值 img:opencv图像矩阵 ''' value = calLaplacianVar(img,size=self.size) judgement = 0#异常判断 if value < self.photoArea[0]: judgement = 1 mark = "异常" if judgement else "正常" print("当前图片指标值为:%d,%s"%(value,mark)) return judgement,value
对程序进行测试,对原图进行遮挡和模糊化,然后用程序进行判断
import os #路径目录 baseDir = ""#当前目录 staticDir = os.path.join(baseDir,'Static')#静态文件目录 resultDir = os.path.join(baseDir,'Result')#结果文件目录 imgDir = staticDir+'/img' size = (250,250) sigmaTimes = 1 viewEvaluate = ViewEvaluate(imgDir,size,sigmaTimes) #本地测试 path = imgDir + '/003713.jpg' color = (0,0,255) img = cv2.imdecode(np.fromfile(path,dtype = np.uint8),-1) img1 = img.copy() judgement,value = viewEvaluate.judgeOutlier(img1) if not judgement: mark = "good" else: mark = "bad" text = "status:%s value:%d"%(mark,value) cv2.putText(img1, text, (30, 30), cv2.FONT_HERSHEY_PLAIN, 2.4, color, 2) #遮挡测试 img2 = img.copy() cv2.rectangle(img2,(0,175),(500,375),(0,0,0),-1) judgement,value = viewEvaluate.judgeOutlier(img2) if not judgement: mark = "good" else: mark = "bad" text = "status:%s value:%d"%(mark,value) cv2.putText(img2, text, (30, 30), cv2.FONT_HERSHEY_PLAIN, 2.4, color, 2) #模糊测试 img3 = cv2.medianBlur(img, 11) judgement,value = viewEvaluate.judgeOutlier(img3) if not judgement: mark = "good" else: mark = "bad" text = "status:%s value:%d"%(mark,value) cv2.putText(img3, text, (30, 30), cv2.FONT_HERSHEY_PLAIN, 2.4, color, 2) #合并3张测试图 combine = np.hstack([img1,img2,img3]) combine = cv2.resize(combine,(900,300)) cv2.imencode('.jpg',combine)[1].tofile(resultDir+'/test.jpg') cv2.imshow('',combine)
计算图片分布: 100%|████████████████████████████████| 102/102 [00:01<00:00, 87.70it/s] 当前分布均值2234,标准差1423 正常区间[810 , 3658] 当前图片指标值为:1564,正常 当前图片指标值为:263,异常 当前图片指标值为:83,异常
从左至右分别为原图、遮挡图和模糊图,对图片的判断写在了图片上方
![show]