Розуміння фільтра кривизни аналізу растрових місцевостей QGIS?


12

Я прочитав вихідний код кількох растрових фільтрів QGis-1.7.4, що обчислюють нахил, аспект та кривизну.

У фільтрі є формула, що обчислює загальну кривизну, яка мене спантеличує.

Вихідний файл знаходиться в поточній версії QGis із наступним шляхом:

qgis-1.7.4 / src / аналіз / растр / qgstotalcurvaturefilter.cpp

Мета цього фільтра - обчислити загальну кривизну поверхні у вікні дев'яти комірок. Код функції такий:

float QgsTotalCurvatureFilter::processNineCellWindow( 
   float* x11, float* x21, float* x31, 
   float* x12, float* x22, float* x32, 
   float* x13, float* x23, float* x33 ) {

  ... some code deleted ...

  double dxx = ( *x32 - 2 * *x22 + *x12 ) / ( 1 );
  double dyy = ( -*x11 + *x31 + *x13 - *x33 ) / ( 4 * cellSizeAvg*cellSizeAvg );
  double dxy = ( *x21 - 2 * *x22 + *x23 ) / ( 1 );

  return dxx*dxx + 2*dxy*dxy + dyy*dyy;
}

Я все в порядку з формулою "dxx" та із виразом повернення. Але я думаю, що формули "dyy" та "dxy" перевернуті: це робить загальний результат асиметричним щодо розмірів x та y.

Я щось пропускаю чи повинен замінити вирази подвійних похідних на:

  double dxx = ( *x32 - 2 * *x22 + *x12 ) / ( 1 ); // unchanged
  // inversion of the two following:
  double dxy = ( -*x11 + *x31 + *x13 - *x33 ) / ( 4 * cellSizeAvg*cellSizeAvg );
  double dyy = ( *x21 - 2 * *x22 + *x23 ) / ( 1 );
  return dxx*dxx + 2*dxy*dxy + dyy*dyy; // unchanged

Чи можете ви сказати мені свою думку щодо цих формул, якщо вони неправильні, як я думав, або якщо я помиляюся? В останньому випадку ви знаєте, чому формули повинні бути асиметричними щодо x і y?


3
повідомте про ці проблеми, щоб їх можна було виправити hub.qgis.org/projects/quantum-gis/isissue/new
underdark

Хм, як увійти за цим посиланням? Здається, веб-сайт не має спільних акаунтів на форумі, але я не бачу жодного "створити акаунт" ... Заздалегідь дякую за вашу відповідь.
Тападі

1
сайт використовує входи в osgeo www2.osgeo.org/cgi-bin/ldap_create_user.py
underdark

Відповіді:


8

Ваша думка правильна. Перевірка симетрії - відмінна ідея: (гауссова) кривизна - це властива поверхня. Таким чином, обертання сітки не повинно змінювати її. Однак обертання вводять помилку дискретизації - за винятком обертів, кратних на 90 градусів. Тому будь-яке таке обертання повинно зберігати кривизну.

Ми можемо зрозуміти, що відбувається , використовуючи велику користь на першій ідеї диференціального числення: похідні - це межі різницьких коефіцієнтів. Це все, що ми насправді повинні знати.

dxxмає бути дискретним наближенням другої часткової похідної у напрямку x. Це особливе наближення (з безлічі можливих) обчислюється шляхом відбору проб поверхні по горизонтальному трансекту через клітинку. Розташовуючи центральну клітинку в другому рядку та колонці 2, записаному (2,2), трансект проходить через клітинки в (1,2), (2,2) та (3,2).

Уздовж цього трансекта перші похідні апроксимуються за різницевими коефіцієнтами, (* x32- * x22) / L та (* x22- * x12) / L, де L - (загальна) відстань між клітинами (очевидно, що дорівнює cellSizeAvg). Другі похідні отримують за різницевими коефіцієнтами цих, поступаючись

dxx = ((*x32-*x22)/L - (*x22-*x12)/L)/L
    = (*x32 - 2 * *x22 + *x12) / L^2.

Зауважте поділ на L ^ 2!

Точно так же, dyyяк передбачається , буде дискретним наближенням для другої похідної в у-напрямку. Трансект вертикальний, проходить через клітини в (2,1), (2,2) та (2,3). Формула буде виглядати так само, як для, dxxале з перенесеними підписниками. Це була б третя формула у питанні - але все одно потрібно розділити на L ^ 2.

Змішане друге часткове похідне, dxyможна оцінити, відмінивши відмінності двох клітин. Наприклад, перша похідна щодо x у комірці (2,3) (верхній середній осередок, а не центральна комірка!) Може бути оцінена, віднімаючи значення ліворуч, * x13, від значення праворуч, * x33 і ділення на відстань між цими клітинками, 2L. Перша похідна щодо x у комірці (2,1) (нижня середня комірка) оцінюється (* x31 - * x11) / (2L). Їх різниця, поділена на 2 л, оцінює змішане часткове, що дає

dxy = ((*x33 - *x13)/(2L) - (*x31 - *x11)/(2L))/(2L)
    = (*x33 - *x13 - *x31 + *x11) / (4 L^2).

Я не дуже впевнений, що розуміється під "загальною" кривизною, але, мабуть, це має бути Гауссова кривизна (яка є добутком основних кривих). Відповідно до рівняння 2.4 Meek & Walton 2000 , рівняння Гаусса виходить діленням dxx * dyy - dxy ^ 2 (зверніть увагу на знак мінус! - це визначальник ) на квадрат норми градієнта поверхні. Таким чином, наведене у питанні повернене значення є не зовсім кривою, але це схоже на заплутане часткове вираження для кривизни Гаусса.

Тоді ми знаходимо шість помилок у коді , більшість з яких є критичними:

  1. dxx потрібно розділити на L ^ 2, а не на 1.

  2. dyy потрібно ділити на L ^ 2, а не на 1.

  3. Знак dxy неправильний. (Це, однак, не впливає на формулу кривизни.)

  4. Формули для dyy та dxy змішуються, як ви зазначаєте.

  5. Відмінний знак відсутній у терміні у зворотному значенні.

  6. Він насправді не обчислює кривизну, а лише чисельник раціонального виразу кривизни.


Як дуже просту перевірку, давайте перевіримо, чи змінена формула повертає розумні значення для горизонтальних розташувань на квадратичних поверхнях. Беручи до уваги таке розташування як джерело системи координат і приймаючи його висоту на нульову висоту, всі такі поверхні мають рівняння форми

elevation = a*x^2 + 2b*x*y + c*y^2.

для постійних a, b і c. З центральним квадратом за координатами (0,0), лівий зліва має координати (-L, 0) тощо. Дев'ять висот

*x13 *x23 *x33     (a-2b+c)L^2, (c)L^2, (a+2b+c)L^2
*x12 *x22 *x32  =  (a)L^2,      0,      (a)L^2
*x11 *x21 *x31     (a+2b+c)L^2, (c)L^2, (a-2b+c)L^2

Отже, за модифікованою формулою,

dxx = (a*L^2 - 2*0 + a*L^2) / L^2
    = 2a;

dxy = ((a+2b+c)L^2 - (a-2b+c)L^2 - (a-2b+c)L^2 + (a+2b+c)L^2)/(4L^2)
    = 2b;

dyy = ... [computed as in dxx] ... = 2c.

Кривизна оцінюється як 2a * 2c - (2b) ^ 2 = 4 (ac - b ^ 2). (Знаменник у формулі Meek & Walton у цьому випадку один.) Чи має це сенс? Спробуйте кілька простих значень a, b і c:

  • a = c = 1, b = 0. Це круговий параболоїд; його гауссова кривизна повинна бути позитивною. Значення 4 (ac-b ^ 2) дійсно є позитивним (рівним 4).

  • a = c = 0, b = 1. Це гіперболоїд з одного аркуша - сідла - стандартний приклад поверхні негативної кривизни. Звичайно, 4 (ac-b ^ 2) = -4.

  • a = 1, b = 0, c = -1. Це ще одне рівняння гіперболоїда одного аркуша (повернутий на 45 градусів). Ще раз 4 (ac-b ^ 2) = -4.

  • a = 1, b = 0, c = 0. Це плоска поверхня, складена в параболічну форму. Тепер 4 (ac-b ^ 2) = 0: нульова гауссова кривизна правильно визначає площинність цієї поверхні.

Якщо ви спробуєте код у запитанні на цих прикладах, ви виявите, що він завжди отримує помилкове значення.


Завжди цікаво читати ваші чіткі розробки вранці.
Томек

@Tomek Тепер є дипломатичний (= тактовний і дуже неоднозначний) коментар! :-)
whuber

1
Дуже дякую за таку повну відповідь! Я збираюся повідомити про помилки формули, оскільки тепер я впевнений, що є про що повідомити. :)
Тападі

@whuber: Я можу підтвердити відповідь Томека, що завжди цікаво читати ваші коментарі на цьому форумі, і я завжди дізнаюся щось нове з них !! Дякуємо, що безкоштовно поділилися з нами своїми безцінними знаннями !! Не заперечуєте, якщо я задаю лише ще одне запитання: У будь-якому застосуванні ГІС, коли виконується аналіз кривизни місцевості (растрових), це завжди гауссова кривизна? Ніколи середня кривизна?
marco
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.