如何显示存储在熊猫数据框中的图像?
Posted
技术标签:
【中文标题】如何显示存储在熊猫数据框中的图像?【英文标题】:How to display image stored in pandas dataframe? 【发布时间】:2018-02-16 20:11:23 【问题描述】: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()
当我尝试显示由 csv 文件加载的图像时,我收到错误:图像数据无法转换为浮点数。但是,当使用数据框df
时,我能够正确显示图像。
我怀疑当我将 df 存储到 csv 文件时,数据类型出现了问题。我该如何解决这个问题?
编辑:我应该补充一点,我的主要目标是
-
将包含图像的 pandas 数据帧写入 csv 文件
从磁盘读取 csv 文件,而不是将整个数据帧存储在 RAM 上
【问题讨论】:
您是否在每个单元格中存储 rgb 元组?你能提供一些 df 的样本吗?img
是3维数据,to_csv
无法处理(查看mypic.csv
的内容)。
是的,我正在存储 rgb 图像。我可以将数据存储在其他类型的文件中吗?
【参考方案1】:
如何在 pandas 数据框中显示图像
如果您有包含 URL 或本地路径的 Pandas 列,您可以生成将显示缩略图或任何其他图像大小的图像列。
1.如果您在列表中有图片的 URL。
您首先需要根据图片 URL 下载图片。 adImageList
包含您要作为列添加到 pandas 的图像的 URL 列表。
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。如果您在 Pandas 数据框中的单独列中有图像 URL。 首先创建获取单个图像的本地 URL 的函数
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)
而不是使用 lambda 表达式将其映射到新列 imageLocal
:
df['imageLocal'] = df.URL.map(lambda f: get_image_local(f))
df['imageLocal']
应该如下所示:
0 C:\Users\username\Documents\Base_folder\01_image.jpg 1 C:\Users\username\Documents\Base_folder\02_image.jpg 2 C:\Users\username\Documents\Base_folder\03_image.jpg
3.使用 PILL 函数,您现在只需复制粘贴即可:
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)">'
我们可以通过以下方式将本地图像路径传递给get_thumbnail(path)
:
df['imagePILL'] = df.imageLocal.map(lambda f: get_thumbnail(f))
df['imagePILL']
应该是这样的:
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>
您可以使用 pandas 数据框将新列放在所需位置:
df= df.reindex(sorted(df.columns), axis=1)
现在,如果您想查看带有调整大小图像的 pandas 数据框,只需在 IPython.display
HTML 函数中调用 image_formatter
函数:
HTML(df.to_html(formatters='imagePILL': image_formatter, escape=False))
您可以使用任何其他方式显示 HTML,重要的是在 pandas 数据帧中获取 PIL 对象。
【讨论】:
【参考方案2】:从问题中不清楚为什么要使用 pandas 数据帧来存储图像。我认为这使事情变得不必要地复杂。您可以改为直接以二进制格式存储 numpy 数组,并在稍后再次加载。
import numpy as np
import matplotlib.pyplot as plt
#create an image
imar = np.array([[[1.,0.],[0.,0.]],
[[0.,1.],[0.,1.]],
[[0.,0.],[1.,1.]]]).transpose()
plt.imsave('pic.jpg', imar)
# read the image
im = plt.imread('pic.jpg')
# show the image
plt.imshow(im)
plt.show()
#save the image array to binary file
np.save('mypic', im)
# load the image from binary file
new_im= np.load('mypic.npy')
# show the loaded image
plt.imshow(new_im)
plt.show()
作为对以下 cmets 的回应,它们以某种方式将问题转向不同的方向,您肯定可以将图像的路径/名称存储在数据框中。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#create an image
imar = np.array([[[1.,0.],[0.,0.]],
[[0.,1.],[0.,1.]],
[[0.,0.],[1.,1.]]]).transpose()
plt.imsave('pic.jpg', imar)
#create dataframe
df = pd.DataFrame([[0,""]], columns=["Feature1","Feature2"])
# read the image
im = plt.imread('pic.jpg')
plt.imshow(im)
plt.show()
#save the image array to binary file
np.save('mypic.npy', im)
# store name of image in dataframe
df.iloc[0,1] = 'mypic.npy'
#save dataframe
df.to_csv("mydf.csv")
del df
#read dataframe from csv
df = pd.read_csv("mydf.csv")
# load the image from binary file, given the path from the Dataframe
new_im= np.load(df["Feature2"][0])
# show the loaded image
plt.imshow(new_im)
plt.show()
最后,您可以按照最初计划的方式将实际图像存储在数据框单元格中,但不是写入 csv,而是对数据框进行映射,以便可以像从未读取过一样读取它之前保存过。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import pickle
#create an image
imar = np.array([[[1.,0.],[0.,0.]],
[[0.,1.],[0.,1.]],
[[0.,0.],[1.,1.]]]).transpose()
plt.imsave('pic.jpg', imar)
#create dataframe
df = pd.DataFrame([[0,""]], columns=["Feature1","Feature2"])
# read the image
im = plt.imread('pic.jpg')
plt.imshow(im)
plt.show()
# store the image itself in dataframe
df.iloc[0,1] = [im]
#save dataframe
pickle.dump(df, file("mydf.pickle", "wb"))
del df
#read dataframe from pickle
df = pickle.load(file("mydf.pickle", "rb"))
# show the loaded image from dataframe cell
plt.imshow(df["Feature2"][0][0])
plt.show()
【讨论】:
我有一个数据电子表格,其中每一行是一个不同的项目,每一列代表项目的一个特征。特征之一由图像文件描述。我认为最好使用 pandas 数据框来有效地访问我的数据。此外,它是一个大型数据集,因此我想从磁盘读取它。是否可以使用 pandas 数据框来做到这一点? 我是否可以链接到我的数据框中的图像文件,而不是将整个图像存储在数据框中? 问题中需要有关您要完成的工作的这类信息。现在我用两种可能对你有帮助的新方法更新了答案。以上是关于如何显示存储在熊猫数据框中的图像?的主要内容,如果未能解决你的问题,请参考以下文章