FPGA实现伽玛变换

一、FPGA伽玛变换原理 

伽玛变换又名指数变换、幂次变换或幂律变换,是另一种采用非线性变换的图像增强方法。

采用的是查找表的方式,先用matlab进行伽马变换,然后生成mif文件,将其存在rom中,然从rom中读取即可。信号同步处只延迟一个时钟,因为输入从rom中读出需要花费一个clk。

表达式一般为S=C*r^\gamma

 二、用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开根(即\gamma=0.5)和square开方(即\gamma=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一样,都是整体变亮了。实验成功。 

, 

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值