Как выполнить деформацию изображения или преобразование из одной системы координат в другую для изображения с бочкообразным искажением? - PullRequest
8 голосов
/ 07 марта 2019

Я использовал этот вопрос , чтобы помочь мне придумать неискаженную скоординированную систему изображения.Теперь я не уверен, как внедрить новую систему координат в изображение, чтобы иметь возможность создавать неискаженное изображение.

У меня проблемы с поиском ответов, которые не связаны с 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 пикселей в изображении 512 x 512.

Как применить это обратно к исходному изображению 512 x 512 - вот с чем я борюсь.Я видел некоторые упоминания на страницах, таких как Open CV page здесь и конкретных предопределенных сдвигов или широтных / продольных сдвигов , используйте SpatialObjectsDataFrame с, но не из одного определенного пользователем списка координат xy в другой.

-Пример получения координат исходного изображения:

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

(обратите внимание, на самом деле я не хочу растровых изображений, это то, что я нашел в то время)

-Код я использую, чтобы получить преобразованные координаты:

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

enter image description here

Мне интересно, может ли кригинг быть полезным?Или gdalwarp или proj4string ?Не уверен, как их реализовать.

ОБНОВЛЕНИЕ: Используя рекомендации Рохита, я смог исказить радужную сетку из:

enter image description here

к этому:

enter image description here

Когда я пробую это с изображением бочки, я получаю это странное наложенное изображение:

enter image description here

Хорошо, я думаю, это зависит от того, какие коэффициенты вы используете, как показано здесь:

enter image description here

1 Ответ

3 голосов
/ 18 марта 2019

На самом деле вам не нужно вычислять преобразованные координаты XY. Вам просто нужна функция, которая принимает координаты x и y и возвращает неискаженные. Учитывая вашу undistort функцию, напишите обертку вокруг нее, которая использует только x и y в качестве входных данных:

im2 <- imwarp(im1, function(x,y){ 
  undistort(x,y,a=1,b=2,c=4) # Give apropriate values for arguements, 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, чтобы увидеть, что работает лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...