I am trying to segment the nucleus of the cell in an image so I can extract its boundary. The nucleus and the background of the image are very similar so I am finding it difficult to do this using the something like erosion.

If anyone could suggest a way to remove the background and keep the nucleus that would be very helpful.


cell nucleus

  • $\begingroup$ Yes it is it's about segmentation methods $\endgroup$
    – user3461851
    May 8 '14 at 15:02
  • $\begingroup$ It's just the red central region I am trying to extract, but when converted to black and white, it doesn't work so well as the background is the same colour as it. $\endgroup$
    – user3461851
    May 8 '14 at 15:04
  • $\begingroup$ Have you looked at working on just the red channel? $\endgroup$
    – Dan
    May 8 '14 at 15:08
  • $\begingroup$ @Dan I'm new to this, how exactly would I go about that. $\endgroup$
    – user3461851
    May 8 '14 at 15:13
  • 1
    $\begingroup$ RGB's approach is fast and can provide a quick fix, but there might be red in other parts of the image. Converting to HSV is an option, or YCbCr as suggested by @Shai $\endgroup$
    – Cape Code
    May 8 '14 at 15:27

You need to work with different color space. Try YCbCr for instance

oimg = imread('http://i.stack.imgur.com/aYhrS.png');
img = rgb2ycbcr(oimg); % conver RGB to YCbCr color space
msk = img(:,:,3)>130;  % apply threshold on Cr channel to get segmentation mask

I picked up 130 as arbitrary threshold, you might need to adjust it a bit.
Showing the input image, the image region for which msk==1, and the background: enter image description here

I'll leave it to you as an exercise to think why the Cr channel performed well for this image.


The reason you're running into difficulty is because you're doing a black-white conversion, and this step is "throwing out" your best differentiating feature. Try doing the segmentation in a non b-w color space. The segmentation itself can be done pretty easily using k-means clustering:

img = imread('http://i.stack.imgur.com/aYhrS.png');

cform = makecform('srgb2lab');
lab_he = applycform(img,cform);

% classify the colors in 'a*b*' Space Using k-means clustering
ab = double(lab_he(:,:,2:3));
nrows = size(ab,1);
ncols = size(ab,2);
ab = reshape(ab,nrows*ncols,2);

% Looks like there are ~3 colors in the image
nColors = 3;

% repeat the clustering 3 times to avoid local minima
[cluster_idx, cluster_center] = kmeans(ab,nColors,'distance','sqEuclidean', ...

pixel_labels = reshape(cluster_idx,nrows,ncols);

% nucleus is in the center. figure out what its label is.
middleX = round(size(img,2)/2);
middleY = round(size(img,1)/2);

nucleusLabel = pixel_labels(middleX,middleY);

tempImg = bsxfun(@eq,pixel_labels,nucleusLabel);
tempImg = bsxfun(@times,double(tempImg),double(img));


  • 1
    $\begingroup$ you can reshape without explicitly computing the number of points: ab=reshape( ab, [], 2 ); $\endgroup$
    – Shai
    May 8 '14 at 15:34
  • 1
    $\begingroup$ you should use bsxfun to get tempImg from the mask pixel_labels ~= nucleusLabel instead of loop over the channels. $\endgroup$
    – Shai
    May 8 '14 at 15:37
  • $\begingroup$ have you tried mean-shift segmentation? should preserve the spatial relations between the pixels... $\endgroup$
    – Shai
    May 8 '14 at 15:38
  • 1
    $\begingroup$ Good point! Replaced the loop with bsxfun. Haven't tried mean-shift segmentation yet, though. $\endgroup$
    – ChuckN
    May 8 '14 at 15:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy