之前经常使用光影魔术手3的补光操作,那么,其补光的原理是什么呢?
老规矩,先上结论:
光影魔术手的补光相当于调整曲线操作,曲线映射关系如下:
连续补光两次,曲线如下:
有时,我会先补光两次,再调整一下gamma值,其曲线如下:
附上补光的映射表的matlab函数封装:
function y=BuGuangTable(x)
% 光影魔术手的补光映射表
% Input:
% x: 整数,x \in [0, 255]
% Output:
% y:整数,y \in [0, 255]
y_uint8=[0,2,3,5,6,8,10,11,13,14,16,18,19,21,22,23,25,27,28,30,31,32,33,35,36,38,39,41,42,44,45,46,47,49,51,52,53,55,56,57,59,60,62,63,64,65,67,68,70,71,71,73,75,76,77,78,79,81,82,83,84,86,87,88,89,91,92,93,94,95,97,98,99,100,101,102,104,105,106,107,109,109,110,112,113,114,115,116,117,118,120,120,122,123,124,125,126,127,127,129,130,131,132,133,134,135,136,137,138,139,140,141,142,142,144,145,145,146,147,148,149,150,151,152,153,154,155,156,156,157,158,159,160,161,162,163,164,164,166,166,167,168,169,170,171,171,173,173,174,175,176,176,178,178,179,180,181,181,182,182,183,183,184,185,185,186,186,187,188,188,189,190,190,191,192,192,193,193,194,195,195,196,197,197,198,199,199,200,201,201,202,203,203,204,205,205,206,207,207,208,209,210,210,211,212,213,213,214,215,215,216,217,218,218,219,220,221,222,222,223,224,225,226,227,227,228,229,230,231,231,232,233,234,235,236,237,238,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,255];
y=y_uint8(x+1);
end
% 测试光影魔术手补光的响应曲线
%%生成测试图像
imr1=0:255;
imr2=[1:255 0];
imr3=255:-1:0;
im=[imr1; imr1; imr2;imr2; imr3;imr3];
im=uint8(im);
imwrite(im,'gray.bmp'); %为了保证像素值不因为jpg的压缩而改变,这里使用bmp格式
%% 验证光影魔术手的补光操作只是一个灰度映射操作;
%需要先用 光影魔术手对'gray.bmp'补光后存为'grayDisposed.bmp'
imDisposed=imread('grayDisposed.bmp');
imDG=imDisposed(:,:,1);
all(imDG(1,:)==imDG(2,:))
all(imDG(3,:)==imDG(4,:))
all(imDG(5,:)==imDG(6,:))
all(imDG(2,:)==[imDG(3,end) imDG(3,1:end-1)])
r2Equal_r5=all(imDG(2,:)==imDG(5,end:-1:1) )
%% 绘制光影魔术手补光的响应曲线
modeName='光影魔术手补光';
x=linspace(0,1,256);
y_uint8=imDG(1,:);
y=double(y_uint8)/255;
figure1 = figure;
axes1 = axes('Parent',figure1,'YTick',0:.1:1,'XTick',0:.1:1,...
'PlotBoxAspectRatio',[1 1 1],...
'DataAspectRatio',[1 1 1]);
% xlim(axes1,[0 1]);
% ylim(axes1,[0 1]);
grid on
box(axes1,'on');
hold(axes1,'all');
plot(x,y,'Parent',axes1,'LineWidth',3,'Color',[1 0 0], 'DisplayName',modeName);
plot(x,x,'Parent',axes1,'LineWidth',2,'LineStyle','--', 'DisplayName','正常模式');
xlabel('补光前的灰度值','FontSize',16);
ylabel('补光后的灰度值','FontSize',16);
title([modeName ' 响应曲线'],'FontSize',16);
legend1 = legend(axes1,'show');
set(legend1,'Location','SouthEast');
% clear all
%%
modeName='光影魔术手补光2次';
x=linspace(0,1,256);
y=BuGuangTable(BuGuangTable(0:255))/255;
figure1 = figure;
axes1 = axes('Parent',figure1,'YTick',0:.1:1,'XTick',0:.1:1,...
'PlotBoxAspectRatio',[1 1 1],...
'DataAspectRatio',[1 1 1]);
% xlim(axes1,[0 1]);
% ylim(axes1,[0 1]);
grid on
box(axes1,'on');
hold(axes1,'all');
plot(x,y,'Parent',axes1,'LineWidth',3,'Color',[1 0 0], 'DisplayName',modeName);
plot(x,x,'Parent',axes1,'LineWidth',2,'LineStyle','--', 'DisplayName','正常模式');
xlabel('补光前的灰度值','FontSize',16);
ylabel('补光后的灰度值','FontSize',16);
title([modeName ' 响应曲线'],'FontSize',16);
legend1 = legend(axes1,'show');
set(legend1,'Location','SouthEast');
%%
modeName='补光2次, 参数为1.2的gamma校正一次';
x=linspace(0,1,256);
y=BuGuangTable(BuGuangTable(0:255))/255;
% y=BuGuangTable(0:255)/255;
y=y.^1.2;
figure1 = figure;
axes1 = axes('Parent',figure1,'YTick',0:.1:1,'XTick',0:.1:1,...
'PlotBoxAspectRatio',[1 1 1],...
'DataAspectRatio',[1 1 1]);
% xlim(axes1,[0 1]);
% ylim(axes1,[0 1]);
grid on
box(axes1,'on');
hold(axes1,'all');
plot(x,y,'Parent',axes1,'LineWidth',3,'Color',[1 0 0], 'DisplayName',modeName);
plot(x,x,'Parent',axes1,'LineWidth',2,'LineStyle','--', 'DisplayName','正常模式');
xlabel('补光前的灰度值','FontSize',16);
ylabel('补光后的灰度值','FontSize',16);
title([ modeName ' 响应曲线'],'FontSize',16);
legend1 = legend(axes1,'show');
set(legend1,'Location','SouthEast');
完整代码、图片见附件~