Search code examples
matlabimage-segmentationpixel

How to group pixels into blobs in Matlab?


I have this image with white points on a dark background:

enter image description here

I want to group pixels that are close by into a single blob. In this image, that would mean that there will be two blobs in the image, one for the pixels at the top and one for the pixels at the bottom. Any pixels that are not too close to these two blobs must be changed into the background color (A threshold must be specified to choose which pixels fall into the blobs and which of them are too far). How do I go about this? Any Matlab function that can be used?


Solution

  • To group dots, one can simply smooth the image sufficiently to blur them together. The dots that are close together (with respect to the blur kernel size) will be merged, the dots that are further apart will not.

    The best way to smooth the image is using a Gaussian filter. MATLAB implements this using the imgaussfilt function since 2015a. For older versions of MATLAB (or Octave, as I'm using here) you can use fspecial and imfilter instead. But you have to be careful because fspecial makes it really easy to create a kernel that is not at all a Gaussian kernel. This is the reason that that method is deprecated now, and the imgaussfilt function was created.

    Here is some code that does this:

    % Load image
    img = imread('https://i.sstatic.net/NIcb9.png');
    img = rgb2gray(img);
    
    % Threshold to get dots
    dots = img > 127; % doesn't matter, this case is trivial
    
    % Group dots
    % smooth = imgaussfilt(img,10); % This works for newer MATLABs
    g = fspecial("gaussian",6*10+1,10);
    smooth = imfilter(img,g,'replicate'); % I'm using Octave here, it doesn't yet implement imgaussfilt
    
    % Find an appropriate threshold for dot density
    regions = smooth > 80; % A smaller value makes for fewer isolated points
    
    % Dots within regions
    newDots = dots & regions;
    

    To identify blobs that are within the same region, simply label the regions image, and multiply with the dots image:

    % Label regions
    regions = bwlabel(regions);
    
    % Label dots within regions
    newDots = regions .* dots;
    
    % Display
    imshow(label2rgb(newDots,'jet','k'))
    

    labeled dots