Why is numpy array wrapping rotating 90 degrees?
I am trying to read images from lmdb
dataset
, zoom in on each one, and then save them to another dataset
for use in my workouts.
This axis of images was originally changed to (3,32,32)
when they were saved in lmdb dataset
. So in order to enlarge them I had to move them back to their actual form.
The problem is that when I try to display them using the matplotlib
show()
or method scipy
toimage()
, they show a rotated version of the image. So we have:
img_set = np.transpose(data_train,(0,3,2,1))
#trying to display an image using pyplot, makes it look like this:
plt.subplot(1,2,1)
plt.imshow(img_set[0])
showing the same image using toimage
:
Now, if I don't transfer data_train
, pyplot
show()
generates an error while
toimage()
displaying the image well:
What's going on here?
When I pass the transposed data_train to my augmenter, I also get the result rotated just like the previous examples.
Now I'm not sure if this is a display issue, or if the actual images are actually rotated!
What should I do?
source to share
First, take a close look. The transposed matrix does not rotate, but is mirrored on the diagonal (i.e. the X and Y axes are swapped).
The original form (3,32,32)
, which I interpret as (RGB, X, Y)
. However imshow
, an array of shape MxNx3
is expected - the color information must be in the last dimension.
By moving the array, you change the size order: (RGB, X, Y)
becomes (Y, X, RGB)
. This is fine for matplotlib because the color information is now in the last dimension, but X and Y are also swapped. If you want to preserve the X, Y order, you can say transpose to do so
:
import numpy as np
img = np.zeros((3, 32, 64)) # non-square image for illustration
print(img.shape) # (3, 32, 64)
print(np.transpose(img).shape) # (64, 32, 3)
print(np.transpose(img, [1, 2, 0]).shape) # (32, 64, 3)
When using imshow
to display an image, be aware of the following errors:
-
It treats the image as a matrix, so the dimensions of the array are interpreted as (ROW, COLUMN, RGB), which is equivalent to (VERTICAL, HORIZONTAL, COLOR) or (Y, X, RGB).
-
It changes the direction of the y axis, so the top left corner is img [0, 0]. This is different from matplotlib's normal coordinate system, where (0, 0) is bottom left.
Example:
import matplotlib.pyplot as plt
img = np.zeros((32, 64, 3))
img[1, 1] = [1, 1, 1] # marking the upper right corner white
plt.imshow(img)
Note that the smaller first dimension corresponds to the vertical direction of the image.
source to share