双目视觉 1 双目视觉的原理

首先我们讲解一下双目视觉中,我们只有两张二维的图片,我们的目的就是通过这两张二位的图片来构建出一个三维的模型,这就要求我们要通过两张图,推算出来一个图片没有展示出来的深度。深度的计算的原理如下

双目视觉 1 双目视觉的原理_第1张图片

图片中C1和C2分别对应着我们双目视觉中两个摄像头的位置

\Delta TOP\sim \Delta O'OD_{1}\Rightarrow \frac{x}{xl} =\frac{z}{f}

\Delta C_{W}EP\sim \Delta C_{2}GD_{2}\Rightarrow \frac{x-b}{xr} =\frac{z}{f}

xl=\frac{x}{z}f\; \;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;1

xr=\frac{x-b}{z}f\; \;\;\;\;\;\;\;\;\;\;\;2

由式1和式2知

diff=xl-xr=\frac{bf}{z}\Rightarrow z=\frac{b\cdot f}{diff}

 由此可知,只要知道焦距f和左目右目的视察,就可以得到物体到摄像头的距离,即照片不能直接显示的深度,这就是双目测距的原理。

接下来进行算法部分的设计

先在Matlab上对我们的数据进行处理,方便理清程序设计架构

clc;
clear;
close all;

% 读取左,右两张目标图片,方便后续操作
pic_l = imread('./IMAG_L50.BMP');
pic_r = imread('./IMAG_R50.BMP');

%将图片的RGB888格式下的各个颜色信息提取出来,方便后续转换
[H, W, C] = size(pic_l);
image_lr = pic_l(:,:,1);
image_lg = pic_l(:,:,2);
image_lb = pic_l(:,:,3);

image_rr = pic_r(:,:,1);
image_rg = pic_r(:,:,2);
image_rb = pic_r(:,:,3);

bin_lo = zeros(H,W);
bin_ro = zeros(H,W);

为了方便图片的二值化,我们先将图片

YCbCr :也叫YCC, YCbCr 是数字信号, 它包含两种形式, 分别为TV range 和 full range, TV range 主要是广播电视采用的标准, full range 主要是pc 端采用的标准, 所以full range 有时也叫 pc range

其转变公式如下

 转换后进行比较,设置一个颜色阈值,如果高于这个值(是红色目标部分)转换为白色,如果低于这个值转换为黑色,通过这种方法来完成图片的二值化。

for v=1 : H
    for u=1 : W
     
%left image
        
        Y_l = uint8(0.257*image_lr(v,u) + 0.564*image_lg(v,u) + 0.098*image_lb(v,u) + 16);
        Cb_l = uint8(-0.148*image_lr(v,u) - 0.291*image_lg(v,u) + 0.439*image_lb(v,u) + 128);
        Cr_l = uint8(0.439*image_lr(v,u) - 0.368*image_lg(v,u) - 0.071*image_lb(v,u) +128);

       if( Cr_l >= 180 && Cb_l < 170 && Cb_l > 140)
           
           bin_lo(v,u) = 255;
       else
           bin_lo(v,u) = 0;
        end 
        
%right image       
        
        Y_r = uint8(0.257*image_rr(v,u) + 0.564*image_rg(v,u) + 0.098*image_rb(v,u) + 16);
        Cb_r = uint8(-0.148*image_rr(v,u) - 0.291*image_rg(v,u) + 0.439*image_rb(v,u) + 128);
        Cr_r = uint8(0.439*image_rr(v,u) - 0.368*image_rg(v,u) - 0.071*image_rb(v,u) +128);

        
        if( Cr_r >= 180 && Cb_r < 170 && Cb_r > 140)
           bin_ro(v,u) = 255;
        else
           bin_ro(v,u) = 0;
        end
        
    end
end

        

 得到二值化的图片后,我们先框选项出图片中物料块的位置

% Calculating coordinates 
row_lmax = 0; row_lmin = 480;
col_lmax = 0; col_lmin = 640;
row_rmax = 0; row_rmin = 480;
col_rmax = 0; col_rmin = 640;

for n=1 : H
    for m=1 : W
        
%   left image
        if(bin_lo(n,m) == 255)
           if(m >= col_lmax) col_lmax = m; end
           if(m <= col_lmin) col_lmin = m; end
           if(n >= row_lmax) row_lmax = n; end
           if(n <= row_lmin) row_lmin = n; end
        end
 %  right image
        if(bin_ro(n,m) == 255)
           if(m >= col_rmax) col_rmax = m; end
           if(m <= col_rmin) col_rmin = m; end
           if(n >= row_rmax) row_rmax = n; end
           if(n <= row_rmin) row_rmin = n; end
        end
    end
end

然后按照我们上述的分析过程进行分析,首先对焦距进行计算、

%用于计算焦距,图片距离为50
% f = (50*(double(aver_lx - aver_rx))*(6*10^-4))/4.6

计算出焦距后,不在调整摄像头,进行距离分析

%计算真实距离
z = uint8((4.6*0.44)/((6*10^-4)*(double(aver_lx - aver_rx))))

将目标物体的周围用绿色的线条包裹,达到物体识别的效果。将算法移植到FPGA中后,利用FPGA的高速的特电,可以实时动态识别物体。

%Box selection
for y=1 : H
    for x=1 : W
        
        %left image
        if((x == col_lmax && y <= row_lmax && y >= row_lmin)|| (x == col_lmin && y <= row_lmax && y >= row_lmin)|| (y == row_lmin && x <= col_lmax && x >= col_lmin)|| (y == row_lmax && x <= col_lmax && x >= col_lmin))
            box_l (y, x , 1)= uint8(0);
            box_l (y, x , 2)= uint8(255);
            box_l (y, x , 3)= uint8(0);
            
        else
            box_l(y, x, 1) = pic_l(y,x,1);
            box_l(y, x, 2) = pic_l(y,x,2);
            box_l(y, x, 3) = pic_l(y,x,3);
        end
        
        %right image
        if((x == col_rmax && y <= row_rmax && y >= row_rmin) || (x == col_rmin && y <= row_rmax && y >= row_rmin)||(y == row_rmax && x <= col_rmax && x >= col_rmin) || (y == row_rmin && x <= col_rmax && x >= col_rmin))
            box_r (y, x ,1)= uint8(0);
            box_r (y, x ,2)= uint8(0);
            box_r (y, x ,3)= uint8(255);
        else
            box_r(y, x, 1) = pic_r(y,x,1);
            box_r(y, x, 2) = pic_r(y,x,2);
            box_r(y, x, 3) = pic_r(y,x,3);
        end
        
    end
end

将处理后的图片显示出来


%display image
Image_mosaic = [pic_l, pic_r];
Image_bin = [bin_lo, bin_ro];
Image_proces = [box_l, box_r];

subplot(2,2,1); imshow(Image_mosaic); title('原图');
subplot(2,2,2); imshow(Image_bin); title('二值化');
subplot(2,1,2); imshow(Image_proces); title('识别');

在整理清楚设计的原理和思路后,下一篇我们将会进行FPGA部分识别部分的算法的设计。

你可能感兴趣的:(单片机,嵌入式硬件,计算机视觉)