本文主要是介绍基于opencv SGBM的双目深度图提取在FPGA上的实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
代码分享于github: https://github.com/tishi43/sgbm
主要包含以下部分:
line_buffer_8row.sv, 从ddr读左图和右图,缓存8行,为什么8行,5x5的cost加窗运算最多要7行图像,此7行用来输出,另一行用来从ddr读入。
calc_bt_cost.sv,代价计算,正向的代价计算,从x=minD开始到width-1,反向的代价计算,从x=width-1开始,计算到x=minD,为什么要反向,右左方向代价聚合时,是从最右边开始的,
sgbm_aggr_down.sv,sgbm_aggr_down_left.sv,sgbm_aggr_right_left.sv
5个方向的代价聚合,sgbm_aggr_down_left复用了down right和down left两个方向的代价聚合,目的是为了省一些资源,
sgbm_aggr_right_left复用了左右和右左方向的代价聚合。
sgbm.sv 顶层文件,也包含其它处理,包括唯一性检测,左右一致性检测,输出结果到ddr。
最长的路径来自左右和右左聚合,左右和右左聚合因为后一点的计算需要用到前一点的最小值,所以不能pipeline,只能1周期算完,有一个128个cost求最小值minLr,Logic level达到44级.
Max Delay Paths--------------------------------------------------------------------------------------Slack: infSource: i_P1[1](input port)Destination: sgbm_aggr_right_left_inst/Delta_reg[9]_rep/DPath Group: (none)Path Type: Max at Slow Process CornerData Path Delay: 15.836ns (logic 6.617ns (41.782%) route 9.219ns (58.218%))Logic Levels: 44 (CARRY4=21 IBUF=1 LUT2=2 LUT3=4 LUT4=4 LUT5=2 LUT6=10)Location Delay type Incr(ns) Path(ns) Netlist Resource(s)------------------------------------------------------------------- -------------------0.000 0.000 r i_P1[1] (IN)net (fo=0) 0.000 0.000 i_P1[1]r i_P1_IBUF[1]_inst/IIBUF (Prop_ibuf_I_O) 0.606 0.606 r i_P1_IBUF[1]_inst/Onet (fo=473, unplaced) 0.419 1.025 sgbm_aggr_right_left_inst/i_P1_IBUF[1]r sgbm_aggr_right_left_inst/ram_reg_46_i_95/I1LUT2 (Prop_lut2_I1_O) 0.043 1.068 r sgbm_aggr_right_left_inst/ram_reg_46_i_95/Onet (fo=1, unplaced) 0.000 1.068 sgbm_aggr_right_left_inst/ram_reg_46_i_95_n_0r sgbm_aggr_right_left_inst/ram_reg_46_i_53/S[1]CARRY4 (Prop_carry4_S[1]_CO[3])0.256 1.324 r sgbm_aggr_right_left_inst/ram_reg_46_i_53/CO[3]net (fo=1, unplaced) 0.007 1.331 sgbm_aggr_right_left_inst/ram_reg_46_i_53_n_0r sgbm_aggr_right_left_inst/ram_reg_46_i_69/CI
这个算法最大的问题是ram的消耗量,以1280x960,disp range 128来计算,4个方向的代价聚合,每个方向需要存1280 * 128 * cost_bits,
这里cost_bits 是每方向聚合后的结果需要的bit数,算12bit,所以一个方向需要1280 * 128 * 12=1966080 bits, 4个方向需要,4 * 1966080 =7864320 bits, 约等于1MB的ram。
如果中间数据放ddr,每帧数据对ddr会产生1280*960*128*12*4= 7549747200 bits,约等于7Gbits,的读写,按照每秒30帧来算,需要占210Gbits约等于26GBytes的ddr读写带宽,这个带宽对于实际系统来说是一个很大的带宽。
这里的代价计算使用了5个calc_bt_cost模块同时算,这样每次加窗计算(window cost), 把这5个calc_bt_cost的计算结果相加,
按照正常的算法,是需要缓存一行window cost,计算最新一行的window cost是缓存的window cost+最新行的cost-最老行的cost,这样又需要1个1280 * 128 * 12bit的大缓存,这里5个calc_bt_cost仅仅是为了省一个大的缓存。
这写都是按照默认blocksize=5来设计的,如果blocksize可配,那这一个大的缓存也是省不的。
起初设计的时候用了10个calc_bt_cost, 5个反向bt cost来求右左方向的聚合,右左方向的聚合比左右和其它三个方向的提前一行算,这样算左右和右左并行。综合下来LUT直接超了1倍,改成5个calc_bt_cost先算右左,再算左右,这样速度降一半,资源还是超很多,后面又经过很多资源上的优化。
这篇关于基于opencv SGBM的双目深度图提取在FPGA上的实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!