あなたは本当にこのためのクロス製品を使用するは必要ありませんが、以下を参照してください。
はあなたの距離画像は関数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値を置き換えるために多くの意味をなすかもしれませんちょうど大きい数。私はその後、いくつかの簡単なシェーディングを行うために計算され、通常の方向を使用しています(
を;による「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);
}"
}
}
ベクトルのイメージをダンプするときのOpenCVの機能によって異なります。 XYZがRGBにマッピングされているように見えず、正/負のコンポーネントの範囲がスケーリングなしで0〜255のピクセル値にうまくマッピングされない場合があります。そのため、私のコードには、法線からグレースケール画像を生成する単純なシェーディングモデルも含まれています。 – timday
こんにちは@timday私はOpenCvの問題だとは思っていません。なぜならMatlabスクリプトからOpencvへの法線を読み込んで、それらを 'imshow()'すると、上記のものと比べて素晴らしい画像が得られるからです。 – ThT
[this](http://stackoverflow.com/q/31217122/2571705)が役に立つかもしれません。 – dhanushka