基于亮度和对比度调整的彩色视网膜图像增强的论文复现(python实现)过程中的对比度限制参数阈值问题

2022年10月21日 16:58 ry 733

这周组会要讲论文,我选的论文是基于亮度和对比度调整的彩色视网膜图像增强,是ieee trans系列上面的一篇论文,针对彩色视网膜图像的亮度和对比度增强过程,整体过程如下所示

难点在于将b,g,r通道转为HSV,LABD等颜色空间,还好python的opencv库有函数可以实现,先读取一张模糊低亮度视网膜彩色图像,然后将b,g,r通道转为HSV,为甚么要转化了,主要bgr通道里面像素相关性太强了,随便改变一个像素值都可以影响整个图片的颜色或者分布,而HSV则分为H,S,V3个通道,H代表色调,也就是颜色,S代表饱和度,也就是颜色浓度,V代表明度,也就是亮度,其中V与HS相关行很少,耦合度低,对于提高视网膜图像的亮度很适合,我们只需要增强里面的V通道即可,而增强我们可以使用经典的伽马变换(非线性变换操作) 伽马变换公式如下

\(w = { u^r}\)

其中u为输入像素值(归一化的像素值),w为输出像素值(反向归一化的像素),r为常数,当r<1时,可以提高低灰度值范围,压缩高灰度值范围,这里按照论文中我们选择1/2.2作为本次实验的r值,将提高后的V值与之前的H和S值进行合并,然后将合并后的img对象转为bgr通道(一般称为rgb,opencv中而是按照bgr顺序),亮度提高方法有了,经过伽马变换后当然也可以适当的提高对比度,但对于亮度均匀的彩色图片对比度提高不明显,一种思路是先将提高亮度后的gbr转化为LAB颜色空间,这个颜色空间更接近我们人类眼部视觉效果,除此之外L与A和B之间的相关性也不高,L代表亮度,AB表示颜色范围,菌体的可以差相关文档,因此提高L来增强我们的对比度,论文使用的CLAHE算法,中文来说就是限制对比度的自适应直方图均衡算法(经典算法),由于BGR与LAB不能直接转化,先经过XYZ,然后才能转,后面经过CLAHE算法进行空间变换后转为bgr最后合并即为最终的效果,如果你想知道其中的原理可以看看具体的论文,本次主要讲论文代码复现,由于论文并没有相关源码,因此我花了较大时间进行复现,代码如下

import cv2
from copy import copy
import numpy as np
import matplotlib.pyplot as plt
bgr = None
def get_rgb_():
    global bgr
    img = cv2.imread(r'meiss.png',cv2.IMREAD_COLOR)
    bgr = img
    HSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    # cv2.imshow('HSV', HSV)
    H, S, V = cv2.split(HSV)
    # cv2.imshow('S', V)
    # cv2.waitKey(0)
    return H,S,V



def HE():
    img = cv2.imread(r'meiss.png', 0)
    equ = cv2.equalizeHist(img)  # 输入为灰度图
    res = np.hstack((img, equ))  # stacking images side-by-side
    cv2.imshow('res.png', res)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
def CLAHE(img):

    # #返回彩色图像
    # image = cv2.imread('meiss.png', cv2.IMREAD_COLOR)
    # #将彩色图像分割为b,g,r3个通道
    # b, g, r = cv2.split(image)
    gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
    #剪辑限制(对比度阈值)为0.01,图块数量为8*8,有点问题
    clahe = cv2.createCLAHE(clipLimit=1.81, tileGridSize=(8, 8))
    l,a,b = cv2.split(gray_image)
    L = clahe.apply(l)
    image = cv2.merge([L, a, b])
    new2_rbg_color = cv2.cvtColor(image,cv2.COLOR_LAB2BGR)



    cv2.imwrite(r'clahe_gama_meiss.jpg', new2_rbg_color, [cv2.IMWRITE_JPEG_QUALITY, 50])



def gama_(img):

    # 默认gamma值为1.0,默认不变化
    def adjust_gamma(image, gamma=2.2):
        invgamma = 1/gamma
        brighter_image = np.array(np.power((image/255), invgamma)*255, dtype=np.uint8)
        return brighter_image

    # gamma大于1,变亮
    img_gamma1 = adjust_gamma(img, gamma=2.2)
    plt.subplot(121)
    plt.title('gamma > 1')
    plt.imshow(img_gamma1, cmap="gray")

    # gamma小于1,变暗
    img_gamma2 = adjust_gamma(img, gamma=0.5)
    plt.subplot(122)
    plt.title('gamma < 1')
    plt.imshow(img_gamma2, cmap="gray")

    plt.show()
    return img_gamma1
def f(img_channel):
    return np.power(img_channel,1/3) if img_channel>(6/29)**3 else (29/6)**2*1/3*img_channel+4/29
def anti_f(img_channel):
    return np.power(img_channel,3) if img_channel > 0.206893 else (img_channel-4/29)/(29/6)**2*1/3
def rbg_XYZ(pixel):
    #RGB2XY空间系数矩阵
    m = np.array([
        [0.412453,0.357580,0.180423],
        [0.212671,0.715160,0.072169],
        [0.019334,0.119193,0.950227]
    ])

    b,g,r = pixel[0],pixel[1],pixel[2]
    rgb = np.array((r,g,b))
    XYZ = np.dot(m,rgb.T)
    XYZ = XYZ/255.0
    return (XYZ[0]/0.95047,XYZ[1]/1.0,XYZ[2]/1.08883)
def XYZ_LAB(xyz):
    F_XYZ = [f(x) for x in xyz]
    L = 116*F_XYZ[1]-16 if xyz[1] > (6/29)**3 else 903.3*xyz[1]
    a = 500*(F_XYZ[0]-F_XYZ[1])
    b = 200*(F_XYZ[1]-F_XYZ[2])
    return (L,a,b)
def RGB2LAB(pixel):
    xyz = rbg_XYZ(pixel)
    Lab = XYZ_LAB(xyz)
    return Lab
if __name__ == '__main__':
    H,S,V = get_rgb_()
    new_V = gama_(V)
    new_img_hsv = cv2.merge((H,S,new_V))
    new_bgr_color = cv2.cvtColor(new_img_hsv,cv2.COLOR_HSV2BGR)
    b_x,g_x,r_x = cv2.split(bgr)
    b1_x,g1_x,r1_x = cv2.split(new_bgr_color)
    print(b1_x/b_x)

    Gxy = list(np.concatenate(np.nan_to_num((b1_x/b_x)).reshape((-1, 1), order="F")))
    print(sum(map(sum,np.nan_to_num(b1_x/b_x)))/len(Gxy))
    print(len(Gxy))
    cv2.imwrite(r'gama_meiss.jpg', new_bgr_color, [cv2.IMWRITE_JPEG_QUALITY, 50])
    # w,h,_ = new_bgr_color.shape
    # lab = np.zeros((w,h,3))
    # for i in range(w):
    #     for j in range(h):
    #         Lab = RGB2LAB(new_bgr_color[i,j])
    #         lab[i,j] = (Lab[0],Lab[1],Lab[2])

    # l,a,b = cv2.split(lab)

    CLAHE(new_bgr_color)

这里走了一个弯路,开始想自己写颜色转换的代码的,发现直接有相关的方法,可以直接调用即可,这里注意下,代码中的1/gama才是对应的公式中的r值,gama变换效果如下

 

由于这是灰度图,我们转回bgr来看效果

左边为原图,右边经过gama校正后的彩色视网膜图像,最后生成的总图像如下所示

根据论文上面说的参数剪辑频率(限制对比度阈值)0.01,代码运行结果显示和前面图像相比对比度几乎没有任何提升,而参数设置为1.多,对比度显著提升,可以达到论文中所述效果!

如果上述代码帮助您很多,可以打赏下以减少服务器的开支吗,万分感谢!

欢迎发表评论~

点击此处登录后即可评论


评论列表
暂时还没有任何评论哦...

赣ICP备2021001574号-1

赣公网安备 36092402000079号