我想知道是否有一种方法可以通过分析图像数据来确定图像是否模糊。
当前回答
谢谢妮基的拉普拉斯建议。 OpenCV文档给我指出了同样的方向: 使用python, cv2 (opencv 2.4.10)和numpy…
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
numpy.max(cv2.convertScaleAbs(cv2.Laplacian(gray, 3)))
结果在0-255之间。我发现任何超过200的东西都非常清晰,而到了100,就明显模糊了。Max从来没有真正低于20,即使它完全模糊。
其他回答
我想到了一个完全不同的解决方案。 我需要分析视频静止帧,以便在每(X)帧中找到最清晰的帧。这样,我将检测运动模糊和/或失焦图像。
我最终使用了Canny边缘检测,我得到了非常非常好的结果,几乎每一种视频(与尼基的方法,我有数字化的VHS视频和沉重的交错视频的问题)。
我通过在原始图像上设置感兴趣区域(ROI)来优化性能。
使用EmguCV:
//Convert image using Canny
using (Image<Gray, byte> imgCanny = imgOrig.Canny(225, 175))
{
//Count the number of pixel representing an edge
int nCountCanny = imgCanny.CountNonzero()[0];
//Compute a sharpness grade:
//< 1.5 = blurred, in movement
//de 1.5 à 6 = acceptable
//> 6 =stable, sharp
double dSharpness = (nCountCanny * 1000.0 / (imgCanny.Cols * imgCanny.Rows));
}
在高度重视的期刊(IEEE Transactions on Image Processing)上发表的两种方法的Matlab代码可在这里获得:https://ivulab.asu.edu/software
检查CPBDM和JNBM算法。如果你检查代码,它并不难移植,顺便说一下,它是基于Marzialiano的方法作为基本特征。
基于耐克的答案。使用opencv实现基于拉普拉斯的方法很简单:
short GetSharpness(char* data, unsigned int width, unsigned int height)
{
// assumes that your image is already in planner yuv or 8 bit greyscale
IplImage* in = cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,1);
IplImage* out = cvCreateImage(cvSize(width,height),IPL_DEPTH_16S,1);
memcpy(in->imageData,data,width*height);
// aperture size of 1 corresponds to the correct matrix
cvLaplace(in, out, 1);
short maxLap = -32767;
short* imgData = (short*)out->imageData;
for(int i =0;i<(out->imageSize/2);i++)
{
if(imgData[i] > maxLap) maxLap = imgData[i];
}
cvReleaseImage(&in);
cvReleaseImage(&out);
return maxLap;
}
将返回一个短消息,指示检测到的最大锐度,根据我对真实世界样本的测试,这是一个很好的指标,说明相机是否对焦。不足为奇的是,正常值是依赖于场景的,但远不如FFT方法,它有很高的假阳性率,在我的应用程序中是有用的。
我目前使用的一种方法是测量图像中边缘的分布。请看这篇论文:
@ARTICLE{Marziliano04perceptualblur,
author = {Pina Marziliano and Frederic Dufaux and Stefan Winkler and Touradj Ebrahimi},
title = {Perceptual blur and ringing metrics: Application to JPEG2000,” Signal Process},
journal = {Image Commun},
year = {2004},
pages = {163--172} }
它通常都是付费版本,但我也看到过一些免费版本。基本上,他们在图像中定位垂直边缘,然后测量这些边缘的宽度。平均宽度给出了图像的最终模糊估计结果。较宽的边缘对应模糊的图像,反之亦然。
该问题属于无参考图像质量估计领域。如果你在谷歌Scholar上查一下,你会得到很多有用的参考资料。
EDIT
下面是nickie发布的5张图片的模糊估计图。数值越高,模糊程度越高。我使用固定大小的11x11高斯滤波器,并改变了标准偏差(使用imagemagick的convert命令来获得模糊的图像)。
如果你比较不同大小的图像,不要忘记通过图像宽度归一化,因为较大的图像会有更宽的边缘。
最后,一个重要的问题是区分艺术模糊和不必要的模糊(由对焦缺失、压缩、拍摄对象相对于相机的运动引起),但这超出了像这样简单的方法。举个艺术模糊的例子,看看莱娜的形象:莱娜在镜子里的倒影是模糊的,但她的脸是完美的聚焦。这有助于对莱纳图像进行更高的模糊估计。
在这篇文章中,我尝试了基于拉普拉斯滤波器的解决方案。这对我没有帮助。所以,我尝试了这篇文章中的解决方案,它对我的情况很好(但很慢):
import cv2
image = cv2.imread("test.jpeg")
height, width = image.shape[:2]
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
def px(x, y):
return int(gray[y, x])
sum = 0
for x in range(width-1):
for y in range(height):
sum += abs(px(x, y) - px(x+1, y))
较少模糊的图像具有最大和值!
你也可以通过改变步长来调整速度和准确度。
这部分
for x in range(width - 1):
你可以用这个替换
for x in range(0, width - 1, 10):
推荐文章
- 使用ImageMagick“Diff”图像
- 如何使用pip安装opencv ?
- 如何用OpenCV2.0和Python2.6调整图像大小
- 如何消除数独方块的凹凸缺陷?
- ImportError: numpy.core.multiarray导入失败
- 我如何量化两幅图像之间的差异?
- 有没有办法检测图像是否模糊?
- 简单和快速的方法来比较图像的相似性
- 如何合并一个透明的png图像与另一个图像使用PIL
- 提取和保存视频帧
- 如何使用c#裁剪图像?
- 什么是最好的java图像处理库/方法?
- 给出一个图像来表示和解决一个迷宫
- 如何通过Conda安装Python OpenCV ?
- 推荐使用ImageMagick压缩JPG文件