Matlab对kinect数据进行对齐

KinectV2 采集数据的图片格式

最近在处理一个数据库,该数据库有kinectv2设备采集,分为rgb图,红外infraded图和深度depth图,但是该数据库没有对深度图和rgb图片进行对齐,都是裸数据,即rgb为1080x1920,depth为424x512.在网上查阅了资料,有人说可以直接利用kinect的sdk进行求解,但是我没有做这个实验,第一是因为自己并不熟悉C++,还要安装kinect sdk和opencv库;第二,我觉得就算安装了可能也用不了,因为不知道kinect相机的一些参数(这个是我自己得猜想可能不对,没有验证,如果有小伙伴做了这一步工作的话可能告知一下),所以,我就没有接着往下做.而是采用matlab进行对齐。

相机参数

相机参数link分为外参和内参,内参指的是center和焦距,kinect一般都是一样的,这个参数差不多。

对于rgb摄像头,intrinsic参数(IntrinsicRGB的文件)为:
1034.3,0,0
1.6609,1034.3,0
970.63,529.07,1

对于红外摄像头,intrinsic参数(InvIntrinsicIR的文件)为:
0.0027132,0,-0
-1.8517e-05,0.0026991,-0
-0.69724,-0.54233,1

这两个intrinsic参数矩阵不用修改!!!

旋转平移矩阵(TransformationD-C)为:
0.99994,-0.0090793,0.0073288,52
0.009138,0.99992,-0.0079812,-10
-0.0072615,0.0080413,0.99995,1
37.331,-42.241,-88.088,1
前三行三列表示的是旋转矩阵,可以理解成两个相机之间的角度,最后一列表示的是平移矩阵,最后一行没有用到。

值得一提的是,因为我没有这个数据库采集用的kinect设备,所以我并不知道实际的参数,所以参数都是在github上找的,对于红外摄像头和rgb摄像头的intrinsic参数,我并没有任何修改(因为内参基本一样),而对于transformD-C的4*4矩阵,我做了一些微调,是它能够更好的对齐(因为不同kinect的摄像头外参不一样),如果发现depth和color之间转换后的图片不平行,那么要对旋转角度进行调整(一般不用调);如果发现depth和color之间需要平移才能完全对齐,那么就调整平移矩阵,也就是TransformationD-C的最后一列。如果你的数据库还提供这些参数,那么你完全可以用你自己的参数,不需要自己调。

Matlab代码

代码总共分为了5个文件,分别为
main_script.m,alignImage.m,IntrinsicRGB,InvIntrinsicIR,TransformationD-C。直接运行main_script.m脚本就可以了。
,IntrinsicRGB,InvIntrinsicIR,TransformationD-C存放就是上面说的三个矩阵参数。
由于自己懒得上传,而且也没想赚积分,就直接贴在这里了。
main_script.m代码为:

[colorizedDepth,coord] = alignImage('05.png','05.jpg','IntrinsicRGB','InvIntrinsicIR','TransformationD-C');%‘05.png’和'05.jpg'分别为424*512的深度图和对应的1080*1920的rgb图

%save computed data
imwrite(colorizedDepth,'Colorized_Depth.png');
figure,imshow(colorizedDepth);

alignImage.m代码为:

function [colorizedDepth, coordinateFrame,binaryDepth] = alignImage(depthImg, rgbImg, intrinsicRGB, intrinsicIR, transformMat)
    
    %read images
    depthImg_raw = imread(depthImg);
    rgbImg_raw = imread(rgbImg);
    intrinsicRGB = load(intrinsicRGB);
    intrinsicIR = load(intrinsicIR);
    transformMat = load(transformMat);
    intrinsicIR = inv(intrinsicIR);
    
    %generate camera parameter object
    RGBcamPar = cameraParameters('IntrinsicMatrix',intrinsicRGB);
    IRcamPar = cameraParameters('IntrinsicMatrix',intrinsicIR);
    
    %undistort images first if there's any skew or lense distortion
    depthImg = undistortImage(depthImg_raw,IRcamPar);
    rgbImg = undistortImage(rgbImg_raw, RGBcamPar);
    
    %get focal length and optical centers out of intrinsic matrices
    fx_d = IRcamPar.FocalLength(1);
    fy_d = IRcamPar.FocalLength(2);
    cx_d = IRcamPar.PrincipalPoint(1);
    cy_d = IRcamPar.PrincipalPoint(2);
    
    fx_c = RGBcamPar.FocalLength(1);
    fy_c = RGBcamPar.FocalLength(2);
    cx_c = RGBcamPar.PrincipalPoint(1);
    cy_c = RGBcamPar.PrincipalPoint(2);
    
    depthHeight = size(depthImg,1);
    depthWidth = size(depthImg,2);
    rgbHeight = size(rgbImg,1);
    rgbWidth = size(rgbImg,2);
    
    %colorizedDepth_6layer image has X,Y,Z,R,G,B values in its layers
    colorizedDepth_6layer = zeros(depthHeight,depthWidth,6);
    binaryDepth = zeros(depthHeight,depthWidth,3);
    
    for v = 1:(depthHeight)
        for u = 1:(depthWidth)
            %apply intrinsics
            z = single(depthImg(v,u));
            x = single((u - cx_d)*z)/fx_d;
            y = single((v - cy_d)*z)/fy_d;
            
            %apply extrinsic
            transformed = (transformMat * [x;y;z;1])';
            colorizedDepth_6layer(v,u,1) = transformed(1);
            colorizedDepth_6layer(v,u,2) = transformed(2);
            colorizedDepth_6layer(v,u,3) = transformed(3);
        end
    end
    coordinateFrame = colorizedDepth_6layer(:,:,1:3);
    
    for v = 1 : (depthHeight)
        for u = 1 : (depthWidth)
            % Apply RGB intrinsics
            x = (colorizedDepth_6layer(v,u,1) * fx_c / colorizedDepth_6layer(v,u,3)) + cx_c;
            y = (colorizedDepth_6layer(v,u,2) * fy_c / colorizedDepth_6layer(v,u,3)) + cy_c;
            
            % "x" and "y" are indices into the RGB frame, but they may contain
            % invalid values (which correspond to the parts of the scene not visible
            % to the RGB camera.
            % Do we have a valid index?
            if (x > rgbWidth || y > rgbHeight ||...
                x < 1 || y < 1 ||...
                isnan(x) || isnan(y))
                continue;
            end
            
            % Need some kind of interpolation. I just did it the lazy way
            x = round(x);
            y = round(y);

            colorizedDepth_6layer(v,u,4) = uint8(rgbImg(y, x, 1));
            colorizedDepth_6layer(v,u,5) = uint8(rgbImg(y, x, 2));
            colorizedDepth_6layer(v,u,6) = uint8(rgbImg(y, x, 3));
            
        end
    end    
    colorizedDepth = uint8(colorizedDepth_6layer(:,:,4:6));
end

这个是我对齐后的结果,由于数据库是从别人那里拿来的,为了保护别人的隐私,我将他的脸给划掉了,但还是可以看出depth和color能很好的对齐。
在这里插入图片描述

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值