介绍
红外摄像机因为对可见光不敏感,所以在一些特殊行业应用越来越广泛。
红外摄像机甚至可以透过太阳镜看到人眼,并且摄像机图像不受白天或夜晚的影响,并且几乎没有环境光。
因为真正的红外sensor价格比较昂贵,所以这次选用一种伪红外sensor,即利用相机自己的光源,即安装在镜头旁边的 LED,反射红外光后进项图像采集,这是一种利用近红外成像,和我们熟知的红外摄像头还是有区别的。
该项目展示了一些红外图像处理算法,这些算法可以提高图像质量。
所选FPGA是 ZYNQ-020 SoC,摄像头是便宜的 Raspberry PI 摄像头,带有两个红外 LED,最大分辨率为 1080p@60Hz。
该项目中呈现的体系结构是可扩展的,可以轻松添加更多算法。
理论
我选择了五种基于 3x3 内核的图像处理算法:
坏点校正
这是所有这类传感器的普遍问题,是一种常见的预处理算法。
中值滤波器
常见的噪声平滑预处理算法。
低通滤波器(平滑滤波器)
噪声平滑,这个算法使图像平滑,不会像中值滤波器那样使图像模糊。
图像锐化
通过“边缘锐化”提高图像质量,即强调边缘。
边缘检测
应用其中一种算法后,对图像边缘处理后,图像尺寸会减小(可选)。
架构
所有算法都基于 3x3 内核,这就是为什么所有算法内核 (PE) 都必须与 FIFO 通信,每个 PE 都有一行的延迟。只有当第二行数据到达时才开始应用算法内核,考虑到图像处理时候会对边界有影响,但是我们需要输出端输出相同的图像大小。
架构
选择模块是一个可扩展的 MUX 网络,在上图情况下,具有五个图像处理算法,由六个级联的 MUX-es 组成,一个用于滤波器输出,一个用于输入信号。数据流可以配置,在这种情况下,视频流从输入到输出,它通过的图像处理元素的顺序和数量是可配置的。
算法内核的结构如下所示,基本上在这种情况下是一个延迟线,它以视频流作为输入并输出一个 3x3 矩阵,输出是处理后的帧。
设计
在该架构中,我在 VDMA 和 Gamma Correction 模块之间插入了我的模块。
我为每个行缓冲区添加了一个 FIFO。
所有模块都使用规定好的帧接口 (FI),它与参考设计中使用的 AXI Stream 接口非常相似(https://reference.digilentinc.com/learn/programmable-logic/tutorials/zybo-z7-pcam-5c-demo/start),可以在两者之间进行转换。从 AXI Stream 到 Frame 不需要转换,反之则必须生成一些额外的信号。AXI Stream 接口只有帧开始和行结束控制信号。
moduleaxi_stream2frame#( parameterDATA_WIDTH=24 )( inputclk,//Systeclock inputrst_n,//Asynchronousresetactivelow //-------------------------Configurationinterface---------------------------------- input[11:0]cfg_img_w,//Imagewidth input[11:0]cfg_img_h,//Imagewidth //-------------------------AXI-Streaminterface------------------------------------- inputm_axi_stream_tuser,//Startofframe inputm_axi_stream_tvalid,//Slavehasvaliddata inputm_axi_stream_tlast,//Endofframe input[DATA_WIDTH-1:0]m_axi_stream_tdata,//Datatransferred outputm_axi_stream_tready,//Masterisreadytoreceive //------------------------------FrameInterface----------------------------------- outputregs_frm_val,//Masterhasvaliddata inputs_frm_rdy,//Slaveisreadytoreceive outputreg[DATA_WIDTH-1:0]s_frm_data,//Datatransferred outputregs_frm_sof,//StartofFrame outputregs_frm_eof,//EndofFrame outputregs_frm_sol,//StartofLine outputregs_frm_eol//EndofLine ); reg[11:0]pix_cnt; reg[11:0]line_cnt; wireinvalrdy; wireoutvalrdy; wireset_eof; assigninvalrdy=m_axi_stream_tvalid&m_axi_stream_tready; assignoutvalrdy=s_frm_rdy&s_frm_val; assignm_axi_stream_tready=s_frm_rdy; assignset_eof=(line_cnt==(cfg_img_h-1'd1))&m_axi_stream_tlast&invalrdy; always@(posedgeclkornegedgerst_n) if(~rst_n)pix_cnt<= 11'd0 ; else if(m_axi_stream_tuser & invalrdy ) pix_cnt <= 11'd0 ; else // Reset at start of frame if(m_axi_stream_tlast & invalrdy ) pix_cnt <= 11'd0 ; else // Reset at end of frame if(invalrdy ) pix_cnt <= pix_cnt + 1'd1; // Increment at each pixel always@(posedge clk or negedge rst_n) if(~rst_n ) line_cnt <= 11'd0 ; else if(m_axi_stream_tuser & invalrdy) line_cnt <= 11'd0 ; else // Reset at start of frame if(m_axi_stream_tlast & invalrdy) line_cnt <= line_cnt + 1'd1; // Increment at each pixel always@(posedge clk or negedge rst_n) if(~rst_n ) s_frm_sol <= 1'b0; else if(outvalrdy & s_frm_sol ) s_frm_sol <= 1'b0; else // Reset sol is transmitted if(m_axi_stream_tuser & invalrdy ) s_frm_sol <= 1'b1; else // Set start of line after last pixel of line is transmitted if(outvalrdy & s_frm_eol & (~s_frm_eof)) s_frm_sol <= 1'b1; // Set at start of frame always@(posedge clk or negedge rst_n) if(~rst_n ) s_frm_eof <= 1'b0; else if(outvalrdy & s_frm_eof) s_frm_eof <= 1'b0; else // Reset after eof is transmitted if(set_eof ) s_frm_eof <= 1'b1; // Set when last pixel is received always@(posedge clk or negedge rst_n) if(~rst_n ) s_frm_val <= 1'b0; else if(s_frm_rdy & (~m_axi_stream_tvalid)) s_frm_val <= 1'b0; else // Reset when ready and no valid data at the input if(invalrdy ) s_frm_val <= 1'b1; // Set if data is received always@(posedge clk or negedge rst_n) if(~rst_n ) s_frm_eol <= 1'b0; else if(outvalrdy & s_frm_eol ) s_frm_eol <= 1'b0; else // Reset after eol is transmitted if(m_axi_stream_tlast & invalrdy) s_frm_eol <= 1'b1; // Set when last pixel in a row is received always@(posedge clk or negedge rst_n) if(~rst_n ) s_frm_sof <= 1'b0; else if(outvalrdy & s_frm_sof ) s_frm_sof <= 1'b0; else // Reset after sof is transmitted if(m_axi_stream_tuser & invalrdy) s_frm_sof <= 1'b1; // Set when first pixel is received always@(posedge clk or negedge rst_n) if(~rst_n ) s_frm_data <= {(DATA_WIDTH){1'b0}}; else if(invalrdy) s_frm_data <= m_axi_stream_tdata ; endmodule //axi_stream2Frame
配置sensor
这个摄像头是搭配树莓派使用的,所有驱动都是闭源的,所以没有配置示例。我在 SCL 和 SDA 引脚上的 I2C 引脚上焊接了两根电线。将相机连接到 Raspeberry Pi 并将逻辑分析仪连接到焊线,我按照相机接口指南
逻辑分析仪解码了I2C,抓取的值将在最后附上excel。
该配置已添加到 C++ 代码中。
摄像头是 RGB 摄像头,只有在房间黑暗时才会启动红外摄像头。为了解决这个问题,我在sensor前面粘上了一块塑料,这是红外 LED 前面的过滤器。这不是一个很好的解决方案,但可以。
配置模块
使用 APB 接口进行配置。
voidfilter_cfg() { Xil_Out32(APB_BASE_ADDR+CFG_IMG_WIDTH_ADDR,IMG_W); Xil_Out32(APB_BASE_ADDR+CFG_IMG_HEIGHT_ADDR,IMG_H); Xil_Out32(APB_BASE_ADDR+CFG_PIX_CORR_SEL_ADDR,0); Xil_Out32(APB_BASE_ADDR+CFG_SHARP_SEL_ADDR,0); Xil_Out32(APB_BASE_ADDR+CFG_SMOOTH_SEL_ADDR,0); Xil_Out32(APB_BASE_ADDR+CFG_MEDIAN_SEL_ADDR,0); Xil_Out32(APB_BASE_ADDR+CFG_LAPLACE_SEL_ADDR,0); Xil_Out32(APB_BASE_ADDR+CFG_OUTPUT_SEL_ADDR,0); Xil_Out32(APB_BASE_ADDR+CFG_PIX_CORR_THR_ADDR,0); Xil_Out32(APB_BASE_ADDR+CFG_SHARP_COEF_ADDR,0); Xil_Out32(APB_BASE_ADDR+CFG_TEST_MODE_EN_ADDR,0); }
上面给出的配置是每个选择器模块的选择。现在它被配置为输入流不进行任何处理的情况下转到输出。
voidfilter_cfg() { Xil_Out32(APB_BASE_ADDR+CFG_IMG_WIDTH_ADDR,IMG_W); Xil_Out32(APB_BASE_ADDR+CFG_IMG_HEIGHT_ADDR,IMG_H); Xil_Out32(APB_BASE_ADDR+CFG_PIX_CORR_SEL_ADDR,0); Xil_Out32(APB_BASE_ADDR+CFG_SHARP_SEL_ADDR,0); Xil_Out32(APB_BASE_ADDR+CFG_SMOOTH_SEL_ADDR,SMOOTH_IN_CODE); Xil_Out32(APB_BASE_ADDR+CFG_MEDIAN_SEL_ADDR,0); Xil_Out32(APB_BASE_ADDR+CFG_LAPLACE_SEL_ADDR,SMOOTH_IN_CODE); Xil_Out32(APB_BASE_ADDR+CFG_OUTPUT_SEL_ADDR,LAPLACE_IN_CODE); Xil_Out32(APB_BASE_ADDR+CFG_PIX_CORR_THR_ADDR,0); Xil_Out32(APB_BASE_ADDR+CFG_SHARP_COEF_ADDR,0); Xil_Out32(APB_BASE_ADDR+CFG_TEST_MODE_EN_ADDR,0); } Xil_Out32(APB_BASE_ADDR+CFG_SMOOTH_SEL_ADDR,SMOOTH_IN_CODE);
将输入视频流放入算法核心。
演示
我展示了带平滑和不带平滑的拉普拉斯滤波器,我们可以观察到图像有噪声,应用平滑滤波器后图像有所变化。
为了比较原始图像和处理后的两个图像,在 Gamma 校正之后添加了第二个 VDMA,,现在校正后的图像和原始图像都在 DDR 中,因此可以复制裁剪处理后的图像并将裁剪区域替换为原始图像。
审核编辑:刘清
-
FPGA
+关注
关注
1625文章
21639浏览量
601355 -
led
+关注
关注
240文章
23089浏览量
657354 -
滤波器
+关注
关注
160文章
7712浏览量
177519 -
红外摄像机
+关注
关注
1文章
18浏览量
8794 -
Raspberry Pi
+关注
关注
1文章
557浏览量
22151
原文标题:工程链接
文章出处:【微信号:Open_FPGA,微信公众号:OpenFPGA】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论