python中深度映射的曲面法线计算

2024-04-16 18:39:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试用python实现以下c++代码:

depth.convertTo(depth, CV_64FC1); // I do not know why it is needed to be 
transformed to 64bit image my input is 32bit

Mat nor(depth.size(), CV_64FC3);

for(int x = 1; x < depth.cols - 1; ++x)
{
   for(int y = 1; y < depth.rows - 1; ++y)
   {
      Vec3d t(x,y-1,depth.at<double>(y-1, x)/*depth(y-1,x)*/);
      Vec3d l(x-1,y,depth.at<double>(y, x-1)/*depth(y,x-1)*/);
      Vec3d c(x,y,depth.at<double>(y, x)/*depth(y,x)*/);
      Vec3d d = (l-c).cross(t-c);
      Vec3d n = normalize(d);
      nor.at<Vec3d>(y,x) = n;
   }
}

imshow("normals", nor);

python代码:

^{pr2}$

输入图像:

enter image description here

c++代码输出:

enter image description here

我的python代码输出:

enter image description here

我找不到这些差异的原因。如何使用python获得c++代码输出?在


Tags: to代码forisnotdocvat
1条回答
网友
1楼 · 发布于 2024-04-16 18:39:07

正如user8408080所说,您的输出似乎有由jpeg格式引起的伪影。还要记住,导入8位图像作为深度贴图不会产生与直接使用深度贴图矩阵相同的结果。在

关于python代码,我的建议是使用向量化函数并尽可能避免循环(这非常慢)。在

zy, zx = np.gradient(d_im)  
# You may also consider using Sobel to get a joint Gaussian smoothing and differentation
# to reduce noise
#zx = cv2.Sobel(d_im, cv2.CV_64F, 1, 0, ksize=5)     
#zy = cv2.Sobel(d_im, cv2.CV_64F, 0, 1, ksize=5)

normal = np.dstack((-zx, -zy, np.ones_like(d_im)))
n = np.linalg.norm(normal, axis=2)
normal[:, :, 0] /= n
normal[:, :, 1] /= n
normal[:, :, 2] /= n

# offset and rescale values to be in 0-255
normal += 1
normal /= 2
normal *= 255

cv2.imwrite("normal.png", normal[:, :, ::-1])

相关问题 更多 >