首先我们讲解一下双目视觉中,我们只有两张二维的图片,我们的目的就是通过这两张二位的图片来构建出一个三维的模型,这就要求我们要通过两张图,推算出来一个图片没有展示出来的深度。深度的计算的原理如下
图片中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 : Hfor u=1 : W%left imageY_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;elsebin_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;elsebin_ro(v,u) = 0;endend
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 : Hfor m=1 : W% left imageif(bin_lo(n,m) == 255)if(m >= col_lmax) col_lmax = m; endif(m <= col_lmin) col_lmin = m; endif(n >= row_lmax) row_lmax = n; endif(n <= row_lmin) row_lmin = n; endend% right imageif(bin_ro(n,m) == 255)if(m >= col_rmax) col_rmax = m; endif(m <= col_rmin) col_rmin = m; endif(n >= row_rmax) row_rmax = n; endif(n <= row_rmin) row_rmin = n; endendend
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 : Hfor x=1 : W%left imageif((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);elsebox_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 imageif((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);elsebox_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);endend
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部分识别部分的算法的设计。