FPGA学习笔记图像处理之对比度调节线性调节
目录
FPGA学习笔记——图像处理之对比度调节(线性调节)
目录
一、任务
将下面这幅图片进行对比度调节,用线性调节。
二、线性调节
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
四、实验现象
以上就是图像处理之对比度调节(线性调节)。(如果有错误的地方,还请大家指出来,谢谢!)