Frosty Filter: To create effect like frosted glass

조회 수: 21(최근 30일)
Rohit Kharat
Rohit Kharat 2022년 1월 21일
편집: DGM 2022년 1월 21일
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?


DGM 2022년 1월 21일
편집: DGM 2022년 1월 21일
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);
function outpix = getpix(sample)
outpix = sample(randi([1 numel(sample)],1));
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);
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]);
These modes don't use uniform sampling from a fixed window. From the synopsis:
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.
Identical to 'spatial', but all pages of the array are displaced with unique displacement maps.
  댓글 수: 2
DGM 2022년 1월 21일
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.

댓글을 달려면 로그인하십시오.


Community Treasure Hunt

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

Start Hunting!

Translated by