图像增强序列——Naturalness Preserved Enhancement Algorithm for Non-Uniform Illumination Image

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上截取的,不知道是否有影响)





猜你喜欢

转载自blog.csdn.net/hit1524468/article/details/80148276
今日推荐