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

  • Post author:
  • Post category:其他


一般在经过显微镜的不断调焦下才能够看清物体,看清与看不清物体主要是通过人眼主观进行判定的,这里总结几种量化评价图像清晰度的函数指标并用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

def tenengrade(img):
    '''
    :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 = cv2.imread(each)
        image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        start_time = time.time()  # 获得当前的时间
        output = tenengrade(image_gray)
        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()

例子:

图像从模糊–清晰–模糊:



清晰度曲线:



版权声明:本文为jancis原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。