Как выполнить линейную гомографию изображения в тензорном потоке - PullRequest
0 голосов
/ 27 сентября 2019

Я хотел бы иметь возможность повторить поведение функции opencv warpPerspective, которая принимает в качестве входных данных изображение и матрицу гомографии и проецирует изображение в соответствии с матрицей гомографии (более подробно здесь: https://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html).

Кажется, что tf.contrib.image.sparse_image_warp должен выполнить работу, но я не могу воспроизвести поведение warpPerspective. Вывод, который я получаю, искажается нелинейным образом, несмотря на использование параметра interpolation_order=1.

С некоторыми дальнейшими исследованиями, я подозреваю, это связано с тем, что tf.contrib.image.interpolate_spline не выполняет линейную интерполяцию, даже когда ее порядок равен 1, а скорее использует некоторые ядра RBF.

Я не вижу способа обойти это, кроме как кодировать его с dense_image_warp, но это кажется немного излишним и, возможно, дорогостоящим. У кого-нибудь есть другое решение?

1 Ответ

0 голосов
/ 30 сентября 2019

После некоторых исследований, вот решение.он использует функцию tf.contrib.image.dense_image_warp и не очень хорош, но, тем не менее, работает:

Эта первая функция вычисляет оптический поток, необходимый для выполнения гомографии:

    def homography_matrix_to_flow(tf_homography_matrix, im_shape1, im_shape2):
        Y, X = np.meshgrid(range(im_shape1), range(im_shape2))
        Z = np.ones_like(X)
        XYZ = np.stack((X, Y, Z), axis=-1)
        tf_XYZ = tf.constant(XYZ.astype("float64"))
        tf_XYZ = tf_XYZ[tf.newaxis,:,:, :, tf.newaxis]

        tf_homography_matrix = tf.tile(tf_homography_matrix[tf.newaxis, tf.newaxis], (1, im_shape2, im_shape1, 1, 1))
        tf_unnormalized_transformed_XYZ = tf.matmul(tf_homography_matrix, tf_XYZ, transpose_b=False)
        tf_transformed_XYZ = tf_unnormalized_transformed_XYZ / tf_unnormalized_transformed_XYZ[:,:,:, -1][:,:,:, tf.newaxis]
        flow = -tf.squeeze(tf_transformed_XYZ-tf_XYZ)[..., :2]

        return flow

Затемиспользуется для деформации исходного изображения в искаженное изображение.

Есть одна хитрость: из-за того, как работает функция tf.contrib.image.dense_image_warp, вам нужно пройти инверсию матрицы гомографии, чтобы найти правильный оптический поток для использования.,

        homography_matrix = np.array([[-4.86219067e-01, -2.20871298e+00,  4.08214879e+02],
        [-1.02940133e-01, -5.60378659e+00,  3.87573763e+02],
        [-1.35051362e-04, -6.59600583e-03,  2.91244998e-01]])

        inv_homography_matrix = np.linalg.inv(homography_matrix)

        tf_inv_homography_matrix = tf.constant(inv_homography_matrix)[tf.newaxis]
        flow = homography_matrix_to_flow(tf_inv_homography_matrix, img.shape[1], img.shape[2])[tf.newaxis]
        flow =tf.tile(flow, (self.bs, 1,1,1))
        image_warped = tf.contrib.image.dense_image_warp(tf.transpose(img, (0,2,1,3)), flow)
        image_warped = tf.transpose(image_warped, (0,2,1,3))

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

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