如何在Python中随机旋转3D图像的角度

4

我正在使用一组32x32x32的灰度图像,希望在使用tflearn + tensorflow训练CNN时将随机旋转应用于图像以进行数据增强。我使用以下代码来执行此操作:

    # Real-time data preprocessing
    img_prep = ImagePreprocessing()
    img_prep.add_featurewise_zero_center()
    img_prep.add_featurewise_stdnorm()


    # Real-time data augmentation
    img_aug = ImageAugmentation()
    img_aug.add_random_rotation(max_angle=360.)

    # Input data
    with tf.name_scope('Input'):
        X = tf.placeholder(tf.float32, shape=(None, image_size, 
    image_size, image_size, num_channels), name='x-input')
        Y = tf.placeholder(tf.float32, shape=(None, label_cnt), name='y-input')


    # Convolutional network building
    network = input_data(shape=[None, 32, 32, 32, 1],
                 placeholder = X,
                 data_preprocessing=img_prep,
                 data_augmentation=img_aug)

(I'm using a combination of TensorFlow and TFLearn to leverage features from both. Please let me know if there are any issues with my placeholder usage. Keep HTML tags intact.)
I have discovered that using the add_random_rotation function (which employs scipy.ndimage.interpolation.rotate) treats the third dimension of my grayscale images as channels, similar to RGB channels. It randomly rotates all 32 images of the third dimension by a random angle around the z-axis (treating my 3D image like a 2D image with 32 channels). However, I want the image to be rotated in space (around all three axes). Do you know of any functions or packages that can easily rotate 3D images in space?
3个回答

11
def random_rotation_3d(batch, max_angle):
    """ Randomly rotate an image by a random angle (-max_angle, max_angle).

    Arguments:
    max_angle: `float`. The maximum rotation angle.

    Returns:
    batch of rotated 3D images
    """
    size = batch.shape
    batch = np.squeeze(batch)
    batch_rot = np.zeros(batch.shape)
    for i in range(batch.shape[0]):
        if bool(random.getrandbits(1)):
            image1 = np.squeeze(batch[i])
            # rotate along z-axis
            angle = random.uniform(-max_angle, max_angle)
            image2 = scipy.ndimage.interpolation.rotate(image1, angle, mode='nearest', axes=(0, 1), reshape=False)

            # rotate along y-axis
            angle = random.uniform(-max_angle, max_angle)
            image3 = scipy.ndimage.interpolation.rotate(image2, angle, mode='nearest', axes=(0, 2), reshape=False)

            # rotate along x-axis
            angle = random.uniform(-max_angle, max_angle)
            batch_rot[i] = scipy.ndimage.interpolation.rotate(image3, angle, mode='nearest', axes=(1, 2), reshape=False)
            #                print(i)
        else:
            batch_rot[i] = batch[i]
    return batch_rot.reshape(size)

4

1
谢谢,我采用了您的建议,并编写了以下函数,以在指定的最大角度下随机旋转一批3D图像(我在此发布它,以防有人需要): - Ary
@kmader,轴参数的顺序是否起作用?即axes=(1,2)是否等同于axes=(2,1) - Tin

0
如果您想要将任何3D图像围绕中心旋转并保持在中心位置,请使用偏移量如下所示的scipy affine_transform:
# create a 3D image
image = np.random.random((20,20,20))
# output shape
output_shape = np.array(image.shape)
# rotation matrix around z axis
theta = 0.01
cosine = np.cos(theta)
sinus = np.sin(theta)
M = np.array([[cosine, -sinus, 0],
                         [sinus, cosine, 0],
                         [0, 0, 1]])
# offset
offset = (np.array(image.shape)-M.dot(np.array(output_shape)))
offset = offset/2.0 # it is important
# affine transformation
f_data = affine_transform(np.asarray(image), np.asarray(M),
                              output_shape=output_shape, offset=offset)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接