2016-08-19 181 views
0

我有一个160x120 OpenCV Mat,其中我在每个位置都存储了一个Vec3F向量。 Vec3f保存用于已经通过使用强度图像和对应的深度图的3D重建计算的特定像素的信息。 所以我基本上从Mat映射到在每个像素保持3D位置信息的每个像素的灰度值到Mat在OpenCV中计算3D梯度方向

然后我试图计算该对象中每个像素的渐变。我因此具有用C语言实现这个代码++/OpenCV的:

for(int x = 0; x < mat.rows; ++x){ 
    for(int y = 0; y < mat.cols; ++y){ 
     float Gx = (mat.at<Vec3f>(x+1, y)[0] - mat.at<Vec3f>(x-1, y)[0])/2.0; 
     float Gy = (depth.at<Vec3f>(x, y+1)[1] - depth.at<Vec3f>(x, y-1)[1])/2.0; 

     Vec3f d = (Gx, Gy, 1.0); 
     Vec3f n = normalize(d); 
     allGradients.push_back(n); 
    } 
} 

// mat.at<Vec3f>(x, y)[0] -> Get the Vec3F vector at the current x-, y- 
// position in the Mat and access its first element (which is the points x-value). 

因此,我所计算的梯度方向和GxGy有限差分近似的方法。

我不明白的是如何计算Z方向的梯度。我确实有存储在Vec3f中的每个像素的z信息以及x和y信息,但是有限差分近似的步骤将不可能,因为数据存储在2D Mat中,对吧?

所以我不能简单地访问像素的前面和后面,他当前做类似这样的:在Mat

float Gz = (mat.at<Vec3f>(x, y, z+1)[2] - mat.at<Vec3f>(x, y, z-1)[2])/2.0; 

,因为我还没有z值,对不对?如果是这样,那我该如何计算z方向上的梯度?我需要将我的信息存储在3D array中吗?或者整个方法不正确?谢谢!

+0

不确定您的2D渐变是否有意义。我知道3D体积数据(如CT扫描或密度三维重建(如kinect融合))等密度网格中的3D渐变。但是,如果需要,可以将稀疏点表示转换为3D网格。可能回答这个问题,你应该告诉你想要用梯度信息做什么。也许足够逼近该物体/像素位置中的二维表面平面。 – Micka

回答

1

看起来你所拥有的是一个三维物体,你以某种方式胁迫成二维矩阵。如果你真的有一个三维立体的对象,你可以使用下面的Opencv Mat构造

Mat::Mat(int ndims, const int* sizes, int type) 

在这里看到的文档:http://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#mat-mat

此构造函数允许你创建n维Mat对象。例如:

cv::Mat m = cv::Mat(3, {100, 100, 10}, CV_32SC1) 

如果输入是具有附着在每个像素一些3维场的二维空间对象,那么当然,spatial gradient沿z方向是0,但我猜测你的输入是一个完整的体积对象?