OpenCV通过边缘检测判断图片是否模糊

《OpenCV系列教程》
《深度学习-如何提高数据集质量》

项目位置:OpenCV-Sample
代码位置:41-Laplacian.py

原理:

对于图片是否清晰的判断,就是看他边缘是否分明,如果边缘不清楚,我们会认为这个图片是模糊的。最简单的方式就是对图片求二阶导数,获取边缘后,然后对边缘求方差,获取方差数值,通过方差的数值判断图片是否模糊。最难确定的是闸值,但闸值可以通过图片对比获取到。我整理了几个例子,很容易获得闸值,以及获取边缘方式的缺陷。

OpenCV

使用OpenCV的两个函数进行处理:

Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)
Laplacian(src, ddepth, dst=None, ksize=None, scale=None, delta=None, borderType=None)

处理后的效果:

OpenCV通过边缘检测判断图片是否模糊_第1张图片
图片从左到右,分别为:原图-Canny-Laplacian。原图是一个边缘清晰的图片,经过处理分值也很高。

OpenCV通过边缘检测判断图片是否模糊_第2张图片
OpenCV通过边缘检测判断图片是否模糊_第3张图片
OpenCV通过边缘检测判断图片是否模糊_第4张图片
这三个图片都是模糊图片,所以Laplacian基本使用‘100’为闸值,Canny函数,还需要参考threshold1, threshold2,这两个参数的设置,判断闸值。以此Laplacian更加方便些。

局限性

OpenCV通过边缘检测判断图片是否模糊_第5张图片
对椒盐噪点的图片具有局限性,图片椒盐噪点很多,将噪点当成了轮廓的一部分了。解决方式:首先要进行滤波处理,效果更好。

OpenCV通过边缘检测判断图片是否模糊_第6张图片
对空旷背景的图片具有局限性,本身是清晰图片,但轮廓在整张图片中所占的比重较少,所以认为不是那么清晰,但分值已经超过了100。解决方式:只计算图像中心部位的边缘,或者只计算焦点附近的边缘。

代码附上:

import cv2 as cv
import numpy as np

fileList = ['res/mohu.jpg', 'res/mohu1.jpg', 'res/mohu2.jpg',
            'res/mohu3.png', 'res/mediablur.png', 'res/jeep.jpeg']

for f in fileList:
    imag = cv.imread(f)
    grayImag = cv.cvtColor(imag, cv.COLOR_BGR2GRAY)
    #grayImag = cv.GaussianBlur(grayImag, (3, 3), 0)
    canny = cv.Canny(grayImag, 200, 200)
    value = canny.var()
    print('Canny : ' + str(value))

    lapla = cv.Laplacian(grayImag, cv.CV_8U)
    imageVar = lapla.var()
    print('Laplacian : ' + str(imageVar))

    grayImag = cv.cvtColor(grayImag, cv.COLOR_GRAY2BGR)
    canny = cv.cvtColor(canny, cv.COLOR_GRAY2BGR)
    cv.putText(canny, str(int(value)), (0, 40), cv.FONT_HERSHEY_COMPLEX, 2, (0, 0, 255), 2)

    lapla = cv.cvtColor(lapla, cv.COLOR_GRAY2BGR)
    cv.putText(lapla, str(int(imageVar)), (0, 40), cv.FONT_HERSHEY_COMPLEX, 2, (0, 0, 255), 2)

    longimag = np.hstack((imag, canny, lapla))
    cv.namedWindow(f, 0)
    cv.imshow(f, longimag)

while(1):
    if(cv.waitKey(100)==27):
        break

你可能感兴趣的:(OpenCV)