FPGA视觉从入门到放弃——灰度直方图提取
一.贴士
1.系统寄存器sysreg0相同的1位线:collect_enable,FPGA_A_DSP_B,DSP_reset_FPGA;
2.系统寄存器相同的16位线:pix_num_threshold,crmaxmin,cbmaxmin。
3.连接系统寄存器的线通常用于设置参数,这里用于设置矩形框的位置。
二.FPGA代码分析——直方图提取
1.直方图提取相比高斯滤波在Camera_AB.v中的区别
除了系统寄存器相同的线,包括10位线upper_border,lower_border,left_border和right_border。
高斯滤波中只有save_Y模块,保存360*288大小的图像;直方图提取顺便包括save_Cb模块和save_Cr模块,保存相同大小的图像。
添加17位线ram_read_data和ram_write_data。
添加1位线ram_write_enable。
添加8位线ram_addr。
问题:SRAM有8个数据位,对应ram_addr才对;每个SRAM有512K=2^17的容量,每个字节数据应该对应1个地址,所以17位地址线对应ram_read_data和ram_write_data。从变量名上看,地址和数据的变量定义应该互换来避免歧义。
RAM_17bits_256depth模块存储灰度像素的直方图。
computer_histogram模块产生灰度像素直方图。
SAVEADDR_hist_lower_9bits(19h'20000)和SAVEADDR_hist_upper_9bits(19h'20100)的类型为parameter,小白我直接把该类型理解为常数项。两者间隔0x100,说明像素计数值的低9位和高9位的地址范围为0-255(2^8),即 共有256个像素值索引。
问题:DCFIFO_512depth怎么创建的?
应该是Quartus软件自带的megafunction(菜单tools=>MegaWizard Plugin Manager)中创建的。
write_to_FIFO_flag为开始写入FIFO的标志位,该位有效时,tempo(2位寄存器)置1。
tempo为0时,ram_addr_count的低8位给ram_addr,ram_addr_count加1。
tempo为3时,如果ram_addr为255时,停止写入FIFO。
问题:ram_rad_data高8位赋值给hist_upper_9bits是什么语法?
hist_lower_9bits选择ram_read_data的低9位,而ram_read_data为17位线,所以hist_upper_9bits的最高位要补0。
tempo为3时,wrfull_hist_lower_9bits和wrfull_hist_upper_9bits(1位线)始终保持为1。
Y_flag_1c为Y_flag前1个时刻的状态,Y_flag_2c为Y_flag前2个时刻的状态;同理,VPO_Y_1c为VPO_in前1个时刻的灰度图像,VPO_Y_2c为VPO_in前2个时刻的图像。
Y_flag为1时,引入新的灰度像素点。如果row和col表示当前像素的横坐标和纵坐标。
Y_flag_1c为1时,row_x和row_y为上1个像素点的横坐标和纵坐标row和col。如果写入SRAM标志位write_to_ram_flag为1时,先清0该标志位,并使能写入SRAM标志位ram_write_enable, ram_write_data为ram_read_data加1。
Y_flag_2c为1时,失能写入SRAM标志位。如果上上1个像素的横纵坐标在矩形框内,则把VPO_Y_2c赋给ram_addr,使能写入SRAM标志位。如果在矩形框外,ram_addr清0,失能写入SRAM标志位。
本质上应该是 分3条流水线,把VPO_Y赋值给ram_addr。ram_addr为灰度直方图的整数像素索引(0-255),ram_write_data为像素的统计值。
问题:ram_write_data真的是像素统计值么?
ram_write_data是computer_histogram模块的 17位寄存器输出(360*288=103680<131072=2^17)。ram_write_data以RAM_17bits_256depth模块为输入写进SRAM。这个RAM_17bits_256depth模块数据是双向传输的,因为没有其它地方读数据到ram_read_data。
DCFIFO_512depth模块用于对SRAM读写hist_lower_9bits和hist_upper_9bits(?)。
//=============================================================================
三.DSP代码分析——直方图提取
1.get_360x288_gray_image()
从capYbuffer为开头的地址读取灰度图像Y_data。
2.get_histogram()
HISTOGRAM_LOWER_9BITS_ADDR为0xA0040000,FPGA_addr2暂存低9位直方图值的地址,每个值占16位。
HISTOGRAM_UPPER_9BITS_ADDR为0xA0040200,FPGA_addr2同样暂存,拼接出第i个像素值的完整17位计数值histogram[i]。
3.set_borders()
UPPER_BORDER_ADDR为0xB000006A;LOWER_BORDER_ADDR为0xB000006C;LEFT_BORDER_ADDR为0xB000006E;RIGHT_BORDER_ADDR为0xB0000070。
边界数据应该是16位的,占2个字节。
upper_bound,lower_bound,left_bound和right_bound用于设置边界的值给FPGA。然后draw_line()填充Y_data的边界框,再把图像发给主机。
四.主机与DSP通信——直方图提取
发送边界参数:500xFF upper_bound lower_bound left_bound right_bound。
五.实验结果
左图为原灰度图像和所选矩形框,右图为矩形框中的灰度直方图。
忘记修改FPGA引脚的结果
修改引脚后的结果