TensorFlow: смещение при повороте изображения и точек на случайный угол - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть изображение и 3 балла.Я хочу повернуть изображение и точки вместе.С этой целью я поворачиваю изображение на некоторый угол a и точки на тот же угол.Когда a фиксируется на скаляре Python (скажем, pi / 3), вращение работает нормально (см. Изображение ниже, синие точки на темных квадратах).

enter image description here

Когда угол выбирается случайным образом с помощью angle = tf.random_uniform([]), между повернутым изображением и повернутыми точками есть смещение.

enter image description here

Ниже приведен полный код, воспроизводящий это поведение.

Мой вопрос: как объяснить это поведение и исправить его?

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# create toy image
square = np.zeros((1, 800, 800, 3))
square[:, 100:400, 100:400] = 1
square[:, 140:180, 140:180] = 0
square[:, 240:280, 240:280] = 0
square[:, 280:320, 280:320] = 0
kp = np.array([[160, 160], [260, 260], [300, 300]])
kp = np.expand_dims(kp, axis=0)

def _rotate(image, keypoints, angle, keypoints_num):
    image = tf.contrib.image.rotate(image, angle)
    cos, sin = tf.cos(angle), tf.sin(angle)
    x0, y0  = .5, .5
    rot_mat = tf.Variable([[cos, -sin], [sin, cos]], trainable=False)
    keypoints -= (x0, y0)
    keypoints = tf.reshape(keypoints, shape=[-1, 2])
    keypoints = tf.matmul(keypoints, rot_mat)
    keypoints = tf.reshape(keypoints, shape=[-1, keypoints_num, 2])
    keypoints += (x0, y0)
    return image, keypoints


image = tf.placeholder(tf.float32, [None, 800, 800, 3])
keypoints = tf.placeholder(tf.float32, [None, 3, 2])

angle = np.pi / 3 # fix angle, works fine
#angle = tf.random_uniform([]) # random angle, does not work
image_r, keypoints_r = _rotate(image, keypoints / 800, angle, 3)
keypoints_r *= 800

sess = tf.Session()
sess.run(tf.initialize_all_variables())

imr, kr = sess.run([image_r, keypoints_r], feed_dict={image: square, keypoints:kp})

# displaying output
plt.imshow(imr[0])
plt.scatter(*zip(*kr[0]))
plt.savefig('rotation.jpg')

1 Ответ

0 голосов
/ 28 ноября 2018

Проблема здесь:

rot_mat = tf.Variable([[cos, -sin], [sin, cos]], trainable=False)

Поскольку rot_mat является переменной, ее значение устанавливается только при инициализации переменных, здесь:

sess.run(tf.initialize_all_variables())

Итак, при этомточка rot_mat получает некоторое значение (используя cos и sin, которые, в свою очередь, зависят от angle, что является случайным), и оно больше не изменяется.Затем, когда вы делаете:

imr, kr = sess.run([image_r, keypoints_r], feed_dict={image: squares, keypoints:kps})

Это вызов, отличный от run, поэтому tf.random_uniform создает новое значение, но rot_mat по-прежнему сохраняет то же значение, что и при инициализации.Поскольку изображение поворачивается с помощью:

image = tf.contrib.image.rotate(image, angle)

А ключевые точки поворачиваются с помощью:

keypoints = tf.matmul(keypoints, rot_mat)

Вращения не совпадают.Самый простой способ - не использовать переменную для rot_mat:

rot_mat = [[cos, -sin], [sin, cos]]

. При этом код работает нормально.Если вам действительно нужно rot_mat, чтобы быть переменной, это возможно, но это немного больше работы, и, похоже, здесь не нужно.Если вам не нравится, когда rot_mat является списком, и вместо него требуется правильный тензор, вы можете использовать tf.convert_to_tensor:

rot_mat = tf.convert_to_tensor([[cos, -sin], [sin, cos]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...