2013-07-04 2 views
2

В моем проекте у меня есть высокие поверхности 20.000 точек, вычисленные алгоритмом. Иногда этот алгоритм имеет ошибку, неправильно вычисляя 1 или несколько точек в небольшой области.Обнаружение неправильных точек на однородной поверхности

Эта ошибка не может быть решена в алгоритме, но должна быть обнаружена впоследствии.

Ошибка можно увидеть на следующем рисунке:

enter image description here

Как вы можете видеть, существует точка неправильно подсчитал, что не только нарушает полную однородную поверхность, но и разрушает aestetics из (что также важно в проекте.)

Иногда это может быть больше, чем точка, обычно не более 5 или 6. Ошибка - это всегда ось Z, поэтому нет необходимости проверять X и Y

I сжимали мой разум, чтобы найти «универсальный» алгоритм для обнаружения этого poitns. Я думаю, что, может быть, это пятна поверхности и смысл Z, а затем определение точек из-за отклонения ... но я не думаю, что это будет работать всегда.

Любые идеи?

ПРИМЕЧАНИЕ: Я не хочу, чтобы кто-то написал для меня код, просто идея.

PD: соответствующий код для avobe изображения:

[x,y] = meshgrid([-2:.07:2]); 
Z = x.*exp(-x.^2-y.^2); 
subplot(1,2,1) 
surf(x,y,Z,gradient(Z)) 
subplot(1,2,2) 
Z(35,35)=Z(35,35)+0.3; 
surf(x,y,Z,gradient(Z)) 

ответ

2

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

  1. Возьмут производную в одном направлении
  2. Вычислить среднее значение и стандартное отклонение производной
  3. Найти точки, ища точки, которые дальше от среднего значения по определенному кратному стандартному отклонению.

Вот код

U=diff(Z); 
V=(U-mean(U(:)))/std(U(:)); 
surf(x(2:end,:),y(2:end,:),V) 
V=[zeros(1,size(V,2)); V]; 
V(abs(V)<10)=0; 
V=sign(V); 
W=cumsum(V); 
[I,J]=find(W); 
outliers = [I, J]; 

Для примера вы получаете этот участок для V с пиком на уровне около 21,7, а второй пик около 1,9528, поэтому, возможно, порог 10 нормально. enter image description here

и запустить код возвращает

outliers = 

    35 35 

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

+0

это кажется довольно приятным. плохо попробуйте и сообщите об этом. –

+1

Хороший ответ, но 'cumsum' не работает для двух последовательных выбросов в том же столбце. Также '10' довольно произволен. По крайней мере, '3' - это стандартное число, соответствующее p-значению ~ 0,001. Хотя, если это ручной процесс для OP, он всегда может изменить это число, чтобы найти больше или меньше выбросов. – Bee

+0

Он работает отлично для двух последовательных выбросов в той же колонке. Измените 'Z (35,35) = Z (35,35) +0,3;' на 'Z (35: 36,35) = Z (35: 36,35) +0,3;' и протестируйте его. –

3

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

Я мог бы предложить несколько способов реализации идеи. Простым является использование моего инструмента gridfit, найденного в File Exchange.(Gridfit по существу использует лапласиан для своей операции сглаживания.) Установите поверхность со всеми включенными точками, затем найдите единственную точку, которая больше всего волновала посадку. Исключить его, а затем снова запустить, снова ищет самый большой выброс. (С помощью gridfit вы можете использовать вес, чтобы дать точкам нулевой вес, простой способ исключить точку или список точек.) Когда наибольшее возмущение, которое было необходимо, достаточно мало, вы можете решить остановить процесс. Приятно, что gridfit также будет приписывать новые значения для выбросов, заполняя все отверстия.

Второй подход заключается в том, чтобы использовать лапласиан непосредственно, в большей части подхода к фильтрации. Здесь вы просто вычисляете значение в каждой точке, которое является средним значением для каждого соседа слева, справа, выше и ниже. Единственное значение, которое больше всего встречается в несогласии с его вычисленным средним значением, заменяется новым значением. Или вы можете использовать средневзвешенное значение нового значения со старым. И снова, итерация, пока процесс не будет генерировать ничего большего, чем некоторый допуск. (Это является основой старой схемы обнаружения и коррекции выбросов, которую я помню из библиотек Fortran IMSL, но, вероятно, датируется примерно 30 лет назад.)

+0

Итак, ваше предложение Лапласа должно использовать del2 (Z) вместо deff (Z), верно? Это кажется более логичным –

+0

+1: Лапласиан выглядит как лучший и более надежный подход. Вы узнаете что-то новое каждый день :-) –

+1

Да. «Гладкая» поверхность должна иметь del^2 всюду. –

Смежные вопросы