一、FPGA伽玛变换原理
伽玛变换又名指数变换、幂次变换或幂律变换,是另一种采用非线性变换的图像增强方法。
采用的是查找表的方式,先用matlab进行伽马变换,然后生成mif文件,将其存在rom中,然从rom中读取即可。信号同步处只延迟一个时钟,因为输入从rom中读出需要花费一个clk。
表达式一般为S=C*r^。
二、用matlab生成mif文件
%--------------------------------------------------------------------------
%-- 生成gamma校正所需的rom mif文件
%--------------------------------------------------------------------------
clear all
close all
clc
depth = 256;
width = 8;
r = [0:1:255];
%--------------------------------------------------------------------------
%-- sqrt开根(变亮)
%--------------------------------------------------------------------------
s_qrt = 16*sqrt(r); %开根
z1 = round(s_qrt);%取整数
fid = fopen('sqrt.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,z1(k));
end
fprintf(fid,'end;');
%--------------------------------------------------------------------------
%-- square开方(变暗)
%--------------------------------------------------------------------------
s_quare = (1/256)*r.^2; %平方
z2 = round(s_quare); %取整数
fid = fopen('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,z2(k));
end
fprintf(fid,'end;');
%--------------------------------------------------------------------------
%-- 曲线展示
%--------------------------------------------------------------------------
hold on
plot(r); %原曲线
plot(s_qrt); %开根
plot(s_quare); %开方
legend('原曲线','开根曲线','开方曲线');
hold off
以上代码可以生成sqrt开根(即=0.5)和square开方(即=2)的mif文件。下面我只需用其中一个sqrt开根给大家演示FPGA的实现就好了 ,因为后面都一样的步骤啦。
三、用mif文件生成rom ip核设置
此处在对数变换讲过,我就不再讲了,配置过程一模一样。(无论是灰度图还是彩色图都一样)
四、 通过FPGAmodelsim读写bmp灰度图片实现
module gamma_sqrt
//========================< 端口 >==========================================
(
input wire clk , //时钟
input wire rst_n , //复位
//input ---------------------------------------------
input wire Y_hsync , //Y行同步
input wire Y_vsync , //Y场同步
input wire [7:0] Y_data , //Y数据
input wire Y_de , //Y数据使能
//output --------------------------------------------
output wire gamma_hsync , //gamma行同步
output wire gamma_vsync , //gamma场同步
output wire [7:0] gamma_data , //gamma数据
output wire gamma_de //gamma数据使能
);
//========================< 信号 >==========================================
reg Y_de_r ;
reg Y_hsync_r;
reg Y_vsync_r;
//==========================================================================
//== gamma变换
//==========================================================================
rom_gamma rom_gamma_inst
(
.address (Y_data ),
.clock (clk ),
.q (gamma_data )
);
//==========================================================================
//== 信号同步,rom给地址到出数据会延迟1clk
//==========================================================================
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
Y_de_r <= 1'b0;
Y_hsync_r <= 1'b0;
Y_vsync_r <= 1'b0;
end
else begin
Y_de_r <= Y_de;
Y_hsync_r <= Y_hsync;
Y_vsync_r <= Y_vsync;
end
end
assign gamma_de = Y_de_r;
assign gamma_hsync = Y_hsync_r;
assign gamma_vsync = Y_vsync_r;
endmodule
原始图
FPGA实现开根的gamma变换后的图
通过对比可知,通过开根的gamma变换后,图像整体变亮了。实验成功。
五、通过FPGA上板的彩色图片实现
module gamma_sqrt
//========================< 端口 >==========================================
(
input wire clk , //时钟
input wire rst_n , //复位
//input ---------------------------------------------
input wire RGB_hsync , //RGB行同步
input wire RGB_vsync , //RGB场同步
input wire [15:0] RGB_data , //RGB数据
input wire RGB_de , //RGB数据使能
//output --------------------------------------------
output wire gamma_hsync , //gamma行同步
output wire gamma_vsync , //gamma场同步
output wire [15:0] gamma_data , //gamma数据
output wire gamma_de //gamma数据使能
);
//========================< 信号 >==========================================
wire [ 7:0] R ;
wire [ 7:0] G ;
wire [ 7:0] B ;
wire [ 7:0] gamma_R ;
wire [ 7:0] gamma_G ;
wire [ 7:0] gamma_B ;
reg RGB_de_r ;
reg RGB_hsync_r ;
reg RGB_vsync_r ;
//==========================================================================
//== RGB565转RGB888
//==========================================================================
assign R = {RGB_data[15:11],RGB_data[13:11]};
assign G = {RGB_data[10: 5],RGB_data[ 6: 5]};
assign B = {RGB_data[ 4: 0],RGB_data[ 2: 0]};
//==========================================================================
//== gamma变换
//==========================================================================
rom_sqrt u_R
(
.address (R ),
.clock (clk ),
.q (gamma_R )
);
rom_sqrt u_G
(
.address (G ),
.clock (clk ),
.q (gamma_G )
);
rom_sqrt u_B
(
.address (B ),
.clock (clk ),
.q (gamma_B )
);
assign gamma_data = {gamma_R[7:3],gamma_G[7:2],gamma_B[7:3]};
//==========================================================================
//== 信号同步,rom给地址到出数据会延迟1clk
//==========================================================================
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
RGB_de_r <= 1'b0;
RGB_hsync_r <= 1'b0;
RGB_vsync_r <= 1'b0;
end
else begin
RGB_de_r <= RGB_de;
RGB_hsync_r <= RGB_hsync;
RGB_vsync_r <= RGB_vsync;
end
end
assign gamma_de = RGB_de_r;
assign gamma_hsync = RGB_hsync_r;
assign gamma_vsync = RGB_vsync_r;
endmodule
原始图
FPGA实现开根的gamma变换后的上板图片
matlab实现图
FPGA实现结果跟matlab一样,都是整体变亮了。实验成功。
,