Python AttributeError: 'numpy.ndarray' object has no attribute 'append' - python

I am trying to parse a folder with contains csv file (These csv files are pixel images position) and store them into a numpy array.
When I try to perform this action, I have an error: AttributeError: 'numpy.ndarray' object has no attribute 'append'.
I understand that NumPy arrays do not have an append().
However in my code I used the method: images.append(img)
Could you tell what I am doing badly in?
Here my code:
# Create an empty list to store the images
images = []
# Iterate over the CSV files in the img_test folder
for file in os.listdir("img_test"):
if file.endswith(".txt"):
# Read the CSV file into a dataframe
df = pd.read_csv(os.path.join("img_test", file), delim_whitespace=True, header=None, dtype=float)
# Convert the dataframe to a NumPy array
image = df.to_numpy()
# Extract the row and column indices and the values
rows, cols, values = image[:, 0], image[:, 1], image[:, 2]
# Convert the row and column indices to integers
rows = rows.astype(int)
cols = cols.astype(int)
# Create a 2D array of the correct shape filled with zeros
img = np.zeros((1024, 1024))
# Assign the values to the correct positions in the array
img[rows, cols] = values
# Resize the image to 28x28
img = cv2.resize(img, (28, 28))
# Reshape the array to a 3D array with a single channel
img = img.reshape(28, 28, 1)
# Append the image to the list
images.append(img)
# Convert the list of images to a NumPy array
images = np.concatenate(images, axis=0)

At the end of the outer for loop you turn images from a list to a NumPy array
images = list()
for file in os.listdir("img_test"):
if file.endswith(".txt"):
...
images = np.concatenate(images, axis=0) # not a list anymore
You might have missalligned the concatenate and wanted to do it after the end of the for loop.

# Create an empty list to store the images
images = []
# Iterate over the CSV files in the img_test folder
for file in os.listdir("img_test"):
if file.endswith(".txt"):
# Read the CSV file into a dataframe
df = pd.read_csv(
os.path.join("img_test", file),
delim_whitespace=True,
header=None,
dtype=float,
)
# Convert the dataframe to a NumPy array
image = df.to_numpy()
# Extract the row and column indices and the values
rows, cols, values = image[:, 0], image[:, 1], image[:, 2]
# Convert the row and column indices to integers
rows = rows.astype(int)
cols = cols.astype(int)
# Create a 2D array of the correct shape filled with zeros
img = np.zeros((1024, 1024))
# Assign the values to the correct positions in the array
img[rows, cols] = values
# Resize the image to 28x28
img = cv2.resize(img, (28, 28))
# Reshape the array to a 3D array with a single channel
img = img.reshape(28, 28, 1)
# Append the image to the list
images.append(img)
# Convert the list of images to a NumPy array
cobmined_images = np.concatenate(images, axis=0)
You are initialzing images as list. Then you are creating numpy array with same name. So on the second iteration images is numpy array so it won't have append property.Try using different names as i have done

The indentation of the last line is wrong. You may want to concatenate after the end of the for loop

Related

How to get data into proper numpy dimension format?

I am trying to train a neural network for image classification. I am having trouble getting my data into a proper numpy array format. To feed into the network, my array must be of dimension (9068,184,184,1). The problem is if I check the length of the array, it just returns (9068,). If I check the length of an individual element in the array, it returns (184,184,1). How can I make it so that the whole array's length will be four dimensional (9068,184,184,1) so my neural network can take it as input?
Below is my code. I have a (9068,2) dataframe with the file names. I am grabbing the file name, reading it in to an array as pixel information, and storing it into another array.
path = '/home/vivek/Downloads/kaggle_ndsb2-master/data_segmenter_trainset/'
for ii in pairing_table['image']:
new_path = os.path.join(path,ii)
img = Image.open(new_path)
print type(ii)
for ii in range(0,len(image_table['image'])):
new_path = os.path.join(path,image_table['image'][ii])
img = Image.open(new_path)
img2 = np.array(img.getdata()).reshape(184, 184, -1)
#print(type(img))
image_table['image'][ii] = img2
img.close()
for ii in range(0,len(image_table['mask'])):
new_path = os.path.join(path,image_table['mask'][ii])
img = Image.open(new_path)
img2 = np.array(img.getdata()).reshape(184, 184, -1)
image_table['mask'][ii] = img2
img.close()
print(image_table['image'][0].shape) #this is returning (184,184,1)
print(image_table['image'].shape) #this is returning (9068,) should be (9068,184,184,1)
print(image_table['mask'][0].shape) #this is returning (184,184,1)
print(image_table['mask'].shape) #this is returning (9068,) should be (9068,184,184,1)

Add 2d array to make 3d in python

I have a requirement to read image files( 28*28) from a folder and stack them together to make a single array for analysis.
I have the following code:
for fname in os.listdir(dirname):
im = Image.open(os.path.join(dirname, fname))
imarray = np.array(im)
final = np.stack((final,imarray ), axis = 0)
am getting the following error:
ValueError: all input arrays must have the same shape
imarray is (28,28) and i have 60K images in that folder so i want to make a array of size (60000,28,28)
Thanks for the help
NK
Build a list of all components and stack them once:
alist = []
for fname in os.listdir(dirname):
im = Image.open(os.path.join(dirname, fname))
imarray = np.array(im)
alist.append(imarray)
final = np.stack(alist) # axis=0 is the default
This will join them on a new initial axis.

How to replace empty numpy array by grayscale image values

EDIT: I have found a workaround, which is assigning it to an array, then use that array to create a numpy array:
a = []
for i in range(0,width/image_size):
for j in range(0,height/image_size):
roi = img[image_size*j:image_size*(j+1),image_size*i:image_size*(i+1)]
a.append(roi)
arr = np.asarray(a) #HERE
ORIGINAL QUESTION:
I have created an empty numpy array of shape (180,28,28), which should hold 180 gray scale images size 28x28.
height, width = img.shape[:2]
arr = np.empty(((height/image_size)*(width/image_size), 28, 28 )) #arr.shape = (180,28,28)
I have multiple image regions size 28x28 that I want to populate into arr
for i in range(0,width/image_size):
for j in range(0,height/image_size):
roi = img[image_size*j:image_size*(j+1),image_size*i:image_size*(i+1)]
#HERE - how can I set the value in arr to be an (28x28) roi
Thank you.
I have found a workaround, which is assigning it to an array, then use that array to create a numpy array:
a = []
for i in range(0,width/image_size):
for j in range(0,height/image_size):
roi = img[image_size*j:image_size*(j+1),image_size*i:image_size*(i+1)]
a.append(roi)
arr = np.asarray(a) #assign it to numpy array here
However, I'm not sure if there is a better, or more elegant way to do it.

Store several images as ndarrays into one 4 dimensional ndarray

I have a loop, where I read images and resize them to 32x32x3
for i, filename in enumerate(os.listdir(path)):
img = plt.imread(path+filename)
out = imresize(img, [32,32])
I tried to store it in a list and convert it to an numpy array
for i, filename in enumerate(os.listdir(path)):
img = plt.imread(path+filename)
out = imresize(img, [32,32])
inet_signs.append(out)
a = np.array(inet_signs)
But this only resulted in the error:
ValueError: could not broadcast input array from shape (32,32,3) into
shape (32,32)

on modifying the shape of numpy array resulting from input image

I am trying to customize an existing code to suit my own need. Originally, the code use imgs = np.ndarray((total, 1, image_rows, image_cols), dtype=np.uint8) to store a list of image files in an numpy array format. Iterating the folder, each image file is read as follows img = skimage.io.imread(os.path.join(train_data_path, image_name)) It works just fine.
The code is as follows:
image_rows = 420
image_cols = 580
imgs = np.ndarray((total, 1, image_rows, image_cols), dtype=np.uint8)
i=0
for image_name in images:
img = skimage.io.imread(os.path.join(train_data_path, image_name))
img = np.array([img])
imgs[i]=img
i+=1
In order to suit my own need, I tend to have image file array with the shape [total, image_rows,image_cols,1]. In other words, I modified it as imgs = np.ndarray((total,image_rows, image_cols,1), dtype=np.uint8) However, running the code causes the following error
imgs[i] = img
ValueError: could not broadcast input array from shape (1,420,580) into shape
(420,580,1)
Are there any way to change the shape of img, which originally has shape of [1,420,580] after reading from file. How can I change it to [420,580,1] without affecting the corresponding pixel values in the image.
You want to transpose the dimensions. It can be done using the transpose method:
img = img.transpose(1,2,0)
(for your case)

Categories