实现“光学补偿”效果

问题描述 投票:0回答:1

我正在尝试复制 Adobe After Effects 中称为“光学补偿”的效果。我认为这与镜头畸变类似。但那里使用的公式不适合。 该效果有几个选项可以操作。该效果有几个参数可以更改。

  1. 中心
  2. 视场。又称视野。值从 0 到 180 度。
  3. FOV 方向(水平、垂直、对角线)

在此视频中我将 FOV 值从 0 度动画到 180 度;中心 = 540,960

还有图像示例:

enter image description here

看起来像桶形畸变或鱼眼畸变。

我尝试了不同的公式。例如“镜头校正模型

enter image description here

但是我不明白如何仅使用 FOV 和中心值来计算所有这些参数。

有谁知道如何达到这个效果吗?应该使用什么公式? 到处都描述了如何修复“镜头畸变”。但如何在图片上应用这样的效果呢?

经过一番研究,我发现了 Mathworks 实现用于桶变换。 enter image description here

代码

[xi,yi] = meshgrid(1:ncols,1:nrows);
xt = xi - ncols/2;
yt = yi - nrows/2;

[theta,r] = cart2pol(xt,yt);
a = 1; % Try varying the amplitude of the cubic term.
rmax = max(r(:));

s1 = r + r.^3*(a/rmax.^2);
[ut,vt] = pol2cart(theta,s1);
ui = ut + ncols/2;
vi = vt + nrows/2;
ifcn = @(c) [ui(:) vi(:)];
tform = geometricTransform2d(ifcn);
I_barrel = imwarp(I,tform,FillValues=fill);
imshow(I_barrel)

我在苹果金属中的实现

fragment float4 opticsCompensationFragment(metalpetal::VertexOut vertexIn [[ stage_in ]],
                                           texture2d<float, access::sample> inputTexture [[ texture(0) ]],
                                           sampler inputTextureSampler [[ sampler(0) ]]) {
    
    float2 center = float2(0.5, 0.5);
    
    // Shift the origin to the center of the image
    float2 st = vertexIn.textureCoordinate - center;
    
    // Convert the Cartesian x- and y-coordinates to cylindrical angle (theta) and radius (r) coordinates
    float theta = sqrt(st.x * st.x + st.y * st.y);
    float r     = atan2(st.y, st.x);
    
    // Try varying the amplitude of the cubic term.
    float a  = 0.1;
    
    //  add a cubic term to r so that r changes nonlinearly with distance from the center pixel.
    float s1 = r + (r*r*r)*(a/(r*r));
    
    // Convert back to the Cartesian coordinate system. Shift the origin back
    float ut = theta * cos(s1) + center.x;
    float vt = theta * sin(s1) + center.y;
    
    
    return inputTexture.sample(inputTextureSampler, float2(ut, vt));
}

但是我的结果不是这样的。

enter image description here

唯一的区别是,在 Mathworks 的代码中,他们使用 meshwarp,但我尝试仅使用 片段着色器 来实现这一点。 我的代码可能有什么问题?

ios opengl-es metal distortion
1个回答
0
投票

一个问题是您在笛卡尔坐标的转换中混淆了半径和角度的公式(或者至少您为这些变量选择了混淆的名称)。因此,当您修改

r
变量时,您实际上是在更改角度,而您想要更改的半径位于未更改的
theta
变量中。

© www.soinside.com 2019 - 2024. All rights reserved.