Отрицательные значения в алгоритме Watershed приводят к черному изображению

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

Я пытаюсь применить алгоритм водораздела с помощью этого кода:

show(RGB_img)


%Convert to grayscale image
I = rgb2gray(RGB_img);

%Take structuring element of a disk of size 10, for the morphological transformations
%Attempt to subtract the background from the image: top hat is the
%subtraction of the open image from the original


%Morphological transformation to subtract background noise from the image
%Tophat is the subtraction of an opened image from the original. Remove all
%images smaller than the structuring element of 10
I1 = imtophat(I, strel('disk', 10));

%Increases contrast
I2 = imadjust(I1);
%show(I2,'contrast')
%Assume we have background and foreground and assess thresh as such 
level = graythresh(I2);
%Convert to binary image based on graythreshold
BW = im2bw(I2,level);
show(BW,'C');



BW = bwareaopen(BW,8);
show(BW,'C2');

BW = bwdist(BW) <= 1;
show(BW,'joined');
%Complement because we want image to be black and background white
C = ~BW;
%Use distance tranform to find nearest nonzero values from every pixel
D = -bwdist(C);

%Assign Minus infinity values to the values of C inside of the D image
%   Modify the image so that the background pixels and the extended maxima
%   pixels are forced to be the only local minima in the image (So you could
%   hypothetically fill in water on the image

D(C) = -Inf;

%Gets 0 for all watershed lines and integers for each object (basins)
L = watershed(D);
show(L,'L');

%Takes the labels and converts to an RGB (Using hot colormap)
fin = label2rgb(L,'hot','w');

% show(fin,'fin');
im = I;

%Superimpose ridgelines,L has all of them as 0 -> so mark these as 0(black)
im(L==0)=0;

clean_img = L;
show(clean_img)

После C = ~BW; все изображение становится темным. Я считаю, что это связано с тем, что все пиксели изображения имеют значение -inf или меньшее отрицательное число. Есть ли способ обойти это, и если да, то что я могу изменить в своем коде, чтобы этот алгоритм работал? Я экспериментировал с тоннами, и я действительно не знаю, что происходит. Любая помощь будет здорово!


person muZero    schedule 22.08.2016    source источник
comment
что делает команда show? Я не узнаю это. Это что-то из 2016а?   -  person Tasos Papastylianou    schedule 22.08.2016
comment
@tasosPapastylianou show - это небольшая функция, которую я написал, - на самом деле она только инкапсулирует figure, imshow и добавляет метку к фигуре. Это должен быть тот же дисплей, что и imshow   -  person muZero    schedule 22.08.2016


Ответы (1)


Проблема с вашей командой show. Как вы сказали в комментариях, это использует imshow под капотом. Если вы попробуете imshow напрямую, вы также увидите черное изображение. Однако, если вы вызовете его с соответствующими ограничениями:

imshow(clean_img,[min(clean_img(:)), max(clean_img(:))])

вы увидите все, что ожидаете увидеть.

В общем, по этой причине я обычно предпочитаю imagesc. imshow делает произвольные суждения о том, какой диапазон представлять, и я обычно не удосуживаюсь следить за ним. Я думаю, что в вашем случае ваше конечное изображение uint16, поэтому imshow выбирает диапазон [1, 65025]. Поскольку все ваши значения пикселей ниже 400, они выглядят черными для этого диапазона невооруженным глазом.

person Tasos Papastylianou    schedule 22.08.2016
comment
Вы также можете просто выполнить imshow(clean_img,[]);, что автоматически вычислит минимальное и максимальное значения и масштабирует их до [0,1] соответственно. - person rayryeng; 22.08.2016
comment
Большое спасибо, это помогло. Однако теперь я использую другой алгоритм, в котором L = watershed(I_mod); идет после: I_eq_c = imcomplement(I_eq); и I_mod = imimposemin(I_eq_c, ~bw4 | mask_em); После L все пиксели изображения устанавливаются равными 1 и, следовательно, снова все черные, есть идеи? - person muZero; 22.08.2016
comment
Также существует ли метод более общего назначения для их сегментации? Кажется, я получаю нечеткие результаты, если вообще результаты, даже несмотря на то, что в учебном коде использовались такие же сложные изображения. - person muZero; 22.08.2016
comment
Не существует единого общеприменимого метода сегментации. До сих пор есть люди, работающие над докторской диссертацией по сегментации клеток. Попробуйте imopen вместо imtophat, вы получите немного более релевантный результат в вашем случае, возможно, вы сможете взять его оттуда. Один из подходов состоит в том, чтобы сначала грубо изолировать формы, используя грубый порог, и применить алгоритм водораздела только к «соединенным» ячейкам; вы можете идентифицировать их как структуры, которые не соответствуют некоторому порогу измерения выпуклости (например, площадь/поверхность) - person Tasos Papastylianou; 22.08.2016
comment
спасибо @rayryeng, я обычно избегаю imshow, поэтому постоянно забываю об этом! :п - person Tasos Papastylianou; 22.08.2016
comment
@Sam, в целом, я бы также не стал работать с индексированными целочисленными изображениями, если для этого нет особой причины. Я бы сначала mat2gray удалил все дерьмо из вашего исходного изображения, а вместо этого поработал бы над ним. Это даже позволяет вам выполнять I.^2, который одним махом разделяет более низкую интенсивность на более высокую. - person Tasos Papastylianou; 22.08.2016
comment
взгляните на соответствующие посты справа. один из них ссылается на blogs.mathworks.com/steve/2006/ 02/06/cell-segmentation, который также может быть полезен - person Tasos Papastylianou; 22.08.2016