【无参考图像模糊度评价方法】统计信息

1.背景介绍

  • 因为所做的项目中,需要对一些图像的模糊度进行评价,所以开始了一些模糊度方面的学习探索
  • 图像模糊会造成高频信息缺损或对比度下降

图像模糊度评价属于是图像质量评价(Image Quality Assessment,IQA),一般分为三种:无参考(No Reference,NR)、全参考(Full Reference,FR)、半参考(Reduced Reference,RR)。

  • 首先手头上有三个数据集,暂时命名为pcm2,real,pred,目前的目标是选取一个简单明了的模糊度评价函数,使得前两者与后者尽可能差距大,编写以下函数对三个数据集进行评价
import cv2,os
import numpy as np
from tqdm import trange


def fun_blur(img_gray):
    # 
    pass


def calAllBlurValue(pngPath,fun_blur):
    pnglist = os.listdir(pngPath)
    blurs = []
    for i in trange(len(pnglist)):
        img = cv2.imread(os.path.join(pngPath,pnglist[i]))
        img_gray =cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
        blurs.append(fun_blur(img_gray))
    return blurs

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
funName = u"算法"
fun_blur = fun_blur
pcm2Path = r""
pcm2Blurs = np.array(calAllBlurValue(pcm2Path,fun_blur))
realPath = r""
realBlurs = np.array(calAllBlurValue(realPath,fun_blur))
predPath = r""
predBlurs = np.array(calAllBlurValue(predPath,fun_blur))
df = pd.DataFrame({'pcm2':pcm2Blurs,'real':realBlurs})
plt.figure(figsize=(8,5))
plt.subplot(1,2,1)
# plt.ylim(0, 900)
sns.boxplot(data=df,width=0.8)  #左图
plt.subplot(1,2,2)
# plt.ylim(0, 900)
sns.boxplot(data=pd.DataFrame({'pred':predBlurs}),width=0.4,color='g')  #右图
plt.suptitle(funName)
plt.savefig(r""+funName+".png",dpi=300)
  • 在实际使用时只需要在函数部分填入即可

2.评价方法

  • 由于场景限制以及重点不在这里,就不采用复杂度较高的算法,而只是采用一些经典且是基于图像本身的统计信息进行评价的方法,主要是参考文献[3]中2.6.2 用于“自动聚焦”领域的算法中的模糊度评价算法

2.1 灰度方差算法

g ˉ = 1 N x × N y ∑ f ( x , y ) s = 1 N x × N y ∑ ( f ( x , y ) − g ˉ ) 2 \bar{g}=\frac{1}{N_x\times N_y}\sum{f(x,y)} \\ s=\frac{1}{N_x\times N_y}\sum{(f(x,y)-\bar{g})^2} gˉ=Nx×Ny1f(x,y)s=Nx×Ny1(f(x,y)gˉ)2

  • 将图像转换为灰度图后,计算灰度图的方差,以方差值的大小评价图像模糊度,表征了图像变化的平均程度
def fun_blur1(img):
    # 1、灰度方差算法
    img_gray =cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    # return np.power(img_gray-img_gray.mean(),2).mean()
    return img_gray.var()
  • 绘制的箱线图如下:

在这里插入图片描述

它表征了图像灰度变化的平均程度,灰度变化的平均程度越大,图像越清晰,灰度变化平均程度越小,图像越模糊。

  • 但是根据实际来看,从人肉眼上看清晰程度是pcm2>real>pred,再做研究

2.2 灰度差分绝对值之和算法

s = ∑ ∑ { ∣ f ( x + 1 , y ) − f ( x , y ) ∣ + ∣ f ( x , y + 1 ) − f ( x , y ) ∣ } s=\sum{\sum{\{|{f(x+1,y)-f(x,y)}|+|{f(x,y+1)-f(x,y)}|\}}} s={f(x+1,y)f(x,y)+f(x,y+1)f(x,y)}

  • 因为n×m的图像经过上述操作后会出现n-1×m的矩阵与n×m-1的矩阵做加运算(或者在每个横竖运算后都填充一行未操作的原数据),所以这里的公式我稍微修改了一下,不知道是否还能具有正确的特征

s = ∑ { ∣ f ( x + 1 , y ) − f ( x , y ) ∣ } + ∑ { ∣ f ( x , y + 1 ) − f ( x , y ) ∣ } s=\sum{\{|{f(x+1,y)-f(x,y)}|\}+\sum{\{|{f(x,y+1)-f(x,y)}|\}}} s={f(x+1,y)f(x,y)}+{f(x,y+1)f(x,y)}

def fun_blur2(img):
    # 2、灰度差分绝对值之和方差算法
    # x方向,Y方向图像差分绝对值的和作为度量标准:
    img_gray =cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    delat_y = np.abs(img_gray[1:,:]-img_gray[:-1,:])
    delat_x = np.abs(img_gray[:,1:]-img_gray[:,:-1])
    return delat_x.sum()+delat_y.sum()

在这里插入图片描述

  • 虽然差距倒是挺大的,但是为了方便和原数据相对比,我尝试了将求和改成了求平均值,公式如下:

s = 1 ( N x − 1 ) × N y ∑ { ∣ f ( x + 1 , y ) − f ( x , y ) ∣ } + 1 N x × ( N y − 1 ) ∑ { ∣ f ( x , y + 1 ) − f ( x , y ) ∣ } s=\frac{1}{(N_x-1)\times N_y}\sum{\{|{f(x+1,y)-f(x,y)}|\}+\frac{1}{N_x\times (N_y-1)}\sum{\{|{f(x,y+1)-f(x,y)}|\}}} s=(Nx1)×Ny1{f(x+1,y)f(x,y)}+Nx×(Ny1)1{f(x,y+1)f(x,y)}

def fun_blur2(img):
    # 2、灰度差分绝对值之和方差算法
    # x方向,Y方向图像差分绝对值的和作为度量标准:
    img_gray =cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    delat_y = np.abs(img_gray[1:,:]-img_gray[:-1,:])
    delat_x = np.abs(img_gray[:,1:]-img_gray[:,:-1])
    return delat_x.mean()+delat_y.mean()

在这里插入图片描述

2.3 灰度差分平方和算法

  • 与2.2相比是将绝对值修改为平方项,突出大的微分项的影响

s = ∑ ∑ { ( f ( x + 1 , y ) − f ( x , y ) ) 2 + ( f ( x , y + 1 ) − f ( x , y ) ) 2 } s=\sum{\sum{\{({f(x+1,y)-f(x,y)})^2+({f(x,y+1)-f(x,y)})^2\}}} s={(f(x+1,y)f(x,y))2+(f(x,y+1)f(x,y))2}

  • 同样基于2.2的考虑,将公式修改为:

s = 1 ( N x − 1 ) × N y ∑ { ( f ( x + 1 , y ) − f ( x , y ) ) 2 } + 1 N x × ( N y − 1 ) ∑ { ( f ( x , y + 1 ) − f ( x , y ) ) 2 } s=\frac{1}{(N_x-1)\times N_y}\sum{\{({f(x+1,y)-f(x,y)})^2\}+\frac{1}{N_x\times (N_y-1)}\sum{\{({f(x,y+1)-f(x,y)})^2\}}} s=(Nx1)×Ny1{(f(x+1,y)f(x,y))2}+Nx×(Ny1)1{(f(x,y+1)f(x,y))2}

def fun_blur3(img):
    # 3、灰度差分平方和方差算法
    # x方向,Y方向图像差分平方值的和作为度量标准,突出微分值的影响,提高信噪比数值
    img_gray =cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    delat_y = np.power(img_gray[1:,:]-img_gray[:-1,:],2)
    delat_x = np.power(img_gray[:,1:]-img_gray[:,:-1],2)
    return delat_x.mean()+delat_y.mean()

在这里插入图片描述

  • 不知道是因为自己修改了的原因,还是因为我的数据确实不适应这种算法,数据集pred模糊程度平均值介于pcm2和real之间,暂不考虑

2.4 Brenner函数

  • Brenner梯度函数简单计算相邻两个像素灰度差的平方

s = ∑ ∑ ( f ( x + 2 , y ) − f ( x , y ) ) 2 s=\sum\sum(f(x+2,y)-f(x,y))^2 s=(f(x+2,y)f(x,y))2

def fun_blur4(img):
    # Brenner梯度函数是最简单的梯度评价函数,它只是简单的计算相邻两个像素灰度差的平方
    img_gray =cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    delat_x = np.power(img_gray[:,2:]-img_gray[:,:-2],2)
    return delat_x.sum()

在这里插入图片描述

2.5 Roberts梯度和

s = ∑ ∑ { ∣ f ( x , y ) − f ( x + 1 , y + 1 ) ∣ + ∥ f ( x + 1 , y ) − f ( x , y + 1 ) ∣ } s=\sum{\sum{\{|{f(x,y)-f(x+1,y+ 1)|}+\|{f(x+1,y)-f(x,y+1)}|\}}} s={f(x,y)f(x+1,y+1)+f(x+1,y)f(x,y+1)}

def fun_blur5(img):
    # 5、Roberts梯度和
    # 定义为相邻四个像素对角线像素灰度值差的绝对值之和
    img_gray =cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    delta11 = np.abs(img_gray[:-1,:-1]-img_gray[1:,1:])
    delta10 = np.abs(img_gray[1:,:-1]-img_gray[:-1,1:])
    return (delta11+delta10).sum()

在这里插入图片描述

  • 这个比较符合预期,数据集间几乎没有相交的地方,但是还是要加个均值比较直观

2.6 拉普拉斯梯度和 1

  • 所谓梯度和1是指用拉普拉斯模板1获得每个像素的拉普拉斯梯度,然后求和,模板1如下

m = [ 0 1 0 1 − 4 1 0 1 0 ] m=\left[ \begin{matrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \end{matrix} \right] m=010141010

s = ∑ ∑ { ∣ f ( x + 1 , y ) + f ( x , y + 1 ) + f ( x − 1 , y ) + f ( x , y − 1 ) − 4 f ( x , y 1 ) ∣ } s=\sum{\sum{\{|{f(x+1,y)+f(x,y+1)+f(x-1,y)+f(x,y-1)-4f(x,y 1)}|\}}} s={f(x+1,y)+f(x,y+1)+f(x1,y)+f(x,y1)4f(x,y1)}

def fun_blur6(img):
    #拉普拉斯模板1
    img_gray =cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    s = img_gray[1:-1,:-2]+img_gray[1:-1,2:]+img_gray[:-2,1:-1]+img_gray[2:,1:-1]-4*img_gray[1:-1,1:-1]
    return np.abs(s).mean()

在这里插入图片描述

2.7 拉普拉斯梯度和 2

m = [ 1 1 1 1 − 8 1 1 1 1 ] m=\left[ \begin{matrix} 1 & 1 & 1 \\ 1 & -8 & 1 \\ 1 & 1 & 1 \end{matrix} \right] m=111181111

def fun_blur7(img):
    #拉普拉斯模板2
    img_gray =cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    s = img_gray[1:-1,:-2]+img_gray[1:-1,2:]+img_gray[:-2,1:-1]+img_gray[2:,1:-1]+img_gray[2:,2:]+img_gray[:-2,:-2]+img_gray[2:,:-2]+img_gray[:-2,2:]-8*img_gray[1:-1,1:-1]
    return np.abs(s).mean()

在这里插入图片描述

  • 同理差距更大了些

2.8 Tenengrad函数

  • 定义模板算子:

K x = [ 0 − 1 0 0 2 0 0 − 1 0 ] , K y = [ 0 0 0 − 1 2 − 1 0 0 0 ] K_x=\left[ \begin{matrix} 0 & -1 & 0 \\ 0 & 2 & 0 \\ 0 & -1 & 0 \end{matrix} \right] , K_y=\left[ \begin{matrix} 0 & 0 & 0 \\ -1 & 2 & -1 \\ 0 & 0 & 0 \end{matrix} \right] Kx=000121000,Ky=010020010

  • 进行卷积操作,并计算模糊度:

f x ( x , y ) = f ( x , y ) ∗ K x ,   f y ( x , y ) = f ( x , y ) ∗ K y f_x(x,y)=f(x,y)*K_x,\ f_y(x,y)=f(x,y)*K_y fx(x,y)=f(x,y)Kx, fy(x,y)=f(x,y)Ky

s = f x 2 ( x , y ) + f y 2 ( x , y ) s = \sqrt{f_x^2(x,y)+f_y^2(x,y)} s=fx2(x,y)+fy2(x,y)

def fun_blur8(img):
    #Tenengrad函数
    img_gray =cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    fx = np.power(img_gray[:,1:-1]*2 - img_gray[:,:-2] - img_gray[:,2:],2)
    fy = np.power(img_gray[1:-1,:]*2 - img_gray[:-2,:] - img_gray[:-2,:],2)
    return np.sqrt(fx.mean()+fy.mean())

在这里插入图片描述

3.总结

  • 以上实现了8种经典的统计学信息的参考模糊度评价方法,其中有很多细节我为了编程实现方便进行了一定的变形,可能会导致一些致命错误,望知者指正
  • 其中不只是基于灰度,也可以基于RGB的图片,但是这里没有一一列举,只需要简单修改一下代码即可实现
  • 依照结果而言,我预计选择拉普拉斯梯度和 2方法进行进一步调研,去研究他评价低的图片和人肉眼的差异,并且确定他的评价是否合适,是否有更有用的变形

4.参考文献

[1] 梅嘉祥,刘展宁,张志佳,等. 图像模糊度评价及其应用综述[J]. 软件工程. 2018, 21(04): 23-26.

[2] 王志明. 无参考图像质量评价综述[J]. 自动化学报. 2015, 41(06): 1062-1079.

[3] 庞胜利. 图像模糊度评价研究[D]. 西安电子科技大学, 2010.

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值