I am taking an RGB image as an input in Python which it obviously converts into 2D numpy array. I would like to replace only a window/part of an image by making it totally white (or replacing it with a 2D numpy array having values of only 255).
Here's what I tried:
img[i:i+r,j:j+c] = (np.ones(shape=(r,c))) * 255
r,c is my window size (128*128) and my input image is of RGB channel. It throws an error:
ValueError: could not broadcast input array from shape (128,128) into shape (128,3)
Note: I would like my final output image to be in RGB channel with specific parts replaced by white windows. I am using Python 3.5.
You can do it like this:
#!/usr/local/bin/python3
import numpy as np
from PIL import Image
# Numpy array containing 640x480 solid blue image
solidBlueImage=np.zeros([480,640,3],dtype=np.uint8)
solidBlueImage[:]=(0,0,255)
# Make a white window
solidBlueImage[20:460,200:600]=(255,255,255)
# Save as PNG
img=Image.fromarray(solidBlueImage)
img.save("result.png")
Essentially, we are using numpy indexing to draw over the image.
Or like this:
#!/usr/local/bin/python3
import numpy as np
from PIL import Image
# Numpy array containing 640x480 solid blue image
solidBlueImage=np.zeros([480,640,3],dtype=np.uint8)
solidBlueImage[:]=(0,0,255)
# Make a white array
h,w=100,200
white=np.zeros([h,w,3],dtype=np.uint8)
white[:]=(255,255,255)
# Splat white onto blue
np.copyto(solidBlueImage[20:20+h,100:100+w,],white)
# Save as PNG
img=Image.fromarray(solidBlueImage)
img.save("result.png")
Essentially, we are using numpy's copyto() in order to paste, (or composite or overlay), one image into another.
Related
I have to integrate my python code in Labview and I am comparing the pixel value of the image in both.
The Labview gives pixel values in U16 and hence I want to see the pixel values of the enter image description heresame image in python and see if the values are the same.
Can someone please help me with the code for the same?
My image is a png image black and white.
You can use PIL or OpenCV or wand or scikit-image for that. Here is a PIL version:
from PIL import Image
import numpy as np
# Open image
im = Image.open('dXGat.png')
# Make into Numpy array for ease of access
na = np.array(im)
# Print shape (pixel dimensions) and data type
print(na.shape,na.dtype) # prints (256, 320) int32
# Print brightest and darkest pixel
print(na.max(), na.min())
# Print top-left pixel
print(na[0,0]) # prints 25817
# WATCH OUT FOR INDEXING - IT IS ROW FIRST
# print first pixel in second row
print(na[1,0]) # prints 24151
# print first 4 columns of first 2 rows
print(na[0:2,0:4])
Output
array([[25817, 32223, 30301, 33504],
[24151, 22934, 19859, 21460]], dtype=int32)
If you prefer to use OpenCV, change these lines:
from PIL import Image
import numpy as np
# Open image
im = Image.open('dXGat.png')
# Make into Numpy array for ease of access
na = np.array(im)
to this:
import cv2
import numpy as np
# Open image
na = cv2.imread('dXGat.png',cv2.IMREAD_UNCHANGED)
If you just want to one-time inspect the pixels, you can just use ImageMagick in the Terminal:
magick dXGat.png txt: | more
Sample Output
# ImageMagick pixel enumeration: 320,256,65535,gray
0,0: (25817) #64D964D964D9 gray(39.3942%)
1,0: (32223) #7DDF7DDF7DDF gray(49.1691%)
2,0: (30301) #765D765D765D gray(46.2364%)
3,0: (33504) #82E082E082E0 gray(51.1238%)
...
...
317,255: (20371) #4F934F934F93 gray(31.0842%)
318,255: (20307) #4F534F534F53 gray(30.9865%)
319,255: (20307) #4F534F534F53 gray(30.9865%)
I am trying to use the python PIL library to convert an image to black and white and then extract the pixels as a 2d array of 0's and 1's.
So far I am able to convert the image to black and white as follows:
bwImage = Image.open(imageFilePath)
bwImage = bwImage.convert(mode="1", dither=Image.NONE)
But from here I don't know how to extract each pixel as a numeric value and enter it into the array. I have tried sum of the numpy functions like asarray() and array() but these don't seem to work for 1-bit images.
As the title states I'm converting my image to a numpy array then converting it right back. Here's my code:
import os
import numpy as np
from PIL import Image
img = Image.open(os.path.join(no_black_border, png_files[0]))
img.show()
np_arr = np.asarray(img)
img1 = Image.fromarray(np_arr)
img1.show()
Here's my before converting it
Here's my after converting it back
Your image is not RGB, it is a palette image. That means it does not have a Red, a Green and a Blue value at every pixel location, instead it has a single 8-bit palette index at each location that PIL uses to know the colour. You lose the palette when you convert to Numpy array.
You have 2 choices.
Either convert your image to RGB when you open it and all 3 values will be carried across to Numpy:
# Load image and make RGB
im = Image.open(...).convert('RGB')
# Convert to Numpy array and process
numpyarray = np.array(im)
Or, do as you currently do, but re-appply the palette from the original image after converting back to PIL Image:
# Load image
im = Image.open()
# Convert to Numpy array
numpyarray = np.array(im)
... do Numpy stuff ...
# Convert back to PIL Image and re-apply original palette
r = Image.fromarray(numpyarray,mode='P')
r.putpalette(im.getpalette())
# Optionally save
r.save('result.png')
See answer here and accompanying comments.
I'm would like to go from an image filename to a list of coordinates of the white pixels in the image.
I know it involves PIL. I have tried using Image.load() but this doesn't help because the output is not indexable (to use in a for loop).
You can dump an image as a numpy array and manipulate the pixel values that way.
from PIL import Image
import numpy as np
im=Image.open("someimage.png")
pixels=np.asarray(im.getdata())
npixels,bpp=pixels.shape
This will give you an array whose dimensions will depend on how many bands you have per pixel (bpp above) and the number of rows times the number of columns in the image -- shape will give you the size of the resulting array. Once you have the pixel values, it ought to be straightforward to filter out those whose values are 255
To convert a numpy array back to an image use:
im=Image.fromarray(pixels)
I want to do some image processing using Python.
Is there a simple way to import .png image as a matrix of greyscale/RGB values (possibly using PIL)?
scipy.misc.imread() will return a Numpy array, which is handy for lots of things.
Up till now no one told about matplotlib.image:
import matplotlib.image as img
image = img.imread(file_name)
Now the image would be a 3D numpy array
print image.shape
Would be something like: (317, 504, 3)
scipy.misc.imread() is deprecated now. We can use imageio.imread instead of that to read it as a Numpy array
im.load in PIL returns a matrix-like object.
you can use PyGame image and use PixelArray to access the pixeldata
Definitely try
from matplotlib.image import imread
image = imread(filename)
The filename preferably has to be an .jpg image.
And then, try
image.shape
This would return :
for a black and white or grayscale image
An (n,n) matrix where n represents the dimension of the images (pixels) and values inside the matrix range from 0 to 255.
Typically 0 is taken to be black, and 255 is taken to be white. 128 tends to be grey!
For color or RGB image
It will render a tensor of 3 channels. Each channel is an (n,n) matrix where each entry represents the respectively the level of Red, Green or Blue at the actual location inside the image.