I have a 2D python list named image, the array contain only integer in the range from 0-255.
For example, the list is like this
image = [[0, 39, 57], [255, 182, 124], [19, 223, 200], [176, 190, 100]]
I have read How to convert a python numpy array to an RGB image with Opencv 2.4?, so i converted the python list to numpy array
image = np.asarray(image)
I could run the following
cv2.imwrite('image.jpg', image)
But how do i load the array as image directly without saving it to file ? something like this
opencvImage = cv2.imread(image, 0)
The above code obviously don't work, so how do i load python list or numpy array directly to opencv without saving it as file? the expected image output is rgb image or greyscale image, and the expected shape is the shape of the list/array itself.
The following code also don't work, i also don't understand why i can save the numpy array as image file but opencv cannot show it directly
cv2.imshow("image", image)
The code above throws assertionfailed error from opencv
Based on the provided information, the only possible output is a gray image with the shape (4, 3). OpenCV image are just basic Numpy arrays. You can convert the list using:
lst = [[0, 39, 57], [255, 182, 124], [19, 223, 200], [176, 190, 100]]
image = np.asarray(lst, dtype=np.uint8) # Specifying dtype is critical here
# image = array([[ 0, 39, 57],
# [255, 182, 124],
# [ 19, 223, 200],
# [176, 190, 100]])
Then you can show it with cv2.imshow("image", image) but be aware that the image is a bit too small to be easily seen. Note also that a cv2.waitKey() loop may be needed so the window does not freeze and print the image correctly.
You can crease numpy.array then divide by 255.0 then show the image with cv2 like below:
import numpy as np
import cv2
image = [[0, 39, 57], [255, 182, 124], [19, 223, 200], [176, 190, 100]]
image = np.array(image, copy=False) / 255.0
cv2.imshow("image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
Or you can use matplotlib for showing the image like below:
import matplotlib.pyplot as plt
import numpy as np
image = [[0, 39, 57], [255, 182, 124], [19, 223, 200], [176, 190, 100]]
image = np.array(image, copy=False) / 255.0
plt.imshow(image); plt.axis('off')
plt.show()
Output:
Related
Is it possible to convert an RGBA image to BGRA without using the following code, i.e. without using opencv?
image = self.cv2.cvtColor(image, self.cv2.COLOR_RGBA2BGRA)
You can convert an image from BGRA to RGBA with this line of code:
image[..., :3] = image[..., 2::-1]
Of course, it modifies the existing array rather than creating a new one (which is good if you don't plan on using the old one again as it's more efficient). Another way is image = image[..., [2,1,0,3]], but since it uses fancy indexing, rather than modifying the old array, it creates a copy of the old array which takes up more memory.
Using the same line of code again converts the image back from RGBA to BGRA.
Like this with "fancy indexing":
# Make a dummy, random 4-channel image
RGBA = np.random.randint(0,256,(2,3,4), np.uint8)
In [3]: RGBA
Out[3]:
array([[[102, 204, 36, 128],
[178, 151, 166, 45],
[199, 49, 104, 98]],
[[ 79, 33, 223, 62],
[ 26, 34, 233, 254],
[ 62, 20, 57, 149]]], dtype=uint8)
# Convert RGBA to BGRA
BGRA = RGBA[..., [2,1,0,3]]
In [5]: BGRA
Out[5]:
array([[[ 36, 204, 102, 128],
[166, 151, 178, 45],
[104, 49, 199, 98]],
[[223, 33, 79, 62],
[233, 34, 26, 254],
[ 57, 20, 62, 149]]], dtype=uint8)
I think OpenCV likes its data contiguous, so if you get issues, use:
BGRA = RGBA[..., [2,1,0,3]].copy()
I have a list of numpy arrays that are RGB values of 3 images, as below:
array([[ 38, 45, 48],
[ 38, 45, 48],
[ 38, 45, 48],
...,
[134, 125, 101],
[134, 125, 101],
[134, 125, 101]], dtype=uint8)
This has been generated with the code as shown below:
r, c, l = img_array.shape
img_disp = np.reshape(image, (r, c, l), order="C")
arr = img_disp.astype(dtype='uint8')
img = np.asarray(Image.fromarray(arr, 'RGB'))
img_to_display = np.vstack(img)
I'm trying to plot these images in a jupyter notebook.
Using plt.figure() and imshow() as suggested in other posts gives the following error.
for ima in images:
plt.figure()
plt.imshow(ima)
Error:
TypeError: Invalid shape (3,) for image data
May be a small thing, but I'm not able to get this around. The shape of my list is (255440, 3).
Appreciate any help!
I'm building a neural network and I'm trying to load colored images into the network but I keep getting a reshaping error. I resized all of the images to the smallest dimensions (in this case 110 x 110) but when I try to convert the X (an unflattened 3d list of the pixels of each image) to a numpy array to be called xTrain with this line of code:
xTrain = np.array(X[:trainNum])
i get this error: "ValueError: could not broadcast input array from shape (110,110,3) into shape (110,110)"
does anyone know why it keeps doing that? i assume it's because of my data because my partner copied the same exact code with his own images and the conversion to a numpy array was successful but mine isn't. for reference the list titled X is in this format:
[array([[[137, 151, 199],
[ 93, 114, 166],
[116, 121, 164],
...,
[124, 124, 175],
[160, 162, 193],
[154, 157, 177]],
[[ 81, 94, 153],
[106, 123, 184],
[119, 124, 180],...
how do I fix this?
Most likely, your X list contains a mixture of grayscale and RGB images.
img_rgb = np.zeros((110, 110, 3))
img_gry = np.zeros((110, 110))
X_good = [img_rgb, img_rgb, img_rgb]
np.array(X_good[:])
# OK
X_bad = [img_rgb, img_gry, img_rgb]
np.array(X_bad[:])
# ValueError: could not broadcast input array from shape (110,110,3) into shape (110,110)
You can convert the grayscale image(s) in X to RGB:
def make_rgb(img):
if len(img.shape) == 3:
return img
img3 = np.empty(img.shape + (3,))
img3[:, :, :] = img[:, :, np.newaxis]
return img3
X_repaired = [make_rgb(im) for im in X_bad]
np.array(X_repaired[:])
# No problem
The problem while reshaping arises because python can not convert an array of shape (110,110,3) to (110,110). The 3 in the shape of the array signifies the RGB or BGR colour code (varies between different image reading functions).Also, product of the length of the array about all axes should stay constant. This means that say, your array is of size (x1, y1, z1) and you reshape it to (x2,y2,z2) then x1y1z1 = x2y2z2 or else the reshape function will give an error.
The most simple walk-around is to read the image as a greyscale image. In opencv, it is implemented as below:
import cv2
# Using cv2.imread() method
# Using 0 to read image in grayscale mode
img = cv2.imread(path, 0)
# Displaying the image
cv2.imshow('image', img)
#if your input image is not 110*110, you resize it
img = cv2.resize(img, (110,110))
I want to import some images with its split RGB values, For some images it works and for some others, the output gives just one value for RGB of a pixel.
Here's the image for which the code works:
if os.path.isfile(location1):
image = imageio.imread(location1)
print("Type : ", type(image[0][0]))
## Type : imageio.core.util.Image
input : image
output: Image([[[167, 126, 94],
[210, 184, 147],
[245, 234, 188],
...,
And this is the image for which the code doesn't work.
if os.path.isfile(location2):
image = imageio.imread(location2)
print("TYpe : ", type(image[0][0]))
## TYpe : <class 'numpy.uint8'>
input: image
output: Image([[81, 78, 74, ..., 72, 71, 69],
[74, 71, 67, ..., 70, 70, 68],
[61, 58, 55, ..., 65, 65, 64],
...,
(I would appreciate any help)
It seems to be the second image you loaded is simply a grayscale image (i.e. not an image with color, but only with gray levels). To convert it to RGB, try the following:
from skimage import color
img = color.gray2rgb(your_image)
Also, as the conversion to RGB is just to repeat each gray value three times, you can use this snippet
import numpy as np
rgb = np.stack((your_image, your_image, your_image), axis=-1)
In numpy, The array method could convert a image to a big array, the question is , whats' the meaning of the numbers in this array?(RGB value? gray-scale value? )
What's more, when I convert a image to mode"1", tried
im = Image.open("test.jpg")
# Some processing ...
im = im.convert("1")
im_arr = array(im,dtype=uint8)
I found that the im_arr array shows not only 0 and 255:
array([[170, 170, 170, ..., 255, 255, 255],
[255, 248, 255, ..., 175, 255, 222],
[255, 255, 247, ..., 175, 170, 171],
...,
[ 32, 105, 110, ..., 32, 124, 32],
[ 32, 32, 32, ..., 101, 115, 39],
[ 41, 10, 32, ..., 109, 111, 115]], dtype=uint8)
Why? (I really want to know the meaning of numbers in array of different modes)
By running im.convert("1"), you are converting your loaded image into a bilevel image which should only have pixel values of 0 or 255. To do this properly,
im_arr = np.array(im.getdata(), dtype = np.uint8).reshape(im.size[0], im.size[1])
With this, you will receive your desired bilevel image, which you could save or view with matplotlib.pyplot.imshow.
The odd number you are receiving are coming from the conversion process to a numpy array. If you choose different data types (np.int, np.int8, np.uint8, ...), you will find that each of these return a different array.
Without knowing much about the object structure of PIL.Image, I couldn't say why this is. But I think it's safe to say that without .getdata() the results are garbage.
The format jpeg does not support mode 1. Save it into a different format, png or bmp, and look at the array for that one instead.
Documentation for PIL Jpeg