首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 做图片清晰度识别

Python 做图片清晰度识别

作者头像
Bob.Chen
发布2018-08-22 16:30:18
5.6K1
发布2018-08-22 16:30:18
举报

在通常情况下,图片是否清晰是个感性认识,同一个图,有可能你觉得还过得去,而别人会觉得不清晰,缺乏一个统一的标准。然而有一些算法可以去量化图片的清晰度,做到有章可循。

原理

如果之前了解过信号处理,就会知道最直接的方法是计算图片的快速傅里叶变换,然后查看高低频分布。如果图片有少量的高频成分,那么该图片就可以被认为是模糊的。然而,区分高频量多少的具体阈值却是十分困难的,不恰当的阈值将会导致极差的结果。

我们期望的是一个单一的浮点数就可以表示图片的清晰度。 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) 转化为灰度图。如下图:

Python 做图片清晰度识别-程序员的诗和远方
Python 做图片清晰度识别-程序员的诗和远方

原图是这样的:

Python 做图片清晰度识别-程序员的诗和远方
Python 做图片清晰度识别-程序员的诗和远方

cv2.Laplacian(img2gray, cv2.CV_64F) 对图片用 3x3 拉普拉斯算子做卷积,这里的 cv2.CV_64F 就是拉普拉斯算子。

原理部分说过,拉普拉斯算子经常用于边缘检测,所以这里经过拉普拉斯算子之后,留下的都是检测到的边缘。上图经过这步处理之后是这样的:

Python 做图片清晰度识别-程序员的诗和远方
Python 做图片清晰度识别-程序员的诗和远方

可以看到这里图片人物大致还是比较清晰的。

cv2.Laplacian(img2gray, cv2.CV_64F).var() 计算出方差,并最后返回。

上面那张图按这个计算出来时 3170 多,这个就是最后我们用来判断清晰度的值。

Python 做图片清晰度识别-程序员的诗和远方
Python 做图片清晰度识别-程序员的诗和远方

可以再找一张看看:

原图:

Python 做图片清晰度识别-程序员的诗和远方
Python 做图片清晰度识别-程序员的诗和远方

做灰度和经过拉普拉斯算子之后,可以看到人物部分已经不是很清晰了。

Python 做图片清晰度识别-程序员的诗和远方
Python 做图片清晰度识别-程序员的诗和远方

最后算出来的方差只有 530

Python 做图片清晰度识别-程序员的诗和远方
Python 做图片清晰度识别-程序员的诗和远方

剩下的工作就是根据整体图片质量确定阀值了。

局限性

通过上面的实操,我们知道这个算法的技巧在于设置合适的阀值,阈值太低会导致正常图片被误断为模糊图片,阈值太高会导致模糊图片被误判为正常图片。阀值依赖于你实际应用的业务场景,需要根据使用场景的不同做不同的定制。

真正的银弹并不存在。除了需要定个阀值外,有些图片可能会故意做个背景模糊或者背景虚化,这种图片很容易被误杀。

比如:

Python 做图片清晰度识别-程序员的诗和远方
Python 做图片清晰度识别-程序员的诗和远方

计算出来是这样的,后面一大片都是黑的。

Python 做图片清晰度识别-程序员的诗和远方
Python 做图片清晰度识别-程序员的诗和远方

这个图前景其实看着还行,但是背景有大片的虚化和模糊,这种情况下比较容易被误杀。

所以最好还是在了解原理之后,根据实际场景来使用。


最后写了个简单的脚本,对传入的图片路径的图片进行计算,然后返回一个 json 字符串。

用法 python getRank.py --imgs=./1.jpg,./2.jpg

源码:https://github.com/bob-chen/demos/blob/master/python-img-clarity-calculate/getRank.py

碎碎念

记录一些所思所想,写写科技与人文,写写生活状态,写写读书感悟,欢迎关注,交流。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-08-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原理
  • 实操
  • 局限性
    • 碎碎念
    相关产品与服务
    图片处理
    图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档