Frosty Filter: To create effect like frosted glass

1 view (last 30 days)
The task is to replace each pixel value in the image with a random value from one of its
neighbors, including self, in an n by m window.
How can I solve this task?

Answers (1)

DGM
DGM on 21 Jan 2022
Edited: DGM on 21 Jan 2022
There isn't really a tool made for this within IPT or base MATLAB. You can certainly roll your own, or you could write a small function and use nlfilter().
A = imread('cameraman.tif');
fsize = [5 5];
B = nlfilter(A,fsize,@getpix);
imshow(B)
function outpix = getpix(sample)
outpix = sample(randi([1 numel(sample)],1));
end
If you want to apply this method to RGB images, you'll have to jump through some extra hoops. You can build an index array and pass it through nlfilter() and then use that to displace the image.
Alternatively, you can do it with direct indexing:
A = imread('peppers.png');
fsize = [5 5];
s0 = size(A);
A = padarray(A,fsize,0,'both');
[xx yy] = meshgrid((1:s0(2))+fsize(2),(1:s0(1))+fsize(1));
d = ceil(fsize/2)
yy = yy + randi([-1 1]*d(1),s0(1:2));
xx = xx + randi([-1 1]*d(2),s0(1:2));
idx = sub2ind(size(A),yy,xx);
B = zeros(s0,class(A));
for c = 1:size(A,3)
thischan = A(:,:,c);
B(:,:,c) = thischan(idx);
end
imshow(B)
Although it's not strictly the same as what you mention, MIMT imnoiseFB() has a couple additional modes, including spatial noise modes.
A = imread('peppers.png');
B = imnoiseFB(A,'spatial',[5 10]);
imshow(B)
These modes don't use uniform sampling from a fixed window. From the synopsis:
imnoiseFB(INPICT,'spatial',{VARIANCE})
Displaces pixels by a random vector. Displacement magnitude is zero-mean gaussian noise with
VARIANCE specified per axis (or as scalar with implicit expansion) (default [1 1]). This is similar
to GIMP's 'spread' plugin, and more remotely, the old 'pick' plugin. Entire pixels are displaced.
imnoiseFB(INPICT,'spatialind',{VARIANCE})
Identical to 'spatial', but all pages of the array are displaced with unique displacement maps.
  2 Comments
Rohit Kharat
Rohit Kharat on 21 Jan 2022
How can I implement without in-built functions? Like using some kind of loops.
DGM
DGM on 21 Jan 2022
Edited: DGM on 21 Jan 2022
Strictly speaking, nothing useful can be done "without built-in functions".
... but I know what you probably mean is "without higher-level tools built to do the whole task conveniently". To that, I'd have to reiterate that there really is no such tool in MATLAB or IPT. The example I gave with nlfilter() still requires you to write the block filter function itself. The only thing nlfilter() does is apply it in a loop.
That said, there really isn't a need for a looped approach like most sliding-window filters. Since it's a 1:1 mapping problem, it can be done with displacement mapping, even as simply as direct indexing. The direct indexing example uses very basic functions (meshgrid, padarray), and the one loop at the end for handling RGB inputs can certainly be avoided. That was just me being lazy to avoid complicating the addressing.
Even the MIMT method doesn't use any higher-level tools built for the purpose. Even as embarassingly overcomplicated as it is (as the internal comments admit), the most complicated tools it uses are padarray(), meshgrid(), interp2(), and basic things like sin(), cos(). It's worth noting that this approach doesn't involve a sliding-window technique either.

Sign in to comment.

Categories

Find more on Creating and Concatenating Matrices in Help Center and File Exchange

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!