Python用枕头对多个作物进行图像处理,并使用散景将其分组并显示在一行中

问题描述 投票:0回答:1

我有以下任务:生成多个图像裁剪,然后将它们按行分组显示。到目前为止,我设法基于坐标生成农作物。我不知道如何按“用户”分组并按“时间”排序以行显示图像。我应该使用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()

图像文件:enter image description here

基于坐标生成农作物:

#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))

输出示例:

enter image description here

python image python-imaging-library bokeh
1个回答
0
投票

这样的事情。请注意,运行脚本时,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)
© www.soinside.com 2019 - 2024. All rights reserved.