Построение карты из матрицы в Matlab - PullRequest
2 голосов
/ 19 июля 2010

У меня есть матрица A, которая содержит целые числа в ограниченном диапазоне (0..255), и мне нужно построить таблицу, отображающую значение (0..255) для всех координат в матрице, которые содержат это значение.

Каков наилучший способ достичь этого? - Я думал об использовании контейнеров. Карта для задачи, но карта не поддерживает несколько значений на ключ. Я мог бы использовать списки, но это казалось бы неэффективным, так как мне пришлось бы создавать новый список на каждой итерации.

Ответы [ 3 ]

1 голос
/ 19 июля 2010

Векторизованное решение, которое дает тот же результат, что и решение от Михаила , состоит в том, чтобы отсортировать все значения пикселей в вашем изображении с помощью функции SORT , преобразовать возвращенные линейные индексыиз SORT в индексы с подпиской, используя функцию IND2SUB , и соберите их вместе в один массив ячеек, используя функции ACCUMARRAY и 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

Теперь для заданного целого значения iValue вы можете получить матрицу N -by-2, содержащую координаты y (первый столбец) и x (второй столбец) дляN пикселей на изображении с этим значением, выполнив следующие действия:

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

Кроме того, на случай, если вам интересно, вы также можете сделать map структурным массивом с полями * 1025.* и y с помощью функции STRUCT :

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

И затем вы можете получить доступ к x и y координатам для пикселей со значением iValue следующим образом:

key = double(iValue)+1;
x = map(key).x;
y = map(key).y
0 голосов
/ 19 июля 2010

Ну, я написал следующее, и, кажется, работает в разумные сроки. Я думаю, что дело в том, чтобы предварительно распределить массивы ячеек на основе гистограммы для каждого значения:

[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.

0 голосов
/ 19 июля 2010

А как насчет использования массива ячеек? Вы можете индексировать его целыми числами. Например:

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

В этом примере индекс 0 находится в матрице в 1,1 и 13,56, индекс 1 в нет и индекс 2 в 4,5

Ваша ячейка будет иметь 256 элементов (у моей - 3), и для доступа вы просто добавите 1 к индексу.

Вы также можете хранить индексы линейно, поэтому код для заполнения таблицы будет:

for ii = 0:255
    map{ii+1} = find( mat(:)==ii )
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...