Reputation: 15
I am trying to stack 3D images to have 4D array. I have code as:
def stack():
x=None
dim=(299,299)
for file in os.listdir(path_to_folder):
if file.endswith('.jpg'):
img = cv2.imread(path_to_folder+ file)
image_a = cv2.resize(img,dim, interpolation = cv2.INTER_AREA)
img2 = cv2.imread(path_to_folder+ file)
image_p = cv2.resize(img2,dim, interpolation = cv2.INTER_AREA)
img3 = cv2.imread(path_to_folder+ file)
image_n = cv2.resize(img3,dim, interpolation = cv2.INTER_AREA)
if (x is None):
x=[(image_a),(image_p),(image_n)]
else:
x[0]=np.stack((x[0], (image_a)))
x[1]= np.stack((x[1],(image_p)))
x[2]=np.stack((x[2],(image_n)))
return x
I am expecting shape as:
stack=stack()
stack[0].shape
>>out: (5,299,299,3)
len(stack)
>>out: 3
but I am getting (1495,299,3)
.
Note: for just focusing on real problem I have kept all 3 image files same. i have taken generate_triplets function from here , but in my case my images are read from folder.
Upvotes: 0
Views: 558
Reputation: 231335
Modifying @Mercury's function:
In [398]: def stack():
...: alist = []
...: dim = (299,299)
...: for i in range(5):
...: img_a = np.random.randn(dim[0],dim[1],3)
...: img_p = np.random.randn(dim[0],dim[1],3)
...: img_n = np.random.randn(dim[0],dim[1],3)
...: alist.append([img_a, img_p, img_n])
...: return np.array(alist)
In [399]: stack().shape
Out[399]: (5, 3, 299, 299, 3)
alist
is a nested (5,3) list containing (299,299,3) arrays. Turned into an array it becomes 5d.
We could just transpose that, stack().transpose(1,0,2,3,4)
. But np.stack
is a concatenate version that lets us specify a new
axis:
In [400]: def stack():
...: alist = []
...: dim = (299,299)
...: for i in range(5):
...: img_a = np.random.randn(dim[0],dim[1],3)
...: img_p = np.random.randn(dim[0],dim[1],3)
...: img_n = np.random.randn(dim[0],dim[1],3)
...: alist.append([img_a, img_p, img_n])
...: return np.stack(alist, axis=1)
...:
In [401]: stack().shape
Out[401]: (3, 5, 299, 299, 3)
Upvotes: 0
Reputation: 4146
There are many ways to do this, and I'll explore some of them. First of all, np.stack requires that all arrays be the same shape. You can't keep calling np.stack repeatedly like this. An easy fix is storing all images in a list, and then calling stack at the very end. Let me whip up some dummy code:
import numpy as np
def stack():
x = [[],[],[]]
dim = (299,299)
for i in range(5):
img_a = np.random.randn(dim[0],dim[1],3)
img_p = np.random.randn(dim[0],dim[1],3)
img_n = np.random.randn(dim[0],dim[1],3)
x[0].append(img_a)
x[1].append(img_p)
x[2].append(img_n)
x = [np.stack(im) for im in x]
return x
stack = stack()
print(out[0].shape)
Out:
(5, 299, 299, 3)
3
If you do, however, want to stack on every iteration for some reason, you can still do it using vstack. You just have to make each 3d image a 4d image by reshaping.
import numpy as np
def stack():
x = None
dim = (299,299)
for i in range(5):
img_a = np.random.randn(dim[0],dim[1],3)
img_p = np.random.randn(dim[0],dim[1],3)
img_n = np.random.randn(dim[0],dim[1],3)
if (x is None):
x=[img_a,img_p,img_n]
else:
s = (-1,dim[0],dim[1],3)
x[0]=np.vstack((x[0].reshape(s), img_a.reshape(s)))
x[1]=np.vstack((x[1].reshape(s), img_p.reshape(s)))
x[2]=np.vstack((x[2].reshape(s), img_n.reshape(s)))
return x
stack = stack()
print(stack[0].shape)
print(len(stack))
Output:
(5, 299, 299, 3)
3
Upvotes: 2