Matlab 对应标签与坐标点

Matlab 对应标签与坐标点,matlab,matrix,coordinates,subset,matrix-indexing,Matlab,Matrix,Coordinates,Subset,Matrix Indexing,如何获得矩阵中每个标签的列主顺序下第一次和最后一次出现的坐标 标签为1到4的标签矩阵示例: 对于上面的示例L,我想获得如下坐标矩阵: M = [ 1 1 1 1 4 1 2 5 2 3 7 2 5 6 3 6 8 3 8 1 4 7 4 4 ]; 其中M的第一列包含水平坐标,第二列包含垂直坐标,第三列包含标签。每个标签应该有2行。您可以使用矩阵的标签检索uniqe值 重新检索它们可以用来获取它们的索引 将矩阵与它组合在一起。您可以

如何获得矩阵中每个标签的列主顺序下第一次和最后一次出现的坐标

标签为1到4的标签矩阵示例:

对于上面的示例L,我想获得如下坐标矩阵:

M = [
    1 1 1
    1 4 1
    2 5 2
    3 7 2
    5 6 3
    6 8 3
    8 1 4
    7 4 4 ];

其中M的第一列包含水平坐标,第二列包含垂直坐标,第三列包含标签。每个标签应该有2行。

您可以使用矩阵的标签检索uniqe值

重新检索它们可以用来获取它们的索引


将矩阵与它组合在一起。

您可以检索矩阵标签上的uniqe值

重新检索它们可以用来获取它们的索引


将矩阵与它组合在一起。

使用for循环,您可以这样做:

M=zeros(2*max(L(:)),3);
for k=1:max(L(:))
   [r,c]=find(L==k);
   s=sortrows([r c],2);
   M(k*2-1:k*2,:)=[s(1,:) k; s(end,:) k];
end

M =
 1     1     1
 1     4     1
 2     5     2
 3     7     2
 5     6     3
 6     8     3
 8     1     4
 7     4     4

也许通过regionprops选项,您可以在不使用循环的情况下完成…

使用for循环,您可以这样做:

M=zeros(2*max(L(:)),3);
for k=1:max(L(:))
   [r,c]=find(L==k);
   s=sortrows([r c],2);
   M(k*2-1:k*2,:)=[s(1,:) k; s(end,:) k];
end

M =
 1     1     1
 1     4     1
 2     5     2
 3     7     2
 5     6     3
 6     8     3
 8     1     4
 7     4     4

也许通过regionprops选项,您可以在不使用循环的情况下执行此操作…

如果您正在寻找矢量化解决方案,您可以执行以下操作:

nTags = max(L(:));
whois = bsxfun(@eq,L,reshape(1:nTags,1,1,[]));
% whois = L == reshape(1:nTags,1,1,[]); % >=R2016b syntax.
[X,Y,Z] = ind2sub(size(whois), find(whois));
tmp = find(diff([0; Z; nTags+1])); tmp = reshape([tmp(1:end-1) tmp(2:end)-1].',[],1);
M = [X(tmp), Y(tmp), repelem(1:nTags,2).'];
或者使用极端变量重用:

nTags = max(L(:));
Z = bsxfun(@eq,L,reshape(1:nTags,1,1,[]));
[X,Y,Z] = ind2sub(size(Z), find(Z));
Z = find(diff([0; Z; nTags+1])); 
Z = reshape([Z(1:end-1) Z(2:end)-1].',[],1);
M = [X(Z), Y(Z), repelem(1:nTags,2).'];
以下是我的基准测试代码:

function varargout = b42973322(isGPU,nLabels,lMat)
if nargin < 3
  lMat = 1000;
end
if nargin < 2
  nLabels = 20; % if nLabels > intmax('uint8'), Change the type of L to some other uint.
end
if nargin < 1
  isGPU = false;
end
%% Create L:
if isGPU
  L = sort(gpuArray.randi(nLabels,lMat,lMat,'uint8'),2);
else
  L = sort(randi(nLabels,lMat,lMat,'uint8'),2);
end
%% Equality test:
M{3} = DeviL2(L);
M{2} = DeviL1(L);
M{1} = Adiel(L);
assert(isequal(M{1},M{2},M{3}));
%% Timing:
% t(3) = timeit(@()DeviL2(L)); % This is always slower, so it's irrelevant.
t(2) = timeit(@()DeviL1(L));
t(1) = timeit(@()Adiel(L));
%% Output / Print
if nargout == 0
  disp(t);
else
  varargout{1} = t;  
end

end

function M = Adiel(L)
  M=[];
  for k=1:max(L(:))
     [r,c]=find(L==k);
     s=sortrows([r c],2);
     M=[M;s(1,:) k; s(end,:) k];
  end
end

function M = DeviL1(L)
  nTags = max(L(:));
  whois = L == reshape(1:nTags,1,1,[]); % >=R2016b syntax.
  [X,Y,Z] = ind2sub(size(whois), find(whois));
  tmp = find(diff([0; Z; nTags+1])); tmp = reshape([tmp(1:end-1) tmp(2:end)-1].',[],1);
  M = [X(tmp), Y(tmp), repelem(1:nTags,2).'];
end

function M = DeviL2(L)
  nTags = max(L(:));
  Z = L == reshape(1:nTags,1,1,[]);
  [X,Y,Z] = ind2sub(size(Z), find(Z));
  Z = find(diff([0; Z; nTags+1])); 
  Z = reshape([Z(1:end-1) Z(2:end)-1].',[],1);
  M = [X(Z), Y(Z), repelem(1:nTags,2).'];
end

如果要寻找矢量化解决方案,可以执行以下操作:

nTags = max(L(:));
whois = bsxfun(@eq,L,reshape(1:nTags,1,1,[]));
% whois = L == reshape(1:nTags,1,1,[]); % >=R2016b syntax.
[X,Y,Z] = ind2sub(size(whois), find(whois));
tmp = find(diff([0; Z; nTags+1])); tmp = reshape([tmp(1:end-1) tmp(2:end)-1].',[],1);
M = [X(tmp), Y(tmp), repelem(1:nTags,2).'];
或者使用极端变量重用:

nTags = max(L(:));
Z = bsxfun(@eq,L,reshape(1:nTags,1,1,[]));
[X,Y,Z] = ind2sub(size(Z), find(Z));
Z = find(diff([0; Z; nTags+1])); 
Z = reshape([Z(1:end-1) Z(2:end)-1].',[],1);
M = [X(Z), Y(Z), repelem(1:nTags,2).'];
以下是我的基准测试代码:

function varargout = b42973322(isGPU,nLabels,lMat)
if nargin < 3
  lMat = 1000;
end
if nargin < 2
  nLabels = 20; % if nLabels > intmax('uint8'), Change the type of L to some other uint.
end
if nargin < 1
  isGPU = false;
end
%% Create L:
if isGPU
  L = sort(gpuArray.randi(nLabels,lMat,lMat,'uint8'),2);
else
  L = sort(randi(nLabels,lMat,lMat,'uint8'),2);
end
%% Equality test:
M{3} = DeviL2(L);
M{2} = DeviL1(L);
M{1} = Adiel(L);
assert(isequal(M{1},M{2},M{3}));
%% Timing:
% t(3) = timeit(@()DeviL2(L)); % This is always slower, so it's irrelevant.
t(2) = timeit(@()DeviL1(L));
t(1) = timeit(@()Adiel(L));
%% Output / Print
if nargout == 0
  disp(t);
else
  varargout{1} = t;  
end

end

function M = Adiel(L)
  M=[];
  for k=1:max(L(:))
     [r,c]=find(L==k);
     s=sortrows([r c],2);
     M=[M;s(1,:) k; s(end,:) k];
  end
end

function M = DeviL1(L)
  nTags = max(L(:));
  whois = L == reshape(1:nTags,1,1,[]); % >=R2016b syntax.
  [X,Y,Z] = ind2sub(size(whois), find(whois));
  tmp = find(diff([0; Z; nTags+1])); tmp = reshape([tmp(1:end-1) tmp(2:end)-1].',[],1);
  M = [X(tmp), Y(tmp), repelem(1:nTags,2).'];
end

function M = DeviL2(L)
  nTags = max(L(:));
  Z = L == reshape(1:nTags,1,1,[]);
  [X,Y,Z] = ind2sub(size(Z), find(Z));
  Z = find(diff([0; Z; nTags+1])); 
  Z = reshape([Z(1:end-1) Z(2:end)-1].',[],1);
  M = [X(Z), Y(Z), repelem(1:nTags,2).'];
end
我只是想尝试一下:

下面是我的计时结果,注意标签的数量不能超过127,因为Adiel的代码使用uint8值作为索引:

因此,对于中等数量的标签和相对较小的尺寸,Adiel的循环解决方案看起来效果最好,而我的解决方案介于his和Dev-iL之间。对于更大尺寸或更多数量的标签,我的解决方案开始占据主导地位。

我只需要尝试一下:

下面是我的计时结果,注意标签的数量不能超过127,因为Adiel的代码使用uint8值作为索引:



因此,对于中等数量的标签和相对较小的尺寸,Adiel的循环解决方案看起来效果最好,而我的解决方案介于his和Dev-iL之间。对于较大尺寸或较大数量的标签,我的解决方案开始领先。

M的第一行不应该是1吗?是的,你说得对!,还有,你用的是哪个版本的MATLAB?R2015版本不是M的第一行是1吗?是的,你说得对!,我还想问一下,您使用的是哪个版本的MATLAB?R2015 AI版本完全同意您的建议,但我不明白为什么在某些情况下,矩阵会出现在我面前[255 255标签],标签很好,但为什么255代表x和y-没关系,我找到原因了!我不是一个双重矩阵,而是一个uint8^^^。感谢您的帮助:-我完全同意您的建议,但我不明白为什么在某些情况下矩阵会显示给我[255标签],标签很好,但为什么x和y为255-没关系,我找到原因了!我不是一个双重矩阵,而是一个uint8^^^。谢谢你的帮助:-+1的创意!但是除了复杂的代码阅读,我不确定它是否更快。。。有时候bsxfun会以这种方式变得很糟糕。哇,好吧,我一点也不习惯这种写作,但谢谢你,这会让我理解矢量化:-D。谢谢!谢谢大家@Adiel是否愿意用更大数据集的基准来支持这些主张所以,我检查了800x800的L,有20100个不同的标签。我的解决方案需要12.03秒,您的第一个解决方案需要17.64秒。你的第二次需要21.88秒。最终的解决方案是相同的。所以bsxfun很漂亮,但并不总是最好的方式…@Adiel我也测试过它。首选项是标签数量的函数。我用20个标签在4000x4000上试用了它,我的第二种方法比它好30%。这是除非矩阵是gpuArray,在这种情况下,循环每慢1.3-x4.+1就丢失一次!但是除了复杂的代码阅读,我不确定它是否更快。。。有时候bsxfun会以这种方式变得很糟糕。哇,好吧,我一点也不习惯这种写作,但谢谢你,这会让我理解矢量化:-D。谢谢!谢谢大家@Adiel是否愿意用更大数据集的基准来支持这些主张所以,我检查了800x800的L,有20100个不同的标签。我的解决方案需要12.03秒,您的第一个解决方案需要17.64秒。你的第二次需要21.88秒。最终的解决方案是相同的。所以bsxfun很漂亮,但并不总是最好的方式…@Adiel我也测试过它。首选项是标签数量的函数。我用20个标签在4000x4000上试用了它,我的第二种方法比它好30%。也就是说,除非矩阵是gpuArray,在这种情况下,循环每慢x1.3-x4就会丢失一次。与此非常一般的指南相反,其他三个答案提供了一个总体方法,我建议要么扩展此答案,也给出一个总体方法,要么删除
根据其他答案,如果你认为这不会增加问题的价值,那么就将其全部删除。由于其他三个答案提供了一种全面的方法,与这个非常笼统的指导方针相反,我建议要么将这个答案扩展为也提供一种全面的方法,或者从其他答案来看,如果你认为它不会增加问题的价值,就把它全部删除。干得好!矢量化FTW:干得好!矢量化FTW: