Чтобы повысить эффективность сценария python, я пытаюсь преобразовать сценарий на основе большого количества операций «для l oop» в облаке точек благодаря Numpy для ускорения процесса .
В двух словах, у меня есть 3d-модель, представленная в виде набора 3d-точек (координаты x, y, z), содержащихся в np .array (размерность: (188706, 3))
[[168.998 167.681 0.] <-- point 1
[169.72 167.695 0.] <-- point 2
[170.44 167.629 0.] <-- point 3
...
[148.986 163.271 25.8] <-- point 188704
[148.594 163.634 25.8] <-- point 188705
[148.547 163.667 25.8]] <-- point 188706
Каждая пара [[строка x -1] [строка x ]] представляет сегмент в 3D
[[168.998 167.681 0.] [169.72 167.695 0.] <-- SEGMENT 1 (points 1 & 2)
[169.72 167.695 0.] [170.44 167.629 0.] <-- SEGMENT 2 (points 2 & 3)
[170.44 167.629 0.] [171.149 167.483 0.] <-- SEGMENT 3 (points 3 & 4)
...
[149.328 162.853 25.8] [148.986 163.271 25.8] <-- SEGMENT 94351 (points 188703 & 188704)
[148.986 163.271 25.8] [148.594 163.634 25.8] <-- SEGMENT 94352 (points 18874 & 188705)
[148.594 163.634 25.8] [148.547 163.667 25.8]] <-- SEGMENT 94353 (points 188705 & 188706)
Моя цель - измерить евклидово расстояние между каждой упорядоченной точкой // парой строк (= длина каждого отрезка), чтобы я мог определить, где мне нужно добавить больше точек для представления немного больше поверхность моей 3d модели. Другими словами, если длина сегмента превышает пороговое значение (= 0,5 мм), мне придется дискретизировать этот конкретный сегмент с большим количеством точек и добавить эти дополнительные точки в мое облако точек.
Я имею нашел способ измерить евклидово расстояние рекурсивно между каждой строкой благодаря этому коду:
EuclidianDistance = np.linalg.norm(PtCloud[:-1] - PtCloud[1:],axis=1)
, который дает этот результат:
[0.72213572 0.72301867 0.72387637 ... 0.54008148 0.5342593 0.05742822]
И я также нашел, как описать сегмент в соответствии с его вершинами (конечностями):
def AddEquidistantPoints(p1, p2, parts):
return np.stack((np.linspace(p1[0], p2[0], parts + 1), np.linspace(p1[1], p2[1], parts + 1)), axis=-1)
if EuclidianDistance > 0.5mm:
dist = AddEquidistantPoints(currentRow, previousRow, 10) #10 --> nb subdivisions
Но моя первая проблема заключается в том, что евклидовы расстояния нужно вычислять только в точках, где координаты z равны. Должен ли я разделить мой массив, когда координаты z не равны? С:
PtCloud = np.split(PtCloud, np.where(np.diff(PtCloud[:,2])!=0)[0]+1)
, который дает мне список массивов, поэтому я полагаю, что мне, к сожалению, придется использовать для l oop ...
Вот правильное поведение, представленное в Excel :
И моя вторая проблема связана с этапом рекурсивной проверки и дискретизации, поскольку я не знаю, как реализовать это в данном конкретном случае. Интересно, есть ли способ сделать это без каких-либо циклов for.
Так что я был бы очень рад, если бы кто-нибудь мог помочь мне решить эту проблему, так как я сейчас "застрял". Это становится очень сложным для меня.
Заранее спасибо, Эрве