使用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有更简单的方法。
这种一般方法的原因是我想分析具有某些属性的元素的任何数组,然后能够在每个元素周围形成一个子数组,基本上放大它以进行进一步的数据分析,如果这是有道理的。
答案 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。这是一个无需其他工具箱的解决方案,使用a
,r
和c
,因为您已在问题中对其进行了定义:
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));