Коррекция искажения линз в бочках в серии x,y в R
Изменить: в идеале, я хотел бы использовать алгоритм, идентичный ImageMagick -distort
функция, но реализована в R для преобразования необработанных координат x,y, а не изображений. Использование ImageMagick также позволило бы мне получить визуальное подтверждение эффективности искажения.
Вопрос
У меня есть серия x,y, созданная на основе анализа видео с помощью программного обеспечения для отслеживания. Исходные изображения в видео имеют некоторые искажения в бочкообразной линзе, которые я хотел бы исправить, чтобы улучшить точность отслеживания координат.
Я могу выполнить то, что выглядит как подходящее исправление, используя оператор искажения в ImageMagick, например:
convert input.jpg -distort barrel '0 -0.022 0' output.jpg
Теперь я знаю, что могу применить это исправление к каждому кадру в видео (до отслеживания), но это не лучший вариант, поскольку у меня есть десятки видео, каждое из которых состоит из>7e4 кадров. Кажется, что было бы намного проще применить коррекцию к самим координатам x,y после отслеживания.
Из документации ImageMagick уравнение искажения бочки:
Rsrc = r * (A r ^ 3 + B r ^ 2 + C * r + D)
Где "r" - радиус назначения, а "Rsrc" - исходный пиксель, из которого можно получить цвет пикселя. радиусы нормализованы так, что радиус = '1,0' для половины минимальной ширины или высоты входного изображения."
Но я не знаю, как реализовать это в R для преобразования серии x,y. Может ли кто-нибудь предложить какую-либо помощь? Спасибо!
Что я пробовал до сих пор
Я экспериментировал со своей собственной функцией, модифицируя простой алгоритм, который я нашел здесь, но это, кажется, вводит большее искажение бочки, если что-нибудь (и полярность которого, кажется, не может быть полностью изменена):
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))
}
Похожие вопросы
Я нашел два похожих вопроса, здесь и здесь, но они касаются неискаженного изображения, а не необработанных координат x,y, и реализованы на Java и C++, с которыми я не знаком.
1 ответ
Я получил несколько удовлетворительное решение, изменив функцию, представленную в вопросе, используя алгоритм искажения ImageMagick:
Rsrc = r * (Ar ^ 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))
}
Хотя я не уверен насчет вычисления тета, и указание нулевого искажения (a=0, b=0, c=0) все равно приводит к трансформации. Тем не менее, он, кажется, делает то, что я хотел в этих примерах:
Участок оригинальных данных x,y:
График скорректированных данных x,y (где: a =0, b= -0.02, c = 0):