在 matlab 中强调邻近区域

问题描述 投票:0回答:1

我有一个包含标签值的矩阵,例如识别谷物、制作地图中的状态等。这些值的范围为数千。

这些值对于同质区域是唯一的。在地图的情况下,不可能有飞地等,但可能有一个区域只有一个邻居。例如以下矩阵:

[a a a c c d
 a a b c c d
 a b b d d d]

我想可视化地图,但没有颜色图给出合理的结果 - 一些颗粒对的颜色几乎匹配。

是否有算法可以重新映射这些值,这样就不会有具有相同值但最大值低得多的邻居?结果看起来像一些政治地图,其中有 4 种颜色足以强调邻居。例如如下-

[1 1 1 3 3 1
 1 1 2 3 3 1
 1 2 2 1 1 1]

我尝试过干预

colormap
尝试
lines
或随机化,但由于区域的“大小”非常谨慎,因此不会产生可预测的结果。

matlab
1个回答
0
投票

感谢烧杯的建议,我能够设计出这个:

输入:

  • Map
    :包含标签值的矩阵。可以是 double、int、char。
  • K
    colormap()
    值的最大计数。选择匹配下面的 K 颜色算法。
  • Distance
    :相邻区域邻域扫描的直径。

0。确保标签一致

Labels = unique(Map);
for ii = 1 : N
  Map(Map == Labels(ii)) = ii;
end

1.矩阵到图表

预分配邻接矩阵。循环所有“颗粒”,使它们膨胀(溢出到它们的邻居)。从列表中排除

0
(邻居商品之外的标签被清零)。填充邻接矩阵中的行。最后矩阵中的对角线为零 - 消除自邻接。

Graph = false(N);

for ii = 1:N
  Grain = imdilate(Map == ii, strel('disk', Distance));
  Neighbours = unique(Map .* Grain);
  Neighbours = Neighbours(Neighbours ~= 0);
  Graph(Neighbours, ii) = true;
  Graph(ii, Neighbours) = true;
end

Graph = Graph & ~eye(size(Graph))

2.使用修改后的 Kempe 的 K 颜色算法

2.1。预分配工作变量

预分配

Stack
变量以保留从图形中删除的节点的踪迹,
Pruned
保持“修剪”图形,
Pool
保持“活动”节点,
Codes
存储“颜色代码”。

N = numel(Labels);
Stack = nan(N, 1);
Pruned = Graph;
Pool = 1 : N;
Codes = nan(1, N);

2.2。拆图

找到具有最少邻居的节点,将其索引放入堆栈并将其从邻接矩阵中删除(修剪它)。重复修剪后的邻接矩阵,直到最后一个节点位于堆栈上并且邻接矩阵为空。

for ii = 1 : N
  Degrees = sum(Pruned);
  [~, idmin] = find(Degrees == min(Degrees), 1);
  [~, Pruned] = pop(Pruned, idmin);
  Stack(ii) = Pool(idmin);
  [~, Pool] = pop(Pool, idmin);
end

2.3。 (“重新组合”图表)并分配代码

for ii = N : -1 : 1 % Start with last node in the stack
  % Read colour codes of neighbouring nodes. `NaN` returned for nodes still on stack* 
  NgbCodes = Codes(Graph(Stack(ii), :));
  % Check count of codes used in neighbouring nodes.
  if sum(~isnan(unique(K))) < Ncolours
    % If lower than number of codes, find the unused codes
    ColorPool = setdiff(CodeList, NgbCodes);
    % Assign the first unused code to the node
    Codes(Stack(ii)) = ColorPool(1);
  else
    % If all codes are used, leave unassigned (let user increase K and try again)
  end
end

3.将代码应用到矩阵

Map = Codes(Map);

嵌套函数

这两个函数分别从矩阵或向量中弹出第

rc
个元素或列。

function [CLMN, B] = prune(A, rc)
  CLMN = A(:, rc);
  B = A([1 : rc - 1, rc + 1 : end], :);
  B = B(:, [1 : rc - 1, rc + 1 : end]);
end

function [Val, B] = pop(A, rc)
  Val = A(rc);
  B = A([1 : rc - 1, rc + 1 : end]);
end

链接演示第 9 页中描述的算法的修改:

  • 我不寻找度数为
    D < K
    的(任何)节点,我寻找度数最低的节点(无论与K有多么相关)。如果
    D < K
    对于至少一个节点有效,则找到它。如果这样的节点不存在(对于 K=3 很容易),则分支不会有显着差异。
  • 我不使用递归调用,堆栈和其他变量大小在一开始就确定了,它们只会缩小。
  • 分配计数
    NC < K
    的相邻颜色代码的条件自动为
    true
    D < K
    - 则无需进行此类检查。
© www.soinside.com 2019 - 2024. All rights reserved.