Can't reshape array with numpy - python

i want to change a image(17x15) to 2d array with code:
from PIL import Image
import numpy as np
list = []
im = Image.open('plus1.jpg')
row,col = im.size
print(row,col)
for i in range (row):
for j in range (col):
r, g, b = im.getpixel((i, j))
list.append([r,g,b])
print(list)
print(len(list))
list = np.array(list)
print(list)
list.reshape(17,15)
It change okay to 1D array but when i using reshape to make 2D array with list.reshape(17,15) got the error:
ValueError: total size of new array must be unchanged
The size is 17x15, and change to 1D array have 255 elements, so why the error appear and how to make it run normaly?

Your image is 17x15, so there are 255 pixels. For each pixel, there are three color values (r,g,b). This means that your array list has shape (255,1,3). This means that it contains 755 elements, and an error is raised when you try to reshape it to (17,15), which does not preserve the number of elements. To obtain an array that has the first two dimensions the same as your image (17,15), and a third axis that contains the rgb values, you should write:
np.reshape(list, (17,15,3) )

Related

how to replace the first 8 elements of last column of array(size = (8,8,3 )) with 2d array of size (8,8) using python

i have two arrays of size (8,8,3) and (8,8).
the first 8 elements of last column of first 3D array has to be replaced by elements of last 2D array using python.
basically m working on images of different sizes. m extracting the blue part of image, doing some calculations on it and replacing it back. the extracted blue part is forming a mxn array whereas the original image has dim= mxnxk.
m currently working on image of size (4,4,3) which will be extended for image of higher dimension. here img is image havg dimension = (4,4,3) and q is array derived from some calculations which results in size (4,4).
img = cv2.imread("ori.jpg")
print(img)
img[:,2] = q #here q is an 4x4 array
Traceback (most recent call last):
File "C:\Python36\fresh_seminar\wm_E && extract.py", line 195, in
img[:,2] = q
ValueError: could not broadcast input array from shape (4,4) into shape (4,3)
this is the error i get for the last code line
After struggling for such a long time i finally found the answer.
Replacing the array b with part of sample image array can be done with the following code. i know its simple but it took me a lot of time to get that!
b = np.ones((8,8), dtype = int) #array b of size(8,8) to be replaced
half_cover = cv2.imread("sample.jpg")
print(half_cover)
print(half_cover.shape) shape = (894, 894, 3)
for i in range(8):
for j in range(8):
half_cover[i,j] = b[i,j]
print(half_cover)

Python/Numpy: How to extract interior of any dimension of numpy array?

Suppose I have a numpy array A which can be of any dimensions len(A.shape) can be 1,2,3,..etc. and a corresponding array, crop which len(crop) = len(A.shape) and I want to extract the interior values of A using crop. Here is an example for 2D array.
A = np.random.rand(30).reshape([5,6])
crop = np.array([1,2])
Wanted output:
A[crop[0]:-crop[0], crop[1]:-crop[1])
Assuming value of crop will be reasonable with respect to size of A. How do I do this for any dimension of array A ?
Here's one way with slice notation -
A[tuple([slice(i,-i,None) for i in crop])]
Or with the shorthand np.s_ -
A[tuple([np.s_[i:-i] for i in crop])]
If the start and end indices are given for each dimension, we can do something like as shown in Slicing NumPy array given start and end indices for generic dimensions.

Python2.7 (numpy) Keeping shape of array when appending a 3-d numpy array to an empty array

I am trying to create an empty numpy array, and save all the images that I get from my device. The images come in as numpy array of shape (240,320,3). Creating an empty array to store these images seems like the correct thing to do. When I try to append however, I get this error:
ValueError: all the input arrays must have same number of dimensions
Code as follows:
import numpy as np
# will be appending many images of size (240,320,3)
images = np.empty((0,240,320,3),dtype='uint8')
# filler image to append
image = np.ones((240,320,3),dtype='uint8') * 255
images = np.append(images,image,axis=0)
I need to append many images to this array, so after 100 appends, the shape of the images array should be of shape (100,240,320,3) if done correctly.
Better than np.append is:
images = np.empty((100,240,320,3),dtype='uint8')
for i in range(100):
image = ....
images[i,...] = image
or
alist = []
for i in range(100):
image = ....
alist.append(image)
images = np.array(alist)
# or images = np.stack(alist, axis=0) for more control
np.append is just a cover for np.concatenate. So it makes a new array each time through the loop. By the time you add the 100th image, you have copied the first one 100 times!. The other disadvantage with np.append is that you have to adjust the dimensions of image, a frequent source of error. The other frequent error is getting that initial 'empty' array shape wrong.
Your images array has four dimensions, so you must append a four dimensional item to it. To do so, simply add a new axis to image like so:
images = np.append(images,image[np.newaxis, ...], axis=0)
In a sense, when passing an axis numpy.append is more akin to list.extend than list.append.

Reshape from flattened indices in Python

I have an image of size M*N whose pixels coordinates has been flattened to a 1D array according to a space-filling curve (i.e. not a classical rasterization where I could have used reshape).
I thus process my 1D array (flattened image) and I then would like to reshape it to a M*N array (initial size).
So far, I have done this with a for-loop:
for i in range(img_flat.size):
img_res[x[i], y[i]] = img_flat[i]
x and y being the x and y pixels coordinates according to my path scan.
However, I am wondering how to do this in a unique line of code.
If x and y are numpy arrays of dimension 1 and lengths n, and img_flat also has length n img_res is a numpy array of dimension 2 (h, w) such that `h*w = n, then:
img_res[x, y] = img_flat
Should suffice
In fact, it was easy:
vec = np.arange(0, seg.size, dtype=np.uint)
img_res[x[vec], y[vec]] = seg[vec]

Mean value for dimension in numpy array

My numpy array (name: data) has following size: (10L,3L,256L,256L).
It has 10 images with each 3 color channels (RGB) and each an image size of 256x256 pixel.
I want to compute the mean pixel value for each color channel of all 10 images. If I use the numpy function np.mean(data), I receive the mean for all pixel values. Using np.mean(data, axis=1) returns a numpy array with size (10L, 256L, 256L).
If I understand your question correctly you want an array containing the mean value of each channel for each of the three images. (i.e. an array of shape (10,3) ) (Let me know in the comments if this is incorrect and I can edit this answer)
If you are using a version of numpy greater than 1.7 you can pass multiple axes to np.mean as a tuple
mean_values = data.mean(axis=(2,3))
Otherwise you will have to flatten the array first to get it into the correct shape.
mean_values = data.reshape((data.shape[0], data.shape[1], data.shape[2]*data.shape[3])).mean(axis=2)

Categories