Hello
I hate it, but I could not figure this out so I’m hoping I might find some help here. I am trying to rotate images for a given rotation using mxnet. I know I can do it more easily in other frameworks, but if nothing else this is a good learning exercise. With that said, here is what I have got so far.
Given a simple 4x4 pixel image,
# batch 1
in_data = nd.arange(4).reshape((1,2,2))
print('in_data is ', in_data)
Also given a simple rotation matrix,
# setup a rotation matrix
rotate_data = rotate_90
print('rotate_90 ', rotate_data)
This is what I have so far:
# NDArrayIter(data, label=None, batch_size=1, shuffle=False,
# last_batch_handle='pad', data_name='data',
# label_name='softmax_label')
#
# Ignore the label parameter.
dataiter = mx.io.NDArrayIter(in_data, batch_size=1, shuffle=False, last_batch_handle='discard')
#batch_index = [0]
for batch in dataiter:
# Does this copy or get an alias to the input image?
input_img = batch.data[0]
# This will get the pixel indices/indexes of the image
input_img_indexes = mx.nd.contrib.index_array(input_img, axes=(1, 2))
# Rewrite to four rows of two colums omitting the batch
orig_indexes = mx.nd.reshape(input_img_indexes, shape=(4,2))
orig_indexes = orig_indexes.astype("float32")
# This will do the matrix multiply using the rotation matrix.
# afterwards, it will retyupe the float results to integer indices/indexes
new_indexes = nd.dot(orig_indexes, rotate_data)
new_indexes = new_indexes.astype('int64')
# slide the indices back to quadrant since I have some negatives
new_indexes = new_indexes + nd.array(nd.array([0, 1])).astype('int64')
# Hmm. I have the original indices, pixel values, and the new indices/indexes
# but no way to reassign the values given the rotated indices
The result of the data after this step looks like this.
print('in_data is ', in_data)
print('rotate_data is ', rotate_data)
print('orig_indexes is ', orig_indexes)
print('new_indexes is ', new_indexes)
print('new_indexes.dtype is ', new_indexes.dtype)
in_data is
[[[0. 1.]
[2. 3.]]]
<NDArray 1x2x2 @cpu(0)>
rotate_data is
[[ 6.123234e-17 -1.000000e+00]
[ 1.000000e+00 6.123234e-17]]
<NDArray 2x2 @cpu(0)>
orig_indexes is
[[0. 0.]
[0. 1.]
[1. 0.]
[1. 1.]]
<NDArray 4x2 @cpu(0)>
new_indexes is
[[0 1]
[1 1]
[0 0]
[1 0]]
<NDArray 4x2 @cpu(0)>
new_indexes.dtype is <class 'numpy.int64'>
So, my problem is that in the last step, I can not figure out how to assign the output based upon the
given results. I have the rotated indices, the original data and the original indices. I thought it might
just be somethine like this:
But this is a fail
output_data[0,new_indices] = in_data[0,original_indices]
I also tried some with the other contrib api
# x = mx.nd.zeros((5,3))
# t = mx.nd.array([[1,2,3],[4,5,6],[7,8,9]])
# index = mx.nd.array([0,4,2])
mx.nd.contrib.index_copy(out_data[0], new_indexes, in_data[0])
But that is not quite it either.
Any advice is appreciated.