首先我们讲解一下双目视觉中,我们只有两张二维的图片,我们的目的就是通过这两张二位的图片来构建出一个三维的模型,这就要求我们要通过两张图,推算出来一个图片没有展示出来的深度。深度的计算的原理如下
图片中C1和C2分别对应着我们双目视觉中两个摄像头的位置
由式1和式2知
由此可知,只要知道焦距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部分识别部分的算法的设计。