Search code examples
matlabimage-processing

Image noise filtering with borders in Matlab


I've got an image with objects border pretty blurried (or confused), but I cannot make a mask able to distinguish in order to count how many objects I have in the image.

This is the one (I cloned on purpose few cells with Photoshop to get the problem):

enter image description here

I played with the contrast like this and used the medfilt2 to remove noise from the image:

image = imread('image.jpg');

figure; imshow(image);
figure;imhist(image);
image_contrasted = imadjust(image,[0.3 0.55],[]);
figure; imshow(image_contrasted);

image_negative = 255-image_contrasted;
mask = imbinarize(rgb2gray(image_negative), 0);
 
mask_cleaned = medfilt2(mask,[5 5]);
mask_cleaned = im2uint8(mask_cleaned);

figure; imshow(mask_cleaned);
N_objects = [bwconncomp(mask_cleaned).NumObjects]

After the denoising some borders may merge with adjacent objects. And using a smaller area for medfilt2does not remove enough noise. Is there any way to enhance borders before or after the contrast adjustment?


Solution

  • The objects borders are blurry, but there is relatively high contrast between the borders and the surrounding area.
    We may strengthen the borders by sharpening the image using imsharpen:

    image_sharpen = imsharpen(image, 'Radius', 2, 'Amount', 1);
    

    Instead of cleaning the image using medfilt2, we may use bwfill, followed by bwareaopen for removing small "objects".
    I selected P = 300 for removing all "objects" smaller than 300 pixels (it may be a bit of an overfitting).

    mask_filled = bwfill(mask, 'holes');
    mask_reaopen = bwareaopen(mask_filled, 300, 4);
    

    Code sample:

    close all
    
    image = imread('image.jpg');
    figure; imshow(image); title('image')
    
    image_sharpen = imsharpen(image, 'Radius', 2, 'Amount', 1);
    figure; imshow(image_sharpen); title('image\_sharpen')
    
    figure;imhist(image_sharpen); title('imhist image\_sharpen')
    image_contrasted = imadjust(image_sharpen, [0.3 0.55], []);
    figure; imshow(image_contrasted); title('image\_contrasted')
    
    image_negative = 255-image_contrasted;
    mask = imbinarize(rgb2gray(image_negative), 0);
    figure; imshow(mask); title('mask')
    
    mask_filled = bwfill(mask, 'holes');
    figure; imshow(mask_filled); title('mask\_filled')
    
    %mask_cleaned = medfilt2(mask,[5 5]);
    %mask_cleaned = im2uint8(mask_cleaned);
    %figure; imshow(mask_cleaned);  title('mask\_cleaned')
    
    mask_reaopen = bwareaopen(mask_filled, 300, 4);
    figure; imshow(mask_reaopen); title('mask\_reaopen')
    
    CC = bwconncomp(mask_reaopen);
    N_objects = CC.NumObjects % N_objects = 18
    

    mask_reaopen:
    enter image description here

    In case you like to count the overlapping objects as you may try something like Watershed Segmentation (I don't know if it's going to work).