介绍的是一种比较实用并且去阴影效果很好的方法,选自2004年Tao的一篇论文,名称是《An Integrated Neighborhood Dependent Approach for Nonlinear Enhancement of Color Images 》,有兴趣的朋友仔细细读一下。论文篇幅很短,所以应该难度不大,而且效果极佳。
通过灰度图,动态范围压缩,高斯滤波结果,得到修复的灰度图。然后根据灰度图进行色彩恢复
Matlab
clc
clear
I=im2double(imread('2.png'));
I1=rgb2gray(I);
%其中的0.24和0.5都是可以调整的常数
In=(I1.^(0.24)+(1-I1).*0.5,I1.^2)/2;
%通过高斯核对灰度增强图像做卷积运算
sigma=3;
window_1 = double(uint8(3*sigma)*2+1);
G1=fspecial('gaussian',window_1,sigma);
Guass1=imfilter(I1,G1,'conv','replicate','same');
r1=Gauss1./I1;
R1=In.^r1;
sigma=20;
window_2=doule(uint8(3*sigma)*2+1);
G2=fspecial('gaussian',window_2,sigma);
Guass2=imfilter(I1,G2,'conv','replicate','same');
r2=Gauss2./I1;
R2=In.^r2;
sigma=240;
window_3 = double(uint8(3*sigma)*2+1);
G3=fspecial('gaussian',window_3,sigma);
Gauss3=imfilter(I1,G3,'conv','replicate','same');
r3=Gauss3./I1;
R3=In.^r3;
R=(R1+R2+R3)/3;
%R就是调整之后的I1,所以按照下面的式子来恢复
Rr=R.*(I(:,:,1)./I1);
Rg=R.*(I(:,:,2)./I2);
Rb=R.*(I(:,:,3)./I3);
rgb=cat(3,Rr,Rg,Rb);
imshow([I rgb])
Python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/5/25 11:17
# @Author : Hran
# @Site :
# @File : work.py
# @Software: PyCharm
"""
论文:An Integrated Neighborhood Dependent Approach for Nonlinear Enhancement of Color Images
想复现一下之后,用暗通道去雾来代替
"""
import sys
import cv2
import numpy as np
e = np.exp(-10)
def Gaussion_kernel(kernel_size=3,sigma=1):
m = n = (kernel_size - 1.) / 2.
y, x = np.ogrid[-m:m + 1, -n:n + 1]
h = np.exp(-(x * x + y * y) / (2. * sigma * sigma))
h[h < np.finfo(h.dtype).eps * h.max()] = 0
sumh = h.sum()
if sumh != 0:
h /= sumh
return h
def gray_img(img):
I1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
return I1 / 255 + e
def light_img(img):
"""
对灰度图进行亮度恢复(动态范围压缩)
:param img:灰度图
:return:
"""
np.power(img, 0.24)
In = (np.power(img, 0.24) + (1 - img) * 0.5 + np.power(img, 2)) / 2
return In
def contrast_enhancement(I1, In, sigma_list=[3,20,240]):
"""
经过对比度增强获取R
:param img:
:return:
"""
R = []
for i in range(len(sigma_list)):
sigma = sigma_list[i]
windows_size = np.float32(np.uint8(sigma*3) * 2 + 1)
if windows_size > 255:
windows_size = 255
print(windows_size)
Gauss = cv2.GaussianBlur(I1, (0,0), sigma)
# kernel = Gaussion_kernel(windows_size, sigma)
# Gauss = cv2.filter2D(I1, -1, kernel)
r = Gauss / I1
R_temp = np.power(In, r)
R.append(R_temp)
R = R[0] + R[1] + R[2]
return R / 3
def color_rebuild(img, I1, R):
img = img / 255.
b, g, r= cv2.split(img)
r_1 = R * (r / I1)
g_1 = R * (g / I1)
b_1 = R * (b / I1)
img = cv2.merge([b_1, g_1, r_1])
return img
if __name__ == '__main__':
img = cv2.imread('/Users/mac/Desktop/Test/6.jpeg')
img = img.astype(np.float32)
I1 = gray_img(img)
a = np.where(I1 == 0)
print(a)
In = light_img(I1)
R = contrast_enhancement(I1, In)
result = color_rebuild(img, I1, R)
result[result > 1] = 1
result = result * 255
result = result.astype(np.uint8)
cv2.imshow('result', result)
cv2.waitKey()