【问题标题】:MATLAB 3D sliding window on a volume体积上的 MATLAB 3D 滑动窗口
【发布时间】:2026-02-07 16:55:02
【问题描述】:

我有一个MxNxD 体积,我需要一个穿过体积的所有体素的lxhxw 滑动窗口。在每个滑动窗口中,我需要计算Root Mean Square Contrast。哪种方法更聪明?

我想限制 for 循环的使用,因为体积很大,1024x1024x146。

【问题讨论】:

  • 你想对这些体素做什么操作?为了清楚起见,滑动窗口意味着您希望为每个操作将窗口移动一行(或列/平面),使其与前一个窗口重叠。
  • 我必须计算每个窗口的均方根对比度 [en.wikipedia.org/wiki/Contrast_%28vision%29]。是的,每当一个体素的窗口在三个方向之一上移动时,下一个窗口就会与前一个窗口重叠。
  • 3D 窗口是否恰好是multiplicatively separable
  • 我不认为在这种特定情况下我的问题是乘法可分的‌​,但这在其他情况下对我很有用。只是为了确保正确理解,如果我的函数是乘法可分的,我可以在 x、y、z 方向上分别应用该函数,然后将结果相加(例如,为了计算梯度幅度,我可以先应用窗口沿行,然后沿列)?
  • 你考虑过使用convn吗? mathworks.com/help/matlab/ref/convn.html

标签: matlab image-processing 3d sliding-window


【解决方案1】:

听起来您想划分为l x h x w 的体素。如果是这种情况并假设您的矩阵称为q,其中size(q) = [M, N, D]

function N = test(q, l, h, w)
    qPrime = mat2cell(q, ...
        [l*ones(1, floor(size(q,1)/l)), mod(size(q,1), l)], ...
        [h*ones(1, floor(size(q,2)/h)), mod(size(q,2), h)], ...
        [w*ones(1, floor(size(q,3)/w)), mod(size(q,3), w)]);

    N = cellfun(@RMS, qPrime, 'uni', 0);
end

function N = RMS(M)
    var = M - mean(M(:));
    N = sqrt(sum(var(:).^2)) ./ numel(M);
end

这会在一个单元格中创建一个包含每个体素的单元格数组。使用 cellfun(@foo, qPrime, 'uni', 0) 将函数应用于每个体素。

【讨论】:

  • 感谢您的回答,但这不是我想做的。您的解决方案非常适合分割体积,但我需要在 lxhxq 窗口和体积之间进行 3d 卷积,并且每次窗口的中心体素获取使用均方根计算的值时对比。
  • 窗口不是l x h x w吗? 3D 卷积是什么意思?这看起来一点也不像 RMS 对比度。
  • 我没有解释清楚。我需要创建一个 3D 地图,其中每个体素包含在 lxhxw 的邻域上计算的 RMS 对比度值。从理论上讲,每次迭代时滑动窗口都必须移动一个体素,但这是我想避免的,因为在这种情况下,for 循环将重复超过 1.5 亿次。
  • 所以您希望输出为M x N x D?
  • 是的,没错,我需要一个MxNxD 输出矩阵!
【解决方案2】:

我已经能够使用 MATLAB 的stdfilt 函数解决这个特定问题,因为均方根对比度是滑动窗口内像素强度的标准偏差。 stdfiltfunction 允许你定义一个

由零和非零元素指定邻居的多维数组。 (MATLAB 帮助)

【讨论】: