原创 【博客大赛】关于用FPGA定点旋转算法的实现

2013-4-25 09:49 2378 23 27 分类: FPGA/CPLD

      图像旋转是指图像以某一点为中心旋转一定的角度,形成一幅新的图像的过程。由于图像旋转过程中会出现浮点数,而对于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[5:3];
   assign cnt_y=coordinate[2:0];
   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 <=  xtmp>>10;
   y0 <=  ytmp>>10;
  x <=  xtmp>>1024;
  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[23:16])+(a1*c1[23:16])+(a2*c2[23:16])+(a3*c3[23:16]))>>10);
g <= (((a0*c0[15:8])+(a1*c1[15:8])+(a2*c2[15:8])+(a3*c3[15:8]))>>10);
b <= (((a0*c0[7:0])+(a1*c1[7:0])+(a2*c2[7:0])+(a3*c3[7:0]))>>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

文章评论4条评论)

登录后参与讨论

wangqiaoyu_888_963244381 2013-4-25 09:55

呵呵,%的位置写的是有问题,已经更改。代码是之前在一个项目中应用的,当时因为要用FPGA实现DSP的图像旋转算法,项目比较急,没有优化,这个只是实现了一部分功能,我当时的测试代码是4*4的图形旋转。但是后来没有用FPGA来实现这个图像旋转,后来也就没有在进行改进和优化了。 虽然用FPGA也做了一些项目,但是对于代码优化和速度性能的提示还是有欠缺,更多的时候是不知道该怎么去做才能提升一些性能。通过算法分析和仿真可以找到一个关键路径,可以寄存器拷贝实现同步等等,都只是一些理论的东西,还没有真的在项目中实现过。 多些sunyzz的批评和指正,望以后有问题能请教你。

sunyzz 2013-4-24 21:34

看了楼主的代码,觉得楼主的代码写的很随意,不知道您写的是不是只是您的一些思想,如果您是认真写的,觉得您的代码太C语言话了,里面值得优化的地方有很多,您里面用了大量的乘法、移位、甚至还有%,如果您考虑后续DC综合的话,建议您不要用%,/之类的,它们很耗硬件资源,其实您仔细思考一下,它们是可以用移位,补齐等操作代替的,如果用fpga综合,同样耗硬件资源,而且您的最终频率肯定上不去。总而言之,您在写代码时如果不考虑FPGA的特性的话,你会写成C或者C++的,也就谈不上使用FPGA了。。。。。班门弄斧了,如有不对之处,请谅解!

用户377235 2013-4-15 21:34

欢迎楼主继续分享

wangqiaoyu_888_963244381 2013-4-5 22:48

欢迎大家讨论

gujunyi1_407560534 2009-9-29 22:59

不好意思,忘了说了,晶振需要是11.0592M的,单片机的型号影响不大,是51的就行了,我在AT和STC系列的单片机上试过。不过真的想要精确定时的话,还是使用定时中断吧,呵呵!

用户1045878 2009-9-29 14:36

哪种单片机 之间 相差还是很大的 系统时钟是多少呢 针对一种单片机,不也是有中断影响吗 哈哈哈
相关推荐阅读
wangqiaoyu_888_963244381 2015-08-28 11:42
【创客】先专注而后全面
      学生时代学的是FPGA相关课程,参与的也是与FPGA相关的项目,毕业后进入一家公司分配的是不相称的职位,正好熟人介绍到新公司做嵌入式电路设计,也算是和原来的学习所得有交叉。    ...
wangqiaoyu_888_963244381 2015-08-27 16:43
【创客】我的DIY之路
1 题记           路漫漫之修远兮,吾将上下而求索!---- 从大学时就喜欢电子电路设计,只可惜开始没有遇到高明之士,也怪自己不够狠心,导致浪费了很多宝贵的时光。 当初对于软件编程更是满怀...
wangqiaoyu_888_963244381 2015-02-28 14:07
【博客大赛】什么是NEMA?
在项目使用的一个蜂鸣器手册中看到了NEMA 3R/4x/12资质,就查找相关资料探个究竟。以下是搜集的NEMA部分资料。 NEMA全称是National Electrical Manufacture...
wangqiaoyu_888_963244381 2013-11-25 20:11
【博客大赛】pspice介绍
PSpice软件的发展: Berkley:    SPICE  (Simulation Program with Integrated  Circuit          Emphasis) ...
wangqiaoyu_888_963244381 2013-11-20 22:40
【博客大赛】chs使用略谈
       这两天正在用chs的captial logic来绘制系统电气原理图,感觉功能很强大,在此稍微做个介绍。      Capital Logic是电气系统的逻辑设计工具,它提供一...
wangqiaoyu_888_963244381 2013-11-17 20:37
【博客大赛】CRC16 verilog产生程序
        生成CRC码的基本原理:       任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’取值的多项式一一对应。例如:代码1010111对应的多项式为...
我要评论
4
23
关闭 站长推荐上一条 /2 下一条