4

MATLAB を使用して、1 つの rgb と別の深度の 2 つの画像を整列させようとしています。私はこれについていくつかの場所をチェックしたことに注意してください -ここ、キネクトデバイスを必要とするここキャリブレーションにはカメラパラメータが必要であると書かれているここ. 方法はわかりませんが、2つの画像を一致させるためにEPIPOLAR GEOMETRYを使用することも提案されました。私が言及しているデータセットはrgb-dt face datasetで与えられています。そのような例の 1 つを以下に示します。

画像

基本的に、関心のある顔領域を指定する境界ボックスを意味するグラウンド トゥルースは既に提供されており、それらを使用して顔領域のみをトリミングします。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);

切り抜かれた 2 つの画像 rgb と depth を以下に示します。トリミングされた画像


画像を登録/整列する方法はありますか。ここからヒントを得まし た。ここでは、基本的なソーベル オペレーターが RGB 画像と深度画像の両方で使用され、エッジ マップが生成されます。次に、一致する目的でキーポイントを生成する必要があります。両方の画像のエッジ マップがここで生成されます。

edge_map.

ただし、ノイズが多いため、この画像のキーポイント マッチングを実行できるとは思えません。

同じことをするためにmatlabでいくつかのアルゴリズムを提案できる人はいますか?

4

2 に答える 2

3

プロローグ

この回答は、私の以前の回答に基づいています。

入力画像を手動でトリミングして、色と深度画像を分離します(私のプログラムではそれらを分離する必要があるためです。これにより、オフセットが数ピクセルだけわずかに変化する可能性があります。また、深度がないため(深度画像はグレースケールRGB8bitのみによるものです)、次に私が扱っている深さの精度は非常に悪いです。

深さ

したがって、私の結果はこれらすべての悪影響を受けます。とにかく、ここにあなたがする必要があることがあります:

  1. 両方の画像の 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 配列に割り当てられた深度画像解像度はどこにありますか。これはDIPpictureの私の画像クラスなので、ここに関連するメンバーがいくつかあります。

    • xs,ysピクセル単位の画像解像度
    • p[ys][xs]の結合としての画像直接ピクセル アクセスであるDWORD dd; BYTE db[4];ため、単一の 32 ビット変数または各カラー チャネルとして個別に色にアクセスできます。
    • rgb2bgr(DWORD col)カラーチャンネルを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();
    

    粗いOpenGLの初期化やカメラ設定などを追加する必要があります。整列していない結果は次のとおりです。

    色

  4. それを揃える

    ofsx,ofsyに変数を追加したことに気付いた場合copy_images()。これはカメラ間のオフセットです。ピクセルごとに矢印キーストロークでそれらを変更し、結果1を呼び出しcopy_imagesてレンダリングします。このようにして、手動でオフセットを非常に迅速に見つけました。

    整列する

    ご覧のとおり、オフセットは+17x 軸の+4ピクセル数と y 軸のピクセル数です。ここでは、深さがよく見えるように側面図を示します。

    側

それが少し役立つことを願っています

于 2016-03-10T10:36:39.657 に答える