编辑:理想情况下,我想对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))
}
我发现了两个类似的问题,here和here,但这些问题与未失真的图像有关,而不是原始的x,y坐标,并且是用Java和C ++实现的,我不熟悉用。
答案 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数据的图:
调整后的x,y数据的图(其中:a = 0,b = -0.02,c = 0):