0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

优秀的IC/FPGA开源项目:伪红外图像处理

OpenFPGA 来源:OpenFPGA 2023-06-09 09:42 次阅读

红外图像处理

副标题:优秀的IC/FPGA开源项目(七)-伪红外图像处理

《优秀的IC/FPGA开源项目》是新开的系列,旨在介绍单一项目,会比《优秀的 Verilog/FPGA开源项目》内容介绍更加详细,包括但不限于综合、上板测试等。两者相辅相成,互补互充~

演示伪红外图像处理。

介绍

红外摄像机因为对可见光不敏感,所以在一些特殊行业应用越来越广泛。

红外摄像机甚至可以透过太阳镜看到人眼,并且摄像机图像不受白天或夜晚的影响,并且几乎没有环境光。

因为真正的红外sensor价格比较昂贵,所以这次选用一种伪红外sensor,即利用相机自己的光源,即安装在镜头旁边的 LED,反射红外光后进项图像采集,这是一种利用近红外成像,和我们熟知的红外摄像头还是有区别的。

502858a0-0297-11ee-90ce-dac502259ad0.png

该项目展示了一些红外图像处理算法,这些算法可以提高图像质量。

所选FPGA是 ZYNQ-020 SoC,摄像头是便宜的 Raspberry PI 摄像头,带有两个红外 LED,最大分辨率为 1080p@60Hz。

该项目中呈现的体系结构是可扩展的,可以轻松添加更多算法。

理论

我选择了五种基于 3x3 内核的图像处理算法:

坏点校正

50326fca-0297-11ee-90ce-dac502259ad0.png

这是所有这类传感器的普遍问题,是一种常见的预处理算法。

中值滤波器

503e2d60-0297-11ee-90ce-dac502259ad0.png

常见的噪声平滑预处理算法。

低通滤波器(平滑滤波器)

504928e6-0297-11ee-90ce-dac502259ad0.png

噪声平滑,这个算法使图像平滑,不会像中值滤波器那样使图像模糊。

图像锐化

50518a54-0297-11ee-90ce-dac502259ad0.png

通过“边缘锐化”提高图像质量,即强调边缘。

边缘检测

5059e406-0297-11ee-90ce-dac502259ad0.png

应用其中一种算法后,对图像边缘处理后,图像尺寸会减小(可选)。

506315bc-0297-11ee-90ce-dac502259ad0.png

架构

所有算法都基于 3x3 内核,这就是为什么所有算法内核 (PE) 都必须与 FIFO 通信,每个 PE 都有一行的延迟。只有当第二行数据到达时才开始应用算法内核,考虑到图像处理时候会对边界有影响,但是我们需要输出端输出相同的图像大小。

506e5260-0297-11ee-90ce-dac502259ad0.png 架构 507936ee-0297-11ee-90ce-dac502259ad0.png

选择模块是一个可扩展的 MUX 网络,在上图情况下,具有五个图像处理算法,由六个级联的 MUX-es 组成,一个用于滤波器输出,一个用于输入信号。数据流可以配置,在这种情况下,视频流从输入到输出,它通过的图像处理元素的顺序和数量是可配置的。

算法内核的结构如下所示,基本上在这种情况下是一个延迟线,它以视频流作为输入并输出一个 3x3 矩阵,输出是处理后的帧。

50903ede-0297-11ee-90ce-dac502259ad0.png

设计

在该架构中,我在 VDMA 和 Gamma Correction 模块之间插入了我的模块。

50a03690-0297-11ee-90ce-dac502259ad0.png50ac9796-0297-11ee-90ce-dac502259ad0.png

我为每个行缓冲区添加了一个 FIFO。

接口

所有模块都使用规定好的帧接口 (FI),它与参考设计中使用的 AXI Stream 接口非常相似(https://reference.digilentinc.com/learn/programmable-logic/tutorials/zybo-z7-pcam-5c-demo/start),可以在两者之间进行转换。从 AXI Stream 到 Frame 不需要转换,反之则必须生成一些额外的信号。AXI Stream 接口只有帧开始和行结束控制信号。

50b642f0-0297-11ee-90ce-dac502259ad0.png

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 并将逻辑分析仪连接到焊线,我按照相机接口指南

https://projects.raspberrypi.org/en/projects/getting-started-with-picamera

逻辑分析仪解码了I2C,抓取的值将在最后附上excel。

50c4f34a-0297-11ee-90ce-dac502259ad0.png

该配置已添加到 C++ 代码中。

摄像头是 RGB 摄像头,只有在房间黑暗时才会启动红外摄像头。为了解决这个问题,我在sensor前面粘上了一块塑料,这是红外 LED 前面的过滤器。这不是一个很好的解决方案,但可以。

配置模块

使用 APB 接口进行配置。

511d8d20-0297-11ee-90ce-dac502259ad0.png

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);
}

上面给出的配置是每个选择器模块的选择。现在它被配置为输入流不进行任何处理的情况下转到输出。

512b0d92-0297-11ee-90ce-dac502259ad0.png

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);

将输入视频流放入算法核心。

51352656-0297-11ee-90ce-dac502259ad0.png

演示

我展示了带平滑和不带平滑的拉普拉斯滤波器,我们可以观察到图像有噪声,应用平滑滤波器后图像有所变化。

为了比较原始图像和处理后的两个图像,在 Gamma 校正之后添加了第二个 VDMA,,现在校正后的图像和原始图像都在 DDR 中,因此可以复制裁剪处理后的图像并将裁剪区域替换为原始图像。

工程链接

I2C 解码的 csv

https://github.com/hszilard13/Infa-red-based-Image-processing-Zybo/blob/master/config_1080p_rgb.csv

整体工程

https://github.com/hszilard13/Infared-based-Image-processing-Zybo

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1602

    文章

    21320

    浏览量

    593195
  • led
    led
    +关注

    关注

    237

    文章

    22449

    浏览量

    645878
  • 光源
    +关注

    关注

    3

    文章

    619

    浏览量

    67440
  • 图像处理
    +关注

    关注

    26

    文章

    1224

    浏览量

    55823
  • I2C
    I2C
    +关注

    关注

    28

    文章

    1346

    浏览量

    120816

原文标题:工程链接

文章出处:【微信号:Open_FPGA,微信公众号:OpenFPGA】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    DSP+FPGA+ASIC设计的实时红外图像处理系统

    1.引言 本文针对红外图像处理系统的实时性要求,提出了基于DSP+FPGA+ASIC的图像处理
    发表于 07-22 15:18 809次阅读

    开源FPGA项目有哪些

    请问开源FPGA项目有哪些?
    发表于 12-26 12:09

    公司项目外包:图像处理FPGA实现)

    本公司有个项目需要寻找外援,价格面谈大概要求:高清网络摄像机采集到的图像是原始图像(贝尔模式下的RGB即CFA模式)经过转换处理成普通的RGB(需在
    发表于 12-07 10:16

    怎么设计多DSP红外实时图像处理系统?

    随着红外探测技术迅猛的发展,当今红外实时图像处理系统所要处理的数据量越来越大,速度要求也越来越快,利用目前主流的单DSP+
    发表于 08-23 08:29

    如何设计多DSP红外实时图像处理系统?

    随着红外探测技术迅猛的发展,当今红外实时图像处理系统所要处理的数据量越来越大,速度要求也越来越快,利用目前主流的单DSP+
    发表于 11-08 06:31

    FPGA开发者项目连载】基于FPGA红外激光图像采集及显示

    项目名称:基于FPGA红外激光图像采集及显示应用领域:医疗,工业相机,商业图像处理参赛计划:将
    发表于 05-12 18:02

    基于FPGA红外图像处理系统及算法设计

    本文在研究红外焦平面阵列非均匀性的特点和成因后,首先设计了红外图像实时处理的硬件平台。本硬件平台以FPGA为核心
    发表于 05-17 14:29 5次下载

    基于FPGA的多功能红外图像源系统设计

    基于FPGA的多功能红外图像源系统设计。
    发表于 08-30 15:10 9次下载

    FPGA图像处理

    FPGA图像处理
    发表于 12-14 22:29 18次下载

    如何使用DSP和FPGA实现红外图像锐化算法的实现

    为了改善红外图像的成像质量,根据红外图像的特点,提出了一种改进的拉普拉斯锐化算法——受限拉普拉斯锐化算法,并采用DSP+FPGA的架构进行实
    发表于 01-25 16:04 6次下载
    如何使用DSP和<b class='flag-5'>FPGA</b>实现<b class='flag-5'>红外</b><b class='flag-5'>图像</b>锐化算法的实现

    FPGA中如何使用Verilog处理图像

    FPGA项目旨在详细展示如何使用Verilog处理图像,从Verilog中读取输入位图图像(.bmp),
    的头像 发表于 09-23 15:50 5247次阅读

    优秀的 Verilog/FPGA开源项目介绍(一)

    优秀的 Verilog/FPGA开源项目介绍(一)-PCIe通信 今天开始会陆续介绍一些优秀开源
    的头像 发表于 10-11 15:31 8541次阅读
    <b class='flag-5'>优秀</b>的 Verilog/<b class='flag-5'>FPGA</b><b class='flag-5'>开源</b><b class='flag-5'>项目</b>介绍(一)

    优秀的 Verilog/FPGA开源项目之 USB通信

    优秀的 Verilog/FPGA开源项目介绍(五)- USB通信 USB是我们生活中非常非常常见的接口,鼠标、键盘以及常见的U 盘等,可以说现在的USB设备已经渗透到生活中的方方面面,
    的头像 发表于 11-02 14:54 7990次阅读
    <b class='flag-5'>优秀</b>的 Verilog/<b class='flag-5'>FPGA</b><b class='flag-5'>开源</b><b class='flag-5'>项目</b>之 USB通信

    TTL FPGA开源项目

    电子发烧友网站提供《TTL FPGA开源项目.zip》资料免费下载
    发表于 07-28 10:18 3次下载
    TTL <b class='flag-5'>FPGA</b><b class='flag-5'>开源</b><b class='flag-5'>项目</b>

    优秀IC/FPGA开源项目(二)-NetFPGA

    从上面的工作可以看出DPU的核心是:网络。所以我们今天讲一个未来的发展核心之一:用FPGA实现NIC(network interface controller,网络接口控制器),从该项目出发可以实现数据可控制化,进而实现DPU功能。
    的头像 发表于 05-19 11:11 2173次阅读
    <b class='flag-5'>优秀</b>的<b class='flag-5'>IC</b>/<b class='flag-5'>FPGA</b><b class='flag-5'>开源</b><b class='flag-5'>项目</b>(二)-Net<b class='flag-5'>FPGA</b>