10

How can one implement the fisheye lens effect illustrated in that image:

fisheye example

One can use Google's logo for a try:

alt text

BTW, what's the term for it?

Community
  • 1
  • 1
user198729
  • 61,774
  • 108
  • 250
  • 348

3 Answers3

13

I believe this is typically referred to as either a "fisheye lens" effect or a "barrel transformation". Here are two links to demos that I found:

Example

In this example, I started with the function radial.m from the first link above and modified the way it relates points between the input and output spaces to create a nice circular image. The new function fisheye_inverse is given below, and it should be placed in a folder on your MATLAB path so you can use it later in this example:

function U = fisheye_inverse(X, T)

  imageSize = T.tdata(1:2);
  exponent = T.tdata(3);
  origin = (imageSize+1)./2;
  scale = imageSize./2;

  x = (X(:, 1)-origin(1))/scale(1);
  y = (X(:, 2)-origin(2))/scale(2);
  R = sqrt(x.^2+y.^2);
  theta = atan2(y, x);

  cornerScale = min(abs(1./sin(theta)), abs(1./cos(theta)));
  cornerScale(R < 1) = 1;
  R = cornerScale.*R.^exponent;

  x = scale(1).*R.*cos(theta)+origin(1);
  y = scale(2).*R.*sin(theta)+origin(2);
  U = [x y];

end

The fisheye distortion looks best when applied to square images, so you will want to make your images square by either cropping them or padding them with some color. Since the transformation of the image will not look right for indexed images, you will also want to convert any indexed images to RGB images using ind2rgb. Grayscale or binary images will also work fine. Here's how to do this for your sample Google logo:

[X, map] = imread('logo1w.png');  % Read the indexed image
rgbImage = ind2rgb(X, map);       % Convert to an RGB image
[r, c, d] = size(rgbImage);       % Get the image dimensions
nPad = (c-r)/2;                   % The number of padding rows
rgbImage = cat(1, ones(nPad, c, 3), rgbImage, ones(nPad, c, 3));  % Pad with white

Now we can create the transform with maketform and apply it with imtransform (or imwarp as recommended in newer versions):

options = [c c 3];  % An array containing the columns, rows, and exponent
tf = maketform('custom', 2, 2, [], ...  % Make the transformation structure
               @fisheye_inverse, options);
newImage = imtransform(rgbImage, tf);   % Transform the image
imshow(newImage);                       % Display the image

And here's the image you should see:

enter image description here

You can adjust the degree of distortion by changing the third value in the options array, which is the exponential power used in the radial deformation of the image points.

gnovice
  • 125,304
  • 15
  • 256
  • 359
  • Where should I place those `.m` files in order for it to work? – user198729 Apr 07 '10 at 05:02
  • You put the files into any folder that is on the Matlab path. For example, when you start Matlab, type 'pwd' and hit return. The path shown is where you can put the files. – Jonas Apr 07 '10 at 08:39
  • Oh it works,but the corner is not so round,how to tune the parameters to get similar effect in my post? – user198729 Apr 07 '10 at 09:32
  • It's not working with true color images like the google logo in my post. – user198729 Apr 07 '10 at 11:20
  • Hi gnovice,how to make the code work for all kinda images?Based on your previous answer,the only case that's not covered yet is how to transform a grayscale or binary image? – user198729 Apr 08 '10 at 10:05
  • How to adjust the parameters so that the image can fit into a circular frame like @upperBound's solution?Though @upperBound's transform will damage the quality.. – user198729 Apr 08 '10 at 10:17
  • I tried `options = [c/2 r/2 max(r,c)/2 1 1 1 1 1]; ` and `options = [c/2 r/2 max(r,c)/2 11 1 1 1 1]; `,both give:`Warning: FINDBOUNDS: Search procedure failed; returning OUTBOUNDS = INBOUNDS.` – user198729 Apr 08 '10 at 14:22
  • @user198729: I updated my example. I think it addresses most of the concerns you raised in the comments. – gnovice Apr 08 '10 at 21:34
  • Seems there is something wrong with the padding,it's not working here,I'll post how it looks like in my question update. – user198729 Apr 09 '10 at 04:30
  • @user198729: I found the typo. The `options` array should be `[c c 3]`, since the array has been padded to be square. – gnovice Apr 09 '10 at 05:02
  • Very impressive!But how to automate the padding for arbitary images?I'll accept this one and post a new question though:) – user198729 Apr 09 '10 at 05:04
  • @gnovice seems the server-hosted resulting image have been removed. Better check that out. – ibrahim mahrir Jun 29 '17 at 14:22
  • 1
    @ibrahimmahrir: Fixed, no thanks to those jerks at photobucket. ;) – gnovice Jul 08 '17 at 03:41
1

I think you are referring to the fisheye lens effect. Here is some code for imitating fisheye in matlab.

Greg Bray
  • 14,929
  • 12
  • 80
  • 104
1

Just for the record:

This effect is a type of radial distortion called "barrel distortion".

For more information please see:

http: //en.wikipedia.org/wiki/Distortion_(optics)

Here is a different method to apply an effect similar to barrel distortion using texture mapping (adapted from MATLAB Documentation):

[I,map] = imread('logo.gif');
[h,w] = size(I);

sphere; 

hS = findobj('Type','surface');

hemisphere = [ones(h,w),I,ones(h,w)];

set(hS,'CData',flipud(hemisphere),...
    'FaceColor','texturemap',...
    'EdgeColor','none')

colormap(map)
colordef black
axis equal
grid off
set(gca,'xtick',[],'ztick',[],'ytick',[],'box','on')
view([90 0])

This will give you the circular frame you are looking for but the aliasing artifacts might be too much to deal with.

upperBound
  • 680
  • 4
  • 11
  • The circular frame is very nice,but the image is blured,how to overcome this? – user198729 Apr 08 '10 at 10:10
  • You may try to increase the image size or use a high resolution image to start with. It will also depend on how your graphics stack handles such mappings. On a positive side, you may map an image on an arbitrary surface and get "carnival mirror" effects... – upperBound Apr 09 '10 at 14:12
  • Can you update the code with the `carnival mirror` you mentioned? – user198729 Apr 11 '10 at 18:50