Подсчет появления каждого цвета (значения пикселей) в изображении - PullRequest
1 голос
/ 21 апреля 2020

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

Проблема в том, что в статье, которую я следую, говорится, что мне нужно либо гистограмма RGB или какая-то структура карты вида:

карта (R, G, B) -> Количество появлений на изображении

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

Мне нужно, чтобы это было, в идеале, быстро, потому что мне нужно суммировать счетчики из набора изображений в наборе данных.

Любые идеи приветствуются.

1 Ответ

1 голос
/ 21 апреля 2020

Может быть, это может помочь:

imdata = double(imread('test.jpg'));
tic 
  [m,n,~] = size(imdata);
  pixels = m*n;  
  x = imdata(:,:,1)*1000000+imdata(:,:,2)*1000+imdata(:,:,3);
  keys = unique(x);
  n_keys = length(keys);
  map = containers.Map(keys,zeros(n_keys,1));
  for i = 1:pixels
    map(x(i)) = map(x(i)) +1;
  end
toc
%here comes post-processing
tic
b = rem(keys, 1000);
g = floor((rem(keys, 1000000) - b)/1000);
r = floor(keys/1000000);
v = map.values;
result = [r g b [v{:}]'];
toc

Я совершенно уверен, что это не самое быстрое и не самое элегантное решение. Что я пытался сделать:

  1. Mare обратимое единственное значение для каждого существующего цвета

  2. Использование уникальных значений в качестве ключей в объекте карты

  3. Подсчет количества появлений для каждого значения

  4. Последняя часть - необязательная - преобразование карты в массив с первыми 3 столбцами для цветовых компонентов и последним для числа внешности.

Я проверил это на простом изображении, как прикрепленное enter image description here

Вы можете использовать его для тестов, оно 500x500 и имеет только 4 цвета. На моем P C прошло менее 7 секунд. И я попробовал это на реальном изображении 1080x1920 пикселей - это заняло 57 секунд. Я полагаю, довольно медленно. Итак, я попробовал другой подход - я заменил l oop на другой:

  for i = 1:n_keys
    map(keys(i)) = sum(sum(x==keys(i)));
  end

Для маленького изображения это работало менее 0,05 секунды (воу!) - в этом случае у нас мало ключей, Итак, мы делаем несколько итераций. Но для большого - он имеет 271833 уникальных цвета - это заняло несколько минут, что делает этот подход неприемлемым. Если мы сможем сгруппировать закрывающие цвета в одну корзину - это будет работать быстрее.

Итак, я бы придерживался первого подхода.

...