目录

FPGA学习笔记图像处理之对比度调节线性调节

FPGA学习笔记——图像处理之对比度调节(线性调节)

目录


一、任务

将下面这幅图片进行对比度调节,用线性调节。

https://i-blog.csdnimg.cn/direct/7520c3916c054e25b4657c943ef7efd0.bmp


二、线性调节

1.表达式

Pout = (Pin - C) * α + C

Pin :输入像素值(0-255)

Pout :输出像素值

C :对比度中心值(通常为128)

α :对比度调节系数

α > 1:增强对比度

α = 1:无变化

0 < α < 1:降低对比度

思路:根据表达式,可以进行流水线操作,先进行减法,再进行乘法,最后进行加法。


三、代码

1.v文件

(1)contrast_adjust

`timescale 1ns / 1ps
module contrast_adjust(
input                   clk                ,
input                   rst_n              ,
input           [7:0]   pixel_in           ,
input           [7:0]   contrast_va        , //对比系数(0-255,128=1.0)
output  reg     [7:0]   pixel_out 
    );
    //Pout = (Pin - C) * α + C
    reg [16:0]  temp0_data; //第一级流水线
    reg [16:0]  temp1_data; //第二级流水线
    reg [9:0]   temp2_data; //第三级流水线
    reg [8:0]   temp3_data; //第四级流水线
    
    //-----第一级流水线-----------------------
    always @(posedge clk)begin
        if(!rst_n)
            temp0_data <= 0;
        else
            temp0_data <= pixel_in - 8'd128;
    end
    
    //-----第二流水线------------------------------------
    always @(posedge clk)begin
        if(!rst_n)
            temp1_data <= 0;
        else
            temp1_data <= temp0_data * contrast_va;
    end
    
    //-------第三级流水线---------------------------------------------
    always @(posedge clk) begin
        if(!rst_n)
            temp2_data <= 0;
        else
            temp2_data <= temp1_data[16:7] + 8'd128;
    end
    
    //-----第四级流水线-------------------------
    always @(posedge clk) begin
        if(!rst_n)
            temp3_data <= 0;
        else if(temp2_data[9]==1)
            temp3_data <= 0;
        else
            temp3_data <= temp2_data[8:0];
            
    end
    
    //----第五级流水线-----------------------------
    always @(posedge clk) begin
        if(!rst_n)
            pixel_out <= 0;
        else if(temp3_data[8]==1)
            pixel_out <= 8'hff;
        else
            pixel_out <= temp3_data[7:0];
    end
    
    
endmodule

(2)Contrast.v

`timescale 1ns / 1ps
module Contrast(
input           clk         ,
input           rst_n       ,
input   [7:0]   contrast_va ,
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 [4:0]   i_vsync_r;
    reg [4:0]   i_hsync_r;
    reg [4:0]   i_vaild_r;
    
    contrast_adjust contrast_adjust_u(
.   clk         (clk)              ,
.   rst_n       (rst_n)            ,
.   pixel_in    (i_rgb888[23:16])  ,
.   contrast_va (contrast_va)      , //对比系数(0-255,128=1.0)
.   pixel_out   (o_rgb888[23:16])
    );
    
        contrast_adjust contrast_adjust_u1(
.   clk         (clk)              ,
.   rst_n       (rst_n)            ,
.   pixel_in    (i_rgb888[15:8])  ,
.   contrast_va (contrast_va)      , //对比系数(0-255,128=1.0)
.   pixel_out   (o_rgb888[15:8])
    );
    
        contrast_adjust contrast_adjust_u2(
.   clk         (clk)              ,
.   rst_n       (rst_n)            ,
.   pixel_in    (i_rgb888[7:0])  ,
.   contrast_va (contrast_va)      , //对比系数(0-255,128=1.0)
.   pixel_out   (o_rgb888[7:0])
    );
    
    //同步打拍,否则图像会平移
always @(posedge clk) begin
    i_vsync_r <= {i_vsync_r[3:0],i_vsync};
    i_hsync_r <= {i_hsync_r[3:0],i_hsync};
    i_vaild_r <= {i_vaild_r[3:0],i_vaild};
end

assign o_vsync = i_vsync_r[4];
assign o_hsync = i_hsync_r[4];
assign o_vaild = i_vaild_r[4];
    
    
    
endmodule

2.仿真文件

(1)tb.v

`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

Contrast Contrast_u(
. clk      (clk)   ,
. rst_n    (rst_n)   ,
. contrast_va  (200)   ,
. 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.v

`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

四、实验现象

https://i-blog.csdnimg.cn/direct/a05160faf7aa4b1fb7ecfb6f8ebf873e.bmp


以上就是图像处理之对比度调节(线性调节)。(如果有错误的地方,还请大家指出来,谢谢!)