What is best way to reduce speckle size?
Show older comments
I have an image with speckle noise. My question is how to reduce the speckle size rather than speckle noise. Please find the attached image for an example. If you look over the image carefully then you can find the speckle noise with huge size, I want to reduce the size of the speckle.
8 Comments
It's not really clear why you want to make the noise smaller, so the expectations aren't obvious. What should the expected speckles should look like?
Should all speckles be reduced to a certain size? To one pixel?
Does retention of the original shape/intensity matter?
Since the image is not binarized and the noise values extend to zero, which noise gets deleted? i.e. what threshold?
Adam Danz
on 23 Aug 2021
Given the size of the speckles, you won't be able to reduce them and maintain their shape at the same time. Consider the following 4x5 pattern of pixels and try to imagine reducing the pattern of 1s without changing its shape.
0 0 0 0 0
0 1 0 0 0
0 1 1 0 0
0 1 1 0 0
It's not possible unless you enlarge the entire image thereby reducing the relative size of the object but when you add other groups of 1 it's gets more complicated.
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0
0 0 0 1 1 0 0 0 0
0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0
Alternatively, you could reduce the shape of each group by eliminating some of its pixels,
0 0 0 0 0
0 1 0 0 0
0 1 1 0 0
0 0 0 0 0
Well then my answer is probably useless to you. Like Adam said, with such a small image, you're going to have a hard time retaining any shape information. The mask-shrinking method in the first example I gave can retain some shape information if used with a small iteration value, but at this scale, removing one pixel's width from the perimeter of an object will often reduce the object to a single pixel.
All I can suggest is to extract the objects of interest using some binarization technique and then do whatever "shrinking" is appropriate for your needs on each blob. It might need to be done in a loop.
Adam Danz
on 23 Aug 2021
If each speckle represents an independent label, you could extract each pixel from the image and then apply the size reduction method I described above.
Dynamic
on 24 Aug 2021
Adam Danz
on 24 Aug 2021
As indicated in my comment, it would be fairly easy to accomplish with a single object in the image but with many objects, it much more complicated and I'm not even 100% sure it's possible. By 'a piece of code' I'm assuming you're looking for an entire solution which I don't have (not even conceptually).
You've got yourself a very hard problem if I understand it correctly. The objects in your image are very noise and due to the low resolution, they are represented by just a few pixels in some cases. You can't shrink that.
DGM
on 24 Aug 2021
I added an example of resizing objects. Note the practical limitations.
Answers (2)
Since it's unclear what properties are important, I'll just make something up.
This does the "shrinking" by essentially cropping the edges of each "speckle" area in a mask:
inpict = imread('text_qss.jpg');
% binarize the image using some method to describe what constitutes a "speckle"
%m = imbinarize(inpict,'adaptive','foregroundpolarity','bright','sensitivity',0);
m = inpict>30;
% shrink said mask by one pixel (or more if desired)
ms = bwmorph(m,'shrink',1);
% extract base noise and "shrunk" speckles, combine
basenoise = uint8(double(inpict).*~m); % remove speckles from image
peaknoise = uint8(double(inpict).*ms); % apply shrunk mask to speckles
outpict = basenoise + peaknoise; % combine
ORIGINAL:

MODIFIED:

Alternatively, "shrinking" could be done with a mask to crudely enforce a desired size and shape.
inpict = imread('text_qss.jpg');
% binarize the image using some method to describe what constitutes a "speckle"
m = inpict>30;
% create gaussian mask around each speckle center
S = regionprops(m,inpict,'weightedcentroid');
C = round(vertcat(S.WeightedCentroid));
cm = zeros(size(m));
cm(sub2ind(size(m),C(:,2),C(:,1))) = 1;
f = mat2gray(fspecial('gaussian',5,1)); % pick some radius,sigma
cm = imfilter(cm,f);
basenoise = uint8(double(inpict).*~m); % extract base noise
peaknoise = uint8(double(inpict).*cm.*m); % extract speckles, apply mask
outpict = basenoise+peaknoise; % combine

EDIT:
This is an example of literally resizing objects and cramming them back into an image. This isn't something that would be practical for tiny images where object features are only 1px wide, so I'm using a larger test image. This also would likely destroy the meaningfulness of certain qualities of the image, given that a nonuniform object can no longer fit in its original location. An object with a hole will shrink to occlude background features which were once visible, and it will leave behind an area of empty image where no background features exist.
I made no attempt to place objects according to their centroid or weighted centroid. That would probably also be worth considering. This is just a simplified example.
% this assumes uint8 images, light-on-dark polarity
inpict = imread('sources/speckleseg.png');
m = bwareafilt(inpict>35,5);
objscale = 0.5;
S = regionprops(m,inpict,'subarrayidx','image');
outpict = uint8(double(inpict).*~m); % remove objects from image
for k = 1:numel(S)
% extract a masked copy of this object
thisobj = uint8(double(inpict(S(k).SubarrayIdx{:})).*S(k).Image);
s0 = size(thisobj);
% shrink by scaling factor
thisobj = imresize(thisobj,objscale);
s1 = size(thisobj);
% pad symmetrically with zero
thisobj = padarray(thisobj,ceil((s0(1:2)-s1(1:2))/2),0,'pre');
thisobj = padarray(thisobj,floor((s0(1:2)-s1(1:2))/2),0,'post');
% insert resized object back into output image
outpict(S(k).SubarrayIdx{:}) = outpict(S(k).SubarrayIdx{:}) + thisobj;
end


Like I said, since objects don't fit back into the holes they left in the background, you'll have to decide where they go. If they simply remain centered in their bounding box, the result can very easily change the structure of an image.


Image Analyst
on 24 Aug 2021
0 votes
I don't have any software for it but a common way to reduce speckle noise is the Knox-Thompson filter. Just Google it. Sorry, I can't help you write the code.
Or see
Categories
Find more on Image Preview and Device Configuration in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!