问题
I have the following picture which is a photo of pancreatic cells
What I would like to do is being able to get the membrane of each cell (red filament) and then do a tessellation in order to get an idea of the length of a filament. So far I have tried to use the example given on the matlab website but the result is not really good...
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]);
I have been searching for hours other way to do it but without any satisfying result... Is there a way to do so ? Maybe an other software than matlab could be more efficient. Thank you by advance !
回答1:
I don't know anything about cells or tessellation or whatever. But if you want to detect those blobs in a non uniform background, then I might help. You need to analyse the blobs individually because of the non uniform background. You can't just set a fixed threshold to detect all blobs at once. First, you will detect each blob individually and then use individual threshold. Here is the example
The original image
im=imread('gxGkH.jpg');
figure,imagesc(im);axis image;
I am choosing only the blue colour to analyse
imb=im(:,:,3);
figure,imagesc(imb);axis image;
1) Blur the image, since after blurring the blobs will have local maxima/minima at their centres
sigma=7;
kernel = fspecial('gaussian',4*sigma+1,sigma);
im2=imfilter(imb,kernel,'symmetric');
figure,imagesc(im2);axis image;
2) Use watershed transform to separate each blob region
% L = watershed(im2);
L = watershed(max(im2(:))-im2);
[x,y]=find(L==0);
Draw the boundaries
figure,imagesc(im2),axis image
hold on, plot(y,x,'r.')
3) Here I analyse each blob individually and find an otsu threshold for each blob, then I detect the blobs and combine all detections
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
Remove some noise
tmp=imopen(tmp,strel('disk',1));
figure,imagesc(tmp),axis image
If the background has higher contrast then the blobs, then you won't need to invert the image in watershed transform.
回答2:
I am not sure if this may get you closer to the solution of your problem, but what I would do would be something like this. Mind you, it's a really simple and naive approach:
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
The binary image should look like this:
Now you can use Mathematical Morphology to eliminate the noise. You first create a structuring element and then you convolve it with the 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
Now your new image should look like this:
At this point you can use another morphological operation that finds the skeleton:
skeleton = bwmorph(closed_im, 'skel', Inf); % Find skeleton image
The skeleton image would look like this:
Of course this method is far from being precise, but may give you an overall information on the length of the filament, especially if you could get rid of the final noise (those appendices of the skeleton).
来源:https://stackoverflow.com/questions/42626416/how-to-properly-tesselate-a-image-of-cells-using-matlab