I created a mask which has the shape (128, 128, 128). I then got the np.sum on that mask n_voxels_flattened = np.sum(mask) (removed the zero voxels so that I can do the transformation on non-zeros voxels) where now the n_voxels_flattened=962517. Then iterated over all images (300 images) which resulted in an array with shape (962517, 300). I did some adjustments to this array and the output has the same shape as input:(962517, 300). I now want to reshape this array and put back the zero voxels I removed so that it has the shape (128,128,128,300).
This is what I tried, but it resulted in a weird looking image when visualized.
zero_array = np.zeros((128*128*128 * 300))
zero_array[:len(result.reshape(-1))]=result.reshape(-1)
Any help would be much appreciated.
Related
I have a 3D array representing a batch of images (batch_size x W x H)
images = np.random.rand(8,100,100)
and a 2D array (batch_size x 2)
indices = np.random.randint(0, 100, size=(8, 2))
which contains x,y indices for accessing pixel values of the images. The following
images[:,indices[:,0],indices[:,1]
returns an array of shape (8,8) but I would like to get an array of shape (8,) that contains pixel values for each image at the respective x, y positions stored in indices.
Looking for a way to index the array w/o using a for loop.
Think I solved it. Just needed to get the diagonal of the output:
output = images[:,indices[:,0],indices[:,1]
np.diag(output) gives pixel values for each image at x,y positions (indices).
I´m currently working on normalizing ct-scans (x, y, layer). Normalizing the first two dimensions is simple using cv2.reshape, but the third dimension... My idea is to flatten the first two dimensions to get a 2d-numpy-array. If I do the reshape to (x * y) for each layer and reshape it back to (x, y) I get a completely different image. I have a img of a lung in the beginning and lines of different gray values afterwords.
test = cv2.resize(img, (img.shape[0] * img.shape[1], 1), interpolation=cv2.INTER_LINEAR)
test = cv2.resize(test, (159, 159), interpolation=cv2.INTER_LINEAR)
self.print_prediction(test, cv2.resize(temp2_masks[:, 0], (159, 159)),
color=False, shape=(159, 159))
I'm sure it's some kind of simple mistake, but I don't see it. So I would be very grateful for help.
The cv2.resize function does not reshape your array.
It actually resizes the image. Your first line is squashing your image horizontally while expanding it a lot vertically. The values are not preserved at all.
Use numpy.reshape to reshape your arrays instead.
I have the following code that reads an image with opencv and displays it:
import cv2, matplotlib.pyplot as plt
img = cv2.imread('imgs_soccer/soccer_10.jpg',cv2.IMREAD_COLOR)
img = cv2.resize(img, (128, 128))
plt.imshow(img)
plt.show()
I want to generate some random images by using keras so I define this generator:
image_gen = ImageDataGenerator(rotation_range=15,
width_shift_range=0.1,
height_shift_range=0.1,
shear_range=0.01,
zoom_range=[0.9, 1.25],
horizontal_flip=True,
vertical_flip=False,
fill_mode='reflect',
data_format='channels_last',
brightness_range=[0.5, 1.5])
but, when I use it in this way:
image_gen.flow(img)
I get this error:
'Input data in `NumpyArrayIterator` should have rank 4. You passed an array with shape', (128, 128, 3))
And it seems obvious to me: RGB, an image, of course it is 3 dimension!
What am I missing here?
The documentation says that it wants a 4-dim array, but does not specify what should I put in the 4th dimension!
And how this 4-dim array should be made? I have, for now, (width, height, channel), this 4th dimension goes at the start or at the end?
I am also not very familiar with numpy: how can I alter the existing img array to add a 4th dimension?
Use np.expand_dims():
import numpy as np
img = np.expand_dims(img, 0)
print(img.shape) # (1, 128, 128, 3)
The first dimension specifies the number of images (in your case 1 image).
Alternatively, you can use numpy.newaxis or None for promoting your 3D array to 4D as in:
img = img[np.newaxis, ...]
# or use None
img = img[None, ...]
The first dimension is usually the batch_size. This gives you lot of flexibility when you want to fully utilize modern hardwares such as GPUs as long as your tensor fits in your GPU memory. For example, you can pass 64 images by stacking 64 images along the first dimension. In this case, your 4D array would be of shape (64, width, height, channels).
I have a numpy matrix of images with shape (50, 17500). Each image has shape (50, 50), so my matrix is like a long row of 350 grayscale images.
I want to use plt.imshow() to display those images. How do I change the dimension of the concatenated images matrix? Say reshaping the array to shape (1750, 500), which is 35 rows and 10 columns of images.
Some posts suggest to use np.reshape(), but if I use my_array.reshape((1750, 500)) the individual image in the new matrix is broken.
My question is how to reshape while preserving each individual (50,50) image?
I have an issue with expanding the size of the Sklearn digit dataset digits from 8*8 to 32*32 pixels.
My approach is to take the 8*8 array and then flatten and expand it. That is, enlarge from 64 to 1024 pixels in total. Therefore I simply want to multiply the values along each row 16 times:
create a new array (=newfeatures) with 1024 NaN values.
Replace every 16. value of the newfeatures array with the values of the original array, that is (0=0),(16=1),(32=2),(...),(1008=64).
3.Replace the remaining NaN values with dropna(ffill) to "expand" the original image to a 32*32 pixels image.
Therefore I use the following code:
#Load in the training dataset
digits=datasets.load_digits()
features=digits.data
targets=digits.target
#Plot original digit
ax[0].imshow(features[0].reshape((8,8)))
#Expand 8*8 image to a 32*32 image (64 to 1024)
newfeatures=np.ndarray((1797,16*len(features[0])))
newfeatures[:]=np.NaN
newfeatures=pd.DataFrame(newfeatures)
for row in range(1797):
for i in range(0,63):
newfeatures.iloc[row,16*i]=features[row][i]
newfeatures.fillna(method="ffill",axis=1,inplace=True)
#Plot expanded image with 32*32 pixels
ax[1].imshow(newfeatures.values[0].reshape((32,32)))
As you can see, the result is not as expected
you can use skimage's resize as shown below
from skimage import transform
new_features = np.array(list
(map
(lambda img: transform.resize(
img.reshape(8,8),#old shape
(32, 32), #new shape
mode='constant',
#flatten the resized image
preserve_range=True).ravel(),
features)))
new_features shape will be (1797, 1024) and displaying the first image will show
Based on the above solution I think the following is a little bit more neater way:
from skimage import transform
newfeatures=[transform.resize(features[i].reshape(8,8),(32,32))for i in
range(len(features))]
plt.imshow(newfeatures[0].reshape((32,32)))