Сгруппировать соседние ячейки с одинаковым zoneID, MATLAB

Скажем, у меня есть следующая матрица "зон"

brk_group =

     1     1     1     1
     3     2     2     3
     3     3     3     3

Я хотел бы создать "матрицу группировки" этих значений. Группа определяется как соседние ячейки (сверху, справа, снизу, слева) с одинаковым значением зоны.

Значение зоны может иметь несколько групп, поскольку зоны не должны быть пространственно объединены.

Данные:

brk_group = [1 1 1 1; 3 2 2 3; 3 3 3 3]

Что не так с "МОЙ ТЕКУЩИЙ КОД" ниже....

Значение зоны "3" в ячейке (2,4) связано со значением зоны "3" в ячейке (2,1), однако, когда цикл в моем текущем ответе достиг (2,4), он не видит эту связь и создаст новую группу, неправильно разгруппировав ячейки (2,1) и (2,4)...

РЕДАКТИРОВАТЬ: Хотелось бы просто использовать базовый MATLAB, пожалуйста, без инструментов обработки изображений! знак равно

ПОЯСНЕНИЕ: зоны определены как ВСЕ ячейки с одинаковым значением зоны. Группы определяются как ВСЕ пространственно соединенные ячейки (сверху, снизу, слева, справа) с одинаковым значением зоны.

МОЙ ТЕКУЩИЙ КОД:

function [groupMat groupIds] = createZoneGroups(zoneMat)
%
% groupMat = createZoneGroups(zoneMat)
%
% Groups zones spatially.
%
%   Input:
%       zoneMat: nxm matrix of "zones".
%
%   Output:
%       groupMat: nxm matrix of group ID's
%       groupIds: An array of unique group ID's
%
%   Note: A group is defined as spatially connected same zones. Diagonal
%       cells are not spatially connected.
%
%   Author: Kyle W. Purdon
%
groupIds = [];
groupMat = nan(size(zoneMat));
for rowIdx = 1:size(zoneMat,1)
    for colIdx = 1:size(zoneMat,2)

        % Check if the cell is nan, if so group(r,c)=nan
        if isnan(zoneMat(rowIdx,colIdx))
            continue;
        end

        % Check if the current cell has a group, if it does, break.
        if ~isnan(groupMat(rowIdx,colIdx))
            continue;
        end

        % Check the surrounding cells for groups, if any of the surrounding
        % cells (1) have a group, and (2) are in the same zone, assighn the
        % current cell that group. If not assign the current cell a new
        % group.

        % Check top cell
        if rowIdx > 1 && ~isnan(groupMat(rowIdx-1,colIdx))
            if isequal(zoneMat(rowIdx,colIdx),zoneMat(rowIdx-1,colIdx));
                groupMat(rowIdx,colIdx) = groupMat(rowIdx-1,colIdx);
                continue;
            end
        end
        % Check right cell
        if colIdx < size(zoneMat,2) && ~isnan(groupMat(rowIdx,colIdx+1))
            if isequal(zoneMat(rowIdx,colIdx),zoneMat(rowIdx,colIdx+1));
                groupMat(rowIdx,colIdx) = groupMat(rowIdx,colIdx+1);
                continue;
            end
        end
        % Check bottom cell
        if rowIdx < size(zoneMat,1) && ~isnan(groupMat(rowIdx+1,colIdx))
            if isequal(zoneMat(rowIdx,colIdx),zoneMat(rowIdx+1,colIdx));
                groupMat(rowIdx,colIdx) = groupMat(rowIdx+1,colIdx);
                continue;
            end
        end
        % Check left cell
        if colIdx > 1 && ~isnan(groupMat(rowIdx,colIdx-1))
            if isequal(zoneMat(rowIdx,colIdx),zoneMat(rowIdx,colIdx-1));
                groupMat(rowIdx,colIdx) = groupMat(rowIdx,colIdx-1);
                continue;
            end
        end

        % If the loop gets to this point, assign a new groupId to the cell.
        if isempty(groupIds)
            groupIds = 1;   % Start with group #1
        else
            groupIds(end+1) = groupIds(end)+1;  %Increment the last group by 1.
        end

        groupMat(rowIdx,colIdx) = groupIds(end);

    end
end
end

1 ответ

Решено с помощью кода, который я действительно должен был найти на бирже MATLAB.

По сути, это "обобщенная" версия bwlabel(), которая использует алгоритм "Union-Find".

http://www.mathworks.com/matlabcentral/fileexchange/26946-label-connected-components-in-2-d-array

Другие вопросы по тегам