python - Python 用 Pillow 对多个作物进行图像处理,并用 Bokeh 分组并显示在一行中
问题描述
我有以下任务:生成多个图像裁剪,然后将它们分组显示在彼此相邻的行中。到目前为止,我设法根据坐标生成作物。我不知道如何按行显示图像,按“用户”分组并按“时间”排序。我应该使用 Bokeh 来绘制图像,因为会有更多的情节需要整合。请帮忙!!!!
数据框:
#Import libraries
import numpy as np
from numpy import asarray
import pandas as pd
from PIL import Image
import matplotlib as plt
#Create the dataframe
data = {'Time': ['2586', '2836', '2986', '3269', '3702'],
'Map': ['Buc.jpg', 'Buc.jpg', 'Buc.jpg', 'Buc.jpg', 'Buc.jpg'],
'Index': ['9', '10', '11', '12', '13'],
'PSize': ['250', '150', '283', '433', '183'],
'X': ['751', '673', '542', '762', '624'],
'Y': ['458', '316', '287', '303', '297'],
'User': ['u1', 'u1', 'u2', 'u2', 'u2'],
}
columns = ['Time','Map','Index','PSize','X','Y','User']
df = pd.DataFrame (data, columns = columns)
df = df.astype(dtype= {"Time":"int64", "Map":"object","Index":"int64", 'PSize':'int64', 'X': 'int64', 'Y':"int64", 'User':'object'})
df.head()
根据坐标生成作物:
#Create coordinate and crop the image
imagefile = 'Buc.jpg'
coordinates = list(df[['X', 'Y']].itertuples(index=False, name=None))
psize = 100
img = Image.open(imagefile)
for x, y in coordinates:
box = (x-psize/2, y-psize/2, x+psize/2, y+psize/2)
img.crop(box).show('%s.x%03d.y%03d.jpg'% (imagefile.replace('.jpg',''), x, y))
输出示例:
解决方案
像这样的东西。请注意,Buc.jpg
当您运行脚本时,它必须在当前工作目录中可用。
import numpy as np
import pandas as pd
from PIL import Image
from bokeh.io import show
from bokeh.models import FixedTicker, FuncTickFormatter, ColumnDataSource
from bokeh.plotting import figure
from bokeh.transform import dodge
df = pd.DataFrame({'Time': [2586, 2836, 2986, 3269, 3702],
'X': [751, 673, 542, 762, 624],
'Y': [458, 316, 287, 303, 297],
'User': ['u1', 'u1', 'u2', 'u2', 'u2']})
imagefile = 'Buc.jpg'
coordinates = list(df[['X', 'Y']].itertuples(index=False, name=None))
psize = 100
img = Image.open(imagefile).convert('RGBA')
cropped_images = []
for x, y in coordinates:
box = (x - psize / 2, y - psize / 2, x + psize / 2, y + psize / 2)
cropped_images.append(np.array(img.crop(box)).view(np.uint32)[::-1])
df['Image'] = cropped_images
# There's probably a better method to populate `TimeCoord` which I don't know.
df = df.sort_values('Time')
df['TimeCoord'] = 0
for u in df['User'].unique():
udf = (df['User'] == u)
df.loc[udf, 'TimeCoord'] = np.arange(udf.sum())
user_coords = dict(zip(df['User'].unique(), range(df.shape[0])))
df['UserCoord'] = df['User'].replace(user_coords)
p = figure(match_aspect=True)
for r in [p.xaxis, p.xgrid, p.ygrid]:
r.visible = False
# Manually creating a categorical-like axis to make sure that we can use `dodge` below.
p.yaxis.ticker = FixedTicker(ticks=list(user_coords.values()))
p.yaxis.formatter = FuncTickFormatter(args=dict(rev_user_coords={v: k for k, v in user_coords.items()}),
code="return rev_user_coords[tick];")
ds = ColumnDataSource(df)
img_size = 0.8
p.image_rgba(image='Image',
x=dodge('TimeCoord', -img_size / 2), y=dodge('UserCoord', -img_size / 2),
dw=img_size, dh=img_size, source=ds)
p.rect(x='TimeCoord', y='UserCoord', width=img_size, height=img_size, source=ds,
line_dash='dashed', fill_alpha=0)
show(p)
推荐阅读
- python - Python 请求遇到状态代码 406 和错误消息“请求不允许”
- mysql - 有多少电影只属于一种类型?
- javascript - 在 objection.js 中使用 json-schema 处理验证的正确方法是什么?
- javascript - 在标题键嵌套对象vue js上搜索和替换字符串
- flutter - 在字符串的单个字母上颤动触摸事件
- mysql - MySQL8 允许多少个 JOIN?
- mongodb - 在 mongodb 中创建唯一 id,每次插入都会增加
- webdriver-io - Webdriverio 6 - 如何右键单击 X 和 Y 位置
- python - 用 16 位图像训练 keras ResNet50V2?
- python - 将 PIL.Image 转换为 skimage