《基于直方图分布特性的水下图像颜色校正方法》论文代码复现完整版

《基于直方图分布特性的水下图像颜色校正方法》论文代码复现完整版


近期一直在准备研究生的开题,更新迟缓,现在关于这篇博文的后续终于来啦!!!!

这篇论文的颜色校正方法第一步是先进行颜色通道的补偿,第二步进行颜色通道的动态拉伸,从而达到颜色校正的目的,去除水下图像偏绿、偏蓝的色偏效果。第一步具体实施方法和效果可以移步到上次我写的博文,博文链接:《基于直方图分布特性的水下图像颜色校正方法》论文代码复现。本文是对后续的动态拉伸环节进行更新:

上次我们分析图像的直方图分布时提到,要想让水下的图像成像效果和陆地上的图像效果相近,起码要满足2个条件:
(1)三通道直方图分布相似;
(2)三通道直方图分布遍及整个动态范围;
其实还应该满足一个条件,那就是三通道直方图均值都近似等于128。衰减补偿后的图像直方图具有一定的相似性,但分布还比较集中,因此还需要对其动态拉伸,使拉伸后直方图分布符合前节所述所有特点。

动态范围的拉伸

统计学上,均值反映数据的集中趋势或者是期望值,标准差反映一个数据集的离散程度,因此我们采用均值和标准差来确定动态拉伸前的范围:
均值标准差计算公式

其中C表示红绿蓝三个颜色通道,Lmean和Lstd表示对应颜色通道的均值和标准差,Lmin和Lmax表示对应通道的最小值和最大值,u表示动态范围,经试验验证,动态范围不能太大也不能太小,取2~3之间就可以,这里取3,读者可以根据自己的水域环境进行更改。

然后进行颜色的校正,校正公式为:
校正公式
Lout为校正后的颜色通道,Lin为校正后的颜色通道。根据公式我们可以看出,这是由传统的拉伸公式演化而来,不理解的可以查一查这个公式。

程序复现(总)

import cv2
import numpy as np
import matplotlib.pyplot as plt

image = cv2.imread("ok4.jpg").astype(np.float32) / 255.0

# 将图像分为BGR三个颜色通道
B, G, R = cv2.split(image)

# 计算蓝色通道的像素平均值
Bavg = np.mean(np.mean(B))

# 计算绿色通道的像素平均值
Gavg = np.mean(np.mean(G))

# 计算红色通道的像素平均值
Ravg = np.mean(np.mean(R))

# 创建颜色通道平均值的列表
means = [Bavg, Gavg, Ravg]

# 根据平均值从高到低对颜色通道进行排序
sorted_channels = [B, G, R]
sorted_channels = [x for _, x in sorted(zip(means, sorted_channels), reverse=True)]

# 将排序结果分别表示为Pfirst(i,j)、Psecond(i,j)、Pthird(i,j)
Pfirst = sorted_channels[0]  # 平均值最大的颜色通道
Psecond = sorted_channels[1]
Pthird = sorted_channels[2]  # 平均值最小的颜色通道,此时的通道是二维数组

# 计算补偿因子a,b
a = (np.mean(Pfirst) - np.mean(Psecond)) / (np.mean(Pfirst) + np.mean(Psecond))
b = (np.mean(Pfirst) - np.mean(Pthird)) / (np.mean(Pfirst) + np.mean(Pthird))

# 对第二均值通道进行逐像素补偿
Psecond_compensated = Psecond + a * Pfirst

# 对第三均值通道进行逐像素补偿
Pthird_compensated = Pthird + b * Pfirst

# 将三个通道(第一均值颜色通道,补偿后的第二、三均值分布通道)进行组合
merged_image = np.dstack((Pfirst, Psecond_compensated, Pthird_compensated))

#计算各个通道的均值和标准差
min_first = np.mean(Pfirst) - 3 * np.std(Pfirst)
max_first = np.mean(Pfirst) + 3 * np.std(Pfirst)

min_second_compensated = np.mean(Psecond_compensated) - 3 * np.std(Psecond_compensated)
max_second_compensated = np.mean(Psecond_compensated) + 3 * np.std(Psecond_compensated)

min_third_compensated = np.mean(Pthird_compensated) - 3 * np.std(Pthird_compensated)
max_third_compensated = np.mean(Pthird_compensated) + 3 * np.std(Pthird_compensated)

#对三个颜色通道进行动态拉伸
Lfirstout = (Pfirst - min_first) * 255 / (max_first - min_first)
#将拉伸后的图像各个像素点限制在0~255之内,如果大于255会出现很多噪点和伪影,出现过曝的现象,影响整个图像
Lfirstout = np.clip(Lfirstout, 0, 255)

Lsecondout = (Psecond_compensated - min_second_compensated) * 255 / (max_second_compensated - min_second_compensated)
Lsecondout = np.clip(Lsecondout, 0, 255)

Lthirdout = (Pthird_compensated - min_third_compensated) * 255 / (max_third_compensated - min_third_compensated)
Lthirdout = np.clip(Lthirdout, 0, 255)

#将拉伸后的通道重新合并为图像
lashen_image = np.dstack((Lfirstout, Lsecondout, Lthirdout)).astype(np.uint8)

print("Lfirstout", Lfirstout)
print("Lsecondout", Lsecondout)
print("Lthirdout", Lthirdout)

# 展示原始图像和动态拉伸后的图像
cv2.imshow("original",image)
cv2.imshow("lashen_image", lashen_image)
cv2.imshow("firstout_image", Lfirstout.astype(np.uint8))
cv2.imshow("secondout_image", Lsecondout.astype(np.uint8))
cv2.imshow("thirdout_image", Lthirdout.astype(np.uint8))

# 等待按键,结束本次服务
cv2.waitKey()
cv2.destroyAllWindows()

运行结果

在这里插入图片描述

结果分析

不管是蓝色、还是绿色的水下环境,图像颜色都能很好的恢复,而且颜色校正后的图像相对衰减补偿后的图像效果更好,偏色现象去除更明显,颜色更自然。但是细节模糊和对比度还是存在问题,可以在后续加入直方图均衡化等算法加大图像的对比度。

欢迎大佬们提出意见,侵权联系速删。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值