Преобразование Гельмерта

Вопросы по свободной ГИС QGIS. Сообщения об ошибках, предложения по улучшению, локализация.
Ответить
Аватара пользователя
Максим Дубинин
MindingMyOwnBusiness
Сообщения: 9129
Зарегистрирован: 06 окт 2003, 20:20
Репутация: 748
Ваше звание: NextGIS
Откуда: Москва
Контактная информация:

Преобразование Гельмерта

Сообщение Максим Дубинин » 28 окт 2008, 18:12

Кто-то понимает, как оно математически выглядит?

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

Lynx
Интересующийся
Сообщения: 29
Зарегистрирован: 04 ноя 2008, 00:40
Репутация: 0

Re: Преобразование Гельмерта

Сообщение Lynx » 04 ноя 2008, 00:50

реализация преобразования Гельмерта:

Код: Выделить всё

void QgsLeastSquares::helmert(std::vector<QgsPoint> mapCoords, 
			      std::vector<QgsPoint> pixelCoords,
			      QgsPoint& origin, double& pixelSize, 
			      double& rotation) {
  int n = mapCoords.size();
  if (n < 2) {
    throw std::domain_error(QObject::tr("Fit to a Helmert transform requires at "
			    "least 2 points.").toLocal8Bit().constData());
  }
  
  double A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0;
  for (int i = 0; i < n; ++i) {
    A += pixelCoords[i].x();
    B += pixelCoords[i].y();
    C += mapCoords[i].x();
    D += mapCoords[i].y();
    E += mapCoords[i].x() * pixelCoords[i].x();
    F += mapCoords[i].y() * pixelCoords[i].y();
    G += std::pow(pixelCoords[i].x(), 2);
    H += std::pow(pixelCoords[i].y(), 2);
    I += mapCoords[i].x() * pixelCoords[i].y();
    J += pixelCoords[i].x() * mapCoords[i].y();
  }
  
  /* The least squares fit for the parameters { a, b, x0, y0 } is the solution
     to the matrix equation Mx = b, where M and b is given below. I *think*
     that this is correct but I derived it myself late at night. Look at 
     helmert.jpg if you suspect bugs. */
  
  double MData[] = { A,   -B,    n,    0,
		     B,    A,    0,    n,
		     G+H,  0,    A,    B,		     
		     0,    G+H, -B,    A };

  double bData[] = { C,    D,    E+F,  J-I };
  
  // we want to solve the equation M*x = b, where x = [a b x0 y0]
  gsl_matrix_view M = gsl_matrix_view_array(MData, 4, 4);
  gsl_vector_view b = gsl_vector_view_array(bData, 4);
  gsl_vector* x = gsl_vector_alloc(4);
  gsl_permutation* p = gsl_permutation_alloc(4);
  int s;
  gsl_linalg_LU_decomp(&M.matrix, p, &s);
  gsl_linalg_LU_solve(&M.matrix, p, &b.vector, x);
  gsl_permutation_free(p);
  
  origin.setX(gsl_vector_get(x, 2));
  origin.setY(gsl_vector_get(x, 3));
  pixelSize = std::sqrt(std::pow(gsl_vector_get(x, 0), 2) +
			std::pow(gsl_vector_get(x, 1), 2));
  rotation = std::atan2(gsl_vector_get(x, 1), gsl_vector_get(x, 0));    
}
взято из qgis_0.11.0/src/plugins/georeferencer/qgsleastsquares.cpp

Аватара пользователя
Максим Дубинин
MindingMyOwnBusiness
Сообщения: 9129
Зарегистрирован: 06 окт 2003, 20:20
Репутация: 748
Ваше звание: NextGIS
Откуда: Москва
Контактная информация:

Re: Преобразование Гельмерта

Сообщение Максим Дубинин » 04 ноя 2008, 03:02

отлично, то что нужно, большое спасибо!
Не лежит ли где-то еще такой файл? Чую формулы в матричном представлении.
Look at helmert.jpg if you suspect bugs. */
пристегивайтесь, турбулентность прямо по курсу

Lynx
Интересующийся
Сообщения: 29
Зарегистрирован: 04 ноя 2008, 00:40
Репутация: 0

Re: Преобразование Гельмерта

Сообщение Lynx » 04 ноя 2008, 11:03

sim писал(а):Не лежит ли где-то еще такой файл?
Look at helmert.jpg if you suspect bugs. */
вот:
Вложения
helmert.jpg
helmert.jpg (92.2 КБ) 12900 просмотров

Аватара пользователя
Максим Дубинин
MindingMyOwnBusiness
Сообщения: 9129
Зарегистрирован: 06 окт 2003, 20:20
Репутация: 748
Ваше звание: NextGIS
Откуда: Москва
Контактная информация:

Re: Преобразование Гельмерта

Сообщение Максим Дубинин » 04 ноя 2008, 18:23

И еще раз спасибо!
Ужас какой...это я про алгоритм, надо переделывать.
пристегивайтесь, турбулентность прямо по курсу

BrainDrain
Интересующийся
Сообщения: 18
Зарегистрирован: 15 сен 2005, 10:57
Репутация: 0

Re: Преобразование Гельмерта

Сообщение BrainDrain » 22 июл 2011, 14:20

Подскажите как аналогично преобразовать любую координату а не (0,0) как в приведенной функции, а то я математику забыл(

Voltron
Гуру
Сообщения: 2627
Зарегистрирован: 29 мар 2007, 14:12
Репутация: 34
Откуда: Ukraine

Re: Преобразование Гельмерта

Сообщение Voltron » 22 июл 2011, 14:40

Эээ... подставить вместо (0,0) нужные координаты? Или вопрос не об этом?

BrainDrain
Интересующийся
Сообщения: 18
Зарегистрирован: 15 сен 2005, 10:57
Репутация: 0

Re: Преобразование Гельмерта

Сообщение BrainDrain » 22 июл 2011, 15:00

QgsLeastSquares::helmert << мож я конечно туплю, но куда там подставлять мои x,y?
Я попробовал так
outX0 = gsl_vector_get(x, 2);
outX = outX0 + X*gsl_vector_get(x, 0); , но это дает правильный результат только если Y=0

BrainDrain
Интересующийся
Сообщения: 18
Зарегистрирован: 15 сен 2005, 10:57
Репутация: 0

Re: Преобразование Гельмерта

Сообщение BrainDrain » 24 июл 2011, 10:34

Реально я тупанул
Формула преобразования:
X' = a*X + b*Y + c, Y' = -b*X + a*Y + d, т.е. другими словами тоже самое, что и на скане в первых двух строчках.
Откуда понятно, как получить то что мне нужно (пока не проверял)

Ответить

Вернуться в «QGIS»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость