# c++ - 使用相鄰像素交叉積來計算來自深度圖像的表面法線

## opencv depth (1)

``````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``````

（然後我使用計算的正常方向做一些簡單的陰影;由於距離圖像的量化，請注意“steppy”外觀;理想情況下，實際距離數據的精度要高於8-bit）。

``````import QtQuick 2.2

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

anchors.fill: parent
blending: false

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

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;
}"

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);
}"
}
}``````

``````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);``````