围绕特定元素制作子数组的一般方法

时间:2010-04-20 21:38:42

标签: matlab arrays

使用MatLab在特定元素周围形成子阵列的快速,优雅方式是什么?元素是从数据中随机选择的,因此您不能以正常方式获取子数组(必​​须针对所选元素进行推广)。我的意思是,形成一个数组,例如5x5或7x7或其他东西,其中中间元素是你想要的。


谢谢,但我的意思是更通用的方法。对不起,不清楚。我的意思是,比方说,

a = magic(10)          
b = find(a<8) %giving linear indices     
m = size(a)      
[r,c] = ind2sub(m,b) %giving rows and columns of the elements that you later want to select

然后我考虑使用for循环进行其余操作,但我不确定如何概括它并且想知道,就像我说的,如果使用MatLab有更简单的方法。

这种一般方法的原因是我想分析具有某些属性的元素的任何数组,然后能够在每个元素周围形成一个子数组,基本上放大它以进行进一步的数据分析,如果这是有道理的。

2 个答案:

答案 0 :(得分:1)

以下是一些如何解决此问题的示例:

mat = rand(10);  %# A 10-by-10 array of random elements

vec = -3:3;      %# To make a 7-by-7 subarray
subArray = mat(5+vec,4+vec);  %# Get subarray centered on element (5,4)

vec = -2:2;      %# To make a 5-by-5 subarray
subArray = mat(3+vec,3+vec);  %# Get subarray centered on element (3,3)

当然,你必须警惕你的下标超出你正在索引的矩阵范围的条件,然后决定你想如何处理这种情况(即只返回子数组的部分)这是在较大的矩阵内,或使用PADARRAY填充较大矩阵的边缘以避免这种情况等。)。

修改

要概括上述要获得子阵列的点集,the solutions given by Jonas应该可以正常工作。唯一的缺点是您需要访问Image Processing Toolbox。这是一个无需其他工具箱的解决方案,使用arc,因为您已在问题中对其进行了定义:

blockSize = 3;                             %# Block size around each point
padSize = floor(blockSize/2);              %# Padding size for the matrix
aPad = padarray(a,[padSize padSize],NaN);  %# Pad the matrix with NaNs
rPad = r+padSize;                          %# Shift the row indices
cPad = c+padSize;                          %# Shift the column indices
blockIndices = (1:blockSize)-ceil(blockSize/2);  %# Create indices for a block
getBlockFcn = @(r,c) aPad(r+blockIndices,c+blockIndices);  %# Function to get
                                                           %#   a block
subArrays = arrayfun(getBlockFcn,rPad,cPad,...  %# Create a cell array with
                     'UniformOutput',false);    %#   one block per cell

这将为您提供N-by-1单元格数组subArrays,其中N是您拥有的点数。例如,如果要获得第3点子阵列的最大值,可以执行以下操作:

maxValue = max(subArrays{3}(:));  %# MAX will ignore NaN values

要取整个子阵列的平均值,您必须先删除NaN值(使用函数ISNAN),或使用NANMEAN中的函数Statistics Toolbox }:

mat = subArray{3}(:);                %# Values from subarray
meanValue = mean(mat(~isnan(mat)));  %# Mean of non-NaN values
%# Or...
meanValue = nanmean(subArrays{3}(:));  %# Mean of non-NaN values

答案 1 :(得分:1)

如果您想将单个(可能是重叠的)邻域聚集到一个数组中,以便您可以单独处理每个邻域,则可以使用IM2COL。如果您想在每个元素周围创建一个“光环”以轻松捕获所有候选区域,那么重叠不会被计算两次,您可以使用IMDILATE

im2col的例子

%# create array and get linear index of interesting elements
a = magic(10);
b = find(a<8);

%# define region size
subSz = 3; %# for 3x3 array
halfSz = floor(subSz/2); %# for a 3x3 array, there window extends 1 pix to each side

%# pad a with NaNs so that sub-window never goes outside the image
ap = padarray(a,[halfSz halfSz],NaN);

%# convert ap to columns - there are 9 rows (for 3x3 window) and as many columns as there
%# are elements in a (100 in this example)
apCol = im2col(ap,[subSz,subSz]);

%# select columns of interest
%# the first column contains the first neighborhood of interest, the second column 
%# the second neighborhood etc.
interestingColumns = apCol(:,b);

%# take e.g. the average of each neighborhood
avg = nanmean(interestingColumns,1);

imdilate的例子

%# create array and get logical mask where 1 indicates an interesting element
a = magic(10);
bw = (a<8);

%# define region size
subSz = 3; %# for 3x3 array

%# grow each element, so that a single 'good' pixel is in the center of a 3x3 mask
bwDil = imdilate(bw,strel('square',subSz));

%# show the centers in white, 'halo' in grey
%# note the overlaps
figure,imshow(bw+bwDil,[])

%# take the average of all 'labeled' pixels
avg = mean(a(bwDil));