【问题标题】:How do I perform an image warp or transformation from one coordinate system to another for a barrel distorted image?对于桶形失真图像,如何执行图像扭曲或从一个坐标系到另一个坐标系的转换?
【发布时间】:2019-03-07 16:57:24
【问题描述】:

我用这个question 来帮助我想出一个不失真的图像协调系统。现在,我不确定如何在图像中实现新的坐标系,以便能够生成不失真的图像。

我无法找到不涉及 Matlab、OpenCV 或 C++ 的答案因为我正在使用 R

我从引用的问题中使用的答案给了我以下转换后的 xy 坐标:

1 -19.50255239, -19.50255239
2 -18.26735544, -18.26735544
3 -17.03391152, -17.03391152
4 -15.80221494, -15.80221494
5 -14.57225998, -14.57225998
6 -13.34404095, -13.34404095
...

512 x 512 图像中的 512 像素等等。

如何将它应用回原始的 512 x 512 图像是我正在努力解决的问题。我在 Open CV 页面here 和特定的pre-defined shiftslatitudinal/longitudinal shifts 等页面上看到了一些提及,使用SpatialObjectsDataFrames,但不是从一个用户定义的xy 坐标列表到另一个。

-获取源图像坐标的示例:

im_coords <- RSAGA::grid.to.xyz(as.matrix(as.raster(im)))

(请注意,我实际上并不想对图像进行光栅化,这正是我当时found 的内容)

-我用来获取转换后坐标的代码:

undistort <- function(X, Y, a, b, c, d = 1, imWidth = 512, imHeight = 512) {

    #radial barrel distortion
    normX <- X - (imWidth / 2)
    normY <- Y - (imHeight / 2)

    #rmax
    radius_u <- sqrt(imWidth^2 + imHeight^2)

    #normalize r so that its between 0 and 1
    r <- sqrt(normX^2 + normY^2) /  radius_u

    #Barrel distorition equation: where "r" is the destination radius and "Rsrc" is the source pixel to get the pixel color from
    Rsrc <- r * (a*r^3 + b*r^2 + c*r + d)

    theta <- ifelse(Rsrc == 0, 1, 1 / atan(Rsrc) * Rsrc)

    newX <- (imWidth / 2) + theta * normX
    newY <- (imHeight / 2) + theta * normY

    return(data.frame(X = newX, Y = newY))
}

这是一个 512x512 .png 桶形扭曲图像示例:https://imgur.com/a/W9Qz70W

我想知道kriging 是否有用?还是gdalwarpproj4string?不知道如何实现这些。

更新: 使用 Rohit 的建议,我能够扭曲彩虹网格:

到这里:

当我尝试使用桶形图像时,我得到了这个奇怪的叠加图像:

好的,我认为这取决于您使用的系数,如下所示:

【问题讨论】:

    标签: r image opencv warp


    【解决方案1】:

    您实际上不需要计算转换后的 xy 坐标。您只需要获取 x 和 y 坐标并返回未失真坐标的函数。给定您的 undistort 函数,围绕它编写一个仅使用 x 和 y 作为输入的包装器:

    im2 <- imwarp(im1, function(x,y){ 
      undistort(x,y,a=1,b=2,c=4) # Give appropriate values for arguments, I'm not an expert.
    })
    

    如果您想专门从一个列表映射到另一个列表,那么您也可以这样做:

    df <- expand.grid(x=1:512,y=1:512) # Original grid coordinates
    df1 <- undistort(X=df$x,Y=df$y) # Undistorted grid coordinates
    im2 <- imwarp(im1, function(x,y){
      df1[df$x==x & df$y==y,] # Map appropriately. Should still work.
    })
    

    interpolation 尝试不同的选项,看看哪个最有效。

    【讨论】:

    • 感谢您的回复。因此,当我尝试将函数 'undistort' 给我的坐标列表传递给 imwarp 时,我收到一个错误:“1:d[4] 中的错误:NA/NaN 参数”。这可能是意料之中的,因为 impwarp 应该使用图像作为扭曲场,而不是坐标列表。我现在正在研究第二个建议。主要问题仍然是我需要从坐标列表中制作图像。
    • ?imager::as.cimg.data.frame
    • @SqueakyBeak 请确保上述解决方案是否有效
    • 也许我不清楚。如果im1 是您的原始图像,df 具有您的原始网格坐标,df1 具有相应的新坐标,则im2 是具有必要映射的图像。如果您进一步查看imager 的文档,您会发现以所需格式加载和保存图像所需的功能。
    • 所以我能够让它在我为扭曲图像而制作的彩虹网格上工作,但是当我在桶形扭曲图片上尝试它时,它只是显示为全黑。我会用图片更新描述。
    猜你喜欢
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多