【问题标题】:Ways to convert an entry from a .csv file back to a figure将条目从 .csv 文件转换回图形的方法
【发布时间】:2020-10-04 02:59:46
【问题描述】:

我正在尝试使用 Image 将图形信息保存到 .csv 文件,但我坚持将其转换回图形。它不断给我错误“AttributeError:'str'对象没有属性'array_interface'”。

我想这意味着我从.csv文件中提取的条目是一个字符串,需要转换为数组?

我将图形转换为 np 数组的代码如下所示:

from PIL import Image
    img = np.array(Image.open(fig_file))

file_name = 'data.csv'
row_contents = [labels, img]

from csv import writer
def append_list_as_row(file_name, list_of_elem):
    # Open file in append mode
    with open(file_name, 'a+', newline='') as write_obj:
        # Create a writer object from csv module
        csv_writer = writer(write_obj)
        # Add contents of list as last row in the csv file
        csv_writer.writerow(list_of_elem)

append_list_as_row(file_name, row_contents)

有问题的部分(将其转换回图形)如下所示:

import pandas as pd
df1 = pd.read_csv(file_name)
fig_array = df1.loc[1, "img"]
img = Image.fromarray(fig_array, 'RGB')
img.save('test.png')

图像行导致错误。也许我不应该使用熊猫来定位条目?有修改的想法吗?我试过 .to_numpy(),它不起作用。

非常感谢!

【问题讨论】:

  • 您是如何将图像保存到 csv 中的?您的代码应显示该内容以进行复制。
  • CSV 不是保存图像的本机方式。数据可能失真了。
  • @BillHuang 我已经添加了代码,请看一下。我只是保存和转换这个特定的条目。
  • @gtomer 嗯...您认为如果我在 csv 文件中存储一个错误矩阵,然后将其提取并绘制它可能是另一种方式吗?或者也许只是做一个带有图形名称的列和一个包含所有图形的单独文件夹,以便我可以交叉引用?

标签: python pandas image csv figure


【解决方案1】:

首先,如果可能,不要这样做。这成本太高了。只需制作一个表格(数据框),记录与每个文件关联的标签,以便以后查询。例如

| file_id | file_path | label     |
|---------|-----------|-----------|
| 1       | a.jpg     | fine-arts |
| 2       | b.png     | manga     |
| 3       | c.jpb     | whatever  |

如果您真的必须将图像编码为字符串,base64 encoding 是一种常见的方法。例如,jupyter notebook 使用base64 格式将图片嵌入到 html 文件中,以便用户轻松分享生成的图片。

其次,由于电子表格软件的列宽限制,仍然不建议将(标签,数据)对保存为 csv 文件。如果不能利用.csv 格式,为什么要使用它?因此,在这种情况下,最好还是做一个上面提到的查找表,以避免不必要的代价高昂的转换。

如果你还在做,好的,这里是示例代码。小号image 取自debian homepage。可以验证数据是否正确恢复。

代码

import numpy as np
from PIL import Image
import base64
import csv

# https://www.debian.org/Pics/openlogo-50.png
img_path = "/mnt/ramdisk/debian-openlogo-50.png"

img = np.array(Image.open(img_path))
img_encoded = base64.b64encode(img).decode("ascii")
label = "fine-arts"

# Simulate multiple records
data = [
    [label, img_encoded],
    [label, img_encoded],
    [label, img_encoded]
]

# save
with open("/mnt/ramdisk/sav.csv", "w+") as f:
    w = csv.writer(f)
    w.writerows(data)

# load
data_loaded = []
with open("/mnt/ramdisk/sav.csv") as f:
    r = csv.reader(f)
    for row in r:
        data_loaded.append(row)

# check data are unchanged after S/L
for i in range(3):
    for j in range(2):
        assert data[i][j] == data_loaded[i][j]

# decode the image (still need shape info)
r = base64.b64decode(data_loaded[0][1].encode("ascii"))
img_decoded = np.frombuffer(r, dtype=np.uint8).reshape((61, 50, 4))

# check image is restored correctly
import matplotlib.pyplot as plt
plt.imshow(img_decoded)
plt.show()

但是,如果使用较大的图像,例如Mona Lisa,则 csv 阅读器会报错:

_csv.Error: field larger than field limit (131072)

而且您仍然需要图像形状来恢复尺寸。因此实际上需要第三列存储图像形状。

【讨论】:

  • 非常感谢!我决定只做一个交叉引用方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-22
  • 2020-03-24
  • 2021-01-03
  • 2020-03-19
  • 2021-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多