LSC(Lens Shading Correction)——镜头阴影矫正
产生原因
由于镜头原因导致光线丢失
注意红线:此时颜色就分离了
校正方法:
网格化或者半径化方法,用一张灰度图来储存增益,各个像素点×增益恢复到最终的情况,网格化的方法通过划分网格节约存储空间
代码:
不考虑像素存储
function LSCCalibrationM(path)
lscRefImg = double(imread(path));
tmp = ones(size(lscRefImg));
corTab = (tmp ./ lscRefImg) * 0.8 * max(max(lscRefImg)); % 最大像素的80 %作为增益
save('src/corTab.mat', 'corTab');
end
test:
lscRefImg = double(imread('images/lscRefImg.jpg'));
load('src/data/corTab.mat')
corImg = uint8(lscRefImg .* corTab);
figure;
subplot(121);imshow(uint8(lscRefImg));title('org');
subplot(122);imshow(corImg);title('corrected');
网格方法
clc;clear;close all;
% --------parameters of calibretion------------
filePath = 'images/lscRefImg.jpg';
side_num = 17;
meshON = 1;
% ---------------------------------------------
image = imread(filePath);
[height, width] = size(image);
side_y = floor(height/side_num);
side_x = floor(width/side_num);
h = imshow(image);
if meshON
for i = 1:side_num-1
line([i*side_x, i*side_x], [1, height], 'color', 'r');
line([1, width], [i*side_y, i*side_y], 'color', 'r');
end
end
title('refImg');
%% compress resolution
image_point = zeros(side_num+1,side_num+1);
for i = 0:side_num
for j = 0:side_num
x_clip = floor([j*side_x - side_x/2, j*side_x + side_x/2]);
y_clip = floor([i*side_y - side_y/2, i*side_y + side_y/2]);
% make sure that the last point on the edge
if(i==side_num && y_clip(2) ~= height)
y_clip(2) = height;
end
if(j==side_num && x_clip(2) ~= width)
x_clip(2) = width;
end
x_clip(x_clip<1) = 1;
x_clip(x_clip>width) = width;
y_clip(y_clip<1) = 1;
y_clip(y_clip>height) = height;
data_in = image(y_clip(1):y_clip(2), x_clip(1):x_clip(2));
image_point(i+1,j+1) = mean(mean(data_in));
end
end
Gain = zeros(side_num+1,side_num+1);
%% caculate lsc luma gain
for i = 1:side_num+1
for j = 1:side_num+1
Gain(i,j) = image_point(uint8(side_num/2) +1, uint8(side_num/2) +1) / image_point(i,j);
end
end
save('./src/data/Gain.mat', 'Gain');
test:
%% --------------------------------
%% author:wtzhu
%% date: 20210706
%% fuction: main file of LSCMesh
%% --------------------------------
clc, clear, close all;
% --------parameters of correction------------
filePath = 'images/lscRefImg.jpg';
side_num = 17;
% --------------------------------------------
% --------load data---------------------------
% load org image
image = imread(filePath);
[height, width] = size(image);
sideX = floor(height/side_num);
sideY = floor(width/side_num);
% load gain of each channel
load('./src/data/Gain.mat');
% --------------correction-------------------
disImg = zeros(size(image));
gainStepX = 0;
gainStepY = 0;
gainTab = zeros(size(image));
for i = 1:height
for j = 1:width
gainStepX = floor(i / sideX) + 1;
if gainStepX > 16
gainStepX = 16;
end
gainStepY = floor(j / sideY) + 1;
if gainStepY > 16
gainStepY = 16;
end
% get tht gain of the point by interpolation(Bilinear interpolation)
% f(x,y) = [f(1,0)-f(0,0)]*x+[f(0,1)-f(0,0)]*y+[f(1,1)+f(0,0)-f(1,0)-f(0,1)]*xy+f(0,0)
gainTab(i, j) = (Gain(gainStepX+1, gainStepY) - Gain(gainStepX, gainStepY)) * (i - (gainStepX - 1) * sideX)/sideX +...
(Gain(gainStepX, gainStepY+1) - Gain(gainStepX, gainStepY)) * (j - (gainStepY - 1) * sideY)/sideY +...
(Gain(gainStepX+1, gainStepY+1) + Gain(gainStepX, gainStepY) - Gain(gainStepX+1, gainStepY)- Gain(gainStepX, gainStepY + 1)) *...
(i - (gainStepX - 1) * sideX)/sideX * (j - (gainStepY - 1) * sideY)/sideY + Gain(gainStepX, gainStepY);
end
end
disImg = double(image) .* gainTab;
figure();
subplot(121);imshow(image);title('org image');
subplot(122);imshow(uint8(disImg));title('corrected image');
颜色为3通道的增益和测试
主要是给自己看的,所以肯定会出现很多错误哈哈哈哈哈