我试着用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代码:
d_im = cv2.imread("depth.jpg")
d_im = d_im.astype("float64")
normals = np.array(d_im, dtype="float32")
h,w,d = d_im.shape
for i in range(1,w-1):
for j in range(1,h-1):
t = np.array([i,j-1,d_im[j-1,i,0]],dtype="float64")
f = np.array([i-1,j,d_im[j,i-1,0]],dtype="float64")
c = np.array([i,j,d_im[j,i,0]] , dtype = "float64")
d = np.cross(f-c,t-c)
n = d / np.sqrt((np.sum(d**2)))
normals[j,i,:] = n
cv2.imwrite("normal.jpg",normals*255)
输入图像:
c++代码输出:
我的python代码输出:
我找不出这些差异的原因。我怎么能得到c++代码输出与python?
3条答案
按热度按时间x8diyxa71#
正如 user8408080 所说,您的输出似乎有jpeg格式引起的伪像。还要记住,导入8位图像作为深度图不会给予与直接使用深度图矩阵相同的结果。
关于你的python代码,我的建议是使用向量化函数,尽可能避免循环(它非常慢)。
kuhbmx9i2#
@sowlosc的答案没有考虑摄像头的内在特性
@百川的回答有明显bug
实现了一个简洁、正确、快速、易用的
get_surface_normal_by_depth
函数,并与修改后的@百川方案进行了比较,验证了结果的正确性。结果:正常1.png和正常2.png
第一节第一节第一节第一节第一次
o2g1uqev3#
代码(矩阵计算)应为:
1.我们应该使用摄像头的内部函数“K”。我认为f和t的值是基于摄像头坐标中的3D点。
1.对于法向量,(-1,-1,100)和(255,255,100)在8比特图像中是相同的颜色,但是它们是完全不同的法向量,因此我们应该通过
normal_map=normal_map*0.5+0.5
将法向量值Map到(0,1)。