Retrieving non-zero blocks from a matrix

23 次查看(过去 30 天)
Hi everyone,
I'd like to figure out a way to extract "blocks" of non-zero values from larger matrices. The following image shows an example of a matrix containing the "blocks" along the diagonal. I added the red brackets manually to better visualize the problem.
The problem I am having is that these "blocks " are not always as nice as the ones in the image above. Sometimes I get the following.
So the dimensionality of the blocks changes from matrix to matrix. Any help is greatly appreciated. Thank you

采纳的回答

Walter Roberson
Walter Roberson 2021-3-31
Data borrowed from @Oleg Iupikov
YourArray = [
0.3899 0 0 0 0 0
0 0.0492 0.3202 0.4881 0 0
0 0.3074 0.4613 0.7067 0 0
0 0 0 0 0.3673 0
0 0 0 0 0.9414 0
0 0 0 0 0 0.2682];
bw = logical(YourArray);
CC = bwconncomp(bw, 4); %4 connectivity... no diagonals
S = regionprops(CC,'SubarrayIdx');
chunks = arrayfun(@(s)YourArray(s.SubarrayIdx{:}), S, 'uniform', 0)
chunks = 4×1 cell array
{[ 0.3899]} {2×3 double} {2×1 double} {[ 0.2682]}

更多回答(1 个)

Oleg Iupikov
Oleg Iupikov 2021-3-31
Here is one possible solution. Please see in-line comments for explanation.
% Generate some data matrix
Data = zeros(6,6);
Data(1,1) = rand;
Data(2:3,2:4) = rand(2,3);
Data(4:5,5) = rand(2,1);
Data(6,6) = rand;
Data
% This matrix will be used to determine if we have found all the blocks.
% 1 means that this element of the matrix has not been processed yet.
FlagMat = Data>0;
% Find all blocks
SubMatCnt = 0;
while true
% Find 1st non-processed element of the matrix. It will correspond to the top-left corner of the sub-matrix.
[irow,icol] = find(FlagMat,1);
% If all elements of FlagMat are 0, we have found everything, exit the loop
if isempty(irow), break; end
% Find all neighboring non-zero elements along row
icol2 = find(~FlagMat(irow,icol:end), 1) + icol - 2; % in fact, we are finding the 1st 0-element in the row irow starting from column icol
if isempty(icol2), icol2 = size(FlagMat,2); end % it is the case when icol pointing to the last column
% Find all neighboring non-zero elements along column
irow2 = find(~FlagMat(irow:end,icol), 1) + irow - 2;
if isempty(irow2), irow2 = size(FlagMat,1); end % it is the case when irow pointing to the last row
% Form the submatrix indices
irows = irow : irow2;
icols = icol : icol2;
% Mark elements of FlagMat correspontding to the submatrix as "processed"
FlagMat(irows,icols) = false;
% Print our submatrix
SubMatCnt = SubMatCnt + 1;
fprintf('Sub-matrix %i:\n',SubMatCnt);
disp(Data(irows,icols));
end
And here is the output:
Data =
0.3899 0 0 0 0 0
0 0.0492 0.3202 0.4881 0 0
0 0.3074 0.4613 0.7067 0 0
0 0 0 0 0.3673 0
0 0 0 0 0.9414 0
0 0 0 0 0 0.2682
Sub-matrix 1:
0.3899
Sub-matrix 2:
0.0492 0.3202 0.4881
0.3074 0.4613 0.7067
Sub-matrix 3:
0.3673
0.9414
Sub-matrix 4:
0.2682

类别

Help CenterFile Exchange 中查找有关 Get Started with Image Processing Toolbox 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by