Я работаю над героем, который рассчитывает статистику по изображению, загруженному пользователем.Предполагается, что изображения представляют собой png-файлы с пикселями, помеченными в соответствии с классами, связанными со значениями rgb.Моя проблема в том, что изображения очень большие (около 10k x 10k пикселей, ~ 3 МБ), и я превышаю квоту памяти на heroku.При локальном тестировании это медленно, но функционально.Я новичок в веб-программировании и не совсем уверен, как решить эту проблему.
Я нашел этот пример https://github.com/plotly/dash-image-processing и протестировал его с большими изображениями на моем аккаунте heroku.Это сработало, но я немного растерялся, пытаясь понять код, и функциональность в любом случае разная (я использую Pillow, чтобы преобразовать изображение rgb в оттенки серого, а затем подсчитать процент пикселей, соответствующий данному классу).Вот функция обратного вызова, в которой выполняются вычисления.
@app.callback(
Output('output-species-count', 'children'),
[Input('upload-image', 'contents')]
)
def species_count(images):
if not images:
return
else:
t_start = time.time()
for image_str in images:
# Convert contents to I/O buffer
image = image_str.split(',')[-1]
string = image.split(';base64,')[-1]
decoded = base64.b64decode(string)
buffer = BytesIO(decoded)
# Read buffer as grayscale PIL image, then convert to numpy array
im = np.array(Image.open(buffer).convert('L'))
# Count number of pixels per species
counts_dict = dict(zip(legend.keys(), [0] * len(legend)))
for k in legend.keys():
counts_dict[k] = len(np.where(im == legend[k]['gray'])[0])
# List the counts to pass to "values" below for percents calculation
counts_list = list(counts_dict.values())
t_end = time.time()
if DEBUG:
print(f"Calculated percent cover in {t_end - t_start:.3f} sec")
children = [
html.Div([
dcc.Graph(
figure={
"data": [
{
"type": "pie",
"hoverinfo": "label+percent",
"labels": list(counts_dict.keys()),
"values": counts_list,
"marker": {
"colors": [
'rgb'+str(tuple(v['rgb']))
for k, v in legend.items()
]
},
"hole": 0.4
}
],
"layout": {
"title": "Species Percent Cover"
}
}
)
])
]
return children
Я обрезал одно из больших (13k x 13k) изображений до 2k, 4k, 6k, 8k и 10k, и оно было выполнено в 0,5, 3,5, 6,0и 17,5 секунд, но разбился на 10к.Вот журнал Heroku:
2019-04-23T14:42:12.508428+00:00 heroku[router]: at=info method=POST path="/_dash-update-component" host=coral-stats.herokuapp.com request_id=aca53727-2642-43bb-903f-6c99745efd36 fwd="152.20.237.233" dyno=web.1 connect=1ms service=465ms status=200 bytes=1218050 protocol=https
2019-04-23T14:42:12.496310+00:00 app[web.1]: 10.30.78.6 - - [23/Apr/2019:14:42:12 +0000] "POST /_dash-update-component HTTP/1.1" 200 1217846 "https://coral-stats.herokuapp.com/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
2019-04-23T14:42:22.977433+00:00 heroku[web.1]: State changed from crashed to starting
2019-04-23T14:42:22.972132+00:00 heroku[web.1]: State changed from up to crashed
2019-04-23T14:42:22.812554+00:00 heroku[web.1]: source=web.1 dyno=heroku.125670006.f31289d1-cba6-4ec7-a802-176bc0e5e051 sample#load_avg_1m=0.21 sample#load_avg_5m=0.11 sample#load_avg_15m=0.04
2019-04-23T14:42:22.812643+00:00 heroku[web.1]: source=web.1 dyno=heroku.125670006.f31289d1-cba6-4ec7-a802-176bc0e5e051 sample#memory_total=1025.27MB sample#memory_rss=511.96MB sample#memory_cache=0.00MB sample#memory_swap=513.30MB sample#memory_pgpgin=988792pages sample#memory_pgpgout=858752pages sample#memory_quota=512.00MB
2019-04-23T14:42:22.813151+00:00 heroku[web.1]: Process running mem=1027M(200.7%)
2019-04-23T14:42:22.813235+00:00 heroku[web.1]: Error R15 (Memory quota vastly exceeded)
2019-04-23T14:42:22.813316+00:00 heroku[web.1]: Stopping process with SIGKILL
2019-04-23T14:42:22.959604+00:00 heroku[web.1]: Process exited with status 137
2019-04-23T14:42:22.901815+00:00 heroku[router]: at=error code=H13 desc="Connection closed without response" method=POST path="/_dash-update-component" host=coral-stats.herokuapp.com request_id=861e4582-924d-4f53-9137-b56e8e55b345 fwd="152.20.237.233" dyno=web.1 connect=1ms service=10902ms status=503 bytes=0 protocol=https
Я также отображаю изображение в браузере в виде эскиза.Так у меня основная проблема с кэшированием или хранением?