在 OpenCV 中计算 3D 梯度方向

Posted

技术标签:

【中文标题】在 OpenCV 中计算 3D 梯度方向【英文标题】:Compute 3D gradient directions in OpenCV 【发布时间】:2016-08-19 15:23:24 【问题描述】:

我有一个160x120 OpenCV Mat,我在每个位置存储了一个Vec3F 向量。 Vec3f 保存特定像素的 (x, y, z) 信息,该信息通过使用强度图像和相应深度图的 3D 重建计算得出。 所以我基本上从在每个像素处保存灰度值的 Mat 映射到在每个像素处保存 3D 位置信息的 Mat

然后我尝试计算Mat 对象中每个像素的梯度。因此,我在 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 中,对吧?

所以我不能通过执行类似这样的操作来简单地访问当前像素前后的像素:

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

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

【问题讨论】:

不确定您的 2D 渐变是否有意义。我知道来自 3D 体积数据的 3D 梯度,例如来自 CT 扫描或密集 3D 重建(如 kinect 融合)的密度网格。但是,如果您愿意,可以将稀疏点表示转换为 3D 网格。可能要回答这个问题,你应该告诉你想用梯度信息做什么。也许在该对象/像素位置近似 2D 表面平面就足够了。 【参考方案1】:

您所拥有的似乎是一个 3 维对象,您以某种方式将其强制转换为 2D 矩阵。如果你真的有一个 3D 体积物体,你可以使用下面的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 维场,那么当然,沿 z 方向的 spatial gradient 为 0,但我猜您的输入是一个完整的体积对象?

【讨论】:

以上是关于在 OpenCV 中计算 3D 梯度方向的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV图像处理篇之边缘检測算子

OpenCV小项目:自实现 Canny 算子

OpenCv 3d 拼接全景图

opencv-python图像处理 ----图像梯度Sobel算子

图像梯度(opencv-c++)

图像梯度(opencv-c++)