1什么是模糊的图像
首先我们看一幅对比图像(为了保护他人隐私,我在脸部和水印都打码了)
对模糊图像的直观感受
有一种若隐若现的赶脚,隐隐约约能看清楚一些事物,但是给人感觉并不是很舒服,不是非常的清晰。
正常的图像经过滤波处理也能产生模糊的效果,那么,例如一张图片使用均值滤波器处理后变模糊了,从其本质上去分析,像素的值发生了什么变化。
假设采用3x3的均值滤波,计算过程是,利用周围的9个点取平均当做这点的像素值(灰度值),很明显,与原图像中相邻点间像素值的梯度和方差相比都会有一定程度降低。
高斯滤波
什么原因导致拍摄图像模糊?
(1)抖动造成模糊
抖动又可分为手抖,相机抖动,三脚架抖动等
(2)快门速度太慢
快门,简单来说,就是控制曝光的一个进光量的闸门。快门速度指的是控制曝光时间的长短,快门越快,曝光时间越短。
详细的技巧可以自行百度。
(3)对焦问题
由于手动对焦或后键对焦时没合焦就按下快门
(4)拍摄对象速度过快
如果拍摄对象比快门速度还快也会导致模糊。
(5)其他原因
如镜头积灰,有划痕等等。
上述内容,仅仅当做科普,下面我们来具体研究和实现一下如何检测模糊图像
2检测模糊图像的原理
常见的类型
一种是根据已有的图像,来判断现在的图像是否模糊
另一种是在无参考图像的情况下,判断图像是否模糊
今天我们研究比较常见的情况,即无参考图像的情况下对其质量进行评价(是否模糊)
主要思想:(1)先对原图像进行灰度化(2)然后用3x3的拉普拉斯算子进行滤波处理(3)在计算处理后图像的均值和方差,将方差当做模糊检测的阈值选定标准即可。从上面的分析可知,假如是一张模糊图片其方差会低于清晰的图片,因此,我们设置一个合理的 方差阈值 ,即可判断是否是模糊图像
关键代码:
def variance_of_laplacian(image): # 对图像进行拉普拉斯变换,并返回拉普拉斯的方差 return cv2.Laplacian(image, cv2.CV_64F).var()# 设置需要输入的参数,-i 输入图像的路径(文件夹名), -t 设置阈值的大小ap = argparse.ArgumentParser()ap.add_argument("-i", "--images", required=True, help="path to input directory of images")ap.add_argument("-t", "--threshold", type=float, default=100.0, help="focus measures that fall below this value will be considered 'blurry'")args = vars(ap.parse_args())# 循环输入图片for imagePath in paths.list_images(args["images"]): # 导入图像并转换为灰度图,计算我们关注的拉普拉斯变换后的方差 image = cv2.imread(imagePath) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) fm = variance_of_laplacian(gray) text = "Not Blurry" # 当方差小于阈值时,显示为模糊 if fm < args["threshold"]: text = "Blurry" # 显示图片 cv2.putText(image, "{}: {:.2f}".format(text, fm), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 3) cv2.imshow("Image", image) key = cv2.waitKey(0)
效果演示:
3总结
上述的采用计算 拉普拉斯算子处理后的图像的方差,并设定方差阈值进行判断是否模糊,基本上能满足我们的要求。
存在的不足之处:
(1)阈值的设定需要靠人去决定,所以阈值设置不合理,会严重影响结果
(2)对于背景模糊或背景虚化,很容易出现误判