Подгонка эллипсоида к трехмерным точкам данных - PullRequest
5 голосов
/ 01 сентября 2011

У меня есть большой набор трехмерных точек данных, к которым я хочу вписаться в эллипсоид.

Моя математика довольно плохая, поэтому у меня возникают проблемы с реализацией метода наименьших квадратов без каких-либо математических библиотек.

Кто-нибудь знает или имеет фрагмент кода, который может вписать эллипсоид в данные, которые я могу подключить прямо к своему проекту? В C было бы лучше, но для меня не должно быть проблем с преобразованием из C ++, Java, C #, python и т. Д.

РЕДАКТИРОВАТЬ: Простая возможность найти центр тоже очень поможет. Обратите внимание, что точки распределены неравномерно, поэтому взятие среднего значения не приведет к центру.

Ответы [ 9 ]

6 голосов
/ 21 ноября 2011

здесь вы идете:

В этой статье описывается подгонка эллипсоида к нескольким измерениям, КАК ХОРОШО, как найти центр для эллипсоида. Надеюсь, это поможет,

http://www.physics.smu.edu/~scalise/SMUpreprints/SMU-HEP-10-14.pdf

(кстати, я предполагаю, что этот ответ немного запоздал, но я решил, что добавлю это решение для тех, кто наткнулся на ваш вопрос в поисках того же:)

2 голосов
/ 01 сентября 2011

Если вы хотите, чтобы эллипсоид включал минимальный объем, проверьте этот SO-ответ для ограничивающего эллипсоида .

Если вы хотите получить наиболее подходящий эллипс в смысле наименьших квадратов, проверьте этот код MATLAB для эллипсоидов ошибок , где вы найдете ковариационную матрицу ваших смещенных в среднем 3D-точек и используйте ее для построения эллипсоид.

1 голос
/ 15 февраля 2017

Мы разработали набор кодов Matlab и Java для размещения здесь эллипсоидов: https://github.com/pierre-weiss

Вы также можете проверить наш плагин Icy с открытым исходным кодом. Следующее руководство может быть полезным: https://www.youtube.com/endscreen?video_referrer=watch&v=nXnPOG_YCxw

Примечание: большинство существующих кодов соответствуют общей квадрике и не навязывают эллипсоидальную форму. Чтобы получить больше надежности, вам нужно перейти к выпуклому программированию, а не просто к линейной алгебре. Это то, что сделано в указанных источниках.

Ура, Pierre

1 голос
/ 23 декабря 2012

Я не смог найти хороший алгоритм на основе Java для подгонки эллипсоида, поэтому я сам написал его.Было несколько хороших алгоритмов для эллипса с 2D точками, но не для эллипсоида с 3D точками.Я экспериментировал с несколькими различными сценариями MATLAB и в конце концов остановился на Ellipsoid Fit Юрия Петрова.Он соответствует эллипсоиду для полинома Ax ^ 2 + By ^ 2 + Cz ^ 2 + 2Dxy + 2Exz + 2Fyz + 2Gx + 2Hy + 2Iz = 1. Он не использует никаких ограничений для наложения эллипсоида, поэтому вам нужно иметьдовольно большое количество точек для предотвращения подгонки случайного квадрика вместо эллипсоида.Кроме того, это работает очень хорошо.Я написал небольшую библиотеку Java с использованием Apache Commons Math, которая реализует сценарий Юрия Петрова на Java.Хранилище GIT можно найти по адресу https://github.com/BokiSoft/EllipsoidFit.

0

1 голос
/ 01 сентября 2011

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

0 голосов
/ 27 июля 2018

Вот очень простой метод поиска фокусов, основанный на случайном поиске.Линейная алгебра не используется.Так что, если у вас все в порядке с неидеальным решением:

3DPoints - Array of some Amount of points
vecCenter - average of 3DPoints
AngleCosine - cos of angle between two vectors

RandomOrder(3DPoints)

vecFocus := (0, 0, 0)
for i := 0 to Amount:
    vecRadius := 3DPoints[i] - vecCenter

    // Change vecRadius direction to parallel
    if AngleCosine(vecFocus, vecRadius) < 0 then
        vecRadius *= -1
    vecFocus += (vecRadius - vecFocus) / Amount

Результат можно улучшить, передав массив во 2-й раз в обратном направлении.

0 голосов
/ 21 февраля 2013

Некоторое время назад я перенес установщик Matlab для наименьших квадратов Юрия Петрова на Java, ему нужна только JAMA: https://github.com/mdoube/BoneJ/blob/master/src/org/doube/geometry/FitEllipsoid.java

0 голосов
/ 20 февраля 2013

Я только что прошел тот же процесс.Вот модуль Python, основанный на работе Нимы Моштага.Упоминается во многих местах, но также и в этом вопросе о Граничном эллипсе

Этот модуль также обрабатывает построение конечного эллипсоида.Наслаждайтесь!

https://github.com/minillinim/ellipsoid/blob/master/ellipsoid.py

0 голосов
/ 01 сентября 2011

У меня есть идея. Примерное решение, не лучшее, но будет держать точки внутри. В плоскости XY найдите радиус R1, который получит все точки. То же самое можно сделать для плоскости XZ (R2) и плоскости YZ (R3). Затем используйте максимумы на каждой оси. A = max (R1, R2), B = max (R1, R3) и C = max (R2, R3). Но, прежде всего, найдите среднее (центр) всех точек и выровняйте его по координатам.

...