Преобразование между двумя наборами точек

У меня есть объект, скажем, на изображении модели. Я хочу вычислить преобразование (смещения, масштаба, поворота )между объектом на изображении модели и объектом на целевом изображении. Я хочу сделать предположение, что объект можно рассматривать как 2D, поэтому следует вычислять только 2D-преобразования.

Сначала я хочу сделать это вручную. Пользователь выбирает базовую точку на изображении модели, а затем целевую точку на целевом изображении. Количество точек должно быть определено пользователем (, но не менее некоторого минимума 2 -3 точек ). Когда точки дают различную информацию, преобразование должно быть усреднено, и, например, на основе этого можно вычислить качество сопоставления.

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

Особенно приветствуются ссылки и советы с некоторыми фрагментами кода или псевдокода.

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

Текущее решение:

void transformFnc(std::vector<PointF> basePoints, std::vector<PointF> targetPoints,
                  PointF& offset, double rotation, double scale)
{
    std::vector<Line> basePointsLines;
    std::vector<Line> targetPointsLines;
    assert(basePoints.size() == targetPoints.size());
    int pointsNumber = basePoints.size();

    for(int i = 0; i < pointsNumber; i++)
    {
         for(int j = i + 1; j < pointsNumber; j++)
         {
             basePointsLines.push_back(Line(basePoints[i], basePoints[j]));
             targetPointsLines.push_back(Line(targetPoints[i], targetPoints[j]));
         }
    }
    std::vector<double> scalesVector;
    std::vector<double> rotationsVector;
    double baseCenterX = 0, baseCenterY = 0, targetCenterX = 0, targetCenterY = 0;
    for(std::vector<Line>::iterator it = basePointsLines.begin(), i = targetPointsLines.begin();
        it != basePointsLines.end(), i != targetPointsLines.end(); it++, i++)
    {
        scalesVector.push_back((*i).length()/(*it).length());
        baseCenterX += (*it).pointAt(0.5).x(); 
        baseCenterY += (*it).pointAt(0.5).y();
        targetCenterX += (*i).pointAt(0.5).x();
        targetCenterY += (*i).pointAt(0.5).y();
        double rotation;
        rotation = (*i).angleTo((*it));
        rotationsVector.push_back(rotation);
    }
    baseCenterX = baseCenterX / pointsNumber;
    baseCenterY = baseCenterY / pointsNumber;
    targetCenterX = targetCenterX / pointsNumber;
    targetCenterY = targetCenterY / pointsNumber;

    offset = PointF(targetCenterX - baseCenterX, targetCenterY - baseCenterY);
    scale = sum(scalesVector) / scalesVector.size();
    rotation = sum(rotationsVector) / rotationsVector.size();
}

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

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

Пока что из ответов я знаю, что:

  • Можно использовать алгоритм RANSAC
  • Мне нужно найти какой-нибудь алгоритм вычисления аффинного преобразования в смысле наименьших квадратов
-. 121 ---935326- PyCharm не распознает файлы Python Мой PyCharm больше не распознает файлы python (прикрепленный снимок экрана )Путь интерпретатора задан правильно.

Мой PyCharm больше не распознает файлы python (прикрепленный снимок экрана )Путь интерпретатора задан правильно.

Screen shot

69
задан Jon Clements 27 July 2012 в 12:27
поделиться