How to prepare PIL Image.Image for tf.image.decode_image - python

For a file read with:
import PIL
import tensorflow as tf
from keras_preprocessing.image import array_to_img
path_image = "path/cat_960_720.jpg"
read_image = PIL.Image.open(path_image)
# read_image.show()
image_decode = tf.image.decode_image(read_image)
print("This is the size of the Sample image:", image_decode.shape, "\n")
print("This is the array for Sample image:", image_decode)
resize_image = tf.image.resize(image_decode, (32, 32))
print("This is the Shape of resized image", resize_image.shape)
print("This is the array for resize image:", resize_image)
to_img = array_to_img(resize_image)
to_img.show()
I keep getting error for this line tf.image.decode_image(read_image):
ValueError: Attempt to convert a value
(<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=960x586 at
0x11AA49F40>) with an unsupported type (<class
'PIL.JpegImagePlugin.JpegImageFile'>) to a Tensor.
How can I pass imae read with PIL to tensorflow so that I could decode and resize,
so that I could resize this big picture to 32x32x3?

A few options, here is 1 if you have to use PIL:
import PIL
import tensorflow as tf
from keras_preprocessing.image import array_to_img
import numpy as np
path_image = "/content/cat.jpg"
read_image = np.asarray(PIL.Image.open(path_image))
resize_image = tf.image.resize(read_image, (32, 32))
print("This is the Shape of resized image", resize_image.shape)
print("This is the array for resize image:", resize_image)
to_img = array_to_img(resize_image)
Here is an option with TF only:
import tensorflow as tf
from keras_preprocessing.image import array_to_img
path_image = "/content/cat.jpg"
read_image = tf.io.read_file(path_image)
read_image = tf.image.decode_image(read_image)
resize_image = tf.image.resize(read_image, (32, 32))
print("This is the Shape of resized image", resize_image.shape)
print("This is the array for resize image:", resize_image)
to_img = array_to_img(resize_image)

Related

Python - tkinter; TypeError: Expected Ptr<cv::UMat> for argument 'src'

I'm trying to build a graphical interface for image processing. I have problem uploading function.
When I try to check if the file / image exists and modify it, I get this error and I don't know how to fix it.
TypeError: Expected Ptr<cv::UMat> for argument 'src'
This is my code:
import cv2
import instructions as instructions
from PIL import Image,ImageTk
from tkinter.filedialog import askopenfile
root = tk.Tk()
logo = Image.open('logo.png')
logo = ImageTk.PhotoImage(logo)
logo_label = tk.Label(image = logo)
logo_label.image = logo
logo_label.grid(column=1,row=0)
def upload():
browse.set("loading...")
file = askopenfile(parent=root,mode="rb",title="Choose an image",filetypes =[("JPG file","*.jpg"),("PNG file","*.png"),("JPEG file","*.jpeg")])
if file:
gray = cv2.cvtColor(file, cv2.COLOR_RGB2GRAY)
gray = cv2.medianBlur(gray,5)
edges = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY, 9, 9)
color = cv2.bilateralFilter(file,9,250,250)
cartoon =cv2.bitwise_and(color,color,mask=edges)
cv2.imshow("Cartoon", cartoon)
intructions = tk.Label(root,text= "Select an image",font = "Raleway")
instructions.grid(columnspan=3,column=0,row=1)
browse = tk.StringVar()
browse_button = tk.Button(root,textvariable = browse,command = lambda:upload(),font = "Raleway",bg="#20bebe",fg ="white",width=15,height =2)
browse.set("Browse")
browse_button.grid(column=1,row=2)
canvas = tk.Canvas(root,width = 600,height = 300)
canvas.grid(columnspan = 3)
root.mainloop()
Thank you!
In line no 20: you are using CvtColor to change the image to grayscale.
gray = cv2.cvtColor(file, cv2.COLOR_RGB2GRAY) you need to pass the file pointer in place of file.
That is why you are getting the error TypeError: Expected Ptr<cv::UMat> for argument 'src'
You need to :
First read the file using img=cv2.imread(file), and then use
CvtColor on the img data using gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY).
So delete the content in line 20 and add
img=cv2.imread(file)
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
Edit:
One important thing on line 6 you are importing askopenfile which returns a binary encoded path of the image. This is wrong implementation.
Instead you should import askopenfilename; this returns the path of the image file.
I am sharing the entire updated code here :
import cv2
import tkinter as tk
import instructions as instructions
from PIL import Image,ImageTk
from tkinter.filedialog import askopenfilename
root = tk.Tk()
logo = Image.open('logo.jpg')
logo = ImageTk.PhotoImage(logo)
logo_label = tk.Label(image = logo)
logo_label.image = logo
logo_label.grid(column=1,row=0)
def upload():
browse.set("loading...")
file = askopenfilename(parent=root,title="Choose an image",filetypes =[("JPG file","*.jpg"),("PNG file","*.png"),("JPEG file","*.jpeg")])
print(file)
if file:
img=cv2.imread(file)
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
gray = cv2.medianBlur(gray,5)
edges = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY, 9, 9)
color = cv2.bilateralFilter(img,9,250,250)
cartoon =cv2.bitwise_and(color,color,mask=edges)
cv2.imshow("Cartoon", cartoon)
intructions = tk.Label(root,text= "Select an image",font = "Raleway")
instructions.grid(columnspan=3,column=0,row=1)
browse = tk.StringVar()
browse_button = tk.Button(root,textvariable = browse,command = lambda:upload(),font = "Raleway",bg="#20bebe",fg ="white",width=15,height =2)
browse.set("Browse")
browse_button.grid(column=1,row=2)
canvas = tk.Canvas(root,width = 600,height = 300)
canvas.grid(columnspan = 3)
root.mainloop()
This should work let me know.
Hope this solves your purpose
You need to pass an image to cv2.cvtColor, you are currently passing a string - file.
if file:
src = cv2.imread(file)
gray = cv2.cvtColor(src, cv2.COLOR_RGB2GRAY)
gray = cv2.medianBlur(gray,5)

Problem in how to do image processing for some images - Error: AttributeError: type object 'Image' has no attribute 'open

I get an error when performing image processing for some images using python. The error is:
"AttributeError: type object 'Image' has no attribute 'open'".
I would be happy if you can review the code below and help me to fix this error. 
#imprint text on image
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
from IPython.display import Image
list2 = ['mydata/marketst670503.jpg','mydata/marketst8407.jpg','mydata/potsdamriot6805.jpg','mydata/rescue671221a.jpg']
outfile = 'sample-text.jpg'
for line in list2:
print (line)
img = Image.open(line)
draw = ImageDraw.Draw(img)
# font = ImageFont.truetype(<font-file>, <font-size>)
font = ImageFont.truetype("Colombia.ttf", 200)
draw.text((0, 0),"Sample Text",(255,0,0),font=font)
img.save(outfile)
display(Image(filename=outfile))
Notice! you have 2 imports under THE SAME NAME, overriding eachother.
I would make this change:
#mabe you replace the original import to a more nutral name..
import PIL.Image as Image
from PIL import ImageFont
from PIL import ImageDraw
from IPython.display import Image as DisplayImage # this line fixes your problem
list2 = ['mydata/marketst670503.jpg','mydata/marketst8407.jpg','mydata/potsdamriot6805.jpg','mydata/rescue671221a.jpg']
outfile = 'sample-text.jpg'
for line in list2:
print (line)
img = Image.open(line)
draw = ImageDraw.Draw(img)
# font = ImageFont.truetype(<font-file>, <font-size>)
font = ImageFont.truetype("Colombia.ttf", 200)
draw.text((0, 0),"Sample Text",(255,0,0),font=font)
img.save(outfile)
display(Image(filename=outfile))
and for next time, don't confuse yourself! choose a more nutral name then Image, and there won't be duplicates :)
*** Edited!***

How to use getpixel() in with PIL

Hello I am testing the getpixel() function in PIL but i keep getting "IndexError: image index out of range."
It works when i do this:
from PIL import ImageGrab, Image
image = ImageGrab.grab(bbox=(0, 0, 1920, 1080))
print(image.getpixel((10,10)))
But not when I do this:
from PIL import ImageGrab, Image
image = ImageGrab.grab(bbox=(1207, 301, 272, 537))
print(image.getpixel((10,10)))

Load image in tkinter from pygame surface in python 3

I would like to load an image in tkinter from a pygame surface and I am having a problem.
This is what I am currently trying:
image= pygame.image.tostring(surf, 'RGB')
tkimage= tkinter.PhotoImage(data= image)
canvas.create_image(0, 0, tkimage)
but I unfortunately get this error:
_tkinter.TclError: couldn't recognize image data
The PhotoImage class can only read GIF and PGM/PPM files, either directly from a file or as base64 encoded string.
You should use the Python Imaging Library for loading and creating the image for Tk.
Here's an example:
import pygame
from PIL import Image
import ImageTk
import Tkinter
# load image in pygame
pygame.init()
surf = pygame.image.load('bridge.png')
# export as string / import to PIL
image_str = pygame.image.tostring(surf, 'RGB') # use 'RGB' to export
w, h = surf.get_rect()[2:]
image = Image.fromstring('RGB', (w, h), image_str) # use 'RGB' to import
# create Tk window/widgets
root = Tkinter.Tk()
tkimage = ImageTk.PhotoImage(image) # use ImageTk.PhotoImage class instead
canvas = Tkinter.Canvas(root)
canvas.create_image(0, 0, image=tkimage)
canvas.pack()
root.mainloop()
------- UPDATE ------
import pygame
from pygame.locals import *
from PIL import Image
import ImageTk
import Tkinter
# load image in pygame
pygame.init()
surf = pygame.image.load('pic_temp.png') # you can use any Surface a Camers is also an Surface
mode = "RGB"
# export as string / import to PIL
image_str = pygame.image.tostring(surf, mode) # use 'RGB' to export
size = (640, 480)
#image = Image.fromstring(mode, size, image_str)
# use frombuffer() - fromstring() is no longer supported
image = Image.frombuffer(mode, size, image_str, 'raw', mode, 0, 1) # use 'RGB' to import
# create Tk window/widgets
root = Tkinter.Tk()
tkimage = ImageTk.PhotoImage(image) # use ImageTk.PhotoImage class instead
label = Tkinter.Label(root, image=tkimage)
label.pack()
root.mainloop()

PIL Draw.text and Lower Resolution

I have the following PIL code to print text in an image
import os, sys
import PIL
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
img = Image.open("one.jpg")
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman.ttf",27)
draw.text((100, 100), "test test test", font=font)
img.save("out.jpg")
This works on one.jpg file. However on another test file called two.jpg, it doesn't print anything. From what I see, the only difference between two documents is the lower resolution on two.jpg. The file one.jpg is 200x200 dpi, two.jpg is 60x60 dpi.
How can I get draw.text to work in lower res?
Thanks,
You need to specify a color for the text:
import os
import sys
import ImageFont
import Image
import ImageDraw
img = Image.open("two.jpg")
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman.ttf",27)
draw.text((100, 100), "test test test", font=font, fill = 'blue')
img.save("out.jpg")

Categories