Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > Python
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.11.2019, 09:26   #1
Krasi
Форумчанин
 
Регистрация: 12.02.2010
Сообщений: 787
По умолчанию Аппроксимация в плоскость точек в 3-х мерном пространстве

Начнем по порядку. У нас есть набор точек, который характеризует, например, поверхность дороги впереди идущего автомобиля, на котором установлен лидар. В итоге должно быть видно, на сколько наклонена дорога по любой из осей, а также будут многочисленные отклонения от уравнения плоскости из-за неровности дороги и посторонних предметов, захваченных лидаром. Получается, что в ряде случаев может быть относительно непонятно, а где собственно плоскость дороги, а где нет.

У каждой точки есть координата X,Y,Z, при этом мы в текстовом файле имеем именно набор точек, то есть априори посмотреть можно, идут ли они по порядку или нет, но допустим мне лень, чтобы не упрощать задачу. Таким образом, % точек принадлежит столу, а процент - нет, например, 50% точек - дорога. Окей, я считываю данные из файла:

Код:
f = open('points.txt', 'r')
i=1
a = [0]*19280
x = [0]*19280
y = [0]*19280
z = [0]*19280
for line in f:
    a = line.split("\t")
    if i>2:
        x[i-3] = a[0]
        y[i-3] = a[1]
        z[i-3] = a[2]
    #a[i] = line.split("\n")
    i = i+1
print(x[1])
с этим жизнь удалась. Далее тут сам по себе просятся метод наименьших квадратов или линейная аппроксимация. И тут, пожалуй, мне не хватает опыта, прошу поделиться

Дело в том, что в линейной аппроксимации, кажется, не должно быть трудностей в случае с 2D:
https://toster.ru/q/634518
Действительно, я попробовал код
Код:
from matplotlib import pyplot as plt
import numpy as np
#функция
x = np.arange(0.1, 10, 1*(10**-2))
y = np.sin(x) + np.log(x)
#полином 1 степени по функции
p = np.polyfit(x,y, 1)
#подставляем значения x к полученному полиному
ya = np.polyval(p, x)

plt.plot(x, y)
plt.plot(x, ya)

plt.show()
и он работает прекрасно - любые изгибы кривой по оси Y устраняются, так как линейная аппроксимация дает линию, которая проходит вдоль кривой.

Первая трудность, с которой я столкнулся: если мы интереса ради перепутали местами точки, что-то изменится? То есть у нас есть точки графика, но шаг непостоянный, а часть значений функции и аргументов, где x > 5, например, перенесены в область после x = 1. Ну то есть данные, допустим перемешаны, их получится также аппроксимировать с помощью polyval?

Идем далее, метод наименьших квардратов относительно подробно описан здесь: http://www.delphikingdom.com/asp/vie...catalogid=1368

но точки задаются по-другому, если у меня есть X,Y,Z, и это одна точка, допустим, из 10000, то в статье показано, что амплитуды X и Y - это уже значения Z. Честно говоря, сейчас здесь тоже плаваю, как это понимать?

Ну я пока концентрируюсь на первом - интерполяция с помощью polyval. Провел также интерполяцию по Y, получил, что при вращении по Y уже нет чего-то, напоминающего плоскость, есть линия, что логично, ведь мы наблюдали это еще на плоскости.

Код:
import sys
import string
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np


f = open('sdc_point_cloud.txt', 'r')
i=1
a = [0]*19280
x = [0]*19280
y = [0]*19280
z = [0]*19280
for line in f:
    a = line.split("\t")
    if i>2:
        x[i-3] = a[0]
        y[i-3] = a[1]
        z[i-3] = a[2]
    #a[i] = line.split("\n")
    i = i+1
print(x[1])
#print(i)

n=10000
x1 = [0]*n
y1 = [0]*n
z1 = [0]*n
i = 0
while i<n:
    x1[i]=np.float32(x[i]);
    y1[i]=np.float32(y[i]);
    z1[i]=np.float32(z[i]);
    #print(y[i])
    i=i+1;

# Plot the surface
#x = np.linspace(-np.pi, np.pi, 50)
#y = x
#z = np.cos(x)

#print(x[1])

fig = plt.figure()
ax = fig.add_subplot(211, projection='3d')
ax1 = fig.add_subplot(212, projection='3d')

p = np.polyfit(x1,y1, 1)
#подставляем значения x к полученному полиному
ya = np.polyval(p, x1)


ax.scatter(x1, y1, z1, c='r', marker='o')
ax1.scatter(x1, ya, z1, c='r', marker='o')

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')

ax1.set_xlabel('X1 Label')
ax1.set_ylabel('Y1 Label')
ax1.set_zlabel('Z1 Label')

plt.show()
Этот код отлично работает, но если бы я понимал, что мне надо) Тут выходит, что по Y я случайно убрал все точки, которые принадлежали дороге - я заменил их прямой линией. Вращаю график, а у меня по Y уже нет ощущения плоскости, осталась только финишная прямая Получается, что так нельзя. С другой стороны, я немного начал понимать, как это решить в виде матричного уравнения, но если в теории как-то все на пальцах, то на практике мне не хватает поддержки, тем более нужно подтвердить или опровергнуть идеи с матричным уравнением или понять, какие все таки альтернативные возможности есть.

Окей, получается, что плоскость дороги не может быть просто аппроксимирована линией по одной из осей - ее надо аппроксимировать сразу по двум осям, так? Подскажите, как это решается?

Последний раз редактировалось Krasi; 29.11.2019 в 09:30.
Krasi вне форума Ответить с цитированием
Старый 29.11.2019, 10:57   #2
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Я так понимаю вы хотите сделать вот такое вот:
https://habr.com/ru/post/477192/


Цитата:
Сообщение от Krasi Посмотреть сообщение
но точки задаются по-другому, если у меня есть X,Y,Z, и это одна точка, допустим, из 10000, то в статье показано, что амплитуды X и Y - это уже значения Z. Честно говоря, сейчас здесь тоже плаваю, как это понимать?
Есть неявная форма представления функции и явная.
-это не явная функция,
Мы её можем написать в виде f(x), т.е. явном. Причем в данном примере аж двумя способами.



В зависимости от того что через что записано говорят... Для первого случая что к x-независимая переменная, а y - зависимая.

Цитата:
Сообщение от Krasi Посмотреть сообщение
Этот код отлично работает, но если бы я понимал, что мне надо) Тут выходит, что по Y я случайно убрал все точки, которые принадлежали дороге - я заменил их прямой линией. Вращаю график, а у меня по Y уже нет ощущения плоскости, осталась только финишная прямая
Да есть такое. Если мы возьмем ленту и будем её вращать с двух концов в противоположные стороны, то не получится оставить только одну линию.

Так что да вам надо апраксиммировать по 2-м осям.
С начало по одной затем по другой.

Так что тут стоит ещё раз подумать какие параметры вам нужны? Если средний угол уклона, то как раз превращения 2D в 1D это то что вам нужно.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .

Последний раз редактировалось Pavia; 29.11.2019 в 11:14.
Pavia вне форума Ответить с цитированием
Старый 29.11.2019, 11:36   #3
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Короче пусть у нас x,y,z представлены массивом.
Вначале найдём плоскость в которой они лежат. Плоскость это прямоугольник 1х1.
Его можно вращать перемещать. Остальное запретить.

Поворачиваем вашу систему точек так что-бы оси нашей плоскости совпадали с X,Y.

Далее разбиваем ваши точки по X с шагом 0,1 на массивы. Точку относим к ближайшему X. Затем применяем 1D аппроксимацию по каждой линии. Затем генерируете по получившейся аппроксимации новые точки с шагом 0,1.

Повторяем процедуру по Y.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создать класс точек в пространстве Halikarnas C# (си шарп) 2 22.05.2018 18:05
Заданы точки в 3-мерном пространстве А(12.1,-3.1, -11.7) В(3.3,-8.7,9.9) С(6.9,22.7,5.1) D(10.9,-5.5,13.8) Определить объём образо schack C++ Builder 6 14.10.2015 01:55
Создать файл, содержащий координаты точек в двумерном пространстве. На Си ganster Общие вопросы C/C++ 2 03.07.2012 11:55
Вывести точки в 3-х мерном пространстве [Паскаль] Елена777Алиса Помощь студентам 4 08.12.2010 21:27