在通常状况下,图片是否清晰是个感性认识,同一个图,有可能你感觉还过得去,而他人会感觉不清晰,不足一个对立的规范。然而有一些算法能够去量化图片的清晰度,做到有章可循。
原理
如果之前理解过信号处理,就会晓得最间接的办法是计算图片的疾速傅里叶变换,而后查看高低频散布。如果图片有大量的高频成分,那么该图片就能够被认为是含糊的。然而,辨别高频量多少的具体阈值却是十分困难的,不失当的阈值将会导致极差的后果。
初学者有什么不懂的能够私信我——我刚整顿了一套 2021 最新的 0 根底入门教程,自私分享,获取办法:关注小编 CSDN,发私信:【学习材料】即可获取,内附:开发工具和安装包,以及零碎学习路线图。
咱们冀望的是一个繁多的浮点数就能够示意图片的清晰度。Pech-Pacheco 在 2000 年模式识别国内会议提出将图片中某一通道(个别用灰度值)通过拉普拉斯掩模做卷积运算,而后计算标准差,进去的值就能够代表图片清晰度。
这种办法凑效的起因就在于拉普拉斯算子定义自身。它被用来测量图片的二阶导数,突出图片中强度疾速变动的区域,和 Sobel 以及 Scharr 算子十分相似。并且,和以上算子一样,拉普拉斯算子也常常用于边缘检测。此外,此算法基于以下假如:如果图片具备较高方差,那么它就有较广的频响范畴,代表着失常,聚焦精确的图片。然而如果图片具备有较小方差,那么它就有较窄的频响范畴,意味着图片中的边缘数量很少。正如咱们所晓得的,图片越含糊,其边缘就越少。
有了代表清晰度的值,剩下的工作就是设定相应的阀值,如果某图片方差低于事后定义的阈值,那么该图片就能够被认为是含糊的,高于阈值,就不是含糊的。
实操
原理看起来比较复杂,波及到很多信号啊图片解决的相干常识,上面咱们来实操一下,直观感触下。
因为人生苦短,以及我集体是朋友圈第一 Python 吹子,我抉择应用 Python 来实现,外围代码简略到令人发指:
import cv2
def getImageVar(imgPath):
image = cv2.imread(imgPath);
img2gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
imageVar = cv2.Laplacian(img2gray, cv2.CV_64F).var()
return imageVar
真是人生苦短啊,外围代码就三行,简略解释下。
import cv2 应用了一个驰名的图像处理库 OpenCV,对于 OpenCV 的装置这里不多赘述,须要留神的是它依赖 numpy。
image = cv2.imread(imgPath) 应用 OpenCV 提供的办法读取图片。img2gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 转化为灰度图。如下图:
原图是这样的:
cv2.Laplacian(img2gray, cv2.CV_64F) 对图片用 3×3 拉普拉斯算子做卷积,这里的 cv2.CV_64F 就是拉普拉斯算子。
原理局部说过,拉普拉斯算子常常用于边缘检测,所以这里通过拉普拉斯算子之后,留下的都是检测到的边缘。上图通过这步解决之后是这样的:
能够看到这里图片人物大抵还是比拟清晰的。
cv2.Laplacian(img2gray, cv2.CV_64F).var() 计算出方差,并最初返回。
下面那张图按这个计算出来时 3170 多,这个就是最初咱们用来判断清晰度的值。所以想学的同学,有必要听一下这位老师的课、支付 python 福利奥,想学的同学能够到梦雅老师的围鑫(同音):前边一组是:mengy , 后边一组是:7762, 把以上两组字母依照先后顺序组合起来即可,她会安顿学习的。
能够再找一张看看:
原图:
做灰度和通过拉普拉斯算子之后,能够看到人物局部曾经不是很清晰了。
最初算进去的方差只有 530
剩下的工作就是依据整体图片品质确定阀值了。
局限性
通过下面的实操,咱们晓得这个算法的技巧在于设置适合的阀值,阈值太低会导致失常图片被误断为含糊图片,阈值太高会导致含糊图片被误判为失常图片。阀值依赖于你理论利用的业务场景,须要依据应用场景的不同做不同的定制。
真正的银弹并不存在。除了须要定个阀值外,有些图片可能会成心做个背景含糊或者背景虚化,这种图片很容易被误杀。
比方:
计算出来是这样的,前面一大片都是黑的。
这个图前景其实看着还行,然而背景有大片的虚化和含糊,这种状况下比拟容易被误杀。
所以最好还是在理解原理之后,依据理论场景来应用。