Коррекция искажения линз в бочках в серии 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):отрегулированный

Другие вопросы по тегам