# 显微调焦图像清晰度评价算法

一般在经过显微镜的不断调焦下才能够看清物体，看清与看不清物体主要是通过人眼主观进行判定的，这里总结几种量化评价图像清晰度的函数指标并用python实现。所用具体函数的定义通过代码就可以看出来。

import cv2
from glob import glob
import numpy as np
import math
from matplotlib import pyplot as plt
import time
from scipy.interpolate import make_interp_spline #平滑函数

def brenner(img):
'''
:param img:narray 二维灰度图像
:return: float 图像越清晰越大
'''
shape = np.shape(img)
out = 0
for x in range(0, shape[0]-2):
for y in range(0, shape[1]):
out += ((img[x+2, y]).astype(np.int)-(img[x, y]).astype(np.int))**2
return out

'''
:param img: input image
:return: float
'''
height, width = img.shape
sobelx_image = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobely_image = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobel_image = sobelx_image*sobelx_image + sobely_image*sobely_image
out = np.sum(sobel_image) / (height * width)
return out

def Laplacian(img):
'''
:param img:narray 二维灰度图像
:return: float 图像越清晰值越大
'''
return cv2.Laplacian(img, cv2.CV_64F).var()#计算输出的方差

#灰度方差
def SMD(img):
'''
:param img:narray 二维灰度图像
:return: float 图像越清晰值越大
'''
shape = np.shape(img)
out = 0
for x in range(0, shape[0]-1):
for y in range(1, shape[1]):
out+=math.fabs(int(img[x,y])-int(img[x,y-1]))
out+=math.fabs(int(img[x,y]-int(img[x+1,y])))
return out

#灰度方差乘积
def SMD2(img):
'''
:param img:narray 二维灰度图像
:return: float 图像越清晰值越大
'''
shape = np.shape(img)
out = 0
for x in range(0, shape[0]-1):
for y in range(0, shape[1]-1):
out+=math.fabs(int(img[x,y])-int(img[x+1,y]))*math.fabs(int(img[x,y]-int(img[x,y+1])))
return out

#方差
def variance(img):
'''
:param img:narray 二维灰度图像
:return: float 图像越清晰值越大
'''
out = 0
u = np.mean(img)
shape = np.shape(img)
for x in range(0,shape[0]):
for y in range(0,shape[1]):
out+=(img[x,y]-u)**2
return out

#能量梯度
def energy(img):
'''
:param img:narray 二维灰度图像
:return: float 图像越清晰值越大
'''
shape = np.shape(img)
out = 0
for x in range(0, shape[0]-1):
for y in range(0, shape[1]-1):
out+=((int(img[x+1,y])-int(img[x,y]))**2)+((int(img[x,y+1]-int(img[x,y])))**2)
return out

def Vollath(img):
'''
:param img:narray 二维灰度图像
:return: float 图像越清晰值越大
'''
shape = np.shape(img)
u = np.mean(img)
out = -shape[0]*shape[1]*(u**2)
for x in range(0, shape[0]-1):
for y in range(0, shape[1]):
out+=int(img[x,y])*int(img[x+1,y])
return out

#熵函数
def entropy(img):
'''
:param img:narray 二维灰度图像
:return: float 图像越清晰值越大
'''
out = 0
count = np.shape(img)[0]*np.shape(img)[1]
p = np.bincount(np.array(img).flatten())
for i in range(0, len(p)):
if p[i]!=0:
out-=p[i]*math.log(p[i]/count)/count
return out
#选取固定数量的点可视化
def pick_arange(arange,num):
if num >len(arange):
print('num out of length')
else:
output=np.array([],dtype=arange.dtype)
seg=len(arange)/num
for n in range(num):
if int(seg * (n+1))>=len(arange):
output=np.append(output,arange[-1])
else:
output=np.append(output,arange[int(seg * n)])
return output
#平滑函数
def smooth(y, box_pts):
box = np.ones(box_pts)/box_pts
y_smooth = np.convolve(y, box, mode='same')
return y_smooth

if __name__ == '__main__':
image_path = r'H:\image_from_blur_clear_blur/'
image_file = glob(image_path + '*.bmp')
i = 0
out_list = []
norm_list = []
total_time = 0.0
for each in image_file:
i += 1
print(i)
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
start_time = time.time()  # 获得当前的时间
cycle_time = time.time() - start_time  # 计算图像清晰度的耗时
total_time += cycle_time  # 总时间累积
out_list.append(output)
print(out_list)
print("Total calculation time: %.3f seconds" % total_time)
out_max = np.max(np.array(out_list))
out_min = np.min(np.array(out_list))
norm_out = [] #归一化
for j in out_list:
norm_value = (j - out_min) / (out_max - out_min)
norm_out.append(norm_value)
#等距选择数据固定数量的数据，进行拟合结果可视化
x = np.array(range(len(norm_out)))
y = pick_arange(np.array(norm_out), len(norm_out))
# x_smooth = np.linspace(x.min(), x.max(), 100)
# y_smooth = make_interp_spline(x, y)(x_smooth)
plt.figure()
plt.plot(x, smooth(y, 50), lw=2)
# plt.plot(x, y, color='r')
plt.xlabel('image_number')
plt.ylabel('evaluation_value')
plt.show()


09-19
07-23 2621