I tried using the PIL library to get a matrix consisting of arrays of pixels and RGB, however, I only get a one-dimensional array and I don’t understand how to form a matrix of them
img = Image.open("E:\\1f9114.png").convert('RGB')
obj = img.load()
width, height = img.size
for j in range(height):
for i in range(width):
matrix1=[i,j,obj[i,j]]
print(matrix1)
print()
I know that the matrix can turn out huge, and the usual sheet does not cope .I hope somebody will help, as it is important for me.
There are several issues with this code snippet:
matrix1 is always overridden. If you want to add pixels to an existing list, use list.append().
im.getdata() should be used to obtain a one-dimensional raw pixel list from the image.
Here is an example (adapted from here) to load pixels into a two-dimensional array that contains (r,g,b) tuples built using list comprehensions and slices.
pixels = list(img.getdata())
matrix1 = [pixels[i*width:(i+1)*width] for i in range(height)]
Related
I have made myself a numpy array from a picture using
from PIL import Image
import numpy as np
image = Image.open(file)
np.array(image)
its shape is (6000, 6000, 4) and in that array I would like to replace pixel values by one number lets say this green pixel [99,214,104,255] will be 1.
I have only 4 such pixels I want to replace with a number and all other pixels will be 0. Is there a fast and efficient way to do so and what is the best way to minimize the size of the data. Is it better to save it as dict(), where keys will be x,y and values, will be integers? Or is it better to save the whole array as it is with the shape it has? I only need the color values the rest is not important for me.
I need to process such a picture as fast as possible because there is one picture every 5 minutes and lets say i would like to store 1 year of data. That is why I'd like to make it as efficient as possible time and space-wise.
If I understand the question correctly, you can use np.where for this:
>>> arr = np.array(image)
>>> COLOR = [99,214,104,255]
>>> np.where(np.all(arr == COLOR, axis=-1), 1, 0)
This will produce a 6000*6000 array with 1 if the pixel is the selected colour, or 0 if not.
How about just storing in a database: the position and value of the pixels you want to modify, the shape of the image, the dtype of the array and the extension (jpg, etc...). You can use that information to build a new image from an array filled with 0.
I have image A with dimension (512, 512, 3).
I want to find all the pixels which != [255,255,255].
Given that pixels, I want to color these coordinates in another image B.
What am I doing wrong?
indices = np.where(imgA!= [255,255,255])
imgB[indices] = [0,0,0]
This template should get you on the right path:
from PIL import image
picture = Image.open(path_to_picture)
width, height = picture.size
for x in range(width):
for y in range(height):
current_color = picture.getpixel( (x,y) )
if current_color[0:3]!=(255,255,255):
picture.putpixel( (x,y), (***, ***,***) + (current_color[-1],))
picture.save(path_to_new_picture)
Note here that getpixel() will return a tuple that contains the RGBA values for the given pixel. In this example, I am assuming that you are retaining the alpha value and simply modifying the RGB values of the current pixel.
you need to loop over each pixel in the image.
... imgA!= [255,255,255] will always return true, because you are comparing a (512,512,3) nd.array to a (3,) nd.array
Even if your images are not built from numpy matricies, this point still applies. If you run into performance issues, use cython for faster for loops.
When I load an image with PIL and convert it into a NumPy array:
image = Image.open("myimage.png")
pixels = np.asarray(image)
The data is stored as [x][y][channel]. I.e., the value of pixels[3, 5, 0] will be the the (3, 5) pixel, and the red component of that pixel.
However, I am using a library which requires the image to be in the format [channel][x][y]. Therefore, I am wondering how I can do this conversion?
I know that NumPy has a reshape function, but this doesn't actually allow you to "swap" over the dimensions as I want.
Any help? Thanks!
In order to get the dimensions in the order that you want, you could use the transpose method as follows:
image = Image.open("myimage.png")
pixels = np.asarray(image).transpose(2,0,1)
At the moment I'm trying to run a ConvNet. Each image, which later feeds the neural net, is stored as a list. But the list is at the moment created using three for-loops. Have a look:
im = Image.open(os.path.join(p_input_directory, item))
pix = im.load()
image_representation = []
# Get image into byte array
for color in range(0, 3):
for x in range(0, 32):
for y in range(0, 32):
image_representation.append(pix[x, y][color])
I'm pretty sure that this is not the nicest and most efficient way. Because I have to stick to the structure of the list created above, I thought about using numpy and providing an alternative way to get to the same structure.
from PIL import Image
import numpy as np
image = Image.open(os.path.join(p_input_directory, item))
image.load()
image = np.asarray(image, dtype="uint8")
image = np.reshape(image, 3072)
# Sth is missing here...
But I don't know how to reshape and concatenate the image for getting the same structure as above. Can someone help with that?
One approach would be to transpose the axes, which is essentially flattening in fortran mode i.e. reversed manner -
image = np.asarray(im, dtype="uint8")
image_representation = image.ravel('F').tolist()
For a closer look to the function have a look to the numpy.ravel documentation.
How to use agglomerative clustering to quantize colors in an Image. For this I extract RGB vector for single pixel and this process require for all positions. So again how to extract all position rgb vectors.
im=Image.open('d:\eye.jpg')
r,g,b = im.convert('RGB')
r,g,b = rgb1.getpixel((1,1))
print r,g,b
this code only extract rgb vector value for only one pixel at a time. How to extract all the values simultaneously.
You can use numpy.array and convert the whole Image into a numpy.ndarray object:
import numpy as np
a = np.array(Image.open('d:\eye.jpg')).swapaxes(0,1)
Where a[i,j] is a position in this array that will give you the same result as rgb1.getpixel((i,j)) (with the difference that the latter returns a tuple).