【发布时间】:2015-11-06 03:34:35
【问题描述】:
我有一个从 3D OCT 扫描获得的 3D 图像数据。数据可以表示为 I(x,y,z),这意味着每个体素都有一个强度值。
我正在编写一个算法,该算法涉及在 C++ 中查找图像在 x、y 和 z 方向上的梯度。 我已经使用 OpenCV 为 2D 编写了 C++ 代码,并希望通过对现有 2D 代码的最小更改将其扩展到 3D。
我熟悉使用 Sobel or Scharr 运算符的 2D 渐变。我的搜索将我带到this post,推荐ITK 和Point Cloud Library 的答案。但是,这些库具有更多可能不需要的功能。由于我对 C++ 不是很有经验,因此这些库需要阅读一些内容,但时间不允许我这样做。此外,这些库不使用 cv::Mat 对象。如果我使用 cv::Mat 以外的任何东西,我的整个代码可能必须更改。
谁能帮我解决这个问题?
更新 1:使用内核可分离性的可能解决方案
根据@Photon 的回答,我正在更新问题。
从@Photon 所说,我了解了如何在 3D 中构建 Sobel 内核。但是,即使我构造了一个 3x3x3 的立方体,如何在 OpenCV 中实现它? OpenCV 中使用 filter2d 的卷积操作仅适用于 2D。
可能有一种方法。由于 Sobel 核是可分离的,这意味着我们可以将 3D 卷积分解为较低维度的卷积。 this link 的评论 20 和 21 也说明了同样的事情。现在,我们可以分离 3D 内核,但即使这样也不能使用 filter2D,因为图像仍然是 3D。有没有办法分解图像?有一个interesting post 暗示了这样的事情。对此有什么进一步的想法吗?
【问题讨论】:
-
自己写过滤器的实现,没那么复杂。对于每个体素(可能除了边缘,由您决定),计算其 Gx、Gy、Gz 并存储输出。最多应该是几十行代码。
-
要计算 Gx、Gy 或 Gz,有 2 个选项。一种是遍历每个体素,这将是低效的。另一种方式是卷积。但是使用 filter2D 的卷积仅适用于 2D 图像。那么,您的意思是我遵循基于循环的方法吗?
-
卷积在内部执行相同的循环。也许比你第一次尝试的效率高一点,但基本上是一样的。如果时间紧迫,您可以稍后尝试使用 SIMD 或 GPU 进行优化。
-
你也可以根据x+1-1、y+1-1、z+1-1计算xyz的梯度,如果这个精度满足你的要求。
标签: c++ opencv image-processing 3d