局部拉普拉斯算法

原创
2020/09/15 22:36
阅读数 1.4K

局部拉普拉斯滤波,使用标准拉普拉斯金字塔作为每个尺度的边缘感知。用简单的像素来描述图像的边缘细节。在此基础上,提出了一组图像滤波器来实现边缘保持平滑、细节增强、色调映射和逆色调映射。只依赖于简单的点非线性和小高斯卷积;不需要优化或后处理。同时,在产生高质量的处理结果的时候,不降低边缘强度或引入光晕,常用于HDR图像处理。

示例输入图像(左图为原图,右图为增强后的图)

MainTest.m

clc ;
clear all;
close all;
%%
I = '肺结核.jpg';

I = double( imread(I) )/255;
I = min(1,max(0, imresize(I,1/4) ));  
%imshow(I);
%%
laplacian_pyramid(I,8);
%%
gaussian_pyramid(I,8);


%figure; imshow(I); set(gcf,'name',image)
%%


sigma_r = 0.4;
alpha = 0.25;
beta = 1;
colorRemapping = 'rgb';
domain = 'lin';%最近邻插值
R = lapfilter(I,sigma_r,alpha,beta,colorRemapping,domain);%8位拉普拉斯滤波
figure;
subplot(1,2,1);imshow(I)
subplot(1,2,2);imshow(R)
%figure; clf; imshow(R);
imwrite(R,'output.png');

gaussian_pyramid.m

%高斯核
function Y = gaussian_pyramid(I,nlev,subwindow)

r = size(I,1);
c = size(I,2);
if ~exist('subwindow','var')
    subwindow = [1 r 1 c];
end
if ~exist('nlev','var')    
    nlev = numlevels([r c]); 
end

Y = cell(nlev,1);
Y{1} = I;
%figure;
%subplot(1,8,1);imshow(I);
filter = pyramid_filter;
for l = 2:nlev
    I = downsample(I,filter,subwindow);
    Y{l} = I;
    %subplot(1,8,l);imshow(I);
end

laplacian_pyramid.m

%拉普拉斯 图像金字塔
function pyr = laplacian_pyramid(I,nlev,subwindow)

r = size(I,1);
c = size(I,2);
if ~exist('subwindow','var')
    subwindow = [1 r 1 c];
end
if ~exist('nlev','var')
    nlev = numlevels([r c]);
end

pyr = cell(nlev,1);
filter = pyramid_filter;
%figure;
%subplot(1,8,1)
%imshow(I);
J = I;
for l = 1:nlev - 1
    [I,subwindow_child] = downsample(J,filter,subwindow);
    
    pyr{l} = J - upsample(I,filter,subwindow);
    
    %subplot(1,8,l)
    %imshow(J);
    J = I;
    subwindow = subwindow_child;
end
pyr{nlev} = J; 
%subplot(1,8,nlev)
%imshow(I);

pyramid_filter.m

%图像滑动窗
function child = child_window(parent,N)
if ~exist('N','var')
    N = 1;
end

child = parent;
for K = 1:N
    child = (child+1)/2;
    child([1 3]) = ceil(child([1 3]));
    child([2 4]) = floor(child([2 4]));
end
end

reconstruct_laplacian_pyramid.m

%重构高斯金字塔
function R = reconstruct_laplacian_pyramid(pyr,subwindow)

r = size(pyr{1},1);
c = size(pyr{1},2);
nlev = length(pyr);

subwindow_all = zeros(nlev,4);
if ~exist('subwindow','var')
    subwindow_all(1,:) = [1 r 1 c];
else
    subwindow_all(1,:) = subwindow;
end
for lev = 2:nlev
    subwindow_all(lev,:) = child_window(subwindow_all(lev-1,:));
end

R = pyr{nlev};
filter = pyramid_filter;
for lev = nlev-1 : -1 : 1
    % 上采样
    R = pyr{lev} + upsample(R,filter,subwindow_all(lev,:));
end

downsample.m

%下采样
function [R,subwindow_child] = downsample(I, filter, subwindow)

r = size(I,1);
c = size(I,2);
if ~exist('subwindow','var')
    subwindow = [1 r 1 c];
end
subwindow_child = child_window(subwindow);

border_mode = 'reweighted';
%border_mode = 'symmetric';

switch border_mode
    case 'reweighted'       
        % 低通滤波
        R = imfilter(I,filter);
        
        Z = imfilter(ones(size(I)),filter);        
        R = R./Z;
        
    otherwise
        % 低通滤波
        R = imfilter(I,filter,border_mode);        
end

reven = mod(subwindow(1),2)==0;
ceven = mod(subwindow(3),2)==0;
R = R(1+reven:2:r, 1+ceven:2:c, :);

end

upsample.m

%上采样
function R = upsample(I, filter, subwindow)

r = subwindow(2) - subwindow(1) + 1;
c = subwindow(4) - subwindow(3) + 1;
k = size(I,3);
reven = mod(subwindow(1),2)==0;
ceven = mod(subwindow(3),2)==0;

border_mode = 'reweighted';

switch border_mode
    case 'reweighted'
        R = zeros(r,c,k);
        R(1+reven:2:r, 1+ceven:2:c, :) = I;
        R = imfilter(R,filter);
        Z = zeros(r,c,k);
        Z(1+reven:2:r, 1+ceven:2:c, :) = 1;
        Z = imfilter(Z,filter);
        R = R./Z;
    otherwise
        I = padarray(I,[1 1 0],'replicate');
        R = zeros(r+4,c+4,k);
        R(1+reven:2:end, 1+ceven:2:end, :) = 4*I;
        R = imfilter(R,filter,border_mode);
        R = R(3:end-2, 3:end-2, :);
end
end

numlevels.m

function nlev = numlevels(im_sz)
min_d = min(im_sz(1:2));
nlev = 1;
while min_d>1
    nlev = nlev+1;
    min_d = floor((min_d+1)/2);
end
end

pyramid_filter.m

% 产生拉普拉斯滤波核
function f = pyramid_filter()
f = [.05, .25, .4, .25, .05]; 
%f = [.0625, .25, .375, .25, .0625];
f = f'*f;
end

引用文献: Paris S, Hasinoff S W, Kautz J. Local Laplacian filters: edge-aware image processing with a Laplacian pyramid[J]. Communications of the ACM, 2015, 58(3): 81-91.

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部