FPGA图像处理 ZYNQ7020 双线性插值缩放

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

实现了双线性插值算法 可支持16倍放大无限缩小 最高4k 30帧
注意:后续技术分享,第一时间更新,以及缩放、白平衡及各种滤波算法完整代码,将在VX群发布,请添加VX:Zeus20010223

一、双线性插值是什么?

简单来说,插值指利用已知的点来“猜”未知的点,图像领域插值常用在修改图像尺寸的过程,由旧的图像矩阵中的点计算新图像矩阵中的点并插入,不同的计算过程就是不同的插值算法。

双线性插值(Bilinear Interpolation):双线性插值是用原图像中4(2*2)个点计算新图像中1个点,效果略逊于双三次插值,速度比双三次插值快,属于一种平衡美,在很多框架中属于默认算法。
在这里插入图片描述
已知Q11(x1,y1)、Q12(x1,y2)、Q21(x2,y1)、Q22(x2,y2),求其中点P(x,y)的值。

在这里插入图片描述

几何中心点重合对应公式:

在这里插入图片描述

在这里插入图片描述

简单来说,根据目标图像的坐标,通过上述公式映射到原图像中,然后根据临近的四个点算出该点的像素值

二、FPGA实现

首先定义缩放大小 支持16倍放大无限缩小

//fix16_12
localparam  [15:0]	sx  =  SRC_IW*4096/DST_IW	;
localparam  [15:0]	sy  =  SRC_IH*4096/DST_IH	;

由状态机引领数据调度

always@(posedge clk)
	if(rst)
		begin
			dst_de 		<= 0;
			state  		<= 0;
		end
	else if(pre_ready==1'b1)
		case(state)
			0:	
				if(wr_data_count<DST_IW*buf_line-13)//不满3行
					begin
						state 	 <= 2;
					end		
				else
					begin
						state 	 <= state;
					end	
			1:  
				if(src_hcnt==SRC_IW-1)
					begin
						state 	<= 2;
					end
				else 
					begin
						state 	<= state;
					end		
			2:  
				if(src_vcnt>=expt_src_vcnt3&&expt_src_vcnt_de3==1'b1)
					begin
						state 	<= 3;
					end
				else if(src_vcnt<expt_src_vcnt3&&expt_src_vcnt_de3==1'b1)
					begin
						state 	<= 1;
					end
				else 
					begin
						state 	<= state;
					end					
			3:  
				if(dst_hcnt==DST_IW-1)
					begin
						dst_de  <= 0;
						state 	<= 0;
					end
				else 
					begin
						dst_de  <= 1;
						state 	<= state;
					end	
			default:;
		endcase				
	else
		begin
			dst_de <= 0;
			state  <= 0;
		end

共有4个状态
0:不满3行跳到2状态 -13是因为对数据处理需要12个周期
2:当前的纵坐标是否大于期待的纵坐标 大于跳到3 小于跳到1
当跳到2状态时 expt_src_vcnt_de拉高 在4拍之后计算出expt_src_vcnt3 该值由expt_src_vcnt2截位加2 加2因为计算坐标时需要用到本行数据和下一行数据
1:当跳到1状态时 src_de拉高 该寄存器直接与pre_req相连 读1行数跳到2
3:当跳到3状态时 dst_de拉高 计算1行之后低 expt_src_vcntp1_de拉高(expt_src_vcnt_de) 该信号为了预先计算下一行是否满足 用于增加带宽

4个双写端口ram用于存数

tdpram #(
			.AW (12),
			.DW (8 )  
		)
		u1_tdpram 
		(
		  .clka		(clk			),
		  .wea		(wr_addr_de[i]	),
		  .addra	(wr_addr[i]		),
		  .dina		(pre_data		),
		  .douta	(douta[i]		),
		  .clkb		(clk			),
		  .web		(1'b0			),
		  .addrb	(rd_addr[i]		),
		  .dinb		(8'd0			),
		  .doutb	(doutb[i]		) 
		);		
  end

筛选数据在哪行

assign src_mod = src_y0%4;
case(src_mod)
		0:
			begin
				rd_addr_w[0] <= src_x0;
				rd_addr[0]   <= src_x1;
				rd_addr_w[1] <= src_x0;
				rd_addr[1]   <= src_x1;
			end	

后面计算u,v省略
讲计算后的数据存到fifo中

三、仿真验证

fpga处理效果

在这里插入图片描述
与matlab结果一致

在这里插入图片描述

仿真波形

在这里插入图片描述
pre_ready拉高 状态机跳转2 expt_src_vcnt_de使能 计算发现不满足跳到1 pre_req拉高读数

在这里插入图片描述
读2行之后 满足条件 跳到3 dst_de高 开始计数 src_xf0 和 src_yf0

  • 28
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值