Retrieving non-zero blocks from a matrix
22 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
NeGM
le 30 Mar 2021
Commenté : Walter Roberson
le 1 Avr 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
0 commentaires
Réponse acceptée
Walter Roberson
le 31 Mar 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)
2 commentaires
Plus de réponses (1)
Oleg Iupikov
le 31 Mar 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
Voir également
Catégories
En savoir plus sur Get Started with Image Processing Toolbox dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!