幂律变换的基本形式为:
(1)
其中c和为正常数。有时考虑到偏移量 可将式(1)写为。偏移量一般是显示标定问题,作为一个结果,通常在式(1)中忽略不计。对于不同的值,s与r的关系如图1所示。
与对数变换的情况类似,部分值的幂律曲线将较窄范围的暗色输入值映射为较宽范围的输出值,相反的,对于输入高灰度级值时也成立。然而与对数函数不同的是,随着值的变化,将简单地得到一簇可能的变化曲线。如图1所示,>1的值所生成的曲线和<1的值所生成的曲线的效果完全相反。当c==1时简化成了恒等变换。
用于图像获取,打印和显示的各种设备根据幂律来产生响应。习惯上,幂律方程中的指数称为伽马。用于校正这些幂律响应现象的处理称为伽马校正。
如图2所示,a航拍原图b~d令c=1且分别等于3.0,4.0和5.0时应用式(1)给出的变换的结果(此例的原图像由NASA提供)。
图3 FPGA实现幂律变换框架图
由图2可知对于灰度图像直接经过幂律变换就可以得到幂律变换图像,但是对于FPGA直接实现对数公式显然难度很大。在FPGA中我们采用基于查找表的方式进行幂律变换。
ROM表的制作:
Matlab源码:
clear all
close all
clc
depth = 256;
width =8;
r = [0:1:255];
x = r; %恒等变换
y =16*sqrt(r);%开根
%z = round(y);
m = (1/256)*r.^2; %r平方
z = round(m);
fid = fopen('E:\matlab_project\log\square.mif','w');%路径
fprintf(fid,'depth= %d; \n',depth);
fprintf(fid,'width= %d; \n',width);
fprintf(fid,'address_radix=uns;\n');
fprintf(fid,'data_radix = uns;\n');
fprintf(fid,'Content Begin \n');
for(k=1:depth)
fprintf(fid,'%d: %d; \n',k-1,z(k));
end
fprintf(fid,'end;');
hold on
plot(x);
plot(y);
plot(m);
hold off
//------------------------------------------
// power law
//------------------------------------------
wire [7:0] sqrt_data; //root
wire [7:0] square_data;//square
rom_sqrt rom_sqrt_inst(
.address(o_y_8b),
.clken(TFT_de),
.clock(TFT_clk),
.q(sqrt_data)
);
rom_square rom_square_inst(
.address(o_y_8b),
.clken(TFT_de),
.clock(TFT_clk),
.q(square_data)
);
//assign TFT_rgb = {sqrt_data[7:3],sqrt_data[7:2],sqrt_data[7:3]}; //Y
assign TFT_rgb = {square_data[7:3],square_data[7:2],square_data[7:3]}; //Y
//assign TFT_rgb = {o_y_8b[7:3],o_y_8b[7:2],o_y_8b[7:3]}; //Y
IP设置:
结果分析:
图9、图10和图8相比,图9明显变暗,图10明显变亮。此技术可以应用在图像采集系统上。当拍摄的光线较暗时,我们可以采取亮变换;当光线过强时,我们可以采取暗变化。从而达到人眼更适合的效果。
欢迎关注微信公众号:FPGA开源工作室
获取更多学习资料。