这周组会要讲论文,我选的论文是基于亮度和对比度调整的彩色视网膜图像增强,是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.多,对比度显著提升,可以达到论文中所述效果!
点击此处登录后即可评论