Я пытаюсь объединить некоторые кадры данных глубины, снятые с помощью камеры глубины Intel RealSense.
Кадры данных глубины имеют следующий формат:
dataframe1 = [[0, 0, 0, 0, 0, 10, 10, 10], [0, 0, 0, 0, 0, 10, 10, 10], [0, 0, 0, 0, 0, 10, 10, 10]]
dataframe2 = [[10, 10, 10, 0, 0, 0, 0, 0], [10, 10, 10, 0, 0, 0, 0, 0], [10, 10, 10, 0, 0, 0, 0, 0]]
Что я хотел бы сделать, так это выполнить некоторую функцию понимания списка (ish), чтобы добавить индексы dataframe2 в dataframe1, если индексы равны нулю. Ожидаемый результат будет выглядеть следующим образом:
dataframe1 = [[10, 10, 10, 0, 0, 10, 10, 10], [10, 10, 10, 0, 0, 10, 10, 10], [10, 10, 10, 0, 0, 10, 10, 10]]
Моя единственная идея сейчас - это функция цикла for, подобная этой:
for idx, frame in enumerate(dataframe1):
for idy, data in enumerate(frame):
if data == 0:
dataframe1[idx][idy] = dataframe2[idx][idy]
Нет ли более разумного способа понимания списка с помощью трехмерных массивов?
Я также попытался добавить кадры данных в один массив, а затем получить среднее значение, используя:
average values = numpy.average(all_arrays, axis=0).astype(uint16)
Но шум в моих данных глубины вызовет много дополнительных шумовых точек в среднем кадре.
Любая помощь приветствуется.
С наилучшими пожеланиями Мартин
Вы можете сделать это с пониманием списка:
dataframe1 = [[0, 0, 0, 0, 0, 10, 10, 10], [0, 0, 0, 0, 0, 10, 10, 10], [0, 0, 0, 0, 0, 10, 10, 10]]
dataframe2 = [[10, 10, 10, 0, 0, 0, 0, 0], [10, 10, 10, 0, 0, 0, 0, 0], [10, 10, 10, 0, 0, 0, 0, 0]]
[[m if not k else k for k, m in zip(i, j)] for i, j in zip(dataframe1, dataframe2)]
Выход:
[[10, 10, 10, 0, 0, 10, 10, 10],
[10, 10, 10, 0, 0, 10, 10, 10],
[10, 10, 10, 0, 0, 10, 10, 10]]
Обновлено: обратите внимание, что это быстрее, чем использование np.where()
, если dataframe1 и dataframe2 еще не являются массивами numpy (в противном случае np.where()
быстрее):
import timeit
d1 = [[0, 0, 0, 0, 0, 10, 10, 10], [0, 1, 0, 0, 0, 10, 10, 10], [0, 0, 0, 0, 0, 10, 10, 10]]*100000
d2 = [[10, 10, 10, 0, 0, 0, 0, 0], [10, 10, 10, 0, 0, 0, 0, 0], [10, 10, 10, 0, 0, 0, 0, 0]]*100000
def lstcomp(dataframe1, dataframe2):
return [[m if not k else k for k, m in zip(i, j)] for i, j in zip(dataframe1, dataframe2)]
def where(dataframe1, dataframe2):
dataframe1 = np.array(dataframe1)
dataframe2 = np.array(dataframe2)
return np.where(dataframe1, dataframe1, dataframe2)
%timeit lstcomp(d1, d2)
%timeit where(d1, d2)
Выход:
233 ms ± 1.53 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
456 ms ± 992 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Можете ли вы объяснить логику функции where? dataframe1 ставится как условие, но без логического оператора. Означает ли это, что если dataframe1[x] равен 0, он возвращает false и берет данные из dataframe2?
Точно, в python bool(0) = False
и bool(n) = True
, где n не равно нулю, поэтому, когда вы используете, когда dataframe1 равен 0 в качестве вашего условия, вам не нужно ничего делать с ним, чтобы он работал как условие в np.where. Аналогично тому, как я использовал if not k
в случае понимания списка, а не if k == 0
.
@MichaelSzczesny Думаю, это работает. Можете ли вы добавить это как ответ, чтобы я мог выбрать его. Я думал, что np.where вернул кортеж, но, возможно, я просто что-то неправильно понял.