FPGA学习笔记——图像处理之亮度调节(乘法型)

目录

一、任务

二、乘法型

1.表达式

三、代码

1.v文件

(1)brightness_adjust_mul.v

(2)brightness.v

2.仿真文件

(1)tb.v

(2)video_source

四、实现现象

(1)变亮

(2)变暗


一、任务

将下面这幅图片进行亮度调节。(RGB888)


二、乘法型

1.表达式

I_out = I_in × k
I_in :输入像素值(0-255)
k :亮度缩放系数(通常0.0-2.0)
I_out :输出像素值
思路:根据表达式,将输入的一个颜色(红、绿、蓝),进行缩放,然后再输出。但是Verilog中没有小数的表示,所以把k给变成(0~255),k为128则图像数据不变,小于128则变暗,大于128则变亮。这个的位宽要考虑清楚,两个数相乘位宽是两个位宽相加,最后输出的要进行截断,也就是成8位输出。


三、代码

1.v文件

(1)brightness_adjust_mul.v

rust 复制代码
`timescale 1ns / 1ps
module brightness_adjust_mul(
input                   clk                ,
input                   rst_n              ,
input           [7:0]   pixel_in           ,
input           [7:0]   scale              , //缩放系数(0-255,128=1.0)
output  reg     [7:0]   pixel_out 
);
reg [15:0]  product ;
//乘法运算调节亮度
always @(posedge clk) begin
    if(!rst_n)
        product <= 0;
    else
        product <= pixel_in * scale;
end

//截断
always @(posedge clk) begin
    if(!rst_n)
        pixel_out <= 0;
    else if (product[15] == 1) //product[15] == 1
        pixel_out <= 8'hff;
    else if(product[15] == 0) //product[15] == 0
        pixel_out <= product[14:7]; // product >> 7
end

endmodule

(2)brightness.v

rust 复制代码
`timescale 1ns / 1ps
module brightness(
input           clk         ,
input           rst_n       ,
input   [7:0]   scale       ,
input   [23:0]  i_rgb888    ,
input           i_vsync     ,
input           i_hsync     ,
input           i_vaild     ,
output  [23:0]  o_rgb888    ,
output          o_vsync     ,
output          o_hsync     ,
output          o_vaild   
    );

reg [1:0]   i_vsync_r;
reg [1:0]   i_hsync_r;
reg [1:0]   i_vaild_r;
       
//红色   
brightness_adjust_mul brightness_adjust_mul_u1(
.   clk        (clk)       ,
.   rst_n      (rst_n)       ,
.   pixel_in   (i_rgb888[23:16])       ,
.   scale      (scale)       , //缩放系数(0-255,128=1.0)
.   pixel_out  (o_rgb888[23:16])
);

//绿色
brightness_adjust_mul brightness_adjust_mul_u2(
.   clk        (clk)       ,
.   rst_n      (rst_n)       ,
.   pixel_in   (i_rgb888[15:8])       ,
.   scale      (scale)       , //缩放系数(0-255,128=1.0)
.   pixel_out  (o_rgb888[15:8])
);

//蓝色
brightness_adjust_mul brightness_adjust_mul_u3(
.   clk        (clk)                ,
.   rst_n      (rst_n)              ,
.   pixel_in   (i_rgb888[7:0])      ,
.   scale      (scale)              , //缩放系数(0-255,128=1.0)
.   pixel_out  (o_rgb888[7:0])
);

//同步打拍,否则图像会平移
always @(posedge clk) begin
    i_vsync_r <= {i_vsync_r[0],i_vsync};
    i_hsync_r <= {i_hsync_r[0],i_hsync};
    i_vaild_r <= {i_vaild_r[0],i_vaild};
end

assign o_vsync = i_vsync_r[1];
assign o_hsync = i_hsync_r[1];
assign o_vaild = i_vaild_r[1];


endmodule

2.仿真文件

(1)tb.v

rust 复制代码
`timescale 1ns / 1ps
module tb();

reg clk = 0;
reg rst_n = 0;
wire  [23:0]  i_rgb888;
wire  [23:0]  o_rgb888;
wire    i_vaild;
wire    o_vaild;

always #10 clk = ~clk;
initial begin
    #100;
    rst_n = 1;
end

brightness brightness_u(
. clk      (clk)   ,
. rst_n    (rst_n)   ,
. scale    (90)   ,
. i_rgb888 (i_rgb888)   ,
. i_vsync  ()   ,
. i_hsync  ()   ,
. i_vaild  (i_vaild)   ,
. o_rgb888 (o_rgb888)   ,
. o_vsync  ()   ,
. o_hsync  ()   ,
. o_vaild  (o_vaild) 
    );

video_source video_source_u(
.         pclk      (clk)   ,
.         rstn      (rst_n)  ,
//----图像输出----------------------
. source_de_o (i_vaild) ,
. source_data_o (i_rgb888),
//----图像输入----------------------
.  de_i        (o_vaild) ,
.  data_i       (o_rgb888)
    );
    

endmodule

(2)video_source

rust 复制代码
`timescale 1ns / 1ps
`define VIDEO_1280_720
module video_source#(
parameter   VSYNC=720,
            HSYNC=1280,
            DELAY1=50_000_000              //鍥惧儚澶勭悊寤惰繜
 
)(
input          pclk         ,
input          rstn         ,
//----鍥惧儚杈撳嚭----------------------
output  reg    source_de_o  ,
output [23:0]  source_data_o,
//----鍥惧儚杈撳叆----------------------
input          de_i         ,
input [23:0]   data_i
    );
//1280X720 74.25MHZ
`ifdef  VIDEO_1280_720
parameter  H_ACTIVE 		= 1280;// 琛屾暟鎹湁鏁堟椂闂?
parameter  H_FRONT_PORCH 	= 110; // 琛屾秷闅愬墠鑲╂椂闂?
parameter  H_SYNC_TIME 		= 40;  // 琛屽悓姝ヤ俊鍙锋椂闂?
parameter  H_BACK_PORCH 	= 220; // 琛屾秷闅愬悗鑲╂椂闂?    
parameter  H_POLARITY       = 1;   // 琛屽悓姝ユ瀬鎬?
parameter  V_ACTIVE 		= 720; // 鍒楁暟鎹湁鏁堟椂闂?
parameter  V_FRONT_PORCH 	= 5;   // 鍒楁秷闅愬墠鑲╂椂闂?
parameter  V_SYNC_TIME  	= 5;   // 鍒楀悓姝ヤ俊鍙锋椂闂?
parameter  V_BACK_PORCH 	= 20;  // 鍒楁秷闅愬悗鑲╂椂闂?
parameter  V_POLARITY       = 1;   // 鍦哄悓姝ユ瀬鎬?
`endif

localparam addr_size=HSYNC*VSYNC*3+54;    //鎬诲瓧鑺傛暟
//鏂囦欢鍚?
integer bmp_file_id;
integer bmp_dout_id;
//鏂囦欢鍙ユ焺
integer h;
reg		[7:0]	rd_data  [addr_size-1:0];      //鏍规嵁鑷繁鍥剧墖澶у皬    BMP鏍煎紡涓猴細浣嶅浘鏂囦欢澶达紙14瀛楄妭锛?+浣嶅浘淇℃伅澶达紙40瀛楄妭锛?+瀹為檯鍍忕礌鐐瑰崰鍐呭瓨
reg		[7:0]	wr_data  [addr_size-1:0];    
integer i=0;
integer    addr_rd=54;
integer    addr_wr=54;


initial begin
    bmp_file_id = $fopen("D:/intelFPGA_lite/haiyunjiexun/text_Vivado/image_isp/image_1.bmp","rb");          //鎵撳紑鍘熷鍥惧儚
    bmp_dout_id = $fopen("D:/intelFPGA_lite/haiyunjiexun/text_Vivado/image_isp/image_1_out.bmp","wb");     //鎵撳紑杈撳嚭鍥惧儚
    h = $fread(rd_data,bmp_file_id);                                   //璇诲彇bmp鏂囦欢     璇诲彇鍒扮殑鏁版嵁灏嗕細渚濇鏀惧叆rd_data涓?
    $fclose(bmp_file_id);                                              //璇诲彇瀹屾瘯
    
       
    #DELAY1  ;                                                             //鍥惧儚澶勭悊寤惰繜

	for(i = 0; i < addr_size; i = i + 1)begin                        //鍥惧儚鏁版嵁鍐欏叆鏂囦欢
	   if(i < 54)
	       $fwrite(bmp_dout_id, "%c", rd_data[i]);//娉ㄦ剰鍙傛暟%c
	   else       
           $fwrite(bmp_dout_id, "%c", wr_data[i]);//娉ㄦ剰鍙傛暟%c
    end
    $fclose(bmp_dout_id);
    #100;
    $stop ;
    
end


//----璇诲嚭鍥惧儚鏁版嵁--------------------------------
always@(posedge pclk)begin
    if(source_de_o) begin
        if(addr_rd >= addr_size-3)
            addr_rd<=54;
        else
            addr_rd<=addr_rd+3;
    end
end


assign source_data_o={rd_data[addr_rd],rd_data[addr_rd+1],rd_data[addr_rd+2]};    //R + G + B

//----鍐欏叆鍥惧儚鏁版嵁--------------------------------
always@(posedge pclk)begin
    if(de_i) begin
        if(addr_wr >= addr_size-3)
            addr_wr<=54;
        else
            addr_wr<=addr_wr+3;
    end
end

always@(posedge pclk)begin
    wr_data[addr_wr]=data_i[23:16];                                   //鍐欏叆瀛樺偍鍣?
    wr_data[addr_wr+1]=data_i[15:8];
    wr_data[addr_wr+2]=data_i[7:0];
end

localparam  H_TOTAL_TIME=H_ACTIVE+H_FRONT_PORCH+H_SYNC_TIME+H_BACK_PORCH;
localparam  V_TOTAL_TIME=V_ACTIVE+V_FRONT_PORCH+V_SYNC_TIME+V_BACK_PORCH;
reg [31:0] cnt_v;   //鍦哄悓姝ヨ鏁板櫒
reg [31:0] cnt_h;   //琛屽悓姝ヨ鏁板櫒

always@(posedge pclk)begin
    if(!rstn)
        source_de_o<=0;
    else if(( cnt_h > (H_SYNC_TIME + H_BACK_PORCH -1)) &&   (cnt_h <= (H_SYNC_TIME + H_BACK_PORCH + H_ACTIVE -1)) &&  (cnt_v > (V_SYNC_TIME + V_BACK_PORCH-1)) && (cnt_v <= (V_SYNC_TIME + V_BACK_PORCH + V_ACTIVE-1)))
        source_de_o<=1;
   else
        source_de_o<=0;
end



always@(posedge pclk)begin
    if(!rstn)
        cnt_h<=0;
    else if(cnt_h == H_TOTAL_TIME-1)
        cnt_h<=0;
    else
        cnt_h<=cnt_h+1;
end

always@(posedge pclk)begin
    if(!rstn)
        cnt_v<=0;
    else if(cnt_h == H_TOTAL_TIME-1)begin
        if(cnt_v == V_TOTAL_TIME-1)
            cnt_v<=0;
        else
            cnt_v<=cnt_v+1;
    end
end



endmodule

注意:这里的图片地址,按照自己的图片路径来修改。


四、实现现象

(1)变亮

(2)变暗


以上就是图像增强之亮度调节(乘法型)。(如果有错误的地方,还请大家指出来,谢谢!)

相关推荐
cmc102815 小时前
127.XIlinx fpga端的pcie(XDMA)与驱动是如何交换数据的
笔记·fpga开发
optimistic_chen15 小时前
【Java EE进阶 --- SpringBoot】Mybatis操作数据库(基础二)
xml·数据库·spring boot·笔记·java-ee·mybatis
在繁华处15 小时前
C语言初步学习:数组的增删查改
c语言·数据结构·学习
呵呵哒( ̄▽ ̄)"15 小时前
专项智能练习(科尔伯格道德发展阶段理论)
学习
摇滚侠15 小时前
Spring Boot 3零基础教程,properties文件中配置和类的属性绑定,笔记14
java·spring boot·笔记
武文斌7716 小时前
项目学习总结:CAN总线、摄像头、STM32概述
linux·arm开发·stm32·单片机·嵌入式硬件·学习·c#
程序员大雄学编程16 小时前
「机器学习笔记12」支持向量机(SVM)详解:从数学原理到Python实战
笔记·机器学习·支持向量机
SPFFC1893803305316 小时前
AI玩具排线专业生产与全球营销策略
人工智能·学习·智能手机·显示器·智能手表·平板·游戏机
。TAT。16 小时前
C++ - vector
开发语言·c++·学习
YJlio16 小时前
Process Monitor 学习笔记(5.7):长时间运行追踪与日志文件体积的控制
java·笔记·学习