1. 参考文献
2. 模型实现
% 论文: Naturalness Preserved Enhancement Algorithm for Non-Uniform Illumination Images
% 作者: Shuhang Wang, Hai-Miao Hu, Bo Li
% 链接:
% Author: HSW
% Date: 2018-04-29
%
clc;
close all;
clear;
img = imread('timg4.png');
[m, n, dims] = size(img);
downSample = 0; % 对图像进行降采样
scale = 0.5; % 降采样的比例
patchSize = 15; % 公式(12)
patchSizeQ = 3; % 公式(6)
neighborMode = 0; % = 0 表示采用四邻域, = 1 表示采用8邻域
isPostProcess = 1; % 是否进行中值滤波后处理
if dims == 3
if downSample == 1
m = uint8(m * scale);
n = uint8(n * scale);
img_in = imresize(img, [m, n]);
else
img_in = img;
end
figure;
imshow(img_in, []);
title('原图像');
% 初始估计亮度: 用亮通道进行初步估计
L_init = Illumination(img_in, 'max_c');
figure;
imshow(L_init, []);
title('L_{init}');
% 构造Bright-Pass Filter
L_r = filter_BPF(L_init, patchSize, patchSizeQ, neighborMode);
figure;
imshow(L_r, []);
title('L_{r}');
% 公式(13)
L_tmp = repmat(double(L_r), [1, 1, 3]);
R_c = double(img_in) ./ (L_tmp + (L_tmp == 0) .* 0.001);
% 公式(14)
epsilon = 1;
L_lg = log(double(L_r) + epsilon);
figure;
imshow(L_lg, []);
title('L_{lg}');
% 公式(17)
[cLv, mp] = weight_hist(L_lg, L_r);
% 公式(18) 和 (19)
[cfz, sz] = log_hist();
% 公式(22)
L_m = filter_BLT(L_r, cLv, cfz);
figure;
imshow(L_m, []);
title('L_{m}');
% 中值滤波
if isPostProcess
L_m_m = L_m;
R_c_m = R_c;
ksize = 3;
hsize = floor(ksize / 2);
for i = hsize + 1 : m - hsize
for j = hsize + 1 : n - hsize
patchSize = L_m(i + [-hsize : hsize], j + [-hsize : hsize]);
L_m_m(i, j) = median(patchSize(:));
patchSize = R_c(i + [-hsize : hsize], j + [-hsize : hsize]);
R_c_m(i, j) = median(patchSize(:));
end
end
figure;
imshow(L_m_m, []);
title('L_{m2}');
img_out = R_c_m .* repmat(double(L_m_m), [1, 1, 3]);
img_out = img_out ./ 255.0;
figure;
imshow(img_out, []);
title('中值滤波后处理:增强结果');
else
% 公式(11)
img_out = R_c .* repmat(double(L_m), [1, 1, 3]);
img_out = img_out ./ 255.0;
figure;
imshow(img_out, []);
title('原论文:增强结果');
end
else
disp('NUE图像增强彩色图像');
end
2.1 亮通道
function T = Illumination(L, method)
% Inputs:
% L:
% Outputs:
% T:
if strcmp(method, 'max_c') == 1
T = max(L, [], 3);
elseif strcmp(method, 'min_c') == 1
T = min(L, [], 3);
end
end
2. Bright-Pass Filter
function L_r = filter_BPF(L_init, patchSize, patchSizeQ, neighborsMode)
% Inputs:
% L_init: m x n, 初始估计得亮度
% patchSize: 默认为15 x 15
% neighborsMode: 默认为0, 表示使用四连通区域
% Outputs:
% L_r: BPF滤波过滤的亮度
%
% Author: HSW
% Date: 2018-04-29
%
if ~exist('neighborsMode', 'var')
neighborsMode = 0;
end
if ~exist('patchSizeQ', 'var')
patchSizeQ = floor((max(max(L_init)) - min(min(L_init))) / 32); % 公式(8)
end
if ~exist('patchSize', 'var')
patchSize = 15;
end
[m, n] = size(L_init);
if neighborsMode == 0
indexX = [0, -1, 0, 1, 0];
indexY = [-1, 0, 0, 0, 1];
elseif neighborsMode == 1
indexX = [-1, 0, 1, -1, 0, 1, -1, 0, 1];
indexY = [-1, -1, -1, 0, 0, 0, 1, 1, 1];
end
% 公式(6)
% x, y, k, l
level = 256;
Q_init = sparse(m * n, level * level);
for x = 2 : m - 1
for y = 2 : n - 1
for idx = 1 : length(indexX)
k = int32(L_init(x, y) + 1);
l = int32(L_init(x + indexX(idx), y + indexY(idx)) + 1);
Q_init((x - 1) * n + y, (k - 1) * level + l) = Q_init((x - 1) * n + y, (k - 1) * level + l) + 1;
end
end
end
Q_1 = zeros(level, level);
for k = 1 : level
for l = 1 : level
Q_1(k, l) = sum(Q_init(:, (k - 1) * level + l));
end
end
figure;
imshow(Q_1 ./ 255, []);
title('Q 1');
% 公式(7)
win = patchSizeQ;
Q = zeros(level, level);
for k = 1 : level
for l = 1 : level
idx = max(1, l - win) : min(level, l + win);
Q(k, l) = sum(Q_1(k, idx)) ./ length(idx) ;
end
end
figure;
imshow(Q ./ 255, []);
title('Q');
% 公式(12)
L_r = zeros(size(L_init));
for x = 1 : m
for y = 1: n
idx_i = max(1, x - patchSize) : min(m, x + patchSize);
idx_j = max(1, y - patchSize) : min(n, y + patchSize);
neighbors = L_init(idx_i, idx_j); % index = 1,..
U = (neighbors >= repmat(L_init(x, y), length(idx_i), length(idx_j)));
Q_neighbors = Q(L_init(x,y) + 1, neighbors(:) + 1);
Q_r = double(Q_neighbors(:)) .* double(U(:)) .* double(neighbors(:));
W = sum(Q_neighbors(:) .* U(:));
L_r(x,y) = uint8(sum(Q_r) ./ (W + (W == 0) * 0.001));
end
end
2.3 Weight Historgram and CDF
function [cLv, map] = weight_hist(L_lg, L_r)
% Inputs:
% L_lg:
% L_r:
% Ouputs:
% map: weight histogram
% cLv: CDF of weighted histogram
% Author: HSW
% Date: 2018-04-29
%
% 公式(15) 和 (16)
level = 256;
map = zeros(level, 1);
cLv = zeros(level, 1);
sum_lg = sum(sum(L_lg));
for k = 1 : level
map(k) = sum(sum(double(L_lg) .* (L_r == k))) / sum_lg;
end
% 公式(17)
for k = 1 : level
if k == 1
cLv(k) = map(k);
else
cLv(k) = cLv(k - 1) + map(k);
end
end
end
2.4 Log-Historgram
function [cfz, sz] = log_hist()
% Inputs:
% -
% Ouputs:
% cfz:
% sz:
% Author: HSW
% Date: 2018-04-29
%
% 公式(18) 和 (19)
level = 256;
cfz = zeros(level, 1);
sz = zeros(level, 1);
epsilon = 1;
for z = 0 : 255
sz(z + 1) = log(z + epsilon) + 0.01;
end
sumSz = sum(sz);
for z = 0 : 255
if z == 0
cfz(z + 1) = sz(z + 1);
else
cfz(z + 1) = cfz(z) + sz(z + 1);
end
end
cfz = cfz ./ sumSz;
end
2.5 直方图规定化
function L_m = filter_BLT(L_r, cLv, cfz)
% Inputs:
% L_r:
% cLv:
% sfz:
% Outputs:
% L_m
%
% Author: HSW
% Date: 2018-04-29
%
[m, n] = size(L_r);
L_m = L_r;
for x = 1 : m
for y = 1 : n
tmp = cLv(L_r(x,y) + 1);
for zv = 1 : 256
if cfz(zv) >= tmp
break;
end
end
L_m(x,y) = zv - 1;
end
end
3. 模型效果(没有原文的效果好,欢迎大家指正编码实现是否有问题,中值滤波是后面加的,用于处理的图像是在论文PDF上截取的,不知道是否有影响)