How Can You Read Image Files from a URL and display it in Google Colab? - image

Using Google Colab, I would like to be able to read in some number of image files each of which is at a different url and then display each of them. I got the following code to work but it only displays the first image (no output for the 2nd or error messages) Also, if I add a print statement to the output, then no image display at all. So what's the trick? Thanks.
!pip install pillow
import urllib.request
from PIL import Image
# First Image
imageURL1 = "https://www.example.com/dir/imagefile1.jpg"
imageName1="file1.jpg"
urllib.request.urlretrieve(imageURL1, imageName1)
img1 = Image.open(imageName1)
img1 # this works but only if it is the only output
# Second Image
imageURL2 = "https://www.example.com/dir/imagefile2.jpg"
imageName2="file2.jpg"
urllib.request.urlretrieve(imageURL2, imageName2)
img2 = Image.open(imageName2)
img2 # does not display
#print("x") # a print kills the image display

Found an answer that works. Use IPython to display the image. It works with multiple images and the print() works as well.
!pip install pillow
import urllib.request
from PIL import Image
from IPython.display import display
# First Image
imageURL1 = "https://www.example.com/dir/imagefile1.jpg"
imageName1="file1.jpg"
urllib.request.urlretrieve(imageURL1, imageName1)
img1 = Image.open(imageName1)
display(img1) # this works but only if it is the only output
print("AND THE PRINT WORKS")
# Second Image
imageURL2 = "https://www.example.com/dir/imagefile2.jpg"
imageName2="file2.jpg"
urllib.request.urlretrieve(imageURL2, imageName2)
img2 = Image.open(imageName2)
display(img2)

Related

Save a .gif from a set of Images

I'm trying to create and save a .gif from a set of 3 images inside a folder, called V_N1.png, V_M2.png and V_M3.png.
I'm using matplotlib.animation but when I open the .gif save it only shows the last image, can someone help me?
Thanks in advance!
I'm not using ImageMagickWriter since it says:
MovieWriter ImageMagickWriter unavailable; using Pillow instead.
Below the code.
import matplotlib.animation as animation
import matplotlib.pyplot as plt
nframes = 3
imgFolder = "C:/ftavdf/Image"
def animate(i):
for idx in range(0, nframes):
im = plt.imread(imgFolder + "/V_M{0}.png".format(idx + 1))
anim = animation.FuncAnimation(plt.gcf(), animate, frames=nframes)
anim.save(imgFolder + "/output.gif", writer='ffmpeg')

UnidentifiedImageError: cannot identify image file when running Streamlit

I'm writing some code for the Streamlit app, where I want the user to upload a .jpg image file and it gives me this error, "UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x00000293778F98B0>"
My code is as follows:
import streamlit as st
import pandas as pd
import numpy as np
from PIL import Image
st.title("Image classification Web App")
# loading images
def load_image(image):
image = image.resize((224,224))
im_array = np.array(image)/255 # a normalised 2D array
im_array = im_array.reshape(-1, 224, 224, 3) # to shape as (1, 224, 224, 3)
return im_array
...
if st.button("Try with the Default Image"):
image=load_image(Image.open('C:/Users/.../image21.jpg'))
st.subheader("Human is detected")
st.image(image)
st.image(initialize_model(model_name, image))
st.subheader("Upload an image file")
uploaded_file = st.file_uploader("Upload a JPG image file", type=["jpg", "jpeg"])
if uploaded_file:
image = load_image(Image.open(uploaded_file))
st.image(initialize_model(model_name, image))
However, I have no problem uploading an image with this line,
st.image(Image.open('C:/Users/../image21.jpg'))
Can anyone advise me whats wrong here?
Thanks.
You got that error because uploaded files in streamlit are file-like objects meaning they are not actual files. To Solve this problem, you will have to save the uploaded file to local directory, fetch the file from that directory and proceed with the rest of execution. This method gives you a total control of the file.
I will recommend you create a new function to accept and save user inputs. And after saving, return the path of the saved file, then read from that path, when that is successful, pass the file as a second argument to initialize_model.
Example:
import os
def get_user_input():
st.subheader("Upload an image file")
uploaded_file = st.file_uploader("Upload a JPG image file", type=["jpg", "jpeg"])
if uploaded_file is not None:
user_file_path = os.path.join("users_uploads/", uploaded_file.name)
with open(user_file_path, "wb") as user_file:
user_file.write(uploaded_file.getbuffer())
return user_file_path
uploaded_file = get_user_input()
if uploaded_file is not None:
image = load_image(uploaded_file)
st.image(initialize_model(model_name, image))

Process depth image message from ROS with openCV

so i am currently writing a python script that is supposed to receive a ros image message and then convert it to cv2 so i can do further processing. Right now the program just receives an image and then outputs it in a little window as well as saves it as a png.
Here is my code:
#! /usr/bin/python
import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
import cv2
bridge = CvBridge()
def image_callback(msg):
print("Received an image!")
print(msg.encoding)
try:
# Convert your ROS Image message to OpenCV2
# Converting the rgb8 image of the front camera, works fine
cv2_img = bridge.imgmsg_to_cv2(msg, 'rgb8')
# Converting the depth images, does not work
#cv2_img = bridge.imgmsg_to_cv2(msg, '32FC1')
except CvBridgeError, e:
print(e)
else:
# Save your OpenCV2 image as a png
cv2.imwrite('camera_image.png', cv2_img)
cv2.imshow('pic', cv2_img)
cv2.waitKey(0)
def main():
rospy.init_node('image_listener')
#does not work:
#image_topic = "/pepper/camera/depth/image_raw"
#works fine:
image_topic = "/pepper/camera/front/image_raw"
rospy.Subscriber(image_topic, Image, image_callback)
rospy.spin()
if __name__ == '__main__':
main()
So my problem is that my code works perfectly fine if i use the data of the front camera but does not work for the depth images.
To make sure i get the correct encoding type i used the command msg.encoding which tells me the encoding type of the current ros message.
The cv2.imshow works exactly like it should for the front camera pictures and it shows me the same as i would get if i used ros image_view but as soon as i try it with the depth image i just get a fully black or white picture unlike what image_view shows me
Here the depth image i get when i use image_view
Here the depth image i receive when i use the script and cv2.imshow
Does anyone have experience working on depth images with cv2 and can help me to get it working with the depth images as well?
I really would appreciate any help :)
Best regards
You could try in the following way to acquire the depth images,
import rospy
from cv_bridge import CvBridge, CvBridgeError
from sensor_msgs.msg import Image
import numpy as np
import cv2
def convert_depth_image(ros_image):
cv_bridge = CvBridge()
try:
depth_image = cv_bridge.imgmsg_to_cv2(ros_image, desired_encoding='passthrough')
except CvBridgeError, e:
print e
depth_array = np.array(depth_image, dtype=np.float32)
np.save("depth_img.npy", depth_array)
rospy.loginfo(depth_array)
#To save image as png
# Apply colormap on depth image (image must be converted to 8-bit per pixel first)
depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.03), cv2.COLORMAP_JET)
cv2.imwrite("depth_img.png", depth_colormap)
#Or you use
# depth_array = depth_array.astype(np.uint16)
# cv2.imwrite("depth_img.png", depth_array)
def pixel2depth():
rospy.init_node('pixel2depth',anonymous=True)
rospy.Subscriber("/pepper/camera/depth/image_raw", Image,callback=convert_depth_image, queue_size=1)
rospy.spin()
if __name__ == '__main__':
pixel2depth()

Reading image file (file storage object) using OpenCV

I am sending an image by curl to flask server, i am using this curl command
curl -F "file=#image.jpg" http://localhost:8000/home
and I am trying to read the file using OpenCV on the server side.
On the server side I handle the image by this code
#app.route('/home', methods=['POST'])
def home():
data =request.files['file']
img = cv.imread(data)
fact_resp= model.predict(img)
return jsonify(fact_resp)
I am getting this error-
img = cv.imread(data)
TypeError: expected string or Unicode object, FileStorage found
How do I read the file using OpenCV on the server side?
Thanks!
I had similar issues while using opencv with flask server, for that first i saved the image to disk and read that image using saved filepath again using cv.imread()
Here is a sample code:
data =request.files['file']
filename = secure_filename(file.filename) # save file
filepath = os.path.join(app.config['imgdir'], filename);
file.save(filepath)
cv.imread(filepath)
But now i have got even more efficient approach from here by using cv.imdecode() to read image from numpy array as below:
#read image file string data
filestr = request.files['file'].read()
#convert string data to numpy array
file_bytes = numpy.fromstring(filestr, numpy.uint8)
# convert numpy array to image
img = cv.imdecode(file_bytes, cv.IMREAD_UNCHANGED)
After a bit of experimentation, I myself figured out a way to read the file using CV2.
For this I first read the image using PIL.image method
This is my code,
#app.route('/home', methods=['POST'])
def home():
data =request.files['file']
img = Image.open(request.files['file'])
img = np.array(img)
img = cv2.resize(img,(224,224))
img = cv2.cvtColor(np.array(img), cv2.COLOR_BGR2RGB)
fact_resp= model.predict(img)
return jsonify(fact_resp)
I wonder if there is any straight forward way to do this without using PIL.
So incase you want to do something like ,
file = request.files['file']
img = cv.imread(file)
then do it like this
import numpy as np
file = request.files['file']
file_bytes = np.fromfile(file, np.uint8)
file = cv.imdecode(file_bytes, cv.IMREAD_COLOR)
Now you don't need to do cv.imread() again, but can use this in the next line of codes.
This applies to OpenCV v3.x and onwards
Two-line solution, change grayscale to what you need
file_bytes = numpy.fromfile(request.files['image'], numpy.uint8)
# convert numpy array to image
img = cv.imdecode(file_bytes, cv.IMREAD_GRAYSCALE)

How to load images from a directory on the computer in Python

Hello I am New to python and I wanted to know how i can load images from a directory on the computer into python variable.
I have a set of images in a folder on disk and I want to display these images in a loop.
You can use PIL (Python Imaging Library) http://www.pythonware.com/products/pil/ to load images.
Then you can make an script to read images from a directory and load them to python, something like this.
#!/usr/bin/python
from os import listdir
from PIL import Image as PImage
def loadImages(path):
# return array of images
imagesList = listdir(path)
loadedImages = []
for image in imagesList:
img = PImage.open(path + image)
loadedImages.append(img)
return loadedImages
path = "/path/to/your/images/"
# your images in an array
imgs = loadImages(path)
for img in imgs:
# you can show every image
img.show()
pip install ThreadedFileLoader
You can use ThreadedFileLoader module. It uses threading to load images.
from ThreadedFileLoader.ThreadedFileLoader import *
instance = ThreadedImageLoader("path_to_folder/*.jpg")
instance.start_loading()
images = instance.loaded_objects
print(len(images))
print(images[0].shape)
You can use glob and imageio python packages to achieve the same. Below is code in python 3:
import glob
import imageio
for image_path in glob.glob("<your image directory path>\\*.png"):
im = imageio.imread(image_path)
print (im.shape)
print (im.dtype)
If you have images in your google drive, and want to load, resize and save the images, then the following code works well.
import os, sys
from os import listdir
from PIL import Image
from google.colab import drive
import matplotlib.pyplot as plt
drive.mount('/content/gdrive')
# need to enter password to access your google drive
from google.colab import files
main_dir = "/content/gdrive/My Drive/Panda/"
files = listdir(main_dir)
# you can change file extension below to read other image types
images_list = [i for i in files if i.endswith('.jpg')] ## output file names only
for idx,image in enumerate(images_list):
print(idx)
img = Image.open(main_dir + image)
#print(img.size)
#plt.imshow(img)
img = img.resize((480, 600))
img.save(main_dir + image)

Resources