Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
353 views
in Technique[技术] by (71.8m points)

python - How to display image stored in pandas dataframe?

import pandas as pd
from scipy import misc
import numpy as np
import matplotlib.pyplot as plt

W = {'img':[misc.imread('pic.jpg')]}
df = pd.DataFrame(W)

# This displays the image
plt.imshow(df.img1[0])
plt.show()

df.to_csv('mypic.csv')
new_df= pd.read_csv('mypic.csv')

# This does not display the image
plt.imshow(new_df.img1[0])
plt.show()

When I try to display the image as loaded by the csv file I obtain the error: Image data can not convert to float. However, I was able to correctly display the image when using the dataframe df.

I suspect that something went wrong with the data type when I stored df onto a csv file. How would I fix this issue?

edit: I should add that my main objective is to

  1. Write a pandas dataframe that contains images onto a csv file
  2. Read the csv file from disk as opposed to storing the entire dataframe on RAM
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

How to display images in pandas dataframe

If you have Pandas column that contains URL or local path you can generate Image column which will display thumbnail or any other image size.

1. In case you have URLs of images in list.

You will first need to download images based on image URLs. adImageList contains list of URL of images which you want to add to pandas as column.

dir_base = os.getcwd() # Get your current directory
for i, URL in enumerate(adImageList):
                image_name= '0{}_{}'.format(i+1,'_image.jpg') # This will show for example 01_image.jpg
                urllib.request.urlretrieve(URL, image_name)
                local_path_thumb = os.path.join(dir_base , image_name)
                df[i]['local_image_path']=local_path # adding that locally fetched image path to pandas column

2. In case you have image URLs in separate column in Pandas dataframe. First create function for getting local URL for single image

   get_image_local(URL):            
        image_name= '0{}_{}'.format(i+1,'_image.jpg')
        urllib.request.urlretrieve(URL, image_name)
        local_path_image = os.path.join(dir_base, image_name)
        return (local_path_image)

Than use lambda expression to map that to new column imageLocal:

df['imageLocal'] = df.URL.map(lambda f: get_image_local(f)) 

df['imageLocal'] should look something like this:

0 C:UsersusernameDocumentsBase_folder1_image.jpg         
1 C:UsersusernameDocumentsBase_folder2_image.jpg                          
2 C:UsersusernameDocumentsBase_folder3_image.jpg

3. With PILL functions you can just copy paste now:

import glob
import random
import base64
import pandas as pd

from PIL import Image
from io import BytesIO
from IPython.display import HTML
import io

pd.set_option('display.max_colwidth', -1)


def get_thumbnail(path):
    path = "\\?\"+path # This "\\?\" is used to prevent problems with long Windows paths
    i = Image.open(path)    
    return i

def image_base64(im):
    if isinstance(im, str):
        im = get_thumbnail(im)
    with BytesIO() as buffer:
        im.save(buffer, 'jpeg')
        return base64.b64encode(buffer.getvalue()).decode()

def image_formatter(im):
    return f'<img src="data:image/jpeg;base64,{image_base64(im)}">'

We can pass our local image path to get_thumbnail(path) with following:

df['imagePILL'] = df.imageLocal.map(lambda f: get_thumbnail(f))

And df['imagePILL'] should look like this:

0    <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=300x400 at 0x265BA323240>
1    <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=200x150 at 0x265BA3231D0>
2    <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=300x400 at 0x265BA3238D0>

You can resort pandas dataframe to get your new column in desired position:

df= df.reindex(sorted(df.columns), axis=1)

And now if you want to view pandas dataframe with resized images just call image_formatter function in IPython.display HTML function:

HTML(df.to_html(formatters={'imagePILL': image_formatter}, escape=False))

You can use any other way of showing HTML, important thing is to get PIL object inside pandas dataframe.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...