在 Matlab 中从矩阵构建地图

发布于 2024-09-10 03:12:07 字数 181 浏览 3 评论 0 原文

我有一个矩阵 A,它保存有界范围 (0..255) 内的整数,我需要构建一个表,将值 (0..255) 映射到保存该值的矩阵中的所有坐标。

实现这一目标的最佳方法是什么? - 我考虑过使用containers.Map来完成任务,但Map不支持每个键多个值。我本来可以使用列表,但这似乎效率低下,因为我必须在每次迭代时创建一个新列表。

I have a matrix A which holds integers in a bounded range (0..255) and I need to build a table mapping a value (0..255) to all the coordinates in the matrix which hold this value.

What is the best way to achieve this? - I thought about using containers.Map for the task but Map doesn't support multiple values per key. I could have used lists but that would seem inefficient as I would have to create a new list on each iteration.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

忘羡 2024-09-17 03:12:07

矢量化解决方案,提供与解决方案相同的输出来自 Mikhail 的方法是使用 SORT 函数,转换从 排序 到下标索引中>IND2SUB,并使用函数 ACCUMARRAYMAT2CELL

A = randi([0 255],[5 5],'uint8');         %# A sample matrix
[values,indices] = sort(double(A(:)));    %# Sort all the pixel values
[y,x] = ind2sub(size(A),indices);         %# Convert linear index to subscript
counts = accumarray(values+1,1,[256 1]);  %# Count number of each value
map = mat2cell([y x],counts);             %# Create a 256-by-1 cell array

现在,对于给定的整数值 iValue,您可以获得包含 y(第一列)的 N×2 矩阵通过执行以下操作,获取图像中具有该值的 x(第二列)像素的坐标:

key = double(iValue)+1;  %# Need to use double to avoid integer saturation
points = map{key};       %# An N-by-2 coordinate matrix

此外,如果您感兴趣,您还可以制作使用函数STRUCT

map = struct('x',mat2cell(x,counts),'y',mat2cell(y,counts));

然后您可以访问 xy 坐标值为 iValue 的像素如下:

key = double(iValue)+1;
x = map(key).x;
y = map(key).y

A vectorized solution, which gives the same output as the solution from Mikhail, is to sort all the pixel values in your image using the SORT function, convert the linear indices returned from SORT into subscripted indices using the function IND2SUB, and collect them together into a single cell array using the functions ACCUMARRAY and MAT2CELL:

A = randi([0 255],[5 5],'uint8');         %# A sample matrix
[values,indices] = sort(double(A(:)));    %# Sort all the pixel values
[y,x] = ind2sub(size(A),indices);         %# Convert linear index to subscript
counts = accumarray(values+1,1,[256 1]);  %# Count number of each value
map = mat2cell([y x],counts);             %# Create a 256-by-1 cell array

Now, for a given integer value iValue you can get the N-by-2 matrix containing the y (first column) and x (second column) coordinates for the N pixels in the image with that value by doing the following:

key = double(iValue)+1;  %# Need to use double to avoid integer saturation
points = map{key};       %# An N-by-2 coordinate matrix

In addition, just in case you're interested, you could also make map a structure array with fields x and y using the function STRUCT:

map = struct('x',mat2cell(x,counts),'y',mat2cell(y,counts));

And you can then access the x and y coordinates for pixels with a value iValue as follows:

key = double(iValue)+1;
x = map(key).x;
y = map(key).y
毅然前行 2024-09-17 03:12:07

使用元胞数组怎么样?您可以使用整数对其进行索引。例如:

map = {[1,1;13,56], [], [4,5]};

在此示例中,索引 0 位于 1,113,56 的矩阵中,索引 1 位于无矩阵中,索引 2 位于 4,5< 中/code>

您的单元格将有 256 个元素(我的单元格有 3 个),要访问,您只需在索引中添加 1 即可。

您还可以线性存储索引,因此填充表的代码为:

for ii = 0:255
    map{ii+1} = find( mat(:)==ii )
end

What about using a cell array? You can index it with integers. For example:

map = {[1,1;13,56], [], [4,5]};

In this example index 0 is in the matrix in 1,1 and 13,56, index 1 in none and index 2 in 4,5

Your cell would have 256 elements (mine has 3) and to acces you would simply add 1 to the index.

You could also store indices linearly so the code to fill the table would be:

for ii = 0:255
    map{ii+1} = find( mat(:)==ii )
end
半葬歌 2024-09-17 03:12:07

好吧,我写了以下内容,它似乎在合理的时间内发挥了作用。我认为解决这个问题的方法是根据每个值的直方图预先分配元胞数组:

[H, W] = size(A);
histogram = hist(A, 256);
AGT = arrayfun(@(avg) {0 cell(1, histogram(avg))}, 1:256, 'UniformOutput', false);
for y = 1:H
    for x = 1:W
        idx = A(y, x) + 1;
        count = AGT{idx}{1};
        AGT{idx}{2}{count + 1} =  [y x];
        AGT{idx}{1} = count + 1;
    end
end

访问表有点烦人:

AGT{200}{2}{:}

访问值为 200 的所有坐标。

Well, I wrote the following and it seems to work in reasonable time. I think the thing that does the trick is preallocating the cell arrays based on the histogram for each value:

[H, W] = size(A);
histogram = hist(A, 256);
AGT = arrayfun(@(avg) {0 cell(1, histogram(avg))}, 1:256, 'UniformOutput', false);
for y = 1:H
    for x = 1:W
        idx = A(y, x) + 1;
        count = AGT{idx}{1};
        AGT{idx}{2}{count + 1} =  [y x];
        AGT{idx}{1} = count + 1;
    end
end

Accessing the table is a bit annoyting though :

AGT{200}{2}{:}

to access all coordinates with value 200.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文