matlab - 对齐已捕获的 rgb 和深度图像

标签 matlab image-processing kinect image-registration

我正在尝试使用 MATLAB 对齐两张图像 - 一张 rgb 和另一张深度。请注意,我为此检查了几个地方 - 比如 here , here这需要一个kinect设备,和here here这表示校准需要相机参数。我还被建议使用 EPIPOLAR GEOMETRY 来匹配两个图像,但我不知道如何匹配。我指的数据集在 rgb-d-t face dataset 中给出。 .一个这样的例子如下所示:

image

ground truth 基本上意味着指定感兴趣的面部区域的边界框已经提供,我使用它们仅裁剪面部区域。 matlab代码如下所示:

I = imread('1.jpg');
I1 = imcrop(I,[218,198,158,122]);
I2 = imcrop(I,[243,209,140,108]);
figure, subplot(1,2,1),imshow(I1);
subplot(1,2,2),imshow(I2);

裁剪后的两张图片rgb和depth如下图:cropped_images


有什么方法可以注册/对齐图像。我从中得到了提示 here其中已在 rgb 和深度图像上使用基本的 sobel 运算符来生成边缘图,然后需要生成关键点以进行匹配。两个图像的边缘图都是在这里生成的。

edge_map .

但是它们太吵了,我认为我们无法对这些图像进行关键点匹配。

有人可以在 matlab 中推荐一些算法来做同样的事情吗?

最佳答案

序言

这个答案是基于我之前的答案:

我手动裁剪你的输入图像,所以我分离颜色和深度图像(因为我的程序需要它们分开。这可能会导致几个像素的微小偏移变化。而且因为我没有深度(深度图像是 8bit 仅由于灰度 RGB) 那么我使用的深度精度非常差,请参阅:

depth

所以我的结果受到所有这些负面影响。无论如何,这是您需要做的:

  1. 确定两个图像的 FOV

    所以找到一些在两张图片上都可见的可测量特征。尺寸越大,结果越准确。例如我选择这些:

    FOV

  2. 形成点云或网格

    我使用深度图像作为引用,因此我的点云在其FOV 中。因为我没有距离,而是 8bit 值,所以我通过乘以常数将其转换为某个距离。所以我扫描整个深度图像,并为我在点云阵列中创建点的每个像素。然后将 dept 像素坐标转换为彩色图像 FOV 并复制其颜色。像这样(在 C++ 中):

    picture rgb,zed; // your input images
    struct pnt3d { float pos[3]; DWORD rgb; pnt3d(){}; pnt3d(pnt3d& a){ *this=a; }; ~pnt3d(){}; pnt3d* operator = (const pnt3d *a) { *this=*a; return this; }; /*pnt3d* operator = (const pnt3d &a) { ...copy... return this; };*/ };
    pnt3d **xyz=NULL; int xs,ys,ofsx=0,ofsy=0;
    
    void copy_images()
        {
        int x,y,x0,y0;
        float xx,yy;
        pnt3d *p;
        for (y=0;y<ys;y++)
         for (x=0;x<xs;x++)
            {
            p=&xyz[y][x];
            // copy point from depth image
            p->pos[0]=2.000*((float(x)/float(xs))-0.5);
            p->pos[1]=2.000*((float(y)/float(ys))-0.5)*(float(ys)/float(xs));
            p->pos[2]=10.0*float(DWORD(zed.p[y][x].db[0]))/255.0;
            // convert dept image x,y to color image space (FOV correction)
            xx=float(x)-(0.5*float(xs));
            yy=float(y)-(0.5*float(ys));
            xx*=98.0/108.0;
            yy*=106.0/119.0;
            xx+=0.5*float(rgb.xs);
            yy+=0.5*float(rgb.ys);
            x0=xx; x0+=ofsx;
            y0=yy; y0+=ofsy;
            // copy color from rgb image if in range
            p->rgb=0x00000000; // black
            if ((x0>=0)&&(x0<rgb.xs))
             if ((y0>=0)&&(y0<rgb.ys))
              p->rgb=rgb2bgr(rgb.p[y0][x0].dd); // OpenGL has reverse RGBorder then my image
            }
        }
    

    **xyz 是我的点云 2D 阵列分配的深度图像分辨率。 picture 是我的 DIP 图像类,所以这里有一些相关成员:

    • xs,ys 是以像素为单位的图像分辨率
    • p[ys][xs] 是作为DWORD dd 并集的图像直接像素访问; BYTE db[4]; 这样我就可以将颜色作为单个 32 位变量或单独的每个颜色 channel 进行访问。
    • rgb2bgr(DWORD col) 只是将颜色 channel 从 RGB 重新排序为 BGR
  3. 渲染它

    我为此使用了 OpenGL,所以这里是代码:

        glBegin(GL_QUADS);
        for (int y0=0,y1=1;y1<ys;y0++,y1++)
        for (int x0=0,x1=1;x1<xs;x0++,x1++)
            {
            float z,z0,z1;
            z=xyz[y0][x0].pos[2]; z0=z; z1=z0;
            z=xyz[y0][x1].pos[2]; if (z0>z) z0=z; if (z1<z) z1=z;
            z=xyz[y1][x0].pos[2]; if (z0>z) z0=z; if (z1<z) z1=z;
            z=xyz[y1][x1].pos[2]; if (z0>z) z0=z; if (z1<z) z1=z;
            if (z0   <=0.01) continue;
            if (z1   >=3.90) continue;  // 3.972 pre vsetko nad .=3.95m a 4.000 ak nechyti vobec nic
            if (z1-z0>=0.10) continue;
            glColor4ubv((BYTE* )&xyz[y0][x0].rgb);
            glVertex3fv((float*)&xyz[y0][x0].pos);
            glColor4ubv((BYTE* )&xyz[y0][x1].rgb);
            glVertex3fv((float*)&xyz[y0][x1].pos);
            glColor4ubv((BYTE* )&xyz[y1][x1].rgb);
            glVertex3fv((float*)&xyz[y1][x1].pos);
            glColor4ubv((BYTE* )&xyz[y1][x0].rgb);
            glVertex3fv((float*)&xyz[y1][x0].pos);
            }
        glEnd();
    

    需要添加coarse的OpenGL初始化和相机设置等。这是未对齐的结果:

    colors

  4. 对齐

    如果您注意到我向 copy_images() 添加了 ofsx,ofsy 变量。这是相机之间的偏移量。我通过 1 像素在箭头按键上更改它们,然后调用 copy_images 并呈现结果。这样我很快就手动找到了偏移量:

    align

    如您所见,x 轴偏移量为 +17 像素,y 轴偏移量为 +4 像素。这里的侧 View 可以更好地看到深度:

    side

希望对你有帮助

关于matlab - 对齐已捕获的 rgb 和深度图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35909833/

相关文章:

matlab - 如何将图片的图像设置为左侧有白色边框?

c++ - bmp to raw 奇怪的问题

opencv - 查找图像中对象的面积和颜色

processing - 使用 Kinect 运动传感器动态时间扭曲来检测手势

matlab - 同时删除矩阵中的一行和一列

matlab - 在每行列之间插入零的行和列

java - 如何在java中检查图像中的匹配像素?

java - 如何在 Linux 中为 OpenNI 编译和运行 java 文件

node.js - Nodejs : How can I optimize writing many files?

matlab - 关于浮点精度 : why the iteration numbers are not equal?