Ripple effect in MATLAB

2.2k Views Asked by At

I want to write a function newim = rippleim(im) that takes an image and returns a new image with ripple effect on it.

I thought calculating the distance of all points from (p,q) and then a multiplication of sin(d).*exp(-d) would give a good effect of fading waves.

n = 800;
m = 800;
im = zeros(n,m,3);
p = [round(m*.5) round(n*.5)];
[x y] = meshgrid(1:m,1:n);
x = x - p(1,1);
y = y - p(1,2);
d = (x .^2 + y .^2).^.5;
R = cos(.05*d) .* exp(-.005*d);
G = cos(.05*d) .* exp(-.005*d);
B = cos(.05*d) .* exp(-.005*d);
im = cat(3,R,G,B);
imshow(im);

And I got,

enter image description here

with normalization to [0 1], it got a little better,

enter image description here

It still doesn't seem right.

I even googled and found some similar cases in python here, about the animation. But I just want a fixed effect.

Q1 How to improve the effect?

Q2 How to apply it on an existing image?

Thanks,

2

There are 2 best solutions below

0
On BEST ANSWER

I finally found my answer. What I was looking for, can be done by warp command.

so I define a 3D rippled surface with help of cos(d)*exp(-d) and texture my picture on it.

im = imread('peppers.png');
n = -10 : .1 : 10;
[X,Y] = meshgrid(n,n);
d = (X .^ 2 + Y .^ 2) .^ .5;
Z = cos(1.5 * d) .* exp(-.1 .* d);
warp(X,Y,Z,im);axis equal;axis off;

enter image description here

2
On

About your first part of question, instead of finding a function that suits your taste by trial and error, I suggest that you create manually by hand a look-up table "function" that you have in mind, and then fit a high-order polynomial to it.

About your second part, I am guessing that by applying you mean using it as a mask. In this case, you can simply multiply a normalized version of ripple effect by your image:

imp = double(imread('peppers.png'));
n = size(imp,1);
m = size(imp,2);
p = [round(m*.5) round(n*.5)];
[x,y] = meshgrid(1:m,1:n);
x = x - p(1,1);
y = y - p(1,2);
d = (x .^2 + y .^2).^.5;
mask = cos(.05*d) .* exp(-.005*d);
im = (mask-min(mask(:)))./ ( max(mask(:))-min(mask(:)));
I = bsxfun(@times,im,imp);
imshow(I/255);

enter image description here