FPGA图像处理系列:图像缩放
2016-03-24 21:25
246 查看
用了一晚上时间实现了一个Avalon-ST总线的简单图像缩放模块,将640*480的图像输入,变成320*240大小的图像输出。主要思想是,得到图像的行列计数值,根据要缩放的比例,在相应的行列值使能valid信号,比如我要将640*480图像缩小成320*240,那么只需控制将其隔行、隔列使能valid就行了。其实就是一个降采样。代码直接贴出
另外,假如对于一幅图像(1920*1080),我想把它缩小到任意的大小,比如320*240大小:
对于水平的320像素,因为1920/320=6,因此只需设置一个列循环计数值,范围0-5,在等于5的时候,输出像素valid为1;
对于竖直方向的240,因为1080除以240不是整数,而是9/2。也就是说,需要每隔4.5行,就应该输出一个valid。为了使其整数化,可以等同为每隔9行输出两个valid。因此可以设置一个行循环计数值,范围0-8,在等于3或者等于8的时候,输出valid为1。代码如下:
</pre><pre name="code" class="cpp">module ST_RESIZE( // global clock & reset input clk, input reset_n, // stream sink input [23:0] sink_data, input sink_valid, output sink_ready, input sink_sop, input sink_eop, // stream source output [23:0] source_data, output source_valid, input source_ready, output source_sop, output source_eop ); localparam CTRL_PKT_NUM = 3; assign sink_ready = source_ready; assign source_sop = sink_sop; assign source_eop = sink_eop; //assign source_valid = sink_valid; //assign source_data = sink_data; parameter WIDTH = 640; parameter HEIGHT = 480; parameter w_LOG_WIDTH = 320; parameter w_LOG_HEIGHT = 240; reg state; localparam STATE_CTRL = 0; localparam STATE_DATA = 1; always@(posedge clk)begin if(~reset_n) state <= STATE_CTRL; else if( process_en && sink_sop&& sink_data == 24'd15) state <= STATE_CTRL; else if( process_en && sink_sop&& sink_data == 24'd0) state <= STATE_DATA; end reg [10:0] h_count; reg [10:0] v_count; wire process_en; assign process_en = source_ready & sink_valid; always@(posedge clk)begin if(~reset_n) h_count <= 11'b0; else if( process_en && sink_sop && sink_data == 24'd0) h_count <= 11'b0; else if( process_en && h_count< WIDTH-1 && state == STATE_DATA) h_count <= h_count + 1'b1; else if( process_en && h_count== WIDTH-1 && state == STATE_DATA) h_count <= 11'b0; end always@(posedge clk)begin if(~reset_n) v_count <= 11'b0; else if( process_en && sink_sop&& sink_data == 24'd0) v_count <= 11'b0; else if( process_en && h_count == WIDTH-1 && state == STATE_DATA) v_count <= v_count + 1'b1; end assign source_valid =(sink_valid & sink_sop & sink_data == 24'd15) | (sink_valid & state == STATE_CTRL )| (sink_valid & sink_sop & sink_data == 24'd00) | ( sink_valid & state == STATE_DATA & h_count[0]==0 & v_count[0]==0) | ( sink_valid & sink_eop ) ; //assign source_data = sink_data; always @(*) begin case (state ) STATE_CTRL : if(source_ready & sink_valid)begin if(dot_cnt==0)source_data = { 4'b0, w_LOG_WIDTH[ 7: 4], 4'b0, w_LOG_WIDTH[11: 8], 4'b0, w_LOG_WIDTH[15:12] }; if(dot_cnt==1)source_data = { 4'b0, w_LOG_HEIGHT[11: 8], 4'b0, w_LOG_HEIGHT[15:12], 4'b0, w_LOG_WIDTH[ 3: 0] }; if(dot_cnt==2)source_data = { 4'b0, 4'b0, 4'b0, w_LOG_HEIGHT[ 3: 0], 4'b0, w_LOG_HEIGHT[ 7: 4] }; end STATE_DATA : source_data = sink_data; default : source_data = sink_data; endcase end reg [11:0] dot_cnt; always @(posedge clk) begin if (!reset_n) begin dot_cnt <= 0; end else begin if (dout_ready & source_ready)begin if ((pkt_state == STATE_CTRL) )begin // control packet if ( dot_cnt < (CTRL_PKT_NUM-1) ) dot_cnt <= dot_cnt + 11'd1; else dot_cnt <= 0; end end end endmodule
另外,假如对于一幅图像(1920*1080),我想把它缩小到任意的大小,比如320*240大小:
对于水平的320像素,因为1920/320=6,因此只需设置一个列循环计数值,范围0-5,在等于5的时候,输出像素valid为1;
对于竖直方向的240,因为1080除以240不是整数,而是9/2。也就是说,需要每隔4.5行,就应该输出一个valid。为了使其整数化,可以等同为每隔9行输出两个valid。因此可以设置一个行循环计数值,范围0-8,在等于3或者等于8的时候,输出valid为1。代码如下:
module ST_RESIZE( // global clock & reset input clk, input reset_n, // stream sink input [15:0] sink_data, input sink_valid, output sink_ready, input sink_sop, input sink_eop, // stream source output [15:0] source_data, output source_valid, input source_ready, output source_sop, output source_eop ); assign sink_ready = source_ready; assign source_sop = sink_sop; assign source_eop = sink_eop; parameter WIDTH = 1920; parameter HEIGHT = 1080; reg state; localparam STATE_CTRL = 0; localparam STATE_DATA = 1; always@(posedge clk)begin if(~reset_n) state <= STATE_CTRL; else if( process_en && sink_sop&& sink_data == 16'd15) state <= STATE_CTRL; else if( process_en && sink_sop&& sink_data == 16'd0) state <= STATE_DATA; end reg [10:0] h_count; reg [10:0] v_count; wire process_en; assign process_en = source_ready & sink_valid; reg [3:0] h_step_count; reg [3:0] v_step_count; always@(posedge clk)begin if(~reset_n)begin h_count <= 11'b0; h_step_count <= 4'b0; end else if( process_en && sink_sop && sink_data == 16'd0)begin h_count <= 11'b0; h_step_count <= 4'b0; end else if( process_en && h_count< WIDTH-1 && state == STATE_DATA)begin h_count <= h_count + 1'b1; if(h_step_count >= 4'd5) h_step_count <= 4'b0; else h_step_count <= h_step_count+1; end else if( process_en && h_count== WIDTH-1 && state == STATE_DATA)begin h_count <= 11'b0; h_step_count <= 4'b0; end end always@(posedge clk)begin if(~reset_n)begin v_count <= 11'b0; v_step_count <= 4'b0; end else if( process_en && sink_sop&& sink_data == 16'd0)begin v_count <= 11'b0; v_step_count <= 4'b0; end else if( process_en && h_count == WIDTH-1 && state == STATE_DATA)begin v_count <= v_count + 1'b1; if(v_step_count >= 4'd8) v_step_count <= 4'b0; else v_step_count <= v_step_count+1; end end assign source_valid =(sink_valid & sink_sop & sink_data == 16'd15) | // (sink_valid & state == STATE_CTRL )| (sink_valid & sink_sop & sink_data == 16'd00) | ( sink_valid & state == STATE_DATA & h_step_count==4'd5 &( v_step_count==4'd3 | v_step_count==4'd8)) | ( sink_valid & sink_eop ) ; assign source_data = sink_data; endmodule
相关文章推荐
- PHP GD 图像处理组件的常用函数总结
- PHP图像处理之imagecreate、imagedestroy函数介绍
- jsvascript图像处理―(计算机视觉应用)图像金字塔
- Javascript图像处理思路及实现代码
- PHP图像处理之使用imagecolorallocate()函数设置颜色例子
- java数字图像处理基础使用imageio写图像文件示例
- 使用Java进行图像处理的一些基础操作
- javascript图像处理―边缘梯度计算函数
- Javascript图像处理―阈值函数实例应用
- Javascript图像处理―虚拟边缘介绍及使用方法
- PHP图像处理类库及演示分享
- php图像处理函数大全(推荐收藏)
- Javascript图像处理―图像形态学(膨胀与腐蚀)
- Javascript图像处理―平滑处理实现原理
- Swift图像处理之优化照片
- 在Ubuntu上安装OpenCV3.0和Python-openCV的经历
- 《FPGA嵌入式项目开发实战》
- VTK学习笔记之图像处理
- vtk 图像处理 多种 操作
- 05-VTK在图像处理中的应用(2)