基于HLS的图像旋转

1,基本原理:

1.1图像旋转的基本公式:

在笛卡尔坐标系中,以图像中心原点O,向右为x轴正方向,向上为y轴正方向,图像中任意一点(x0,y0),以图像的中心为圆心顺时针旋转a角后的坐标变换为(x,y),则有:

1.2,HLS的处理过程:

裸核与逻辑之间的AXI4接口,可以实现裸核,逻辑,DDR之间的大量数据交互工作。我们可以规定一个DDR的初始地址(本文使用0x1000000),然后将需要转化的图像,连同操作需要的参数sina、cosa、偏移x、偏移y等一起存入对应的内存中。然后ARM使用GPIO接口PS_LED启动IP核开始计算工作。接下来,等到IP核完成计算,再通过PL_KEY0产生EMIO中断通知ARM可以读取旋转好的图像数据。

系统框图如下:

2,HLS部分的修改总结

打开Vivado HLS 2018.3

->选择OpenExampleProject

->选择axi_master /Next/保存到D:\work\AXI_GaohuiNot1\axi_master

修改C代码如下:

//在头文件中定义

#define pi 3.1405926

#define IMAGE_W 864

#define IMAGE_H 450

#define RImg_W 720

#define RImg_H 320

void example(unsigned char *imgdata)

{

#pragma HLS INTERFACE m_axi port=imgdata depth=864*450*2

int px =imgdata[1]*256+imgdata[0];

int py =imgdata[3]*256+imgdata[2];

int MoneyW =imgdata[5]*256+imgdata[4];

int MoneyH =imgdata[7]*256+imgdata[6];

int sina =imgdata[9]*256+imgdata[8];

int cosa =imgdata[11]*256+imgdata[10];

int k,x,y;

int x0,y0;

int Mx=(px-RImg_W/2);//347,161

int My=(py-RImg_H/2);

for(y=0;y<IMAGE_H;y+=2)

for(x=0;x<IMAGE_W;x+=2)

{

if( ((x-Mx-RImg_W/2 )<MoneyW/2)

&&((RImg_W/2 -(x-Mx) )<MoneyW/2)

&&((y-My-RImg_H/2)<MoneyH/2)

&&((-y+My+RImg_H/2)<MoneyH/2)

)

{

x0=(int)((x-px)*cosa/1000-(y-py)*sina/1000)+px;//

y0 = (x)*sina/1000-(px)*sina/1000;

y0 += py + (y)*cosa/1000-(py)*cosa/1000;

y0 *= IMAGE_W;

y0 += x0;

imgdata[(RImg_W/2)*((y-My)/2)+(x-Mx)/2+IMAGE_H*IMAGE_W]=imgdata[y0];

}

}

}

修改Solution Setting(小齿轮)

Synthesys->时钟150MHz

Part:xc7z010clg400-1

将example.cpp,example_test.cpp改为合适的代码

(怎么改,后边会单独介绍)

->Run C Simulation/(小绿三角)结果正确

->Run C Synthesis/(大绿三角)结果正确

将电脑系统日期改为2000年

->Export RTL/(田字格)结果正确

修改IP名称例如Description:HLS20221218_001

2 Vivado部分

打开Vivado 2018.3

->Creat Project->修改项目名->Part:xc7z010clg400-1

->Creat Block Design->AddIP 选择zynq7

DDR Control Confifuration器件 7010 :MT41J128M16HA-125

Peripheral I/O Pins :UART0 设置14与15脚

MIO :Bank1电压LVCMOS1.8V

PS/PL->AXI Non->GP Master :关闭M AXI GP0

->General->Enable Clk:FCLK_RESET0_N:开(默认就是开)

->HP Slave AXI :S AXI HP0 打开

Clock->PL->FCLK CLK0 : 150 (单位是M, 最大150M,要和IP一致)

添加4个EMIO(1个输出,1个输入)

输出1:HLS开始 裸核输出 D20 (L20为Led)

输入2:HLS结束输入中断 M18 (J18为Key)

原来的{输入1:HLS开始 逻辑输入 [J18]}

原来的{输出2:HLS结束输出 [J20]}

MIO GPIO EMIO_GPIO 打钩

位宽Width2

(引脚make external)

添加IP核

拷贝IP目录到Vivado目录

Setting->IP->Repository(仓库)->选中添加的IP

+->hls IP

->Run Connection 更新

->管脚 Make External

->修改IP的 基地址0x10000000

Data width:32 (其他设置会异常)

逻辑框图如下:

生成顶层模板包装 Creat HDL Wrapper

生成输出 Generate Output Products->2 Out of context per IP

分配管脚

set_property IOSTANDARD LVCMOS33 [get_ports ap_ctrl_0_done]

set_property IOSTANDARD LVCMOS33 [get_ports ap_ctrl_0_idle]

set_property IOSTANDARD LVCMOS33 [get_ports ap_ctrl_0_ready]

set_property IOSTANDARD LVCMOS33 [get_ports ap_ctrl_0_start]

set_property PACKAGE_PIN J20 [get_ports ap_ctrl_0_start]

set_property PACKAGE_PIN M18 [get_ports ap_ctrl_0_done]

set_property PACKAGE_PIN H18 [get_ports ap_ctrl_0_idle]

set_property PACKAGE_PIN H16 [get_ports ap_ctrl_0_ready]

set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_0_tri_io[0]}]

set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_0_tri_io[1]}]

set_property PACKAGE_PIN T14 [get_ports {GPIO_0_0_tri_io[0]}]

set_property PACKAGE_PIN J18 [get_ports {GPIO_0_0_tri_io[1]}]

生成Bit

导出硬件Export Hardware:注意要包含bit

Launch SDK

3, SDK部分

1,使用EMIO按键中断的代码

2,准备数据,输出数据的内容

3,start信号0->1->0;

4,等待中断,当有中断后输出结果

int main()

{

//中断初始化等

...

Xil_DCacheDisable();

//准备数据

//对图像进行旋转

int m_Angle=-15;

double angle=-m_Angle*pi/180;//15度

double cosa=0.990;//0.965;//cos(angle);

double sina=0.139;//0.258;//sin(angle);

int m_CentX =360;//360;

int m_CentY =160;//160;

int m_Width =600;

int m_Height=300;

//=====================

memset(imgdata2,0,12);

imgdata2[0] = m_CentX%256;

imgdata2[1] = m_CentX/256;

imgdata2[2] = m_CentY%256;

imgdata2[3] = m_CentY/256;

imgdata2[4] = m_Width%256;

imgdata2[5] = m_Width/256;

imgdata2[6] = m_Height%256;

imgdata2[7] = m_Height/256;

imgdata2[8] = (int)((int)(sina*1000)%256);

imgdata2[9] = (int)((int)(sina*1000)/256);

imgdata2[10]= (int)((int)(cosa*1000)%256);

imgdata2[11]= (int)((int)(cosa*1000)/256);

for(i=0;i<IMAGE_W*IMAGE_H;i++)

{

Xil_Out8(0x10000000+i, imgdata2[i]);

}

printf("start\r\n");

//等待中断

key_val = 1;

XGpioPs_WritePin(&gpio, LED, key_val);//输出LED灯效果

usleep(20);

key_val = 0;

XGpioPs_WritePin(&gpio, LED, key_val);//输出LED灯效果

//中断触发时,key_press为TURE,延时一段时间后判断按键是否按下,是则反转LED

while (1)

{

if (key_press)

{

usleep(100);

if (XGpioPs_ReadPin(&gpio, KEY) == 0)

{

//打印图片

for(j=0;j<RImg_H/2;j++)//RImg_H/2

{

for(i=0;i<RImg_W/2;i++)

{ printf("%d,",(int)( Xil_In8(0x10000000+IMAGE_W*IMAGE_H+j*RImg_W/2+i)));

}

printf("\r\n");

}

}

key_press = FALSE;

XGpioPs_IntrClearPin(&gpio, KEY); //清除按键KEY中断

XGpioPs_IntrEnablePin(&gpio, KEY); //使能按键KEY中断

}

}

return XST_SUCCESS;

}

时间测试运行时间约100um(还要进一步测试)

运行效果

原图:

输出数据:

结论:

通过HLS制作图像旋转的IP核可以将图像旋转功能实现,同时也可以满足速度要求。

参考书目:

  1. 领航者ZYNQ开发板视频盘(D盘) 65_AXI4读写DDR测试实验

  1. 领航者ZYNQ开发板视频盘(D盘) 13_GPIO之EMIO按键控制LED实验_程序设计

  1. 哔站:Vivado HLS 基本应用与图像处理

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
HLS(Hardware Description Language)图像跟踪算法开发是指使用硬件描述语言来开发图像跟踪算法。 图像跟踪算法是计算机视觉领域的重要研究方向,其目标是通过对连续图像序列的分析和处理,跟踪目标的运动轨迹。在HLS环境中进行图像跟踪算法开发,可以将算法直接部署在可编程逻辑器件(如FPGA)上,提供实时的图像处理性能。 在HLS图像跟踪算法开发中,首先需要选取适合的图像跟踪算法,例如基于特征的方法(如Harris角点检测算法、SIFT特征匹配算法等)、基于模型的方法(如卡尔曼滤波器、粒子滤波器等)等。然后,使用硬件描述语言(如VHDL、Verilog)对选定的图像跟踪算法进行建模和实现。 在建模过程中,需要将算法的各个模块转化为适合HLS环境的硬件描述语言表示形式,并根据算法的需求进行相应的优化。例如,对于计算密集型的算法,可以利用并行计算和流水线技术实现高效的硬件加速。在优化过程中,还需要考虑资源利用效率和功耗消耗等因素,以提高整体系统性能。 完成建模和优化后,将硬件描述语言代码综合为目标平台上的逻辑电路。然后,进行功能验证和性能测试,确保图像跟踪算法在HLS环境下的正确性和高效性。 总而言之,HLS图像跟踪算法开发利用硬件描述语言将选定的图像跟踪算法实现为硬件电路,提供实时的图像处理能力。这种方法能够在保证算法功能的情况下,显著提升图像处理性能,适用于各种实时图像跟踪应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hunter高

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值