2016-08-19 143 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,但我猜測你的輸入是一個完整的體積對象?