Plotly Scatter3d пикселей вдоль компонентов RGB
Я пытаюсь построить 3D-компоненты RGB для всех пикселей изображения с помощью графика (каждый пиксель - это точка в трехмерном пространстве, где оси - это R, G и B), в то время как каждый пиксель окрашивается его цвет:
Я использовал следующий подход, который отлично работает с небольшим количеством пикселей:
import plotly.offline as pyo
import plotly.graph_objs as go
import numpy as np
pyo.init_notebook_mode()
data = list()
# for each pixel
for pixel in image_to_plot:
# add trace as follows:
data.append(
go.Scatter3d(
# only one point
x=[pixel[0]],
y=[pixel[1]],
z=[pixel[2]],
# set its color
mode='markers',
marker=dict(size=2, color='rgb('+', '.join(pixel.astype(str))+')'),
)
)
layout = dict(scene=dict(xaxis=dict(title='R'), yaxis=dict(title='G'), zaxis=dict(title='B')), showlegend=False)
pyo.iplot({'data': data, 'layout': layout}, filename='so_example')
где image_to_plot
это массив пикселей (форма (1000, 3)
).
Но из-за растущего числа трассировок мой браузер падает почти на 1000 баллов и даже не рендерится выше этого. Конечно, есть лучший подход?
Моя цель состоит в том, чтобы эта работа приносила от 100 до 1 миллиона баллов. Для уменьшенного количества цветов (например, группирование точек в следы одного и того же цвета после кластеризации K-средних) это работает отлично.
Я думал о том, чтобы сделать это наоборот и построить трассу для каждого существующего цвета, чтобы избежать множественных точек наложения на разных трассах, но это приводит к 16M (256^3) возможных трасс, поэтому, вероятно, также не подходит.
1 ответ
marker
словарь может взять список для своего ключа color
и применять его поэлементно, так что это разрешено:
# Instead of this in a for-loop:
x=[pixel[0]]
color='rgb('+', '.join(pixel.astype(str))+')'
# Do this:
x=image_to_plot[:, 0]
color=list(map(lambda e: 'rgb('+', '.join(e.astype(str))+')', image_to_plot))
Комплексное решение для переменной data
:
data = [
go.Scatter3d(
x=image_to_plot[:, 0],
y=image_to_plot[:, 1],
z=image_to_plot[:, 2],
mode='markers',
marker=dict(
size=2,
color=list(map(lambda e: 'rgb('+', '.join(e.astype(str))+')', image_to_plot)),
),
)
]
Это намного красивее и может показать до 500 тыс. Баллов за несколько секунд на моем компьютере. За этим порогом пределы памяти достигнуты.