关键字:blur detection
Function:图像的清晰度检测英文表达为 image blue detection; 以此为关键字可以找到很多有关清晰度检测的demo和算法。
图像的清晰度检测方法主要分为两种情况:
- 一种是根据已有的图像,来判断现在的图像是否模糊;
- 另一种是在无参考图像的情况下,判断图像是否模糊;
我们目前解决的问题属于 无参考图像的质量评价
根据参考文献[8,9]可以得知在无参考图像下的,比较好的方法有:Brenner 梯度函数、Tenengrad 梯度函数、Laplacian 梯度函数等;相关代码实现在github,详情参见GitHub。
实验环境
Python3
OpenCV3.2
Window 10
算法描述
注意:在实际的操作中,还需要对图片进行预处理操作(检测出人脸区域、设置相同大小的图片、图片灰度化等等)
只有这样才不会受到图像大小以及除去人脸以外的因素的影响。
在此假设人脸区域已经识别
本文初步对以上几种方法进行了实现。
(1)拉普拉斯算子
这个方法最简便,根据参考文献[3]可以,opencv中提供了对laplace的封装方法,直接调用即可,得到拉普拉斯算子边缘检测的图片:
def lapulase(dir,name): """ :param dir: 操作目录 :param name: 操作的文件名称 :return: 分数 """ filePath=dir+name # img = filePath # Laplace梯度法 frame = cv2.imread(img) #cv2.imshow("原始图", frame); resImg = cv2.resize(frame, (800, 900),interpolation=cv2.INTER_CUBIC) img2gray = cv2.cvtColor(resImg, cv2.COLOR_BGR2GRAY) # 将图片压缩为单通道的灰度图 #img_resize = cv2.resize(img2gray, (112, 112)) # 为方便与其他图片比较可以将图片resize到同一个大小 res = cv2.Laplacian(img2gray, cv2.CV_64F) score = res.var() font = cv2.FONT_HERSHEY_SIMPLEX fontSize=5 # 照片 添加的文字 /左上角坐标 字体 字体大小 颜色 字体粗细 cv2.putText(resImg, str(score), (0, 200), font, fontSize, (0, 255, 0),6) newDir=dir+"/_Laplace_/" if not os.path.exists(newDir): os.makedirs(newDir) newName=newDir+name cv2.imwrite(newName, resImg) cv2.imshow('image', resImg) cv2.waitKey(0) #print("Laplacian score of given image is ", score) #cv2.imshow(r"gray效果图", img2gray); #cv2.imshow(r"laplace效果图", resImg); return score
(2)Brenner 检测
Brenner梯度函数最简单的梯度评价函数指标,他只是简单的计算相邻两个像素灰度差的平方,该函数定义如下:
其中f(x,y)f(x,y)表示图像ff所对应的像素点(x,y)(x,y)的灰度值,D(f)D(f)为图像清晰度计算的结果。
代码实现:
########################################### def ImageToMatrix(dir,name): # 读取图片 im = Image.open(dir+name) # 显示图片 #im.show() width,height = im.size im = im.convert("L") data = im.getdata() data = np.matrix(data,dtype='float')/255.0 new_data = np.reshape(data,(height,width)) return new_data def Brenner(img): x, y = img.shape D = 0 for i in range(x-2): for j in range(y-2): D += (img[i+2, j] - img[i, j])**2 return D def TestBrener(): dir = "D:/document/ZKBH/bug/face/" imgList = getAllImg(dir) for i in range(len(imgList)): frame = ImageToMatrix(dir , imgList[i]) score = Brenner(frame) print(str(imgList[i]) + " is " + str(score)) ########################################### def ImageToMatrix(dir,name): # 读取图片 im = Image.open(dir+name) # 显示图片 #im.show() width,height = im.size im = im.convert("L") data = im.getdata() data = np.matrix(data,dtype='float')/255.0 new_data = np.reshape(data,(height,width)) return new_data def Brenner(img): x, y = img.shape D = 0 for i in range(x-2): for j in range(y-2): D += (img[i+2, j] - img[i, j])**2 return D def TestBrener(): dir = "D:/document/ZKBH/bug/face/" imgList = getAllImg(dir) for i in range(len(imgList)): frame = ImageToMatrix(dir , imgList[i]) score = Brenner(frame) print(str(imgList[i]) + " is " + str(score)) ################################
(3)Tenengrad梯度函数
Tenengrad梯度函数采用Sobel算子分别提取水平和垂直方向的梯度,基于Tenengrad的图像清晰度定义如下:
G(x,y)的形式如下:
其中,T是给定的边缘检测阈值,Gx和Gy分别是像素点(x,y)处Sobel水平和垂直方向边缘检测算子的卷积。(参见参考文档[12,17])其余的方式都是一个这种类似的方式计算的额,
还有很多其他的模糊检测方法,再此不再一一赘述,详情参见GitHub。
参考文献
1. opencv将图像转换成二维数组再将数组数据传给新图像
3. 用 Opencv 和 Python 对汪星人做模糊检测(英文原版)(***)
4. 图像清晰度的评价及分析(****)
6. 利用Laplacian变换进行图像模糊检测(****)
8. 图像清晰度的评价指标
9. 图像清晰度的评价及分析
10. Atitit 图像清晰度 模糊度 检测 识别 评价算法 原理
11. 【OpenCV】图像模糊检测
12. 无参考图像的清晰度评价方法(****)
15. OpenCV with Laplacian formula to detect image is blur or not in iOS
16. 有没有一种方法来检测某个影像是模糊的?
17. python skimage图像处理(一)
19. OpenCV——图片的加载、显示、保存(python)
===========以下还没有仔细看===========
21. https://github.com/whdcumt/BlurDetection
22. Face recognition with OpenCV, Python, and deep learning
23. https://www.pyimagesearch.com/author/adrian/
24. Is there a way to detect if an image is blurry?(***)
25. http://www.doc88.com/p-6951865955255.html
26. https://github.com/WillBrennan/BlurDetection2
27. https://github.com/xLinkOut/blur-detection
28. https://github.com/xBazilio/cv_blurdetect/blob/master/main.cpp