赞
踩
光照因素一直是影响成像质量的一个关键因素,夜间等光照环境较差的条件下的图片往往细节丢失、分辨不清,信噪比低下。低照度图像增强是指通过一系列算法和技术,增强在低照度或弱光条件下拍摄的图像的可视化质量。本文主要介绍一些传统的低照度图像增强算法,给出具体的实现代码,便于测试各类图片的增强效果和比较各个算法的性能。
该算法通过对图像的直方图进行均衡化,使图像的灰度分布更加均匀,从而增强图像的亮度和对比度。但是该算法容易出现过度增强和噪声增加的问题。
cv2.equalizeHist()
函数实现import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread("250114358f54e0bd46e0d0590d031e1.png") B,G,R = cv2.split(img) #get single 8-bits channel b=cv2.equalizeHist(B) g=cv2.equalizeHist(G) r=cv2.equalizeHist(R) equal_img=cv2.merge((b,g,r)) #merge it back hist_b=cv2.calcHist([equal_img],[0],None,[256],[0,256]) hist_B=cv2.calcHist([img],[0],None,[256],[0,256]) plt.subplot(1,2,1) plt.plot(hist_B,'b') plt.title('原图B通道的直方图',fontdict={'family':'KaiTi', 'size':10}) plt.subplot(1,2,2) plt.title('均衡化后B通道的直方图',fontdict={'family':'KaiTi', 'size':10}) plt.plot(hist_b,'b') plt.show() cv2.imshow("orj",img) cv2.imshow("equal_img",equal_img) cv2.waitKey(0)
增强效果
直方图变化
该算法通过将低照度图像的直方图映射到高照度图像的直方图上,从而增强图像的亮度和对比度。但是该算法需要有高照度图像作为参考,且对图像的颜色信息敏感。
from PIL import Image import numpy as np import matplotlib.pyplot as plt img1 = np.array(Image.open('11.png')) # 读入原图像 img2 = np.array(Image.open('13.png')) # # 读入参考图像 plt.subplot(2,2,1) plt.imshow(img1, cmap='gray') plt.axis('off') plt.title('原图像',fontdict={'family':'KaiTi', 'size':10}) plt.subplot(2,2,2) plt.imshow(img2, cmap='gray') plt.axis('off') plt.title('参考图像',fontdict={'family':'KaiTi', 'size':10}) # 计算原图像和参考图像的直方图 hist1, bins1 = np.histogram(img1.flatten(), 256, [0,256]) hist2, bins2 = np.histogram(img2.flatten(), 256, [0,256]) # 将直方图归一化 hist1 = hist1 / float(np.sum(hist1)) hist2 = hist2 / float(np.sum(hist2)) # 计算原图像和参考图像的累积分布函数(CDF) cdf1 = hist1.cumsum() cdf2 = hist2.cumsum() # 将CDF归一化 cdf1 = cdf1 / float(cdf1[-1]) cdf2 = cdf2 / float(cdf2[-1]) # 创建新的图像数组 img3 = np.zeros_like(img1) # 计算灰度值映射 lut = np.interp(cdf1, cdf2, np.arange(0, 256)) # 针对每个像素应用灰度映射 for i in range(256): img3[img1 == i] = lut[i] # 显示规定化后的图像 plt.subplot(2,2,3) plt.imshow(img3, cmap='gray') plt.axis('off') plt.title('规定化后的图像',fontdict={'family':'KaiTi', 'size':10}) plt.show()
代码:
import numpy as np import matplotlib.pyplot as plt import cv2 img = cv2.imread('11.png') img = img.astype(np.float32) / 255.0 def gamma_correction(img, gamma): return np.power(img, gamma) gamma = 0.5 img_gamma = gamma_correction(img, gamma) plt.subplot(1,2,1) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.title('原图像',fontdict={'family':'KaiTi', 'size':10}) plt.subplot(1,2,2) plt.imshow(cv2.cvtColor(img_gamma, cv2.COLOR_BGR2RGB)) plt.title('伽马变换后图像',fontdict={'family':'KaiTi', 'size':10}) plt.show()
代码:
import cv2 import numpy as np import matplotlib.pyplot as plt def adaptive_gamma_correction(img, gamma=1.0, eps=1e-7): img_float = img.astype(np.float32) / 255.0 img_max = np.max(img_float) img_norm = img_float / img_max img_log = np.log(img_norm + eps) img_mean = np.exp(np.mean(img_log)) gamma_new = np.log(0.5) / np.log(img_mean) gamma_corr = np.power(img_norm, gamma_new) gamma_corr = np.uint8(gamma_corr * 255.0) return gamma_corr # 读取输入图片 img = cv2.imread('11.png') # 进行自适应伽马校正 gamma_corr = adaptive_gamma_correction(img) # 显示输入和输出图片 plt.subplot(121) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.title('原图像',fontdict={'family':'KaiTi', 'size':10}) plt.axis('off') plt.subplot(122) plt.imshow(gamma_corr, cmap='gray') plt.title('自适应伽马变换后图像',fontdict={'family':'KaiTi', 'size':10}) plt.axis('off') plt.show()
该算法通过模拟人眼对光照变化的适应能力,将图像(
S
S
S)分解成反射分量(
R
R
R)和光照分量(
I
I
I),原理就是将
I
I
I去除,保留反映物体本质的量
R
R
R。
S
(
x
,
y
)
=
R
(
x
,
y
)
∗
I
(
x
,
y
)
S(x,y)=R(x,y)*I(x,y)
S(x,y)=R(x,y)∗I(x,y)
两边做对数变换:
l
o
g
(
R
(
x
,
y
)
)
=
l
o
g
(
S
(
x
,
y
)
)
−
l
o
g
(
I
(
x
,
y
)
)
\\两边做对数变换:log(R(x,y))=log(S(x,y))-log(I(x,y))
两边做对数变换:log(R(x,y))=log(S(x,y))−log(I(x,y))
S
S
S 是输入的低照度图像,
R
R
R 是待输出的增强后图像。因此,该算法的关键就是如何得到这里的光照量
I
I
I,而
R
e
t
i
n
e
x
Retinex
Retinex 理论的提出者认为
S
S
S经过高斯滤波后就可以得到
I
I
I,即对图像作模糊或平滑处理。
import cv2 import torch from torchvision import datasets,transforms import numpy as np from PIL import Image, ImageFilter # S = I * R # S:输入图片 # I:光照量;需要对图像进行高斯模糊得到 # R:增强后图片 torch.set_default_tensor_type('torch.cuda.FloatTensor') device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') transform = transforms.ToTensor() GaussianBlur = transforms.GaussianBlur(3,sigma=(0.1,0.1)) #高斯模糊 to_pil = transforms.ToPILImage() #将Tensor转换成PIL格式 img_path = 'F:\Picture\低照度图片' out_path = 'F:\SCI-main\传统增强算法\测试结果\SSR测试结果/' img = datasets.ImageFolder(img_path,transform = transform) def SSR(image): img_S = image.cuda() ln_S = torch.log((img_S + 0.001) / 255.0) img_I = GaussianBlur(img_S) ln_I = torch.log((img_I + 0.001) / 255.0) ln_R = ln_S - ln_I * ln_S # 这里ln_S起到调节作用,不加的话效果很差 R = cv2.normalize(ln_R.cpu().numpy(), None, 0, 1, cv2.NORM_MINMAX) final_image = to_pil(torch.tensor(R)) return final_image for i in range(len(img.imgs)): image = SSR(img[i][0]) image.save(out_path + str(i) + '.png')
几个注意点:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。