我正在处理具有测量强度的图像文件,基本上提取尺寸为1x1x1像素的体素。图像文件形成一个体积以避免峰值强度。我想找到一种平均超过3x3x3像素的方法。
我的问题是要解决问题,因为它是图像中由零和其他值分隔的形状。所以,我首先考虑了一个带有for
语句的if
循环。这些是我迄今为for
- 循环和if
语句所做的考虑。 MATLAB将体积视为长矩阵,因此通过简单的for
循环,应该很容易找到非零值及其相邻值,并取这些值的平均值。当我不得不考虑z维度时,问题就出现了。
这显然不是最佳工作,我发现很难解释边界效应。
答案 0 :(得分:6)
我希望我能正确解释你的问题,但你想找到输入图像中每个体素的3 x 3 x 3体素体积的平均值,其中每个输入体素作为每个3 x的中心要平均3 x 3体素体积。如果您可以选择使用MATLAB的内置函数,请考虑使用带有convn
的N-D卷积。不要在这里使用循环,因为它会非常慢。对于convn
,第一个参数是3D图像,第二个参数是3 x 3 x 3内核,其值均等于1/27。如果卷积内核超出输入图像的限制,您还可以选择指定沿边界发生的情况。通常,您希望返回与输入大小相同的输出图像,因此您可能希望将'same'
标志指定为第三个可选参数。这种平均机制还假设外边缘是零填充的。
因此,假设您的图片存储在im
中,请执行以下操作:
%// Create kernel of all 1/27 in a 3 x 3 x 3 matrix
kernel = ones(3,3,3);
kernel = kernel / numel(kernel);
%// Perform N-D convolution
out = convn(double(im), kernel, 'same'); %// Cast to double for precision
out = cast(out, class(im)); %// Recast back to original data type
或者,如果您有权访问图像处理工具箱,请改用imfilter
。与此convn
的区别在于imfilter
是使用Intel Integrated Performance Primitives (IIPP)编写的,因此性能肯定会更快:
%// Create kernel of all 1/27 in a 3 x 3 x 3 matrix
kernel = ones(3,3,3);
kernel = kernel / numel(kernel);
%// Perform N-D convolution
out = imfilter(im, kernel);
额外的好处是您无需更改输入类型。 imfilter
自动推断出这一点,关于输入图像的原始类型和imfilter
的输出类型的处理是否与输入类型相同。使用convn
时,您必须确保数据在使用前是浮点数。