Устранение шумов в сечениях поверхности

Devid

Задача сложная, так что максимум я надеюсь на удачную идею.
Есть некоторая гладкая поверхность в R^3. Строятся ее сечения плоскостями, параллельными XY, расстояние между соседними плоскостями одинаковое. Каждое сечение аппроксимируется ломаной так, что каждая вершина каждой ломаной отстоит от поверхности не более, чем на delta.
Сама задача:
Есть набор этих ломаных. Нужно его пошевелить (т.е. подвинуть вершины не более чем на delta не меняя Z координаты) так, чтобы он стал как можно более "регулярным". Про исходную поверхность ничего не известно.
Примеры "нерегулярности":
1) может оказаться, что несколько подряд идущих (т.е. соседних по Z) ломаных на каком-то участке оказываются
на delta внутри поверхности, а следующая ломаная на этом участке наоборот на delta снаружи поверхности.
2) соседние точки одной ломаной могут оказаться на сильно разном расстоянии от поверхности.
На ум приходит разложение Фурье и выкидывание высоких частот, но не понятно, как его тут использовать.

margadon

мне почему-то кажется, что шевелить срезы, не смотря на них как на срезы 3д-поверхности, не стоит
лучше уж приблизить поверхность и уже её шевелить в R^3

Devid

Это без шансов, никакой поверхности во входных данных нет (даже ее триангуляции).

margadon

построить меш :) а потом сплайнами, сплайнами его!
хотя вероятно я не представляю масштаба задачи или каких-то тонкостей
а то ведь ты вот так регуляризуешь каждый срез, а на стыках вдоль оси z у тебя будут сильные скачки

lipa

1. Формализовать функцию "нерегулярности"
2. Найти минимум функции N переменных
3. ?
4. PROFIT

Devid

1. Хз как.
2. Это будет вечность считаться.

Serab

2. здесь используется какой-то неизвестный мне постулат тормознутости всех методов многомерной оптимизации?

marina7573

если нет поверхности, то как ты определяешь, внутри поверхности ломаная или снаружи (п. 1. из примеров нерегулярности)?

Devid

а то ведь ты вот так регуляризуешь каждый срез, а на стыках вдоль оси z у тебя будут сильные скачки
Я этого не понял.
Конечно, улучшать срезы по отдельности нельзя. Самый простой пример - поверхность=плоскость. Тогда идеальные сечения это параллельные прямые с одинаковым расстоянием между соседними, например 1. Приблизительные сечения это ломаные, которые не отклоняются от соответствующих прямых более чем на delta.
Допустим мы улучшим каждую ломаную отдельно, получим в идеале опять набор параллельных прямых, но расстояния между ними уже будут колебаться на +-2*delta. Т.е. может оказаться несколько подряд идущих прямых с расстоянием 1-2*delta, а следующая будет на расстоянии 1+2*delta, а потом опять 1-2*delta и т.д. Это плохо (1-й пример нерегулярности в первом посте).

Devid

Нет, это следует из предположения, что пункт 1 будет считаться небыстро.

marina7573

п.2 примеров нерегулярности можно убрать, введя целевую функцию "максимальный из углов между соседним звеньями". Или "сумма квадратов углов между соседними звеньями". И делать многомерную оптимизацию с ограничениями, что передвигать их начальных точек можно не более чем на дельта

Devid

Да, это неплохой способ сделать каждую отдельную ломаную гладкой, но никак не решает проблемы с расстояниями между ломаными.

marina7573

по п.1 можно как-то построить триангуляцию для боковой поверхности и смотреть на углы, образованные между соседними по слоям боковыми гранями. Если будет ясность, что считать соседними по высоте боковыми гранями, то тогда минимизировать и их тоже.
Как-то стрёмно в целом.

5777

Не трожь Фурье, тут намного более простыми методами можно сделать всё.
0) подразбиение участков ломаных на куски размером с delta
1) стыки ломаных => множество точек в пространстве.
2) Сглаживание этого множества точек. Алгоритмов тонны, выбирай любой. Под твои требования, скорее всего, подойдёт тупое локальное усреднение координат. Веса координат соседних точек взять из ядра Гаусса, дисперсия порядка шага между плоскостями по оси Z и порядка delta по остальным осям.
3) пододвинуть узлы исходных ломаных поближе к сглаженному множеству точек.
Идеи черпать можно из алгоритмов шумоподавления изображений/видео/результатов лазерного сканирования, тема мусолится десятилетиями и понапридумано всего много.

Devid

Под твои требования, скорее всего, подойдёт тупое локальное усреднение координат. Веса координат соседних точек взять из ядра Гаусса, дисперсия порядка шага между плоскостями по оси Z и порядка delta по остальным осям.
Не подойдет.
Например поверхность=сфера. Пусть все сечения получились хорошими (вершины ломаных лежат на сфере а одно (например по 45-й параллели) плохим (все вершины этой ломаной лежат на delta внутри сферы).
Предложенное тобой усреднение не исправит плохое сечение, оно будет по-прежнему выбиваться из общей кучи. Менее важно, но тоже неприятно, что оно ухудшит хорошие сечения: они были идеальными и изменились.
Забыл раньше написать, расстояние между соседними сечениями по Z сильно больше delta и просто больше длины звеньев ломаных.

5777

Пусть все сечения получились хорошими (вершины ломаных лежат на сфере а одно (например по 45-й параллели) плохим (все вершины этой ломаной лежат на delta внутри сферы)
Ну так давай определимся, с какими искажениями боремся.
Усреднение отлично сработает для белого шума.
Для описанных тобой единичных провалов подойдёт медианная фильтрация.
Предложенное тобой усреднение не исправит плохое сечение, оно будет по-прежнему выбиваться из общей кучи
выбиваться оно будет существенно меньше. И тем меньше, чем больше радиус усреднения.
Кроме того, алгоритму вполне естественно предположить наличие на сфере канавки вдоль 45й параллели.
Либо же есть ряд априорных предположений о возможной структуре объекта, которые ты не назвал, но неявно преполагаешь.
Короче, можешь привести картинки-примеры реальных данных? Иначе получается отстрел лошадей в вакууме

yroslavasako

Попробуй заюзать базу алгоритмов 3d-редактора блендера. Он скриптуется на питоне и его можно стартовать в headless режиме для исполнения пакетных заданий. Можно и 3d модель построить и операции над ней проводить.

Devid

выбиваться оно будет существенно меньше. И тем меньше, чем больше радиус усреднения.
Думаю нет. Совсем простой пример. Возьмем правильный 100-угольник в плоскости. Пусть расстояние от каждой точки до центра масс точек в ее окрестности D. Сдвинем одну точку на delta=D*0.01 в сторону центра 100-угольника. Сделаем усреднение. Все вершины сдвинуться на delta в сторону центра, кроме одной, которая сдвинется на 0.99*delta или же на delta (в зависимости от того, будем ли мы нормировать величину сдвига на расстояние до центра масс). В итоге выбивающаяся точка продолжит выбиваться на ту же delta.
Либо же есть ряд априорных предположений о возможной структуре объекта, которые ты не назвал, но неявно преполагаешь.

Есть. Известно, что исходная поверхность была небольшой степени и не имела никаких особенностей размера порядка delta.

Devid

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

5777

Думаю нет. Совсем простой пример. Возьмем правильный 100-угольник в плоскости. Пусть расстояние от каждой точки до центра масс точек в ее окрестности D. Сдвинем одну точку на delta=D*0.01 в сторону центра 100-угольника. Сделаем усреднение. Все вершины сдвинуться на delta в сторону центра, кроме одной, которая сдвинется на 0.99*delta или же на delta (в зависимости от того, будем ли мы нормировать величину сдвига на расстояние до центра масс). В итоге выбивающаяся точка продолжит выбиваться на ту же delta.
Мы точно про локальное усреднение координат соседних точек говорим?
Точки сдвинутся на:
D для вершин вне окрестности испорченной точки
D+delta/n, для окрестности испорченной точки, где n-число точек в окрестности.
(Это для случая одинаковых весов точек в окрестности. Ядро Гаусса даст более мягкую картину сдвига, ступенька delta/n размажется по соседним пикселям и станет ещё менее заметна)

Devid

Точки сдвинутся на:D для вершин вне окрестности испорченной точки
На D они сдвинуться не смогут, т.к. двигать точки больше, чем на delta, нельзя.

5777

При R порядка delta D < delta.
ещё раз: мы выбираем радиус усреднения по заданной delta. А не ищем delta, при которой усреднение с заданным радиусом налажает :)

Devid

Хорошо, пусть ломаная=правильный 100-угольник со стороной сильно больше delta. Подвинем одну вершину на delta к центру и назовем ее плохой.
Теперь разобьем стороны 100-угольника на куски по delta. Новые вершины, близкие к плохой, тоже будут подвинуты к центру на почти delta, поэтому их центр масс тоже будет подвинут на delta. В итоге как плохая так и хорошие вершины сместятся к центру на одинаковый D и плохая вершина останется на delta ближе к центру.

marat7256

Можно попробовать каждое сечение аппроксимировать b-сплайном.

Devid

Я уже говорил, обрабатывать каждое сечение отдельно бесполезно.

marat7256

Ну, так продолжай действовать.
Вторым этапом сделай "вертикальные" сечения (тут все зависит от геометрии - можно параллельно какой-нибудь плоскости, можно с поворотом относительно какой-либо оси/прямой). И в этих сечениях также построй b-сплайны. Мм?

marina7573

Если твоя поверхность представляет собой график функции, т.е. каждой точке (x,y) соответствует единственное z, то можно все твои точки нанести на одну плоскость и поставить им координаты z (получить плоский график этой функции в вид изолиний). Затем можно построить глобальную поверхность методом, который как-то фильтрует шумы в данных. Например, Surfer умеет строить поверхности методом минимальной кривизны - мб ты что-то похожее ищешь.
Оставить комментарий
Имя или ник:
Комментарий: