Retrieving non-zero blocks from a matrix

27 visualizaciones (últimos 30 días)
NeGM
NeGM el 30 de Mzo. de 2021
Comentada: Walter Roberson el 1 de Abr. de 2021
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

Respuesta aceptada

Walter Roberson
Walter Roberson el 31 de Mzo. de 2021
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]}
  2 comentarios
NeGM
NeGM el 1 de Abr. de 2021
Walter,
Imnot familiar with bwconncomp, what does the "4" do?

Iniciar sesión para comentar.

Más respuestas (1)

Oleg Iupikov
Oleg Iupikov el 31 de Mzo. de 2021
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

Categorías

Más información sobre Loops and Conditional Statements en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by