范文写作网站,wordpress 自定义查询,洛阳网站建设网站建设,宁波公司注销如图所示#xff0c;这是整个视频采集系统的原理框图。 上电初始#xff0c;FPGA 需要通过 IIC 接口对 CMOS Sensor 进行寄存器初始化配置。这些初始化的基本参数#xff0c;即初始化地址对应的初始化数据都存储在一个预先配置好的 FPGA 片内 ROM中。在初始化配置完成后这是整个视频采集系统的原理框图。 上电初始FPGA 需要通过 IIC 接口对 CMOS Sensor 进行寄存器初始化配置。这些初始化的基本参数即初始化地址对应的初始化数据都存储在一个预先配置好的 FPGA 片内 ROM中。在初始化配置完成后CMOS Sensor 就能够持续输出标准 RGB 的视频数据流FPGA 通过对其同步信号如时钟、行频和场频进行检测从而从数据总线上实时的采集图像数据。 在 FPGA 内部采集到的视频数据先通过一个 FIFO将原本 25MHz 频率下同步的数据流转换到 50MHz 的频率下。接着将这个数据再送入写 DDR3 缓存的异步 FIFO 中这个 FIFO 中的数据一旦达到一定数量就会通过 AXI HP0 总线写入 DDR3 中。与此同时AXI HP0 总线也会读取 DDR3 中缓存的图像数据缓存到 FIFO 中并最终送往 LCD 驱动模块进行显示。LCD驱动模块不断的发出读图像数据的请求并驱动液晶显示器显示视频图像。 本实例除了前面提到对原始图像做 DDR3 缓存和显示还会在原始图像缓存到 DDR3 之前另外做图像的多行缓存和平滑处理运算获得新的平滑后的图像流这个图像流通过AXI HP1 总线写入到 DDR3 中。AXI HP1 总线也会根据 LCD 显示模块的请求读取处理后的图像进行显示。最终在 VGA 液晶显示器上可以看到左侧图像是原始的图像右侧图像是经过平滑处理后的图像。
1、图像平滑与滤波
1.1 基本概念 从统计学的观点来看凡是统计特征不随时间变化的噪声称为平稳噪声而统计特征随时间变化的噪声称为非平稳噪声。幅值基本相同但是噪声出现的位置是随机的称为椒盐噪声如果噪声的幅值是随机的根据幅值大小的分布有高斯型和瑞利型两种分别称为高斯噪声和瑞利噪声。 图像滤波即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制是图像预处理中不可缺少的操作其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。 消除图像中的噪声成分叫作图像的平滑化或滤波操作。信号或图像的能量大部分集中在幅度谱的低频和中频段是很常见的而在较高频段感兴趣的信息经常被噪声淹没。因此一个能降低高频成分幅度的滤波器就能够减弱噪声的影响。 图像滤波的目的有两个一是抽出对象的特征作为图像识别的特征模式另一个是为适应图像处理的要求消除图像数字化时所混入的噪声。而对滤波处理的要求也有两条一是不能损坏图像的轮廓及边缘等重要信息二是使图像清晰视觉效果好。 平滑滤波是低频增强的空间域滤波技术。它的目的有两类一类是模糊另一类是消除噪音。空间域的平滑滤波一般采用简单平均法进行就是求邻近像元点的平均亮度值。邻域的大小与平滑的效果直接相关邻域越大平滑的效果越好但邻域过大平滑会使边缘信息损失的越大从而使输出的图像变得模糊因此需合理选择邻域的大小。 关于滤波器一种形象的比喻法是我们可以把滤波器想象成一个包含加权系数的窗口当使用这个滤波器平滑处理图像时就把这个窗口放到图像之上透过这个窗口来看我们得到的图像。举一个滤波在我们生活中的应用美颜的磨皮功能。如果将我们脸上坑坑洼洼比作是噪声的话那么滤波算法就是来取出这些噪声使我们自拍的皮肤看起来很光滑。
1.2滤波算法 各种不同的滤波算法如下 • 限幅滤波法又称程序判断滤波法 • 中位值滤波法 • 算术平均滤波法 • 高斯滤波法 • 递推平均滤波法又称滑动平均滤波法 • 中位值平均滤波法又称防脉冲干扰平均滤波法 • 限幅平均滤波法 • 一阶滞后滤波法 • 加权递推平均滤波法 • 消抖滤波法 • 限幅消抖滤波法 • 卡尔曼滤波非扩展卡尔曼
1.3均值滤波 均值滤波器是图像处理中一种常见的滤波器它主要应用于平滑噪声。它的原理主要是利用某像素点周边像素的平均值来达到平滑噪声的效果。 例如1~8 像素是x,y点周围邻近的 8 个像素点。最简单的均值滤波即对x,y以及周边 8 个像素点求平均替代原来的x,y点。 这种滤波方式的优点很明显算法简单计算速度快。缺点是降低噪声的同时使图像产生模糊特别是景物的边缘和细节部分。
1.4加权均值滤波器 由于我们已经注意到了中心点和周边像素点的重要程度不同因此可以将均值滤波进行改进获得图像平滑滤波效果的同时也在一定程度上尽量降低图像边缘和细节的损失。 基于 1/16 的加权均值滤波我们的 Matlab 代码如下
clear
clc
I1imread(.\lena.jpg);
Iim2double(I1);
[m,n,c]size(I);
Azeros(m,n,c);% 1 2 1
% 1/16 * 2 4 2
% 1 2 1%for R
for i2:m-1for j2:n-1A(i,j,1)I(i-1,j-1,1)I(i1,j-1,1)I(i-1,j1,1)I(i1,j1,1)2*I(i1,j,1)2*I(i-1,j,1)2*I(i,j1,1)2*I(i,j-1,1)4*I(i,j,1);end
end%for G
for i2:m-1for j2:n-1A(i,j,2)I(i-1,j-1,2)I(i1,j-1,2)I(i-1,j1,2)I(i1,j1,2)2*I(i1,j,2)2*I(i-1,j,2)2*I(i,j1,2)2*I(i,j-1,2)4*I(i,j,2);end
end%for B
for i2:m-1for j2:n-1A(i,j,3)I(i-1,j-1,3)I(i1,j-1,3)I(i-1,j1,3)I(i1,j1,3)2*I(i1,j,3)2*I(i-1,j,3)2*I(i,j1,3)2*I(i,j-1,3)4*I(i,j,3);end
endBA/16;%outputimwrite(B,lena.tif,tif);imshow(.\lena.jpg);title(origin image);figureimshow(lena.tif);title(image after average filter)滤波效果如下。 2、基于FPGA 的图像平滑处理 工程中average_filter.v 模块实现了1/16 的图像加权均值滤波处理。该模块功能框图如下使用 2 个 FIFO分别缓存前后行即进入图像处理的 3 组数据流分别是第 n-1 行、第 n 行和第 n1 行的图像控制输入数据流和 2 个 FIFO 缓存的图像在同一个位置、寄存器对前后 2 个像素的图像值进行缓存这样便可实现中心像素点以及前后列、上下行之间数据的同步处理了。 average_filter.v 模块的接口定义如下。时钟信号 clk 和复位信号 rst_ni_image_ddr3_* 信号为输入图像数据流接口复位信号 i_image_ddr3_clr 拉高表示复位当 i_image_ddr3_clr 为低电平时图像输入使能信号 i_image_ddr3_wren 拉高表示图像数据 i_image_ddr3_wrdb 有效而每行最好一个有效数据输入时图像行尾指示信号 i_image_ddr3_line_end 拉高o_image_ddr3_*信号为输出图像数据流接口当图像输出使能信号 o_image_ddr3_wren 拉高时图像数据输出总线 o_image_ddr3_wrdb 上的数据有效。
module average_filter(input clk, //50MHz时钟input rst_n, //复位信号低电平有效//Image Data flow from Image Sensorinput i_image_ddr3_wren,input i_image_ddr3_line_end,input i_image_ddr3_clr,input[15:0] i_image_ddr3_wrdb, //Image Data flow after average transformoutput reg o_image_ddr3_wren,output[15:0] o_image_ddr3_wrdb );
IMAGE_WIDTH 和 IMAGE_HIGHT 两个参数分别定义图像分辨率的宽度和高度像素数。
parameter IMAGE_WIDTH 10’d640;
parameter IMAGE_HIGHT 10’d480;
以图像行尾指示信号 i_image_ddr3_line_end 拉高进行计数的数据行计数器 r_line_cnt 逻辑如下。
//数据行计数器
reg[9:0] r_line_cnt;always (posedge clk or negedge rst_n)if(!rst_n) r_line_cnt 10d0;else if(i_image_ddr3_clr) r_line_cnt 10d0;else if(i_image_ddr3_line_end) r_line_cnt r_line_cnt1b1;else ;
下面例化的两个 FIFO 分别缓存前后两行的图像数据。
//FIFO for cache 1 line image data
reg r_fifo1_rd_en;
wire[15:0] w_fifo1_dout;
wire[9:0] w_fifo1_data_count;fifo_generator_3 uut1_fifo_generator_3 (.clk(clk), // input wire clk.srst(!rst_n || i_image_ddr3_clr), // input wire srst.din(i_image_ddr3_wrdb), // input wire [15 : 0] din.wr_en(i_image_ddr3_wren), // input wire wr_en.rd_en(r_fifo1_rd_en), // input wire rd_en.dout(w_fifo1_dout), // output wire [15 : 0] dout.full(), // output wire full.empty(), // output wire empty.data_count(w_fifo1_data_count) // output wire [9 : 0] data_count
);reg r_fifo2_wr_en;
reg r_fifo2_rd_en;
wire[15:0] w_fifo2_dout;
wire[9:0] w_fifo2_data_count;fifo_generator_3 uut2_fifo_generator_3 (.clk(clk), // input wire clk.srst(!rst_n || i_image_ddr3_clr), // input wire srst.din(w_fifo1_dout), // input wire [15 : 0] din.wr_en(r_fifo2_wr_en), // input wire wr_en.rd_en(r_fifo2_rd_en), // input wire rd_en.dout(w_fifo2_dout), // output wire [15 : 0] dout.full(), // output wire full.empty(), // output wire empty.data_count(w_fifo2_data_count) // output wire [9 : 0] data_count
); 下面的状态机主要用于FIFO的读写控制信号产生。上电初始处于复位状态RFIFO_RESET 若 FIFO1 中的数据量满 1 行w_fifo1_data_count IMAGE_WIDTH则进入 FIFO1 读取状态RFIFO_RDDB1RFIFO_RDDB1 状态下将会读取 FIFO1 中 1 行的数据并写入到 FIFO2 中完成操作后进入空闲状态 RFIFO_IDLERFIFO_IDLE 状态下等待 FIFO2 中的数据量满 1 行w_fifo2_data_count IMAGE_WIDTH则进入读 FIFO1/FIFO2 状态 RFIFO_RDDB2RFIFO_RDDB2 状态下读取 1 行 FIFO1 数据并写入 FIFO2 中同时也会读取 1 行 FIFO2 数据FIFO2 中读出第 n 行数据、FIFO1 中读出第 n1 行数据和即将写入 FIFO1 中的第 n2 行数据会进行均值滤波的处理后输出数据RFIFO_RDDB2 状态处理完成后返回空闲状态RFIFO_IDLE 继续等待下一行的处理。 在 RFIFO_IDLE 状态、RFIFO_RDDB2 状态下会同时判断若所有数据行已经操作完成r_line_cnt IMAGE_HIGHT则进入 RFIFO_WAIT 状态RFIFO_WAIT 状态稍作延时后进入 RFIFO_RDDB3 从FIFO1/FIFO2中读出最后1行的数据最后返回复位状态RFIFO_RESET。 //连续读出640个数据计数控制状态机
parameter RFIFO_RESET 3d0;
parameter RFIFO_IDLE 3d1;
parameter RFIFO_RDDB1 3d2;
parameter RFIFO_RDDB2 3d3;
parameter RFIFO_WAIT 3d4;
parameter RFIFO_RDDB3 3d5;
reg[2:0] rfifo_state;
reg[9:0] dcnt; //读FIFO数据个数计数器
reg[9:0] average_num;
reg[3:0] dly_cnt;always (posedge clk or negedge rst_n)if(!rst_n) rfifo_state RFIFO_RESET;else if(i_image_ddr3_clr) rfifo_state RFIFO_RESET;else begincase(rfifo_state)RFIFO_RESET: if(w_fifo1_data_count IMAGE_WIDTH) rfifo_state RFIFO_RDDB1;else rfifo_state RFIFO_RESET;RFIFO_RDDB1: if(dcnt (IMAGE_WIDTH-1)) rfifo_state RFIFO_IDLE;else rfifo_state RFIFO_RDDB1;RFIFO_IDLE: if(r_line_cnt IMAGE_HIGHT) rfifo_state RFIFO_WAIT;else if(w_fifo2_data_count IMAGE_WIDTH) rfifo_state RFIFO_RDDB2;else rfifo_state RFIFO_IDLE; RFIFO_RDDB2: if(r_line_cnt IMAGE_HIGHT) rfifo_state RFIFO_WAIT;else if(dcnt (IMAGE_WIDTH-1)) rfifo_state RFIFO_IDLE;else rfifo_state RFIFO_RDDB2;RFIFO_WAIT: if(dly_cnt 4hf) rfifo_state RFIFO_RDDB3; else rfifo_state RFIFO_WAIT;RFIFO_RDDB3: if(dcnt (IMAGE_WIDTH-1)) rfifo_state RFIFO_RESET;else rfifo_state RFIFO_RDDB3; default: rfifo_state RFIFO_IDLE;endcaseend
RFIFO_WAIT 状态的延时计数逻辑如下。
always (posedge clk or negedge rst_n)if(!rst_n) dly_cnt 4d0;else if(rfifo_state RFIFO_WAIT) dly_cnt dly_cnt1b1;else dly_cnt 4d0;
RFIFO_RDDB1 状态、RFIFO_RDDB2 状态和 RFIFO_RDDB3 状态下读数据的计数逻辑如 下。 //读FIFO数据个数计数器
always (posedge clk or negedge rst_n)if(!rst_n) dcnt 10d0;else if((rfifo_state RFIFO_IDLE) || (rfifo_state RFIFO_RESET)) dcnt 10d0;else if(((rfifo_state RFIFO_RDDB1) || (rfifo_state RFIFO_RDDB2)) i_image_ddr3_wren) dcnt dcnt1b1;else if(rfifo_state RFIFO_RDDB3) dcnt dcnt1b1; else dcnt 10d0;
均值滤波运算的数据计数器 average_num 逻辑如下。
//average transform数据计数器
always (posedge clk or negedge rst_n)if(!rst_n) average_num 10d0;else if(dcnt 10d4) average_num 10d1;else if(average_num ! 10d0) beginif(average_num IMAGE_WIDTH) average_num average_num1b1;else average_num 10d0;endelse average_num 10d0;
读 FIFO1 使能信号产生逻辑如下。
always (posedge clk or negedge rst_n)if(!rst_n) r_fifo1_rd_en 1b0;else if(((rfifo_state RFIFO_RDDB1) || (rfifo_state RFIFO_RDDB2)) i_image_ddr3_wren) r_fifo1_rd_en 1b1;else if((rfifo_state RFIFO_RDDB3) (dcnt IMAGE_WIDTH)) r_fifo1_rd_en 1b1;else r_fifo1_rd_en 1b0;
写 FIFO2 使能信号产生逻辑如下。
//写FIFO2是能信号产生逻辑
always (posedge clk or negedge rst_n)if(!rst_n) r_fifo2_wr_en 1b0;else r_fifo2_wr_en r_fifo1_rd_en;
读 FIFO2 使能信号产生逻辑如下。
//读FIFO2使能信号产生逻辑
always (posedge clk or negedge rst_n)if(!rst_n) r_fifo2_rd_en 1b0;else if(((rfifo_state RFIFO_RDDB2) || (rfifo_state RFIFO_RDDB3)) i_image_ddr3_wren) r_fifo2_rd_en 1b1;else r_fifo2_rd_en 1b0;
以下逻辑对多个不同列临近数据进行缓存便于均值滤波处理时使用。
/*
对图像进行均值滤波平滑处理
第1行、最后1行、第1列、最后1列不做处理使用原始图像像素值输出
对其余图像像素点对周围像素点做如下运算
% 1 2 1
% 1/16 * 2 4 2
% 1 2 1
*///图像缓存3拍
reg[15:0] data_temp_line_1[2:0];
reg[15:0] data_temp_line_2[2:0];
reg[15:0] data_temp_line_3[4:0];always (posedge clk) begindata_temp_line_1[0] w_fifo2_dout;data_temp_line_1[1] data_temp_line_1[0];data_temp_line_1[2] data_temp_line_1[1];
endalways (posedge clk) begindata_temp_line_2[0] w_fifo1_dout;data_temp_line_2[1] data_temp_line_2[0];data_temp_line_2[2] data_temp_line_2[1];
endalways (posedge clk) begindata_temp_line_3[0] i_image_ddr3_wrdb;data_temp_line_3[1] data_temp_line_3[0];data_temp_line_3[2] data_temp_line_3[1];data_temp_line_3[3] data_temp_line_3[2];data_temp_line_3[4] data_temp_line_3[3];
end
以下逻辑为图像的均值滤波运算。
//图像输出average filter运算
reg[9:0] sum_a_r,sum_b_r1,sum_b_r2;
reg[9:0] sum_a_g,sum_b_g1,sum_b_g2;
reg[9:0] sum_a_b,sum_b_b1,sum_b_b2;reg[15:0] average_result; always (posedge clk) beginsum_a_r {3b000,data_temp_line_2[1][15:11],2b00};sum_a_g {2b0,data_temp_line_2[1][10:5],2b00};sum_a_b {3b000,data_temp_line_2[1][4:0],2b00};
end always (posedge clk) beginsum_b_r1 {4d0,data_temp_line_2[0][15:11],1b0} {4d0,data_temp_line_2[2][15:11],1b0} {4d0,data_temp_line_1[1][15:11],1b0} {4d0,data_temp_line_3[3][15:11],1b0};sum_b_g1 {3d0,data_temp_line_2[0][10:5],1b0} {3d0,data_temp_line_2[2][10:5],1b0} {3d0,data_temp_line_1[1][10:5],1b0} {3d0,data_temp_line_3[3][10:5],1b0};sum_b_b1 {4d0,data_temp_line_2[0][4:0],1b0} {4d0,data_temp_line_2[2][4:0],1b0} {4d0,data_temp_line_1[1][4:0],1b0} {4d0,data_temp_line_3[3][4:0],1b0};sum_b_r2 {5d0,data_temp_line_1[0][15:11]} {5d0,data_temp_line_1[2][15:11]} {5d0,data_temp_line_3[2][15:11]} {5d0,data_temp_line_3[4][15:11]};sum_b_g2 {4d0,data_temp_line_1[0][10:5]} {4d0,data_temp_line_1[2][10:5]} {4d0,data_temp_line_3[2][10:5]} {4d0,data_temp_line_3[4][10:5]};sum_b_b2 {5d0,data_temp_line_1[0][4:0]} {5d0,data_temp_line_1[2][4:0]} {5d0,data_temp_line_3[2][4:0]} {5d0,data_temp_line_3[4][4:0]};
end wire[9:0] temp_r sum_a_r(sum_b_r1sum_b_r2);
wire[9:0] temp_g sum_a_g(sum_b_g1sum_b_g2);
wire[9:0] temp_b sum_a_b(sum_b_b1sum_b_b2);always (posedge clk) beginif((average_num 10d1) || (average_num IMAGE_WIDTH)) average_result data_temp_line_2[2]; //第1列和最后1列使用原值else beginaverage_result[15:11] temp_r[8:4]; average_result[10:5] temp_g[9:4];average_result[4:0] temp_b[8:4]; end
end
最终输出图像的是能信号产生如下。
//图像输出有效信号产生
reg r_image_ddr3_wren;
reg[3:0] r_average_line_wren;
reg r_last_line_wren;always (posedge clk or negedge rst_n)if(!rst_n) r_last_line_wren 1b0;else if((rfifo_state RFIFO_RDDB3) (dcnt IMAGE_WIDTH)) r_last_line_wren 1b1;else r_last_line_wren 1b0;always (posedge clk or negedge rst_n)if(!rst_n) r_average_line_wren 4d0;else beginr_average_line_wren[3:1] r_average_line_wren[2:0];if((rfifo_state RFIFO_RDDB2) (r_line_cnt 10d1) i_image_ddr3_wren) r_average_line_wren[0] 1b1;else r_average_line_wren[0] 1b0;end always (posedge clk or negedge rst_n)if(!rst_n) r_image_ddr3_wren 1b0;else if(r_average_line_wren[3]) r_image_ddr3_wren 1b1;else if(r_last_line_wren) r_image_ddr3_wren 1b1;else r_image_ddr3_wren 1b0;always (posedge clk or negedge rst_n)if(!rst_n) o_image_ddr3_wren 1b0;else if((r_line_cnt 10d0) i_image_ddr3_wren) o_image_ddr3_wren 1b1;else if(r_image_ddr3_wren) o_image_ddr3_wren 1b1;else o_image_ddr3_wren 1b0;最终输出图像数据的产生如下。
//图像数据输出
reg[15:0] r_image_ddr3_wrdb; always (posedge clk or negedge rst_n)if(!rst_n) r_image_ddr3_wrdb 16d0;else if(r_line_cnt 10d0) r_image_ddr3_wrdb i_image_ddr3_wrdb;else if(r_image_ddr3_wren (r_line_cnt IMAGE_HIGHT)) r_image_ddr3_wrdb w_fifo1_dout;else ;reg output_link; always (posedge clk or negedge rst_n)if(!rst_n) output_link 1b0;else if(r_line_cnt 10d0) output_link 1b1;else if(r_image_ddr3_wren (r_line_cnt IMAGE_HIGHT)) output_link 1b1;else output_link 1b0; assign o_image_ddr3_wrdb output_link ? r_image_ddr3_wrdb:average_result;工程架构
average_filter.v
timescale 1ns / 1ps
/*
对图像进行均值滤波平滑处理
第1行、最后1行、第1列、最后1列不做处理使用原始图像像素值输出
对其余图像像素点对周围像素点做如下运算
% 1 2 1
% 1/16 * 2 4 2
% 1 2 1
*/
module average_filter(input clk, //50MHz时钟input rst_n, //复位信号低电平有效//Image Data flow from Image Sensorinput i_image_ddr3_wren,input i_image_ddr3_line_end,input i_image_ddr3_clr,input[15:0] i_image_ddr3_wrdb, //Image Data flow after average transformoutput reg o_image_ddr3_wren,output[15:0] o_image_ddr3_wrdb );parameter IMAGE_WIDTH 10d640;
parameter IMAGE_HIGHT 10d480; //数据行计数器
reg[9:0] r_line_cnt;always (posedge clk or negedge rst_n)if(!rst_n) r_line_cnt 10d0;else if(i_image_ddr3_clr) r_line_cnt 10d0;else if(i_image_ddr3_line_end) r_line_cnt r_line_cnt1b1;else ;//FIFO for cache 1 line image data
reg r_fifo1_rd_en;
wire[15:0] w_fifo1_dout;
wire[9:0] w_fifo1_data_count;fifo_generator_3 uut1_fifo_generator_3 (.clk(clk), // input wire clk.srst(!rst_n || i_image_ddr3_clr), // input wire srst.din(i_image_ddr3_wrdb), // input wire [15 : 0] din.wr_en(i_image_ddr3_wren), // input wire wr_en.rd_en(r_fifo1_rd_en), // input wire rd_en.dout(w_fifo1_dout), // output wire [15 : 0] dout.full(), // output wire full.empty(), // output wire empty.data_count(w_fifo1_data_count) // output wire [9 : 0] data_count
);reg r_fifo2_wr_en;
reg r_fifo2_rd_en;
wire[15:0] w_fifo2_dout;
wire[9:0] w_fifo2_data_count;fifo_generator_3 uut2_fifo_generator_3 (.clk(clk), // input wire clk.srst(!rst_n || i_image_ddr3_clr), // input wire srst.din(w_fifo1_dout), // input wire [15 : 0] din.wr_en(r_fifo2_wr_en), // input wire wr_en.rd_en(r_fifo2_rd_en), // input wire rd_en.dout(w_fifo2_dout), // output wire [15 : 0] dout.full(), // output wire full.empty(), // output wire empty.data_count(w_fifo2_data_count) // output wire [9 : 0] data_count
);//连续读出640个数据计数控制状态机
parameter RFIFO_RESET 3d0;
parameter RFIFO_IDLE 3d1;
parameter RFIFO_RDDB1 3d2;
parameter RFIFO_RDDB2 3d3;
parameter RFIFO_WAIT 3d4;
parameter RFIFO_RDDB3 3d5;
reg[2:0] rfifo_state;
reg[9:0] dcnt; //读FIFO数据个数计数器
reg[9:0] average_num;
reg[3:0] dly_cnt;always (posedge clk or negedge rst_n)if(!rst_n) rfifo_state RFIFO_RESET;else if(i_image_ddr3_clr) rfifo_state RFIFO_RESET;else begincase(rfifo_state)RFIFO_RESET: if(w_fifo1_data_count IMAGE_WIDTH) rfifo_state RFIFO_RDDB1;else rfifo_state RFIFO_RESET;RFIFO_RDDB1: if(dcnt (IMAGE_WIDTH-1)) rfifo_state RFIFO_IDLE;else rfifo_state RFIFO_RDDB1;RFIFO_IDLE: if(r_line_cnt IMAGE_HIGHT) rfifo_state RFIFO_WAIT;else if(w_fifo2_data_count IMAGE_WIDTH) rfifo_state RFIFO_RDDB2;else rfifo_state RFIFO_IDLE; RFIFO_RDDB2: if(r_line_cnt IMAGE_HIGHT) rfifo_state RFIFO_WAIT;else if(dcnt (IMAGE_WIDTH-1)) rfifo_state RFIFO_IDLE;else rfifo_state RFIFO_RDDB2;RFIFO_WAIT: if(dly_cnt 4hf) rfifo_state RFIFO_RDDB3; else rfifo_state RFIFO_WAIT;RFIFO_RDDB3: if(dcnt (IMAGE_WIDTH-1)) rfifo_state RFIFO_RESET;else rfifo_state RFIFO_RDDB3; default: rfifo_state RFIFO_IDLE;endcaseendalways (posedge clk or negedge rst_n)if(!rst_n) dly_cnt 4d0;else if(rfifo_state RFIFO_WAIT) dly_cnt dly_cnt1b1;else dly_cnt 4d0;//读FIFO数据个数计数器
always (posedge clk or negedge rst_n)if(!rst_n) dcnt 10d0;else if((rfifo_state RFIFO_IDLE) || (rfifo_state RFIFO_RESET)) dcnt 10d0;else if(((rfifo_state RFIFO_RDDB1) || (rfifo_state RFIFO_RDDB2)) i_image_ddr3_wren) dcnt dcnt1b1;else if(rfifo_state RFIFO_RDDB3) dcnt dcnt1b1; else dcnt 10d0;//average transform数据计数器
always (posedge clk or negedge rst_n)if(!rst_n) average_num 10d0;else if(dcnt 10d4) average_num 10d1;else if(average_num ! 10d0) beginif(average_num IMAGE_WIDTH) average_num average_num1b1;else average_num 10d0;endelse average_num 10d0;//读FIFO1使能信号产生逻辑
always (posedge clk or negedge rst_n)if(!rst_n) r_fifo1_rd_en 1b0;else if(((rfifo_state RFIFO_RDDB1) || (rfifo_state RFIFO_RDDB2)) i_image_ddr3_wren) r_fifo1_rd_en 1b1;else if((rfifo_state RFIFO_RDDB3) (dcnt IMAGE_WIDTH)) r_fifo1_rd_en 1b1;else r_fifo1_rd_en 1b0;//写FIFO2是能信号产生逻辑
always (posedge clk or negedge rst_n)if(!rst_n) r_fifo2_wr_en 1b0;else r_fifo2_wr_en r_fifo1_rd_en; //读FIFO2使能信号产生逻辑
always (posedge clk or negedge rst_n)if(!rst_n) r_fifo2_rd_en 1b0;else if(((rfifo_state RFIFO_RDDB2) || (rfifo_state RFIFO_RDDB3)) i_image_ddr3_wren) r_fifo2_rd_en 1b1;else r_fifo2_rd_en 1b0; //图像缓存3拍
reg[15:0] data_temp_line_1[2:0];
reg[15:0] data_temp_line_2[2:0];
reg[15:0] data_temp_line_3[4:0];always (posedge clk) begindata_temp_line_1[0] w_fifo2_dout;data_temp_line_1[1] data_temp_line_1[0];data_temp_line_1[2] data_temp_line_1[1];
endalways (posedge clk) begindata_temp_line_2[0] w_fifo1_dout;data_temp_line_2[1] data_temp_line_2[0];data_temp_line_2[2] data_temp_line_2[1];
endalways (posedge clk) begindata_temp_line_3[0] i_image_ddr3_wrdb;data_temp_line_3[1] data_temp_line_3[0];data_temp_line_3[2] data_temp_line_3[1];data_temp_line_3[3] data_temp_line_3[2];data_temp_line_3[4] data_temp_line_3[3];
end //图像输出average filter运算
reg[9:0] sum_a_r,sum_b_r1,sum_b_r2;
reg[9:0] sum_a_g,sum_b_g1,sum_b_g2;
reg[9:0] sum_a_b,sum_b_b1,sum_b_b2;reg[15:0] average_result; always (posedge clk) beginsum_a_r {3b000,data_temp_line_2[1][15:11],2b00};sum_a_g {2b0,data_temp_line_2[1][10:5],2b00};sum_a_b {3b000,data_temp_line_2[1][4:0],2b00};
end always (posedge clk) beginsum_b_r1 {4d0,data_temp_line_2[0][15:11],1b0} {4d0,data_temp_line_2[2][15:11],1b0} {4d0,data_temp_line_1[1][15:11],1b0} {4d0,data_temp_line_3[3][15:11],1b0};sum_b_g1 {3d0,data_temp_line_2[0][10:5],1b0} {3d0,data_temp_line_2[2][10:5],1b0} {3d0,data_temp_line_1[1][10:5],1b0} {3d0,data_temp_line_3[3][10:5],1b0};sum_b_b1 {4d0,data_temp_line_2[0][4:0],1b0} {4d0,data_temp_line_2[2][4:0],1b0} {4d0,data_temp_line_1[1][4:0],1b0} {4d0,data_temp_line_3[3][4:0],1b0};sum_b_r2 {5d0,data_temp_line_1[0][15:11]} {5d0,data_temp_line_1[2][15:11]} {5d0,data_temp_line_3[2][15:11]} {5d0,data_temp_line_3[4][15:11]};sum_b_g2 {4d0,data_temp_line_1[0][10:5]} {4d0,data_temp_line_1[2][10:5]} {4d0,data_temp_line_3[2][10:5]} {4d0,data_temp_line_3[4][10:5]};sum_b_b2 {5d0,data_temp_line_1[0][4:0]} {5d0,data_temp_line_1[2][4:0]} {5d0,data_temp_line_3[2][4:0]} {5d0,data_temp_line_3[4][4:0]};
end wire[9:0] temp_r sum_a_r(sum_b_r1sum_b_r2);
wire[9:0] temp_g sum_a_g(sum_b_g1sum_b_g2);
wire[9:0] temp_b sum_a_b(sum_b_b1sum_b_b2);always (posedge clk) beginif((average_num 10d1) || (average_num IMAGE_WIDTH)) average_result data_temp_line_2[2]; //第1列和最后1列使用原值else beginaverage_result[15:11] temp_r[8:4]; average_result[10:5] temp_g[9:4];average_result[4:0] temp_b[8:4]; end
end //图像输出有效信号产生
reg r_image_ddr3_wren;
reg[3:0] r_average_line_wren;
reg r_last_line_wren;always (posedge clk or negedge rst_n)if(!rst_n) r_last_line_wren 1b0;else if((rfifo_state RFIFO_RDDB3) (dcnt IMAGE_WIDTH)) r_last_line_wren 1b1;else r_last_line_wren 1b0;always (posedge clk or negedge rst_n)if(!rst_n) r_average_line_wren 4d0;else beginr_average_line_wren[3:1] r_average_line_wren[2:0];if((rfifo_state RFIFO_RDDB2) (r_line_cnt 10d1) i_image_ddr3_wren) r_average_line_wren[0] 1b1;else r_average_line_wren[0] 1b0;end always (posedge clk or negedge rst_n)if(!rst_n) r_image_ddr3_wren 1b0;else if(r_average_line_wren[3]) r_image_ddr3_wren 1b1;else if(r_last_line_wren) r_image_ddr3_wren 1b1;else r_image_ddr3_wren 1b0;always (posedge clk or negedge rst_n)if(!rst_n) o_image_ddr3_wren 1b0;else if((r_line_cnt 10d0) i_image_ddr3_wren) o_image_ddr3_wren 1b1;else if(r_image_ddr3_wren) o_image_ddr3_wren 1b1;else o_image_ddr3_wren 1b0;//图像数据输出
reg[15:0] r_image_ddr3_wrdb; always (posedge clk or negedge rst_n)if(!rst_n) r_image_ddr3_wrdb 16d0;else if(r_line_cnt 10d0) r_image_ddr3_wrdb i_image_ddr3_wrdb;else if(r_image_ddr3_wren (r_line_cnt IMAGE_HIGHT)) r_image_ddr3_wrdb w_fifo1_dout;else ;reg output_link; always (posedge clk or negedge rst_n)if(!rst_n) output_link 1b0;else if(r_line_cnt 10d0) output_link 1b1;else if(r_image_ddr3_wren (r_line_cnt IMAGE_HIGHT)) output_link 1b1;else output_link 1b0; assign o_image_ddr3_wrdb output_link ? r_image_ddr3_wrdb:average_result;endmodule