Правильное использование алгоритма Matlab Watershed для сегментации ячеек

Я столкнулся с массой проблем, пытаясь заставить алгоритм водораздела правильно работать с моими изображениями. В различных онлайн-учебниках они всегда используют изображения, которые столь же сложны / нечетки, и поэтому я не уверен, что не так с моим. Я уже сделал пару пятнистых постов по этому поводу, но хотел действительно уточнить и спросить в целом. Тем не менее, я использую такие изображения, как:

Однако, когда я пытаюсь применить один из алгоритмов водораздела:

imshow(RGB,[]);

gray_img = rgb2gray(RGB);
tophat_filter = imtophat(gray_img, strel('disk', 10)); %Read into this

level = graythresh(tophat_filter);
BW = im2bw(tophat_filter,level);
imshow(BW)

BW = bwdist(BW) <= 3;

imshow(BW)
bgn_remove = bwareaopen(BW,8); %remove background noise

D = -bwdist(~bgn_remove); %Read into this
D(~BW) = -Inf;
L = watershed(D);

figure;
imshow(L,[]);
figure;
imshow(label2rgb(L))
clean_img = im2bw(L,0.001);

figure;
imshow(clean_img,[]);

Кажется, это никогда не работает. По какой-то причине он определяет, что каждая ячейка состоит из множества более мелких: введите здесь описание изображения

Я попытался обойти это, объединив сегментированные компоненты с помощью BW = bwdist(BW) <= 3;, чтобы изображение не было фрагментировано AS:

введите здесь описание изображения

Как показано на первом изображении, должно быть 3 ячейки, и хотя водораздел распознает две отдельные ячейки слева, он регистрирует больше, чем должен (даже после объединения). Я не добился большого прогресса после всего, что я пробовал, поэтому любая помощь или предложения будут очень признательны.

Пройдя процедуру полного водораздела, я получаю такие максимумы, как:

введите здесь описание изображения

введите здесь описание изображения

введите здесь описание изображения


person muZero    schedule 22.08.2016    source источник


Ответы (1)


Вы должны использовать засеянный/ограниченный/маркерный водораздел. Если вы используете классический (больше не используемый) водораздел, вы сталкиваетесь с чрезмерной сегментацией.

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

  1. Небольшое закрытие для уменьшения шума.
  2. (опционально) Небольшое отверстие для выравнивания краев ячеек.
  3. Эрозия. Результат эрозии — ваш внутренний маркер.
  4. Расширение. Результат расширения — ваш внешний маркер.
  5. Градиент полученного изображения после шага 1 (или 2, если вы его сделали).
  6. Водораздел на градиентном изображении (шаг 5) с помощью маркеров (шаги 3 и 4).

Но в вашем случае с такими четко определенными ячейками я бы просто сделал шаги 1 и 2, а затем цилиндр. Это будет так же эффективно и намного быстрее.

person FiReTiTi    schedule 22.08.2016
comment
Большое спасибо за помощь. Тем не менее, я очень новичок в этом, и у меня есть пара вопросов: для шага 1 маленькое закрытие является морфологическим закрытием, таким как imclose? Или, скорее, закрыть что-то вроде bwareaopen для шумоподавления? Для шага 2 нужно ли упорядочить края ячеек, чтобы выровнять их? и если да, то чем он будет отличаться от шага 1? Я думаю, что понимаю шаги 3 и 4, но я рассмотрю их подробнее. На шаге 5/6 я не уверен, как бы я предварительно сформировал водораздел, используя эти конкретные маркеры - похоже, это отличается от общего случая. Можете ли вы в любом случае предоставить пример кода для некоторых из этих шагов? - person muZero; 22.08.2016
comment
1/ Да, inclose делает закрытие, когда bwareaopen открывает область на черно-белых изображениях (здесь не ваш случай). 2/ Это просто будет неправильной формы. Как я уже сказал, это необязательно. Шаг 1 удалит весь эффект пыли в основном в середине ячеек, когда шаг 2 после шага 1 повлияет в основном на контур. 5/6 Для градиента используйте Sobel. Для водораздела ищите засеянную (также называемую ограниченной) версию, тогда градиентное изображение и маркеры будут частью параметров. И извините, я не использую MatLab. - person FiReTiTi; 23.08.2016
comment
Потрясающе, спасибо. Также вы упомянули об использовании tophat, есть ли причина, по которой это приведет к исчезновению ячеек? Изображение выглядит намного чище после выполнения шагов 1 и 2. Могу ли я потенциально использовать водораздел только для них? Или было бы гораздо разумнее сначала использовать метод эрозионного расширения/или метод tophat? - person muZero; 23.08.2016
comment
Вам нужна эрозия и расширение, чтобы вычислить маркеры, так как вам нужен градиент, чтобы выделить края ячеек. Для Top-Hat вам нужно использовать БОЛЬШОЙ структурирующий элемент. Структурирующий элемент, достаточно большой, чтобы стереть ячейки. - person FiReTiTi; 23.08.2016
comment
Хорошо, спасибо большое. Я следовал вашим инструкциям вместе с mathworks.com/help/ images/examples/, но я все еще застрял - в конце процесса каждый комок распознается как один. Шаг, определяющий каждую пару как единую: fgm = imregionalmax(Iobrcbr), который представляет собой «Региональные максимумы открытия-закрытия путем реконструкции (fgm)». Любые советы, как я могу снизить этот порог или это безнадежное дело? Спасибо еще раз! - person muZero; 23.08.2016
comment
Не могли бы вы опубликовать пример вашего результата? - person FiReTiTi; 23.08.2016
comment
Лучшим решением в вашем случае будет: уменьшить размер замыкания, чтобы уменьшить влияние на границу, а затем вычислить конечный размыв. Это даст вам один центр/маркер на ячейку. - person FiReTiTi; 23.08.2016