图像复原--Color Balance and Fusion for Underwater Image Enhancement

2024-01-04 20:10

本文主要是介绍图像复原--Color Balance and Fusion for Underwater Image Enhancement,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

图像复原–Color Balance and Fusion for Underwater Image Enhancement

参考链接: (建议先阅读原论文和参考链接内容,本文纯属记录性质)

https://blog.csdn.net/qq_43287277/article/details/104901501
https://github.com/fergaletto/Color-Balance-and-fusion-for-underwater-image-enhancement.-.
https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8058463&isnumber=8071125

1. 摘要:

​ 对水下因为介质散射和吸收导致的图像质量下降问题, 提出了一种融合颜色补偿和白平衡图像的算法,同时定义两幅融合图像及其相关的权重图,强化边缘和颜色对比度向输出图像的传输。为了避免权值变换在重建图像的低频分量中产生伪影,还采用了多尺度融合策略。实验表明增强图像全局对比度和边缘清晰度能够明显改善。

2. 背景

​ 水下成像通常包含三个分量,分别是直接分量(direct composed)、前向散射(forward scattering)、后向散射(back scattering),前向散射在实际模型中经常被忽略, 所以最终的成像是直接分量和后向散射两个分量的叠加:
I c = J c e − η d ( x ) + B c ∞ ( 1 − e − η d ( x ) ) (1) I_c = J_ce^{-\eta d(x)}+B^{\infty}_c(1-e^{-\eta d(x)}) \tag{1} Ic=Jceηd(x)+Bc(1eηd(x))(1)
J c J_c Jc是未衰减的直接分量, d d d是观察者与物体之间的距离函数, η \eta η是衰减系数, B c ∞ B^{\infty}_c Bc是背景光,指数项是通过水下介质的传输公式。sea-Thru算法对 η \eta η取同一个值提出了质疑,采用两个不同的系数控制衰减,取得了比较好的结果。

3. 算法实现

​ 文章提出的图像增强方法采用两步策略,分别为白平衡和图像融合。白平衡的目的是补偿颜色随深度的选择性吸收而产生的颜色投射,而图像融合则被考虑用于增强场景的边缘和细节,以减轻由于后向散射而造成的对比度损失。

白平衡

​ 不同光源色温也不同。当拍摄画面出现偏色时,多采用白平衡来解决这一问题。传统的白平衡有很多种方法,比如灰色世界,灰色边缘,灰色阴影等,原文作者对各种白平衡方法进行比较,发现灰色世界法对于水下图像有良好的效果但经过观察发现,这种方法存在严重的红色伪影。

灰色世界白平衡法假设对于一幅图像来说, RGB 三个分量的平均值趋于同一个灰度K。灰度K可以自己定义,也可以使用三个通道的平均值,之后使用K比上每一个通道的平均值,算出每一个通道的权重,若一个通道在图像中的成分过多,则权值会小于1,反之,权重值会大于1。最后再将各个通道依照此权重进行相加即可。灰色世界白平衡法对水下图像使用会产生的红色伪影。按照其算法原理来分析,**红色分量在水下图像(以蓝色或绿色为主题颜色)中,比重实在太小,导致权值过大,从而被极大地放大。那么调整红色的权重就很关键。**原文作者提出的白色补偿白平衡法的表达式如下:
I r c ( x ) = I r ( x ) + a ( I g ˉ − I r ˉ ) ( 1 − I r ( x ) ) I g ( x ) (2) I_{rc}(x)=I_r(x)+a(\bar{I_g}-\bar{I_r})(1-I_r(x))I_g(x) \tag{2} Irc(x)=Ir(x)+a(IgˉIrˉ)(1Ir(x))Ig(x)(2)
其中, I r , I g I_r,I_g Ir,Ig表示图像 I I I的红色和绿色通道,每个通道的值要根据本通道的最大最小值范围归一化到[0,1]内, I r ˉ \bar{I_r} Irˉ I g ˉ \bar{I_g} Igˉ表示 I r , I g I_r,I_g Ir,Ig的平均值, a a a表示常量参数,在实际测试中, a = 1 a=1 a=1的值适合于各种照明条件和采集设置。式(2)具体含义为, I r c I_{rc} Irc代表增加补偿项的红色分量, a a a通常为1, I r ˉ \bar{I_r} Irˉ I g ˉ \bar{I_g} Igˉ相减得到一个系数,这个系数与红色分量成反比,红色分量越小时,系数越大, 1 − I r 1-I_r 1Ir代表后面绿色通道的补偿系数,如果红色分量越多,那么绿色通道的补偿则越少,相反,则越大。可以看出这个补偿项是将绿色成分的一部分拿来补偿红色,另外也加入了图像整体红色分量的比重和各个像素点的红色分量比重,考虑的非常完备。

不过有的时候,因为水下过于浑浊或者微生物太多的原因,水下会呈现绿色而非蓝色,这个时候只需要再将蓝色通道进行相同方式的补偿即可。

'''
白平衡
'''
def white_balance(img):B, G, R = np.double(img[:, :, 0]), np.double(img[:, :, 1]), np.double(img[:, :, 2])# 获取每个通道归一化后[0, 1]的值R_norm = signal_channel_normal(R)G_norm = signal_channel_normal(G)B_norm = signal_channel_normal(B)# 获取归一化后的每个通道的均值mean_R_norm = np.mean(R_norm)mean_G_norm = np.mean(G_norm)mean_B_norm = np.mean(B_norm)# 对红蓝通道补偿rc = R_norm + (mean_G_norm - mean_R_norm)*(1-R_norm)*G_normbc = B_norm + (mean_G_norm - mean_B_norm)*(1-B_norm)*G_norm# 判断补偿参数,大于1的变成1rc[rc > 1] = 1bc[bc > 1] = 1# 现在红蓝通道是补偿后的值newr = rc # 红色通道补偿newb = bc # 蓝色通道补偿newg = G_norm# 进行白平衡B_ave, G_ave, R_ave = np.mean(newb), np.mean(newg), np.mean(newr)# factor = G_ave/B_ave;K = (B_ave + G_ave + R_ave) / 3Kb, Kg, Kr = K / B_ave, K / G_ave, K / R_aveBa = (newb * Kb)Ga = (newg * Kg)Ra = (newr * Kr)for i in range(len(Ba)):for j in range(len(Ba[0])):Ba[i][j] = 255 if Ba[i][j] > 255 else Ba[i][j]Ga[i][j] = 255 if Ga[i][j] > 255 else Ga[i][j]Ra[i][j] = 255 if Ra[i][j] > 255 else Ra[i][j]# print(np.mean(Ba), np.mean(Ga), np.mean(Ra))dst_img = np.double(np.zeros_like(img))dst_img[:, :, 0] = Badst_img[:, :, 1] = Gadst_img[:, :, 2] = Rareturn dst_img
锐化

​ 白平衡的目的是补偿颜色随深度的选择性吸收而产生的颜色投射,而图像融合则用于增强场景的边缘和细节,以减轻由于后向散射而造成的对比度损失。接下来对以上算法处理之后得到的图像进行锐化处理,传统的锐化公式:
S = I + β ( 1 − G ∗ I ) S=I+\beta(1-G*I) S=I+β(1GI)

I I I是要锐化的图像(白平衡图像), G ∗ I G*I GI表示对I进行高斯滤波,β是参数。在实际应用中,β的选择并不简单。较小的β不能锐化I,但过大的β会导致过饱和,具有较亮的高光和较暗的阴影。为了避免这个问题,新的锐化图像算法表达式如下:
S = ( I + N ( 1 − G ∗ I ) ) 2 S=\frac{(I+N(1-G*I))}{2} S=2(I+N(1GI))
N表示线性归一化运算,也是直方图拉伸运算,上述方式称为normalized unsharp masking不需要考虑 β \beta β值的选取,此处要注意的是,直方图拉伸并不等于直方图均衡化。

def imageSharp_(img):# 图像线性拉伸锐化# S=(I+N(1-G*I))/2# 高斯滤波sigma = 20kernel_size = (0,0) # 0,0函数会自己计算卷积核Igauss_ = imgN=30for i in range(N):Igauss = cv2.GaussianBlur(img, kernel_size, sigmaX=sigma, borderType=cv2.BORDER_REPLICATE)Igauss_ = np.minimum(img, Igauss)gain = 1 # Norm = img-gain*Igauss_#执行直方图拉伸操作,对三个通道分别执行B, G, R = np.double(Norm[:, :, 0]), np.double(Norm[:, :, 1]), np.double(Norm[:, :, 2])# 计算原图灰度直方图equ_R = cv2.normalize(R, None, 1.0, 0.0, cv2.NORM_MINMAX, dtype=cv2.CV_64F)equ_G = cv2.normalize(G, None, 1.0, 0.0, cv2.NORM_MINMAX, dtype=cv2.CV_64F)equ_B = cv2.normalize(B, None, 1.0, 0.0, cv2.NORM_MINMAX, dtype=cv2.CV_64F)hist_norm_img = np.double(np.zeros_like(img))hist_norm_img[:, :, 0] = equ_Bhist_norm_img[:, :, 1] = equ_Ghist_norm_img[:, :, 2] = equ_Rout = (img + hist_norm_img)/2return out
权重计算

​ 图像融合肯定是要依靠一定的权重的,原文作者提供了如下几个权重:Laplacian contrast weight(拉普拉斯对比度权重)、Saliency weight(显著性权重)、Saturation weight(饱和权重)每个权重都要对白平衡后的图像和锐化后的图像做

Laplacian contrast weight(拉普拉斯对比度权重): 主要是针对亮度通道进行拉普拉斯滤波而来的。首先把rgb图像转化为hsv图像,提取亮度层,然后进行拉普拉斯滤波便可。

def getLaplacianContrast_(img):#提取亮通道lab_color = color.rgb2lab(img)R1 = np.double(lab_color[:, :, 0])/255localContrast = img[:, :, 0]- R1localContrast = np.sqrt((1.0/3)*(np.power((lab_color[:, :, 0]-R1),2)+np.power((lab_color[:, :, 1]-R1),2)+np.power((lab_color[:, :, 2]-R1),2)))return localContrast

Saliency weight (显著性权重): 首先要将图像从RGB转化到LAB,L是明度,A, B是两种颜色。然后计算三个通道各个的平均值,记为 m L , m A , m B mL,mA,mB mL,mA,mB再计算各个通道的均方差,最后进行加和,表达式如下:
W s a l = ( L − m L ) 2 + ( A − m A ) 2 + ( B − m B ) 2 W_{sal}=(L-mL)^2+(A-mA)^2+(B-mB)^2 Wsal=(LmL)2+(AmA)2+(BmB)2

def getSaliencyWeight(img):lab_color = color.rgb2lab(img)l = np.double(lab_color[:, :, 0])a = np.double(lab_color[:, :, 1])b = np.double(lab_color[:, :, 2])lm = np.mean(l)am = np.mean(a)bm = np.mean(b)sm_weight = np.power((l-lm),2) +np.power((a-am),2)+ np.power((b-bm),2)return sm_weight

Saturation weight (饱和权重):主要是利用RGB三个通道与亮度的偏差来计算的,表达式如下:
W s a t = 1 3 [ ( R − I ) 2 + ( G − I ) 2 + ( B − I ) 2 ] W_{sat}=\sqrt{\frac{1}{3}[(R-I)^2+(G-I)^2+(B-I)^2]} Wsat=31[(RI)2+(GI)2+(BI)2]
其中 R G B RGB RGB分别表示的是红绿蓝三个通道, I I I代表亮度通道。

def getSaturationWeight_(img):lab_color = color.rgb2lab(img)R1 = np.double(lab_color[:, :, 1]) / 255localContrast = np.sqrt((1.0/3)*(np.power((lab_color[:, :, 0]-R1),2)+np.power((lab_color[:, :, 1]-R1),2)+np.power((lab_color[:, :, 2]-R1),2)))return localContrast
融合

​ 图像融合采用的是高斯金字塔和拉普拉斯金字塔来实现,图像金字塔其实就是由一组不同尺寸的图像组成的,把尺寸小的图像放在最上层,把尺寸大的图像放在最下层,这样看起来就像一座金字塔,这是最直观的解释。但是这一组不同尺寸的图片可不能是随意组成的,他们都是由最底层的原始图像,经过滤波然后隔行隔列采样而来,所以上一层的图像的尺寸是下一层图像尺寸的四分之一。之所以叫高斯金字塔,是因为他的滤波过程选择的是高斯低通滤波器,这样构成的图像金字塔就是高斯金字塔了,而拉普拉斯金字塔是用来重建高斯金字塔的,就是高斯金字塔的逆过程。

​ 作者将白平衡图像的三个权重和锐化图像的三个权重看成两个整体再将二者进行归一化处理,用两个归一化权重来构建高斯金字塔再使用锐化后的白平衡图像和进行过gamma变换的白平衡图像建立拉普拉斯金字塔。这里使用gamma变换是将图像做一个非线性的变换(幂函数映射),是一种简单的图像增强方法,为的是提升图像的视觉效果。接下来就是将权重金字塔的对应层与图像金字塔的对应层相乘,形成一个新的加入权重的图像金字塔,具体表达式如下:
N k = G w b k × L w b k + G s k × L s k N_k=Gwb_k×Lwb_k+Gs_k×Ls_k Nk=Gwbk×Lwbk+Gsk×Lsk
其中 k k k代表金字塔的层数, G w b Gwb Gwb是对白平衡图像归一化权重的高斯金字塔, L w b Lwb Lwb是白平衡图像的拉普拉斯金字塔, G s G_s Gs为对锐化图像归一化权重的高斯金字塔, L s L_s Ls为锐化图像的拉普拉斯金字塔。

def gaussian_pyramid2(img, level):h = 1/16 * np.array([1, 4, 6, 4, 1])filt = np.outer(h, h)out = [convolve2d(img, filt, mode='same', boundary='wrap')]temp_img = img.copy()for i in range(2, level+1):temp_img = temp_img[::2, ::2]out.append(convolve2d(temp_img, filt, mode='same', boundary='wrap'))return outdef laplacian_pyramid2(img, level):h = 1/16 * np.array([1, 4, 6, 4, 1])out = [img]temp_img = img.copy()for i in range(2, level + 1):temp_img = temp_img[::2, ::2]out.append(temp_img.copy())# Calculate the DoG (Difference of Gaussians)for i in range(level - 1):m, n = out[i].shapeout[i] = out[i] - cv2.resize(out[i + 1], (n, m))return outdef pyramid_reconstruct2(pyramid):level = len(pyramid)for i in range(level - 1, 0, -1):m, n = pyramid[i - 1].shapepyramid[i - 1] = pyramid[i - 1] + cv2.resize(pyramid[i], (n, m))out = pyramid[0]return out
4. 结果图

上面图是对应的naive_funsion结果,中间图是对应的金字塔多尺度融合结果, 最后三联图是对应RGB三通道多尺度融合后每个通道结果,native_funsion明显有局部地方出现偏白的问题:
Native_Fusion
MulscaleFusion
在这里插入图片描述
Naivefusion
malscalefusion
在这里插入图片描述

5. python复现中出现的问题: 使用cv2.imshow/plt.imshow显示图片正常,但保存下来的图片不正常或者全黑

最后输出结果保存的时候,用opencv或matplotlib都可以正常显示,但是保存下来的图像是黑的,感谢以下博主提供的解决方案。

参考链接: https://blog.csdn.net/qq_40682833/article/details/124049695

这篇关于图像复原--Color Balance and Fusion for Underwater Image Enhancement的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/570463

相关文章

lvgl8.3.6 控件垂直布局 label控件在image控件的下方显示

在使用 LVGL 8.3.6 创建一个垂直布局,其中 label 控件位于 image 控件下方,你可以使用 lv_obj_set_flex_flow 来设置布局为垂直,并确保 label 控件在 image 控件后添加。这里是如何步骤性地实现它的一个基本示例: 创建父容器:首先创建一个容器对象,该对象将作为布局的基础。设置容器为垂直布局:使用 lv_obj_set_flex_flow 设置容器

三色标记(Tri-color marking)

维基百科部分 原文 https://en.wikipedia.org/wiki/Tracing_garbage_collection#TRI-COLOR Because of these performance problems, most modern tracing garbage collectors implement some variant of the tri-color ma

VMware Fusion Pro 13 Mac版虚拟机 安装Win11系统教程

Mac分享吧 文章目录 Win11安装完成,软件打开效果一、VMware安装Windows11虚拟机1️⃣:准备镜像2️⃣:创建虚拟机3️⃣:虚拟机设置4️⃣:安装虚拟机5️⃣:解决连不上网问题 安装完成!!! Win11安装完成,软件打开效果 一、VMware安装Windows11虚拟机 首先确保自己的mac开启了网络共享。不然虚拟机连不上👀的 1️⃣:准备镜像

VMware Fusion Pro 13 for Mac虚拟机软件

Mac分享吧 文章目录 效果一、下载软件二、开始安装安装完成!!! 效果 一、下载软件 下载软件 地址:www.macfxb.cn 二、开始安装 安装完成!!!

HDU 1556 Color the ball (树状数组-- 区间更新,单点求值)

OJ题目 :点这里~~ 与 单点更新,区间求值 稍有不同,需要理解注意。 AC_CODE int n;int num[100002];int lowbit(int x){return x&(-x);}int sum(int x){int ret = 0;while(x > 0){ret += num[x];x -= lowbit(x);}return ret;}void ad

IMAGE LIST

   CImageList就是一个容器,用来存储图片资源,方便这些资源被CListBox,CComboBox,CComboBoxEx,CTabCtrl以及CTreeCtrl,CListCtrl等使用。      要使用CImgeList首先要使用它的create函数:      一般用的比较多的是这一个函数,当然,它还有很多重载,自己可以去翻阅msdn.       BOOL

【vscode】vscode paste image插件设置

本文首发于 ❄️慕雪的寒舍 vscode编辑md文件的时候,如果想插入图片,自带的粘贴只会粘贴到当前目录下,也没有文件重命名,很不友好。 在扩展商店里面有mushan的Paste Image插件,相比自带的,更加友好一点。但是它的配置把我弄糊涂了,简单测试了一下才明白处理的逻辑。 注意,本文编写的是对mushan的Paste Image插件的教程。 首先是安装这个插件,这个不多说

pytorch时空数据处理4——图像转文本/字幕Image-Captionning(二)

pytorch时空数据处理4——图像转文本/字幕Image-Captionning(二) pytorch时空数据处理4——图像转文本/字幕Image-Captionning(二)DatasetInputs to modelCaption LengthsData pipelineEncoderAttentionDecoder代码数据集初始化 create_input_files.py训练 tr

Show,Attend and Tell: Neural Image Caption Generation with Visual Attention

简单的翻译阅读了一下 Abstract 受机器翻译和对象检测领域最新工作的启发,我们引入了一种基于注意力的模型,该模型可以自动学习描述图像的内容。我们描述了如何使用标准的反向传播技术,以确定性的方式训练模型,并通过最大化变分下界随机地训练模型。我们还通过可视化展示了模型如何能够自动学习将注视固定在显着对象上,同时在输出序列中生成相应的单词。我们通过三个基准数据集(Flickr9k,Flickr

Docker Image 命令

文章目录 目录 文章目录 1 . Docker镜像是什么? 2 . 镜像命令详解 docker images docker tag docker pull docker rmi  docker save 总结 1 . Docker镜像是什么? Docker image 本质上是一个 read-only 只读文件, 这个文件包含了文件系统、 源码、库文件、依赖、工具等一些