Okay so this is a pretty long question. Here's the problem:
Problem: So I'm transfering images (3d arrays) into a numpy array. I'm trying to get a 4d array containing all of my images but for some reason, it prints out a 1d np.array containing 3d np.arrays.
Suggested solutions: - Images have different dimentions. This was the case but didn't help when resizing them.
First I'm transfering the each picture:
cv2.imdecode(np.frombuffer(image_bytes, np.uint8), -1) converts my images from byte code to a 3d np array.
def transferPictures():
x_dataset = []
y_dataset = []
x_decoded = []
shoeNames = os.listdir(SHOES_DIRECTORY)
print(len(shoeNames))
for shoes in shoeNames[:20]:
shoeDirectoriesPath = os.path.join(SHOES_DIRECTORY, shoes)
if(os.path.isdir(shoeDirectoriesPath)):
eachPicture = os.listdir(shoeDirectoriesPath)
for pic in eachPicture:
print(pic)
picPath = os.path.join(shoeDirectoriesPath, pic)
f = open(picPath, 'rb')
image_bytes = f.read()
#This is to convert the image from byte format to a 3d np array:
decoded = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), -1)
x_dataset.append(decoded)
y_dataset.append(pic)
return [x_dataset, y_dataset]
And converting my x_dataset list (containing all my images) to an np.array():
dataset = transferPictures()
x_dataset=np.array(dataset[0])
I get a 1d x_dataset np.array containing 3d np.arrays:
print("This is the type of the array of images, x_dataset: "+ str(type(x_dataset)))
print("This is the type of each image, x_dataset[0]: "+ str(type(x_dataset[0])))
print("This is the dimension of the array of images, x_dataset: "+ str(np.shape(x_dataset)))
print("This is the dimension of each image, x_dataset[0]: "+ str(np.shape(x_dataset[0])))
Prints:
This is the type of the array of images, x_dataset: <class 'numpy.ndarray'>
This is the type of each image, x_dataset[0]: <class 'numpy.ndarray'>
This is the dimension of the array of images, x_dataset: (130,)
This is the dimension of each image, x_dataset[0]: (289, 200, 3)
Why does the np.shape(x_dataset) return (130,) and the np.shape(x_dataset[0]) return (289, 200, 3)?
1) Shouldn't the np.shape(x_dataset) return (130, 289, 200, 3)?
2) How can I get a 4d x_dataset with shape (130, 289, 200, 3)?
EDIT:
V. Ayrat suggested it might be because of the difference in shape of each image. Some images were in fact of different dimensions that others. So I resized all images to have the same shape. But, the problem seems to persist:
Finding the dimensions of the smallest image:
minx = 1000
miny = 1000
minz = 1000
for image in x_dataset:
if np.shape(image)[0] < minx:
minx = np.shape(image)[0]
if np.shape(image)[1] < miny:
miny = np.shape(image)[1]
if np.shape(image)[2] < minz:
minz = np.shape(image)[2]
print(minx)
print(miny)
print(minz)
Prints:
288
200
3
Resizing images:
for i in range(0,len(x_dataset)):
x_dataset[i] = np.resize(x_dataset[i], (minx,miny,minz))
The images have all the same dimensions but checking for the dimension x_dataset still returns (130,). Any other ideas to have it return a 4d array?
EDIT 2: Making 100% sure each image is of the same dimension:
minx = 1000
miny = 1000
minz = 1000
maxx = 0
maxy = 0
maxz = 0
for image in x_dataset:
if np.shape(image)[0] < minx:
minx = np.shape(image)[0]
if np.shape(image)[1] < miny:
miny = np.shape(image)[1]
if np.shape(image)[2] < minz:
minz = np.shape(image)[2]
if np.shape(image)[0] > maxx:
maxx = np.shape(image)[0]
if np.shape(image)[1] > maxy:
maxy = np.shape(image)[1]
if np.shape(image)[2] > maxz:
maxz = np.shape(image)[2]
print()
print(minx)
print(miny)
print(minz)
print(maxx)
print(maxy)
print(maxz)
Prints:
288
200
3
288
200
3
And rechecking the type:
print(type(x_dataset))
print(type(x_dataset[0]))
print(np.shape(x_dataset))
Prints:
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
(130,)
This is really confusing...