基于FPGA的双目相机目标深度图像提取实现——简略版

目录

一、理论基础

二、核心程序

三、测试结果


一、理论基础

       基于FPGA的双目相机目标深度图像提取实现是一种利用双目视觉原理来获取目标深度信息的技术。其基本原理是通过对双目相机获取的图像进行一系列处理,包括图像校正、立体匹配和深度获取等步骤,来得到目标的深度信息。

       双目视觉是通过两个相机从不同的角度同时拍摄同一目标,然后根据相机之间的几何关系以及拍摄时的光学参数,将两个图像进行匹配和计算,得到目标的深度信息。其基本原理可以用以下公式表示:

Z = f * (u2 - u1) / (p2 - p1)

      其中,Z为目标深度,f为双目相机的焦距,(u1, p1)和(u2, p2)分别为左右相机拍摄的图像中目标在水平和垂直方向上的像素坐标。

      在实际应用中,由于双目相机拍摄的图像存在差异,需要进行图像校正,使得两个图像在水平和垂直方向上对齐。然后,通过立体匹配算法,将两个图像中相同的目标点匹配起来,得到视差d。视差与目标深度成反比,即视差越大,目标深度越小。最后,根据视差和相机的几何关系,可以计算出目标的深度信息。

       基于FPGA的双目相机目标深度图像提取实现具有实时性和并行处理的优势。FPGA具有高效的并行计算能力和高度可配置的硬件资源,可以大大加速图像处理和计算密集型任务。同时,基于FPGA的实现还可以降低功耗和成本,适合于嵌入式和移动应用等对功耗和体积要求较高的场景。

      在实际应用中,基于FPGA的双目相机目标深度图像提取实现需要优化算法和硬件设计,以提高实时性和精度。例如,使用局部匹配算法来减小计算量和提高匹配速度,利用GPU加速立体匹配和深度计算等。此外,还需要考虑相机硬件参数的标定、图像质量、光照条件等因素对目标深度信息提取的影响。

        总之,基于FPGA的双目相机目标深度图像提取实现是一种有效的技术,可以实现对目标深度信息的快速、高精度获取。它在机器人视觉、自动化检测、三维重建等领域具有广泛的应用前景。


系统的整体框架结构如下图所示:

       双目立体视觉模拟了人类双眼感知环境的方式其结构如图2-1所示,主要包括图像采集、摄像机表达、图像校正、立体匹配、及深度获取等五部分构成。


      为了使得双目立体视觉能够走出实验室进入到实际应用中,研究者们在优化双目立体视觉系统实时性方面做了许多努力。在这些工作中有一些是基于资源受限的平台如FPGA、DSP或者ASIC等,它们都具有良好的并行计算的能力,并且使用T兼容性很好的局部匹配算法,但是它们的设计都十分复杂,并且具有较长的开发周期。而一些最近的研究确信FPGA是目前较为适合硬件开发的平台P41。在早期的研究中,大部分基于FPGA的平台为了满足实时性W及嵌入式应用的需求,大都使用原理较为简单的基于SAD的算法。而对于PC平台来说,即使是最简单的SAD算法也是不可能满足实时性的需求。然而,对于硬件平台来说,算的速度W及资源的占用是设计的核也内容,而准确性却被忽视了。在这之后,随着立体视觉技术W及FPGA制造工艺技术的发展,越来越多的基于FPGA的平台涌现出来。这些平台使用了更新更有效的算法,但是大部分都没有进行准确性方面的实验和测试。

二、核心程序

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date:    18:11:17 06/08/2018 
// Design Name: 
// Module Name:    deep_image1 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//
module deep_image19(
                   FCLK_CLK0,
						 gpio_rtl_tri_o_0,
						 Edis0,
						 disparity0,
						 FIFO_M_AXIS_0_tdata,
						 FIFO_M_AXIS_1_tdata,
						 Edis1,
						 disparity1
	               );
 
input      FCLK_CLK0;
input      gpio_rtl_tri_o_0;
input[15:0]Edis0; 
input[15:0]disparity0; 
input[23:0]FIFO_M_AXIS_0_tdata;
input[23:0]FIFO_M_AXIS_1_tdata;
output[15:0]Edis1; 
output [15:0]disparity1; 
 
 
reg [7:0]R1;
reg [7:0]G1;                          
reg [7:0]B1; 
reg [7:0]Rdelay1;
reg [7:0]Gdelay1;                          
reg [7:0]Bdelay1;   
reg [7:0]Rdelay1a;
reg [7:0]Gdelay1a;                          
reg [7:0]Bdelay1a;  
reg [7:0]Rdelay1b;
reg [7:0]Gdelay1b;                          
reg [7:0]Bdelay1b;  
reg [7:0]Rdelay1c;
reg [7:0]Gdelay1c;                          
reg [7:0]Bdelay1c;  
reg [7:0]Rdelay1d;
reg [7:0]Gdelay1d;                          
reg [7:0]Bdelay1d;  
reg [7:0]Rdelay1e;
reg [7:0]Gdelay1e;                          
reg [7:0]Bdelay1e;  
reg [7:0]Rdelay1f;
reg [7:0]Gdelay1f;                          
reg [7:0]Bdelay1f;  
reg [7:0]Rdelay1g;
reg [7:0]Gdelay1g;                          
reg [7:0]Bdelay1g;  
reg [7:0]Rdelay1h;
reg [7:0]Gdelay1h;                          
reg [7:0]Bdelay1h;  
reg [7:0]Rdelay1i;
reg [7:0]Gdelay1i;                          
reg [7:0]Bdelay1i;  
reg [7:0]Rdelay1j;
reg [7:0]Gdelay1j;                          
reg [7:0]Bdelay1j; 
reg [7:0]Rdelay1k;
reg [7:0]Gdelay1k;                          
reg [7:0]Bdelay1k; 
reg [7:0]Rdelay1l;
reg [7:0]Gdelay1l;                          
reg [7:0]Bdelay1l; 
reg [7:0]Rdelay1m;
reg [7:0]Gdelay1m;                          
reg [7:0]Bdelay1m; 
reg [7:0]Rdelay1n;
reg [7:0]Gdelay1n;                          
reg [7:0]Bdelay1n; 
reg [7:0]Rdelay1o;
reg [7:0]Gdelay1o;                          
reg [7:0]Bdelay1o; 
reg [7:0]Rdelay1p;
reg [7:0]Gdelay1p;                          
reg [7:0]Bdelay1p; 
reg [7:0]Rdelay1q;
reg [7:0]Gdelay1q;                          
reg [7:0]Bdelay1q; 
reg [7:0]Rdelay1r;
reg [7:0]Gdelay1r;                          
reg [7:0]Bdelay1r; 
 
 
reg [7:0]Rdelay11;
reg [7:0]Gdelay11;                          
reg [7:0]Bdelay11;  
 
                     
always @(posedge FCLK_CLK0 or negedge gpio_rtl_tri_o_0)
begin
     if(!gpio_rtl_tri_o_0)
     begin
     R1     <= 8'd0;
     G1     <= 8'd0;
     B1     <= 8'd0;
     Rdelay1<= 8'd0;
     Gdelay1<= 8'd0;
     Bdelay1<= 8'd0; 
	  
     Rdelay1a<= 8'd0;
     Gdelay1a<= 8'd0;
     Bdelay1a<= 8'd0; 	  
     Rdelay1b<= 8'd0;
     Gdelay1b<= 8'd0;
     Bdelay1b<= 8'd0; 	
     Rdelay1c<= 8'd0;
     Gdelay1c<= 8'd0;
     Bdelay1c<= 8'd0; 	
     Rdelay1d<= 8'd0;
     Gdelay1d<= 8'd0;
     Bdelay1d<= 8'd0; 	
     Rdelay1e<= 8'd0;
     Gdelay1e<= 8'd0;
     Bdelay1e<= 8'd0; 	  
     Rdelay1f<= 8'd0;
     Gdelay1f<= 8'd0;
     Bdelay1f<= 8'd0; 		  
     Rdelay1g<= 8'd0;
     Gdelay1g<= 8'd0;
     Bdelay1g<= 8'd0; 		  
     Rdelay1h<= 8'd0;
     Gdelay1h<= 8'd0;
     Bdelay1h<= 8'd0; 		  
     Rdelay1i<= 8'd0;
     Gdelay1i<= 8'd0;
     Bdelay1i<= 8'd0; 	  
     Rdelay1j<= 8'd0;
     Gdelay1j<= 8'd0;
     Bdelay1j<= 8'd0; 	  
     Rdelay1k<= 8'd0;
     Gdelay1k<= 8'd0;
     Bdelay1k<= 8'd0; 		  	  
     Rdelay1l<= 8'd0;
     Gdelay1l<= 8'd0;
     Bdelay1l<= 8'd0; 	  
     Rdelay1m<= 8'd0;
     Gdelay1m<= 8'd0;
     Bdelay1m<= 8'd0; 		  
     Rdelay1n<= 8'd0;
     Gdelay1n<= 8'd0;
     Bdelay1n<= 8'd0; 		  
     Rdelay1o<= 8'd0;
     Gdelay1o<= 8'd0;
     Bdelay1o<= 8'd0; 		  
     Rdelay1p<= 8'd0;
     Gdelay1p<= 8'd0;
     Bdelay1p<= 8'd0; 		  
     Rdelay1q<= 8'd0;
     Gdelay1q<= 8'd0;
     Bdelay1q<= 8'd0; 	  
     Rdelay1r<= 8'd0;
     Gdelay1r<= 8'd0;
     Bdelay1r<= 8'd0; 	  
	  
     Rdelay11<= 8'd0;
     Gdelay11<= 8'd0;
     Bdelay11<= 8'd0;      
     end
else begin
     R1      <= FIFO_M_AXIS_0_tdata[23:16];
     G1      <= FIFO_M_AXIS_0_tdata[15:8];
     B1      <= FIFO_M_AXIS_0_tdata[7:0];
	  
	  
     Rdelay1 <= FIFO_M_AXIS_1_tdata[23:16];
     Gdelay1 <= FIFO_M_AXIS_1_tdata[15:8];
     Bdelay1 <= FIFO_M_AXIS_1_tdata[7:0];
	  
     Rdelay1a<= Rdelay1;
     Gdelay1a<= Gdelay1;
     Bdelay1a<= Bdelay1;  
     Rdelay1b<= Rdelay1a;
     Gdelay1b<= Gdelay1a;
     Bdelay1b<= Bdelay1a;  	  
     Rdelay1c<= Rdelay1b;
     Gdelay1c<= Gdelay1b;
     Bdelay1c<= Bdelay1b;  
     Rdelay1d<= Rdelay1c;
     Gdelay1d<= Gdelay1c;
     Bdelay1d<= Bdelay1c;  
     Rdelay1e<= Rdelay1d;
     Gdelay1e<= Gdelay1d;
     Bdelay1e<= Bdelay1d;  
     Rdelay1f<= Rdelay1e;
     Gdelay1f<= Gdelay1e;
     Bdelay1f<= Bdelay1e;  
     Rdelay1g<= Rdelay1f;
     Gdelay1g<= Gdelay1f;
     Bdelay1g<= Bdelay1f;  
     Rdelay1h<= Rdelay1g;
     Gdelay1h<= Gdelay1g;
     Bdelay1h<= Bdelay1g;  
     Rdelay1i<= Rdelay1h;
     Gdelay1i<= Gdelay1h;
     Bdelay1i<= Bdelay1h;  
     Rdelay1j<= Rdelay1i;
     Gdelay1j<= Gdelay1i;
     Bdelay1j<= Bdelay1i;  	  
     Rdelay1k<= Rdelay1j;
     Gdelay1k<= Gdelay1j;
     Bdelay1k<= Bdelay1j;  	  
     Rdelay1l<= Rdelay1k;
     Gdelay1l<= Gdelay1k;
     Bdelay1l<= Bdelay1k;  		  
     Rdelay1m<= Rdelay1l;
     Gdelay1m<= Gdelay1l;
     Bdelay1m<= Bdelay1l;  		  
     Rdelay1n<= Rdelay1m;
     Gdelay1n<= Gdelay1m;
     Bdelay1n<= Bdelay1m;  	  
     Rdelay1o<= Rdelay1n;
     Gdelay1o<= Gdelay1n;
     Bdelay1o<= Bdelay1n;  	  
     Rdelay1p<= Rdelay1o;
     Gdelay1p<= Gdelay1o;
     Bdelay1p<= Bdelay1o;  		  
     Rdelay1q<= Rdelay1p;
     Gdelay1q<= Gdelay1p;
     Bdelay1q<= Bdelay1p;  		  
     Rdelay1r<= Rdelay1q;
     Gdelay1r<= Gdelay1q;
     Bdelay1r<= Bdelay1q; 	  
	  
     Rdelay11<= Rdelay1r;
     Gdelay11<= Gdelay1r;
     Bdelay11<= Bdelay1r;    
     end
end
 
 
 
                    
reg [7:0]Rd1;
reg [7:0]Gd1;                          
reg [7:0]Bd1;                           
reg [15:0]Rdata1;
reg [15:0]Gdata1;                          
reg [15:0]Bdata1;                          
reg [15:0]Sdata1;  
reg [15:0]ErrorEnergy1;      
 
 
                     
always @(posedge FCLK_CLK0 or negedge gpio_rtl_tri_o_0)
begin
     if(!gpio_rtl_tri_o_0)
     begin
     Rd1    <= 8'd0;
     Gd1    <= 8'd0;
     Bd1    <= 8'd0;
     Rdata1 <= 16'd0;
     Gdata1 <= 16'd0;
     Bdata1 <= 16'd0;  
	  Sdata1 <= 16'd0;  
	  ErrorEnergy1 <= 16'd0;  
     end
else begin
     if(R1>Rdelay11)
     Rd1    <= R1-Rdelay11;
	  else
	  Rd1    <= Rdelay11-R1;
	  
     if(G1>Gdelay11)
     Gd1    <= G1-Gdelay11;
	  else
	  Gd1    <= Gdelay11-G1;	  
	  
     if(B1>Bdelay11)
     Bd1    <= B1-Bdelay11;
	  else
	  Bd1    <= Bdelay11-B1; 
 
     Rdata1 <= Rd1*Rd1;
     Gdata1 <= Gd1*Gd1;
     Bdata1 <= Bd1*Bd1; 
	  
	  Sdata1 <= Rdata1+Gdata1+Bdata1;
	  ErrorEnergy1 <=  Sdata1;
	  end
end
 
reg [15:0]Edis1; 
reg [15:0]disparity1; 
 
always @(posedge FCLK_CLK0 or negedge gpio_rtl_tri_o_0)
begin
     if(!gpio_rtl_tri_o_0)
     begin
     Edis1      <= 16'd0;
	  disparity1 <= 16'd0;
     end
else begin
          if(Edis0 >= ErrorEnergy1)
			 begin
			 disparity1 <= 16'd19;
			 Edis1      <= ErrorEnergy1;
			 end
	  else begin
			 disparity1 <= disparity0;
			 Edis1      <= Edis0;
          end	  
	  end
end
 
 
endmodule

三、测试结果

点击run之后,程序就下载到FPGA开发板中了。

A23-44 

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
视觉和3D视觉的原理是什么? 根据引用中提供的资料,Halcon双目视觉和3D视觉的原理包括以下几个方面: 1. 双目视觉原理: 双目视觉是利用两个摄像头同时拍摄同一场景,并将两个图像进行分析和比较,从而获取深度信息双目视觉系统通常使用两个相机来模拟人类双眼视觉,通过计算两个图像之间的差异来计算目标物体的三维位置。 2. 3D视觉原理: 3D视觉是指通过分析图像中的深度信息,从而实现对物体的三维重建和测量。在Halcon中,3D视觉可以通过多种方法实现,包括双目视觉、结构光和激光扫描等。这些方法可以通过计算图像中的纹理、边缘和深度信息,从而生成三维点云或模型。 3. 双目立体重构原理: 双目立体重构是指利用两个摄像头获取图像进行立体匹配,从而恢复物体的三维形状和位置。在Halcon中,双目立体重构通过计算两个图像之间的视差来确定物体的深度。视差是指在两个图像中对应点之间的像素位移,通过测量视差,可以计算出物体的距离和形状。 总的来说,Halcon的双目视觉和3D视觉原理是通过分析图像中的深度信息,利用双目立体匹配的方法来恢复物体的三维形状和位置。这些原理可以应用于机器视觉领域,例如机器人导航、三维测量和物体识别等应用。<span class="em">1</span> #### 引用[.reference_title] - *1* [halcon双目立体视觉原理入门资料.ppt](https://download.csdn.net/download/caotameiddd/12685820)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

fpga和matlab

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

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

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

打赏作者

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

抵扣说明:

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

余额充值