小淼博客

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

锐度图像质量评估

图像锐度评分是用来描述图像清晰度的一个指标。常见的图像锐度评分算法包括方差法、点锐度法、差分法和梯度法等。

1. 实验方案

从左到右从上到下依次为:原始图像,高质量、中质量、低质量图像。

image

I. 方差评估法

     该方法是通过计算图像像素值的方差来评估图像锐度。锐度越高,像素值的变化就越大,方差也就越大。方差法计算简单,但对噪声敏感,需要进行滤波或者预处理。

实验代码

# 方差法是一种基于图像像素值的方差来评估图像锐度的方法。它的基本思路是,图像锐度越高,像素值的变化就越大,因此,通过计算图像中像素值的方差来反映图像的锐度。方差法计算简单,但对噪声比较敏感,需要进行滤波或者预处理。
import numpy as np

def SEM_Function(ori_img_data):
    ori_img_float = np.array(ori_img_data, np.float32)
    ori_img_sum = sum(sum(sum(ori_img_float)))
    
    width, height, depth = ori_img.shape
    ori_img_avg = ori_img_sum / width / height / depth
    
    ori_img_flatten = ori_img_float.reshape(width*height*depth, -1)
    SEM_val = 0
    for pixel in ori_img_flatten:
        SEM_val += (pixel - ori_img_avg)**2
    SEM_val /= width*height*depth
    return SEM_val
print(SEM_Function(ori_img))
print(SEM_Function(ass_img_1))
print(SEM_Function(ass_img_2))
print(SEM_Function(ass_img_3))

实验结果

[3424.9414]
[4654.0073]
[3207.4294]
[2849.543]

II. 点锐度估计法

     点锐度法是一种基于图像中每个像素的局部对比度来评估图像锐度的方法。它的基本思路是,锐度越高,图像中的细节和边缘就越明显,因此,通过计算像素周围像素值的差分或者梯度来反映局部对比度。

实验代码

def SR_Function(ori_img_data, kernel, p):
    kernel_size = kernel.shape
    padding_w = int(kernel_size[0] / 2)
    padding_h = int(kernel_size[1] / 2)
    extern_data = np.pad(ori_img_data, ((0,0),(padding_h,padding_h),(padding_w,padding_w)),'constant', constant_values=((0,0),(0,0),(0,0)))
    img_size = ori_img_data.shape
    PixelValue = np.zeros(ori_img_data.shape, np.float64)
    for dep in range(img_size[0]):
        for row in range(img_size[1]):
            for clo in range(img_size[2]):
                for i in range(-padding_w, padding_w+1):
                    for j in range(-padding_h, padding_h+1):
                        PixelValue[dep][row][clo] += (extern_data[dep][row+i][clo+j] - ori_img_data[dep][row][clo])**p * kernel[i][j]
    return PixelValue

kernel = np.array([[1,1,1],[1,0,1],[1,1,1]], np.float32)

ori_imgSRArray = SR_Function(ori_img, kernel, 1)
ass_img_1SRArray = SR_Function(ass_img_1, kernel, 1)
ass_img_2SRArray = SR_Function(ass_img_2, kernel, 1)
ass_img_3SRArray = SR_Function(ass_img_3, kernel, 1)
SRArraySize = ori_imgSRArray.shape

ori_imgSRAve = sum(sum(sum(ori_imgSRArray))) / SRArraySize[0] / SRArraySize[1] / SRArraySize[2]
ass_img_1SRAve = sum(sum(sum(ass_img_1SRArray))) / SRArraySize[0] / SRArraySize[1] / SRArraySize[2]
ass_img_2SRAve = sum(sum(sum(ass_img_2SRArray))) / SRArraySize[0] / SRArraySize[1] / SRArraySize[2]
ass_img_3SRAve = sum(sum(sum(ass_img_3SRArray))) / SRArraySize[0] / SRArraySize[1] / SRArraySize[2]

print(ori_imgSRAve)
print(ass_img_1SRAve)
print(ass_img_2SRAve)
print(ass_img_3SRAve)

实验结果

833.2670499999999
852.269175
805.43485
705.5661999999999

III. 梯度估计法

     梯度法是一种基于图像中像素值的梯度来评估图像锐度的方法。它的基本思路是,锐度越高,像素值的变化就越大,因此,通过计算像素周围像素值的梯度来反映锐度,梯度法的计算公式为:

实验代码

img_sobel_x=cv2.Sobel(ori_img,cv2.CV_64F,1,0,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度
img_sobel_y=cv2.Sobel(ori_img,cv2.CV_64F,0,1,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度

sobel_img_x_abs=cv2.convertScaleAbs(img_sobel_x)
img_sobel_y_abs=cv2.convertScaleAbs(img_sobel_y)

img0_sobel_xy_abs=cv2.addWeighted(sobel_img_x_abs,0.5,img_sobel_y_abs,0.5,0)

plt.figure()
plt.subplot(2,2,1)
plt.imshow(img0_sobel_xy_abs)

img_sobel_x=cv2.Sobel(ass_img_1,cv2.CV_64F,1,0,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度
img_sobel_y=cv2.Sobel(ass_img_1,cv2.CV_64F,0,1,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度

sobel_img_x_abs=cv2.convertScaleAbs(img_sobel_x)
img_sobel_y_abs=cv2.convertScaleAbs(img_sobel_y)

img1_sobel_xy_abs=cv2.addWeighted(sobel_img_x_abs,0.5,img_sobel_y_abs,0.5,0)

plt.subplot(2,2,2)
plt.imshow(img1_sobel_xy_abs)

img_sobel_x=cv2.Sobel(ass_img_2,cv2.CV_64F,1,0,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度
img_sobel_y=cv2.Sobel(ass_img_2,cv2.CV_64F,0,1,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度

sobel_img_x_abs=cv2.convertScaleAbs(img_sobel_x)
img_sobel_y_abs=cv2.convertScaleAbs(img_sobel_y)

img2_sobel_xy_abs=cv2.addWeighted(sobel_img_x_abs,0.5,img_sobel_y_abs,0.5,0)

plt.subplot(2,2,3)
plt.imshow(img2_sobel_xy_abs)

img_sobel_x=cv2.Sobel(ass_img_3,cv2.CV_64F,1,0,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度
img_sobel_y=cv2.Sobel(ass_img_3,cv2.CV_64F,0,1,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度

sobel_img_x_abs=cv2.convertScaleAbs(img_sobel_x)
img_sobel_y_abs=cv2.convertScaleAbs(img_sobel_y)

img3_sobel_xy_abs=cv2.addWeighted(sobel_img_x_abs,0.5,img_sobel_y_abs,0.5,0)

plt.subplot(2,2,4)
plt.imshow(img3_sobel_xy_abs)
plt.show()

print(sum(sum(sum(img0_sobel_xy_abs))))
print(sum(sum(sum(img1_sobel_xy_abs))))
print(sum(sum(sum(img2_sobel_xy_abs))))
print(sum(sum(sum(img3_sobel_xy_abs))))

实验结果

image

486
279
396
114

2. 锐度算法的评估总结

  1. 考虑锐度评估图像质量的方法能够较为清晰地反应实际的图像质量,可以看到均方差估计算法数值较大,有较好的灵敏度,能够作为图像判定的标准之一。

Reference

点击查看代码
# 方差法是一种基于图像像素值的方差来评估图像锐度的方法。它的基本思路是,图像锐度越高,像素值的变化就越大,因此,通过计算图像中像素值的方差来反映图像的锐度。方差法计算简单,但对噪声比较敏感,需要进行滤波或者预处理。
import numpy as np

def SEM_Function(ori_img_data):
    ori_img_float = np.array(ori_img_data, np.float32)
    ori_img_sum = sum(sum(sum(ori_img_float)))
    
    width, height, depth = ori_img.shape
    ori_img_avg = ori_img_sum / width / height / depth
    
    ori_img_flatten = ori_img_float.reshape(width*height*depth, -1)
    SEM_val = 0
    for pixel in ori_img_flatten:
        SEM_val += (pixel - ori_img_avg)**2
    SEM_val /= width*height*depth
    return SEM_val
print(SEM_Function(ori_img))
print(SEM_Function(ass_img_1))
print(SEM_Function(ass_img_2))
print(SEM_Function(ass_img_3))



def SR_Function(ori_img_data, kernel, p):
    kernel_size = kernel.shape
    padding_w = int(kernel_size[0] / 2)
    padding_h = int(kernel_size[1] / 2)
    extern_data = np.pad(ori_img_data, ((0,0),(padding_h,padding_h),(padding_w,padding_w)),'constant', constant_values=((0,0),(0,0),(0,0)))
    img_size = ori_img_data.shape
    PixelValue = np.zeros(ori_img_data.shape, np.float64)
    for dep in range(img_size[0]):
        for row in range(img_size[1]):
            for clo in range(img_size[2]):
                for i in range(-padding_w, padding_w+1):
                    for j in range(-padding_h, padding_h+1):
                        PixelValue[dep][row][clo] += (extern_data[dep][row+i][clo+j] - ori_img_data[dep][row][clo])**p * kernel[i][j]
    return PixelValue

kernel = np.array([[1,1,1],[1,0,1],[1,1,1]], np.float32)

ori_imgSRArray = SR_Function(ori_img, kernel, 1)
ass_img_1SRArray = SR_Function(ass_img_1, kernel, 1)
ass_img_2SRArray = SR_Function(ass_img_2, kernel, 1)
ass_img_3SRArray = SR_Function(ass_img_3, kernel, 1)
SRArraySize = ori_imgSRArray.shape

ori_imgSRAve = sum(sum(sum(ori_imgSRArray))) / SRArraySize[0] / SRArraySize[1] / SRArraySize[2]
ass_img_1SRAve = sum(sum(sum(ass_img_1SRArray))) / SRArraySize[0] / SRArraySize[1] / SRArraySize[2]
ass_img_2SRAve = sum(sum(sum(ass_img_2SRArray))) / SRArraySize[0] / SRArraySize[1] / SRArraySize[2]
ass_img_3SRAve = sum(sum(sum(ass_img_3SRArray))) / SRArraySize[0] / SRArraySize[1] / SRArraySize[2]

print(ori_imgSRAve)
print(ass_img_1SRAve)
print(ass_img_2SRAve)
print(ass_img_3SRAve)


img_sobel_x=cv2.Sobel(ori_img,cv2.CV_64F,1,0,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度
img_sobel_y=cv2.Sobel(ori_img,cv2.CV_64F,0,1,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度

sobel_img_x_abs=cv2.convertScaleAbs(img_sobel_x)
img_sobel_y_abs=cv2.convertScaleAbs(img_sobel_y)

img0_sobel_xy_abs=cv2.addWeighted(sobel_img_x_abs,0.5,img_sobel_y_abs,0.5,0)

plt.figure()
plt.subplot(2,2,1)
plt.imshow(img0_sobel_xy_abs)

img_sobel_x=cv2.Sobel(ass_img_1,cv2.CV_64F,1,0,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度
img_sobel_y=cv2.Sobel(ass_img_1,cv2.CV_64F,0,1,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度

sobel_img_x_abs=cv2.convertScaleAbs(img_sobel_x)
img_sobel_y_abs=cv2.convertScaleAbs(img_sobel_y)

img1_sobel_xy_abs=cv2.addWeighted(sobel_img_x_abs,0.5,img_sobel_y_abs,0.5,0)

plt.subplot(2,2,2)
plt.imshow(img1_sobel_xy_abs)

img_sobel_x=cv2.Sobel(ass_img_2,cv2.CV_64F,1,0,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度
img_sobel_y=cv2.Sobel(ass_img_2,cv2.CV_64F,0,1,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度

sobel_img_x_abs=cv2.convertScaleAbs(img_sobel_x)
img_sobel_y_abs=cv2.convertScaleAbs(img_sobel_y)

img2_sobel_xy_abs=cv2.addWeighted(sobel_img_x_abs,0.5,img_sobel_y_abs,0.5,0)

plt.subplot(2,2,3)
plt.imshow(img2_sobel_xy_abs)

img_sobel_x=cv2.Sobel(ass_img_3,cv2.CV_64F,1,0,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度
img_sobel_y=cv2.Sobel(ass_img_3,cv2.CV_64F,0,1,ksize=3)#1,0 表示选择水平还是竖直放心计算梯度

sobel_img_x_abs=cv2.convertScaleAbs(img_sobel_x)
img_sobel_y_abs=cv2.convertScaleAbs(img_sobel_y)

img3_sobel_xy_abs=cv2.addWeighted(sobel_img_x_abs,0.5,img_sobel_y_abs,0.5,0)

plt.subplot(2,2,4)
plt.imshow(img3_sobel_xy_abs)
plt.show()

print(sum(sum(sum(img0_sobel_xy_abs))))
print(sum(sum(sum(img1_sobel_xy_abs))))
print(sum(sum(sum(img2_sobel_xy_abs))))
print(sum(sum(sum(img3_sobel_xy_abs))))
posted on 2024-04-16 21:26  小淼博客  阅读(60)  评论(0)    收藏  举报

大家转载请注明出处!谢谢! 在这里要感谢GISPALAB实验室的各位老师和学长学姐的帮助!谢谢~