Как правильно разбить изображение ячеек с помощью Matlab?

У меня есть следующая картинка, которая представляет собой фотографию клеток поджелудочной железы введите здесь описание изображения

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

 I = imread('picture.tiff');
 I_gray = rgb2gray(I);
 [~, threshold] = edge(I_gray, 'sobel');
 fudgeFactor = .5;
 BWs = edge(I_gray,'sobel', threshold * fudgeFactor);
 se90 = strel('line', 3, 90);
 se0 = strel('line', 3, 0);
 BWsdil = imdilate(BWs, [se90 se0]);

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

Я часами искал другой способ сделать это, но без какого-либо удовлетворительного результата... Есть ли способ сделать это? Возможно, другое программное обеспечение, кроме Matlab, может быть более эффективным. Заранее спасибо!


person Hyppolite    schedule 06.03.2017    source источник
comment
Часами?! только в течение нескольких часов? Итак, вы хотите внедрить метод исследовательского уровня для автоматического сегментирования ячеек, и вы искали часы? Я имею в виду, что люди делают 4 года докторской степени, чтобы сделать это правильно. Вашим первым шагом должна стать книга/курс по обработке изображений.   -  person Ander Biguri    schedule 06.03.2017
comment
Нить кажется довольно красной, я бы попытался использовать эту информацию на вашем месте.   -  person UJIN    schedule 06.03.2017
comment
Я понимаю, что это сложно, я не буду описывать свою личную ситуацию, но этот проект, над которым я работаю, является побочным проектом, частью моей докторской диссертации (я физик, а не биолог), и у меня нет много времени, чтобы посвящать ему. Я пытаюсь использовать тот факт, что нить довольно красная, но это никогда не заканчивается так хорошо...   -  person Hyppolite    schedule 06.03.2017
comment
Сейчас у меня нет времени экспериментировать, но если вы этого не сделали, вы можете попробовать проверить канал Hue после преобразования изображения из RGB в HSV с помощью rgb2hsv. Канал оттенка не зависит от освещения, поэтому красная нить должна быть практически однородной.   -  person UJIN    schedule 06.03.2017


Ответы (2)


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

Исходное изображение

im=imread('gxGkH.jpg');
figure,imagesc(im);axis image;

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

Я выбираю только синий цвет для анализа

imb=im(:,:,3);
figure,imagesc(imb);axis image;

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

1) Размыть изображение, так как после размытия капли будут иметь локальные максимумы/минимумы в своих центрах.

sigma=7;
kernel = fspecial('gaussian',4*sigma+1,sigma);
im2=imfilter(imb,kernel,'symmetric');

figure,imagesc(im2);axis image;

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

2) Используйте преобразование водораздела, чтобы отделить каждую область блоба.

% L = watershed(im2);
L = watershed(max(im2(:))-im2);
[x,y]=find(L==0);

Нарисуйте границы

figure,imagesc(im2),axis image
hold on, plot(y,x,'r.')

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

3) Здесь я анализирую каждую каплю отдельно и нахожу порог otsu для каждой капли, затем я обнаруживаю капли и объединяю все обнаружения.

tmp=zeros(size(imb));

for i=1:max(L(:))
  ind=find(L==i);
  mask=L==i;
  [thr,metric] =multithresh(imb(ind),1);
  if metric>0.7
    tmp(ind)=imb(ind)>thr;
  end
end

Убрать шум

tmp=imopen(tmp,strel('disk',1));
figure,imagesc(tmp),axis image

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

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

person Ozcan    schedule 09.03.2017

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

image = imread('picture.tiff'); % load image
image = rgb2hsv(image); % convert to hsv colorspace
image = image(:,:,1); % take the hue channel

binary_im = imbinarize(image); % make binary image

Бинарное изображение должно выглядеть так:

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

Теперь вы можете использовать математическую морфологию для устранения шума. Сначала вы создаете элемент структурирования, а затем сворачиваете его с двоичным изображением:

str_el = strel('disk', 5, 0); % create a round, 5px radius, str_el
closed_im = imclose(binary_im, str_el); % close image with str_el

Теперь ваше новое изображение должно выглядеть так:

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

В этот момент вы можете использовать другую морфологическую операцию, которая находит скелет:

skeleton = bwmorph(closed_im, 'skel', Inf); % Find skeleton image

Изображение скелета будет выглядеть так:

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

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

person UJIN    schedule 06.03.2017
comment
Это действительно не точно, но, поскольку я могу повторить обработку для большого набора изображений, этого может быть достаточно. Я буду работать над этим! Большое спасибо ! - person Hyppolite; 06.03.2017