首頁>Program>source

我正在尝試使用MATLAB分配两个圖像-一个rgb和另一个深度.請註意,我已经檢查了几个地方-例如此處此處(需要kinect設備)和rgb-dt人脸資料集< / a>.下面是一个這樣的示例:

地面真相(基本上是指指定感兴趣的脸部區域的邊界框)已经提供,我仅使用它们来裁剪脸部區域. 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和深度如下所示:


有什麼方法可以註册/分配圖像.我从 此處,其中,基本sobel運算符已用於rgb和深度圖像上, 生成邊缘圖,然後需要生成關键點以进行匹配.在此生成两个圖像的邊缘圖.

但是它们太吵了,以至於我认為我们將無法對此圖像进行關键點匹配.

Can anybody suggest some algorithms in matlab to do the same ?

最新回復
  • 6月前
    1 #

    prologue

    此答案基於我先前的答案:

      Does Kinect Infrared View Have an offset with the Kinect Depth View

    我手動裁剪您的輸入圖像,因此我將颜色和深度圖像分開(因為我的程式需要將它们分開。這可能会匯致少量偏移變化,只有几个畫素。另外,因為我没有深度(深度圖像是 8bit 仅由於灰度級 RGB ),那麼我使用的深度精度很差,請參阅:

    因此,我的結果受到所有負面影响.無論如何,這是您需要做的:

    determine FOV for both images

    因此找到在两个圖像上都可见的一些可測量功能.尺寸越大,結果越準確.例如,我選擇這些:

    form a point cloud or mesh

    我使用深度圖像作為參考,所以我的點云在它的 FOV中 .因為我没有距离,但是我 取而代之的是,我通過乘以常數將其轉換為一定距离.因此,我会掃描整个深度圖像,並為我在點云陣列中建立的每个畫素點掃描.然後將單位畫素坐標轉換為彩色圖像 8bit 並複製其颜色.像這樣的东西(在 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 } } 是我的點云2D陣列分配的t深度圖像分辨率.維兹威兹 是我對 **xyz的圖像類 所以這裏有一些相關的成員:

    picture DIP 是圖像分辨率(以畫素為單位)

      是作為 xs,ys聯合的圖像直接畫素訪問 因此我可以將颜色作為單个32位變數或每个颜色通道进行單独訪問。

      p[ys][xs] 只需从 DWORD dd; BYTE db[4];重新排列颜色通道 到 rgb2bgr(DWORD col) .

      RGB

      我用 BGR 為此,這裏是代碼:

      render it
      

      您需要添加 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();

      如果您註意到我添加了 OpenGL align it的變數 .這是相機之間的偏移量.我在 ofsx,ofsy的箭頭击键上更改了它们 畫素,然後致電 copy_images() 並呈現結果.這樣,我可以非常快速地手動找到偏移量:

      您可以看到偏移量是 1 x轴和 copy_images中的畫素 y轴上的畫素.在這裏可以更好地看到深度的侧视圖:

      希望它会有所帮助

  • 6月前
    2 #

    好吧,我在阅讀了很多博客和所有文章之後都尝試這樣做.我仍然不確定我是否做對了.如果發現不妥之處,請隨時發表評論.為此,我使用了可在此處找到的mathworks fex提交:ginputc函式。

    matlab代碼如下:

    +17
    
    步骤1

    我使用sobel邊缘檢測器提取深度和rgb圖像的邊缘,然後使用阈值获取邊缘圖.我將主要只使用梯度幅度.這樣就给了我两张圖片:

    步骤2

    接下来,我使用 +4clc; clear all; close all; % no of keypoint N = 7; I = imread('2.jpg'); I = rgb2gray(I); [Gx, Gy] = imgradientxy(I, 'Sobel'); [Gmag, ~] = imgradient(Gx, Gy); figure, imshow(Gmag, [ ]), title('Gradient magnitude') I = Gmag; [x,y] = ginputc(N, 'Color' , 'r'); matchedpoint1 = [x y]; J = imread('2.png'); [Gx, Gy] = imgradientxy(J, 'Sobel'); [Gmag, ~] = imgradient(Gx, Gy); figure, imshow(Gmag, [ ]), title('Gradient magnitude') J = Gmag; [x, y] = ginputc(N, 'Color' , 'r'); matchedpoint2 = [x y]; [tform,inlierPtsDistorted,inlierPtsOriginal] = estimateGeometricTransform(matchedpoint2,matchedpoint1,'similarity'); figure; showMatchedFeatures(J,I,inlierPtsOriginal,inlierPtsDistorted); title('Matched inlier points'); I = imread('2.jpg'); J = imread('2.png'); I = rgb2gray(I); outputView = imref2d(size(I)); Ir = imwarp(J,tform,'OutputView',outputView); figure; imshow(Ir, []); title('Recovered image'); figure,imshowpair(I,J,'diff'),title('Difference with original'); figure,imshowpair(I,Ir,'diff'),title('Difference with restored'); 用於在两个圖像上標記關键點的功能.點之間的對應關係是我事先確定的.我尝試使用 ginput 功能,但在深度圖像上效果不佳。

    步骤3

    使用 ginputc 得到變換矩陣 SURF 然後使用此矩陣恢複運動圖像的原始位置.下一組圖像讲述了這个故事。

    当然,我仍然相信,如果對两张圖片中的關键點进行更明智的選擇,都可以进一步改善結果.我也认為@Specktre方法更好.我只是註意到,与問题相比,我在答案中使用了單独的圖像對.两张圖片都来自同一資料集,可在vap rgb-d-t資料集中找到。

    estimategeometrictransform

  • java:無法轉換為已實現的介面
  • c:將二維陣列傳遞给常量引數的函式