如何在 MATLAB 中实现鱼眼镜头效果(桶形变换)?

Posted

技术标签:

【中文标题】如何在 MATLAB 中实现鱼眼镜头效果(桶形变换)?【英文标题】:How can I implement a fisheye lens effect (barrel transformation) in MATLAB? 【发布时间】:2010-04-07 03:37:57 【问题描述】:

如何实现该图像中所示的鱼眼镜头效果:

大家可以试试谷歌的logo:

顺便说一句,它的术语是什么?

【问题讨论】:

链接失效。它给出了一条消息:You don't have permission to access the requested object. 等一下,我来修复它.. 【参考方案1】:

我相信这通常被称为“鱼眼镜头”效果或“桶形变换”。以下是我找到的两个演示链接:

Sample code 了解如何使用来自Image Processing Toolbox 的函数maketform'custom' 选项将鱼眼扭曲应用于图像。

An image processing demo 使用函数tformarray 执行桶形变换。

示例

在此示例中,我从 first link above 中的函数 radial.m 开始,并修改了它在输入和输出空间之间关联点的方式以创建漂亮的圆形图像。新函数fisheye_inverse 如下所示,它应该放在MATLAB path 上的一个文件夹中,以便稍后在此示例中使用它:

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

鱼眼失真在应用于方形图像时看起来最好,因此您需要通过裁剪或填充一些颜色来使图像呈方形。由于图像的转换不适用于indexed images,因此您还需要使用ind2rgb 将任何索引图像转换为RGB images。 Grayscale 或 binary images 也可以正常工作。以下是如何为您的示例执行此操作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

现在我们可以使用maketform 创建转换并使用imtransform(或在较新版本中推荐的imwarp)应用它:

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

这是您应该看到的图像:

您可以通过更改options数组中的第三个值来调整失真程度,这是图像点径向变形中使用的指数幂。

【讨论】:

我应该把那些.m 文件放在哪里才能让它工作? 您将文件放入 Matlab 路径上的任何文件夹中。例如,当您启动 Matlab 时,键入“pwd”并按回车键。显示的路径是您可以放置​​文件的位置。 哦,它可以,但是角落不是那么圆,如何调整参数以在我的帖子中获得类似的效果? 它不适用于像我帖子中的谷歌徽标这样的真彩色图像。 @ibrahimmahrir:已修复,不感谢 photobucket 的那些混蛋。 ;)【参考方案2】:

我认为您指的是fisheye 镜头效果。 Here是matlab中模仿鱼眼的代码。

【讨论】:

【参考方案3】:

仅作记录:

这种效果是一种称为“桶形畸变”的径向畸变。

更多信息请见:

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

这是一种使用纹理映射(改编自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])

这将为您提供您正在寻找的圆形框架,但锯齿伪影可能太多而无法处理。

【讨论】:

圆形边框很好看,但是图像模糊,如何克服? 您可以尝试增加图像大小或使用高分辨率图像开始。它还取决于您的图形堆栈如何处理此类映射。积极的一面是,您可以将图像映射到任意表面并获得“狂欢节镜子”效果...... 你能用你提到的carnival mirror更新代码吗?

以上是关于如何在 MATLAB 中实现鱼眼镜头效果(桶形变换)?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过openCV模拟鱼眼镜头效果?

如何通过openGL创建鱼眼镜头效果? [复制]

在Matlab中去除图像的鱼眼镜头失真时出错[重复]

图像提取基于matlab鱼眼图像有效区域提取含Matlab源码 2186期

鱼眼失真校正

相机畸变与标定