热度 27
2013-4-25 09:49
2375 次阅读|
4 个评论
图像旋转是指图像以某一点为中心旋转一定的角度,形成一幅新的图像的过程。由于图像旋转过程中会出现浮点数,而对于FPGA来说浮点运算会浪费很多的资源。本文采用一种将浮点转换为定点累加和移位的操作方式来处理旋转算法,减少了浮点运算的复杂性和充分利用FPGA的特性来并行和以为操作,可以在很少的时钟周期内处理完一个像素点的旋转。 本文不是直接计算原始像素旋转后的像素值,而是由旋转后的像素值的坐标位置计算出原始图像的相关坐标值,然后通过相关面积计算出旋转像素的像素值,减少了像素的边缘丢失和单纯旋转的丢失精度的问题。由于图像的选择不是一个标准的圆形参考旋转,所以对于图像的像素中心会有一定的误差,导致不能简单的直接运算。通过本文的方法可以更好的计算旋转像素值,同时可以应用FPGA的并行特性加速程序的运行效率。 下面简要的对程序说明:coordinate为旋转后的像素坐标,angle1为旋转的角度cos值,angle2为旋转的角度sin,clk为程序时钟,reset为系统复位信号,,old_buffer_rd为原始像素读信号,old_buffer_addr为原始像素存储地址, old_buffer_data为原始像素存储数据,new_buffer_addr为旋转后的像素存储地址,new_buffer_data为旋转后的像素值,new_buffer_wr为旋转后的像素写信号, new_buffer_wren为旋转后的像素写使能信号,roate_done为旋转完成信号,cnt_x和cnt_y为测试信号。 以下为实现程序的部分内容,采用的测试像素矩阵为4X4: 以下部分为模块定义部分: module roate_new(coordinate,angle1,angle2,clk,reset,old_buffer_rd,old_buffer_addr, old_buffer_data,new_buffer_addr,new_buffer_data,new_buffer_wr, new_buffer_wren,roate_done,cnt_x,cnt_y); assign cnt_x=coordinate ; assign cnt_y=coordinate ; assign ncos=angle1; assign nsin=angle2; 以下部分为函数的具体执行代码: if(cont==1) begin xtmp = (cnt_x-2) * ncos + (cnt_y-2) * nsin + 2 * 1024; ytmp = -(cnt_x-2) * nsin + (cnt_y-2) * ncos + 2* 1024; cont=cont+1; end else if(cont==2) begin x0 = xtmp10; y0 = ytmp10; x = xtmp1024; y = ytmp 1024; xy = (x*y)10; cont=cont+1; end else if(cont==3) begin old_buffer_addr=6*(x0+1)+(y0+1); cont=cont+1; end else if(cont==4) begin c0 = old_buffer_data; cont=cont+1; end else if(cont==5) begin old_buffer_addr=6*((x0+1)+1)+(y0+1); cont=cont+1; end else if(cont==6) begin c1 = old_buffer_data; cont=cont+1; end else if(cont==7) begin old_buffer_addr=6*(x0+1)+((y0+1)+1); cont=cont+1; end else if(cont==8) begin c2 = old_buffer_data; cont=cont+1; end else if(cont==9) begin old_buffer_addr=6*((x0+1)+1)+((y0+1)+1); cont=cont+1; end else if(cont==10) begin c3 = old_buffer_data; cont=cont+1; end else if(cont==11) begin old_buffer_rd=0; a0 = (1024+xy-x-y); a1 = (x-xy); a2 = (y-xy); a3 = (xy); cont=cont+1; end else if(cont==12) begin r = (((a0*c0 )+(a1*c1 )+(a2*c2 )+(a3*c3 ))10); g = (((a0*c0 )+(a1*c1 )+(a2*c2 )+(a3*c3 ))10); b = (((a0*c0 )+(a1*c1 )+(a2*c2 )+(a3*c3 ))10); cont=cont+1; end else if(cont==13) begin new_buffer_data = {r,g,b}; new_buffer_wren=1; new_buffer_wr=1; new_buffer_addr=4*cnt_x+cnt_y; cont=cont+1; roate_done =1; end else if(cont==14) begin new_buffer_wr=0; cont=1; roate_done =0; end endmodule