for some reason this isn't working.
i may be making a silly mistake somewhere.
please help
# importing modules
import urllib.request
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
from PIL import Image
#dowload mona lisa image
urllib.request.urlretrieve(
'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/1024px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg',
"Mona_Lisa.png")
#open the file
img = Image.open("/content/Mona_Lisa.png")
#convert to from rgba to rgb
rgb_image = img.convert('RGB')
rgb_image_rgb = np.array(rgb_image)
#show image
plt.imshow(rgb_image_rgb, cmap = cm.Greys_r)
have you tried this answer ?
How can I convert an RGB image into grayscale in Python?
from PIL import Image
img = Image.open('image.png').convert('L')
img.save('greyscale.png')
you can convert the image to grayscale using PIL.Image.convert:
img = Image.open("/content/Mona_Lisa.png").convert("L")
Related
I need to invert the colors of an image in Python using PIL, the problem is that I only have to invert the colors of the right half of the image and I don't know how to do it. Here is an example of how the image should look like.
And here is the code I made, bot it invert the colors of all the image.
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import PIL.ImageOps
image_file = Image.open("Abbildung1.jpg")
image_file.load()
image_data = np.asarray(image_file, dtype=np.uint8)
inverted_image = PIL.ImageOps.invert(image_file)
inverted_image.save("neuesBild.jpg")
You can use numpy to make two parts of the image then apply the transformation and finally combine it.
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import PIL.ImageOps
image_file = Image.open("some_image.jpeg")
image_file.load()
image_data = np.asarray(image_file, dtype=np.uint8)
width = image_data.shape[1]
left_half = image_data[:,0:width//2, :]
right_half = image_data[:,width//2:, :]
inverted_image_right = np.asarray(PIL.ImageOps.invert(Image.fromarray(right_half)))
total_image = np.hstack((left_half, inverted_image_right))
inverted_image = Image.fromarray(total_image)
inverted_image.save("invertion_half.jpeg")
That's it:
from PIL import Image
import PIL.ImageOps
img = Image.open('img.png').convert('RGB')
img.paste(ImageOps.invert(img.crop((img.width/2,0,img.width,img.height))),box=(int(img.width/2),0))
We have croped, inverted and pasted this croped-inverted image back.
Then you can check:
img.show()
I'm a newbie to tensorflow and keras, and I'm trying to create a CNN model for The Street View House Numbers (SVHN) dataset. The dataset contains color images, and I want to turn them in grayscale. I found some code on the web that claims they're turning image to grayscale, but it just changes colors.
People are reading the second image with a gray colormap. Is there any way to actually turn this image to grayscale?
(I do not know how to process an image in this kind of programming languages. If this is a dumb question, please forgive me and provide a brief explain.)
I provided images and code below, I'll be grateful for any help.
Code:
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
#Read picture:
picture = plt.imread('google.jpg')
print("google logo's shape is: ",picture.shape) #(500, 500, 3)
#saving picture as an np array:
pic_array = np.array(picture)
#Turning image to grayscale
grayscale_pic = np.expand_dims(np.dot(pic_array[...,:3],[0.299, 0.587, 0.144]),axis = 0)
#Dimensions shifted, (probly my mistake):
grayscale_pic = np.moveaxis(grayscale_pic, 0, -1)
print("shape of grayscale pic = ", grayscale_pic.shape) # (500, 500, 1)
plt.imshow(picture) #Figure_1
plt.show()
plt.imshow(grayscale_pic) #Figure_2
plt.show()
U can convert a normal image to grayscale using opencv like this:
import cv2
gray = cv2.cvtColor(picture,cv2.COLOR_RGB2GRAY)
If u prefer numpy over opencv, then u can use this:
gray = np.dot(picture[...,:3], [0.2989, 0.5870, 0.1140])
You can use matplotlib with weights:
import numpy as np
import matplotlib.pyplot as plt
an_image = plt.imread('google.png')
rgb_weights = [0.2989, 0.5870, 0.1140]
grayscale_image = np.dot(an_image[..., :3], rgb_weights)
plt.axis('off')
plt.imshow(grayscale_image, cmap=plt.get_cmap("gray"), aspect='auto')
plt.show()
Output:
If you remove aspect='auto' parameter:
or you can use opencv
import cv2
an_image = cv2.imread("google.png")
grey_image = cv2.cvtColor(an_image, cv2.COLOR_BGR2GRAY)
or you can use PIL library
from PIL import Image
img = Image.open('google.png').convert('LA')
LA mode is L (8-bit pixels, black and white) with ALPHA desinged for .gif and .png. If your images are .jpeg use L.
Output:
There can be several ways to do this. One potential way is to utilize PIL(Pillow) library:
from PIL import Image
import matplotlib.pyplot as plt
picture = Image.open('google.jpg')
grayscale_pic = picture.convert('LA')
grayscale_pic.save('grayscale.png')
fig,ax = plt.subplots(nrows=1, ncols=2)
plt.subplot(1,2,1)
plt.imshow(picture)
plt.subplot(1,2,2)
plt.imshow(grayscale_pic)
plt.show()
Output:
Here, I want to change the default sharpness of the image dataset. It works fine for a single image, but when I apply on multiple images, it shows me an error like AttributeError: 'numpy.ndarray' object has no attribute 'filter'. What should I do to fix this? To that end, my code is given below-
from PIL import Image
from PIL import ImageEnhance
import cv2
import glob
dataset = glob.glob('input/*.png')
other_dir = 'output/'
for img_id, img_path in enumerate(dataset):
img = cv2.imread(img_path,0)
enhancer = ImageEnhance.Sharpness(img)
enhanced_im = enhancer.enhance(8.0)
cl2 = cv2.resize(enhanced_im, (1024,1024), interpolation = cv2.INTER_CUBIC)
cv2.imwrite(f'{other_dir}/enhanced_{img_id}.png',cl2)
You're trying to use PIL to enhance a numpy array. cv2 converts images from image paths into numpy arrays. This doesn't work with PIL image operations.
You can load the image using PIL, do the PIL enhancements then convert it to a numpy array to pass into your cv2.resize() method.
Try:
from PIL import Image
from PIL import ImageEnhance
import cv2
import glob
import numpy as np
dataset = glob.glob('input/*.png')
other_dir = 'output/'
for img_id, img_path in enumerate(dataset):
img = Image.open(img_path) # this is a PIL image
enhancer = ImageEnhance.Sharpness(img) # PIL wants its own image format here
enhanced_im = enhancer.enhance(8.0) # and here
enhanced_cv_im = np.array(enhanced_im) # cv2 wants a numpy array
cl2 = cv2.resize(enhanced_cv_im, (1024,1024), interpolation = cv2.INTER_CUBIC)
cv2.imwrite(f'{other_dir}/enhanced_{img_id}.png',cl2)
from PIL import Image, ImageDraw, ImageFilter
im_rgb = Image.open('x.JPG')
im_a = Image.open('blackandwhitex.png').convert('L').resize(im_rgb.size)
im_rgba = im_rgb.copy()
im_rgba.putalpha(im_a)
im_rgba.save('xtransparent.png')
Thanks to this code I made transparent on blacka and put another photo on it, so in the end I have transparent background.
How it will be look like in opencv. I need open cv, because PIL rotate photos. But it is hard to write this for someone new in opencv and google colab.
I've made transparent black using this code:
import cv2
file_name = "x.png"
src = cv2.imread(file_name, 1)
tmp = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
_,alpha = cv2.threshold(tmp,0,255,cv2.THRESH_BINARY)
b, g, r = cv2.split(src)
rgba = [b,g,r, alpha]
dst = cv2.merge(rgba,4)
cv2.imwrite("newx.png", dst)
It's not so good...
After puttingc togehter second and third photo I want this:
It is the input of using PIL. (All images have the same size.)
Show color photo:
%pylab inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
img2=mpimg.imread('colorphoto.JPG')
imgplot = plt.imshow(img2)
plt.show()
Some photos are flipped after that.
Show black and white photo:
%pylab inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
img2=mpimg.imread('bawphoto.png')
imgplot = plt.imshow(img2)
plt.show()
For some of the photos I need to use:
from PIL import Image
def rotate(image_path, saved_location):
image_obj = Image.open(image_path)
transposed = image_obj.transpose(Image.ROTATE_90)
transposed = transposed.transpose(Image.ROTATE_180)
transposed.save(saved_location)
transposed.show()
if __name__ == '__main__':
image = 'colorphoto.JPG'
rotate(image, 'rotated_colorphoto.JPG')
And after that I convert them into one photo:
from PIL import Image, ImageDraw, ImageFilter
im_rgb = Image.open('rotated_colorphoto.JPG')
im_a = Image.open('bawphoto.png').convert('L').resize(im_rgb.size)
im_rgba = im_rgb.copy()
im_rgba.putalpha(im_a)
im_rgba.save('imagewithtransparentbackground.png')
I don't want flipped photos. I need them original size not flipped..
The input is an image(document) from the scanner and my task is to crop the background and return only the document, just like this: Input Output
I've done this through thresholding and getbbox:
import matplotlib.pyplot as plt
import matplotlib.image as pli
from skimage.filters import threshold_otsu as otsu
from PIL import Image
cnh_gray = Image.open("cnh.jpg").convert('L')
cnh_gray.save('cnhgray.jpg')
img = pli.imread('cnhgray.jpg')
imagem = Image.open('cnhgray.jpg')
thresh = otsu(img)
mask = img < thresh
msk = Image.fromarray(mask,'L')
box = msk.getbbox()
crop = imagem.crop(box)
The problem is: The getbbox function doesn't work when the document isn't vertical. Since I don't know the angle, how can I rotate the image to use the getbbox funcion? If there's another function that I can use for inclined images instead of getbbox, please tell me.
Thanks for the help.