I have this image with white points on a dark background:
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?
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'))