2016-01-06 23 views
13

を横切ります。 Opencvを使ってPCLの使用を避けたいと思っていますが、実際にこの手順を理解していないのは、私の知識がかなり限られているからです。したがって、私は誰かがいくつかのヒントを提供できることに感謝します。私は奥行き画像とRGB画像なので、ノーKカメラ行列情報を除き、その他の情報を持っていないことをここで言及します。計算面の法線は、製品

enter image description here

、私は以下の画像のように対応する深度値に対応する点における法線ベクトルを見つけたい:

したがって、我々は次の奥行き画像を持っていることを言うことができます

enter image description here

どうすれば隣接ピクセルの外積を使用できますか?法線があまり正確でない場合は気にしません。

ありがとうございました。


更新:

[OK]を、私はOpenCVのにtimdayの答えとポート彼のコード@従うことをしようとしていました。次のコードで:

enter image description here:私は正しい、次の結果を取得しています

Mat depth = <my_depth_image> of type CV_32FC1 
Mat normals(depth.size(), CV_32FC3); 

for(int x = 0; x < depth.rows; ++x) 
{ 
    for(int y = 0; y < depth.cols; ++y) 
    { 

     float dzdx = (depth.at<float>(x+1, y) - depth.at<float>(x-1, y))/2.0; 
     float dzdy = (depth.at<float>(x, y+1) - depth.at<float>(x, y-1))/2.0; 

     Vec3f d(-dzdx, -dzdy, 1.0f); 
     Vec3f n = normalize(d); 

     normals.at<Vec3f>(x, y) = n; 
    } 
} 

imshow("depth", depth/255); 
imshow("normals", normals); 

(私はかかわらず、すべての違いを生むだろう、なぜ、私にはわからないfloatVecfVecddoubleを交換しなければなりませんでした)

+0

ベクトルのイメージをダンプするときのOpenCVの機能によって異なります。 XYZがRGBにマッピングされているように見えず、正/負のコンポーネントの範囲がスケーリングなしで0〜255のピクセル値にうまくマッピングされない場合があります。そのため、私のコードには、法線からグレースケール画像を生成する単純なシェーディングモデルも含まれています。 – timday

+0

こんにちは@timday私はOpenCvの問題だとは思っていません。なぜならMatlabスクリプトからOpencvへの法線を読み込んで、それらを 'imshow()'すると、上記のものと比べて素晴らしい画像が得られるからです。 – ThT

+1

[this](http://stackoverflow.com/q/31217122/2571705)が役に立つかもしれません。 – dhanushka

答えて

14

あなたは本当にこのためのクロス製品を使用するは必要ありませんが、以下を参照してください。

はあなたの距離画像は関数z(x、y)が検討します。

面の法線方向は、(-dz/DX、-dz/DY、1)です。 (dz/dxは微分を意味します:zとxの変化率)。そして、法線は、従来、単位長に正規化されています。

ちなみに、(-dz/dx、-dz/dy、1)がどこから来たのか疑問に思っているのなら...平面parellelの2つの直交接ベクトルをx軸とy軸にとった場合、それらは(1,0、dzdx)と(0,1、dzdy)です。通常は、X(0,1、dzdy)接線に垂直である、そうでなければならない(1,0、dzdx) - (-dzdx、-dzdy、1)である - ここで、 'X' は、クロス積です。だから、あなたのクロスプロダクトはノーマルになりますが、ノーマルの結果の式を直接使うことができれば、コードで明示的に計算する必要はほとんどありません。 (x、y)に、通常の単位長さを計算する

擬似コードは、あなたがやろうとしている内容に応じて

dzdx=(z(x+1,y)-z(x-1,y))/2.0; 
dzdy=(z(x,y+1)-z(x,y-1))/2.0; 
direction=(-dxdz,-dydz,1.0) 
magnitude=sqrt(direction.x**2 + direction.y**2 + direction.z**2) 
normal=direction/magnitude 

ようになり、それがでNaN値を置き換えるために多くの意味をなすかもしれませんちょうど大きい数。私はその後、いくつかの簡単なシェーディングを行うために計算され、通常の方向を使用しています(

enter image description here

を;による「steppy」外観の点に注意してください。そのアプローチを使用して

、あなたの距離画像から、私はこれを取得することができますレンジ画像の量子化には理想的ですが、実際のレンジデータでは8ビットよりも高い精度があります)。

OpenCVやC++コードではありませんが、完全性のために:その画像を生成した完全なコード(Qt QMLファイルに埋め込まれたGLSL、Qt5のqmlsceneで実行可能)は以下のとおりです。上記の擬似コードは、フラグメントシェーダのmain()関数にあります。

import QtQuick 2.2 

Image { 
    source: 'range.png' // The provided image 

    ShaderEffect { 
    anchors.fill: parent 
    blending: false 

    property real dx: 1.0/parent.width 
    property real dy: 1.0/parent.height 
    property variant src: parent 

    vertexShader: " 
     uniform highp mat4 qt_Matrix; 
     attribute highp vec4 qt_Vertex; 
     attribute highp vec2 qt_MultiTexCoord0; 
     varying highp vec2 coord; 
     void main() { 
     coord=qt_MultiTexCoord0; 
     gl_Position=qt_Matrix*qt_Vertex; 
     }" 

    fragmentShader: " 
    uniform highp float dx; 
    uniform highp float dy; 
    varying highp vec2 coord; 
    uniform sampler2D src; 
    void main() { 
     highp float dzdx=(texture2D(src,coord+vec2(dx,0.0)).x - texture2D(src,coord+vec2(-dx,0.0)).x)/(2.0*dx); 
     highp float dzdy=(texture2D(src,coord+vec2(0.0,dy)).x - texture2D(src,coord+vec2(0.0,-dy)).x)/(2.0*dy); 
     highp vec3 d=vec3(-dzdx,-dzdy,1.0); 
     highp vec3 n=normalize(d); 
     highp vec3 lightDirection=vec3(1.0,-2.0,3.0); 
     highp float shading=0.5+0.5*dot(n,normalize(lightDirection)); 
     gl_FragColor=vec4(shading,shading,shading,1.0); 
    }" 
    } 
} 
+0

答えてくれてありがとう私はあなたのコードをopencvに移植しようとしています。しかし、私はそれを行う必要があるので、私はどのようにクロス製品を使用して同じを行うだろうが、その方法。あなたの例で – ThT

+0

あなたは4人の隣人を使っていますか?私が8人の隣人を使いたいなら、私は対角線のピクセルに対して同じ手続きを適用すべきです、そうですか? – ThT

+0

@theodore:それを考えるには、十字積への「入力」は2つの接ベクトルであり、十字積は垂直法線を生成するということです。上の例では、2つの接ベクトルの終点として4つの近傍を効果的に使用しています。それを8つの隣接点に拡張する方法は明白ではありません...しかし、私は、近傍にもっと多くの点にスプラインを当てはめたより高度な方法があることを知っていますし、スプライン面の法線を使用します(例:https:// bib .irb.hr/datoteka/150807.1-0239.pdf)。 – timday