我正在尝试使用 MATLAB 对齐两张图像 - 一张 rgb 和另一张深度。请注意,我为此检查了几个地方 - 比如 here , here这需要一个kinect设备,和here here这表示校准需要相机参数。我还被建议使用 EPIPOLAR GEOMETRY 来匹配两个图像,但我不知道如何匹配。我指的数据集在 rgb-d-t face dataset 中给出。 .一个这样的例子如下所示:
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);
有什么方法可以注册/对齐图像。我从中得到了提示 here其中已在 rgb 和深度图像上使用基本的 sobel 运算符来生成边缘图,然后需要生成关键点以进行匹配。两个图像的边缘图都是在这里生成的。
但是它们太吵了,我认为我们无法对这些图像进行关键点匹配。
有人可以在 matlab 中推荐一些算法来做同样的事情吗?
最佳答案
序言
这个答案是基于我之前的答案:
我手动裁剪你的输入图像,所以我分离颜色和深度图像(因为我的程序需要它们分开。这可能会导致几个像素的微小偏移变化。而且因为我没有深度(深度图像是 8bit
仅由于灰度 RGB) 那么我使用的深度精度非常差,请参阅:
所以我的结果受到所有这些负面影响。无论如何,这是您需要做的:
确定两个图像的 FOV
所以找到一些在两张图片上都可见的可测量特征。尺寸越大,结果越准确。例如我选择这些:
形成点云或网格
我使用深度图像作为引用,因此我的点云在其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。
渲染它
我为此使用了 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初始化和相机设置等。这是未对齐的结果:
对齐
如果您注意到我向
copy_images()
添加了ofsx,ofsy
变量。这是相机之间的偏移量。我通过1
像素在箭头按键上更改它们,然后调用copy_images
并呈现结果。这样我很快就手动找到了偏移量:如您所见,x 轴偏移量为
+17
像素,y 轴偏移量为+4
像素。这里的侧 View 可以更好地看到深度:
希望对你有帮助
关于matlab - 对齐已捕获的 rgb 和深度图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35909833/