校正R中x,y系列的镜筒失真

时间:2014-08-06 12:05:35

标签: r image-processing geometry distortion

编辑:理想情况下,我想对ImageMagick的-distort函数使用相同的算法,但是在R中实现,以便转换原始x,y坐标,而不是图像。使用ImageMagick还可以让我获得非失真有效性的视觉证据。

问题

我有一个x,y系列,由跟踪软件分析视频而制作。视频中的原始图像有一些镜筒失真,我想纠正,以提高跟踪坐标的准确性。

我可以使用ImageMagick中的扭曲运算符执行看似合适的修正,例如:

convert input.jpg -distort barrel '0 -0.022 0' output.jpg

现在我知道我可以对视频中的每一帧(跟踪前)应用此校正,但这似乎不是最好的选择,因为我有几十个视频,每个视频都包含> 7e4帧。在跟踪之后,似乎更容易将校正应用于x,y坐标本身。

从ImageMagick documentation,桶形失真方程式为:

  

Rsrc = r *(A r ^ 3 + B r ^ 2 + C * r + D)

     

其中“r”是目标半径,“Rsrc”是获取像素颜色的源像素。对于输入图像的半个最小宽度或高度,半径是标准化的,因此半径='1.0'。“

但我不知道如何在R中实现它以转换x,y系列。有人可以提供任何帮助吗?谢谢!

到目前为止我尝试了什么

我已经尝试了我自己的功能,修改了我发现here的简单算法,但这似乎引入了更大的桶形失真(如果有的话)(其极性似乎无法逆转) ):

undistortFun <- function(X, Y, strength) {

    imWidth <- 640
    imHeight <- 480

    radius_u <- sqrt(imWidth^2 + imHeight^2) / strength

    normX <- X - (imWidth / 2)
    normY <- Y - (imHeight / 2)

    distance <- sqrt(normX^2 + normY^2)
    r <- distance / radius_u

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

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

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

}

类似问题

我发现了两个类似的问题,herehere,但这些问题与未失真的图像有关,而不是原始的x,y坐标,并且是用Java和C ++实现的,我不熟悉用。

1 个答案:

答案 0 :(得分:2)

通过使用ImageMagick失真算法修改问题中提供的功能,我得到了一个令人满意的解决方案:

  

Rsrc = r *(A r ^ 3 + B r ^ 2 + C * r + D)

像这样:

undistortFun <- function(x, y, a, b, c, d = 1, imWidth = 640, imHeight = 480) {

    normX <- X - (imWidth / 2)
    normY <- Y - (imHeight / 2)

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

    r <- sqrt(normX^2 + normY^2) /  radius_u

    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))
}

虽然我对theta的计算不确定,并且指定零失真(a = 0,b = 0,c = 0)仍然会导致转换。然而,它似乎在这些样本中做了我想要的事情:

原始x,y数据的图:

original

调整后的x,y数据的图(其中:a = 0,b = -0.02,c = 0): adjusted