Я знаю, что преобразование квадрата в трапецию является линейным преобразованием и может быть выполнено с использованием проективной матрицы, но я немного затрудняюсь в том, как построить матрицу.
Использование проективной матрицы для перевода, масштабирования, поворота и сдвига является простым. Существует ли простая проективная матрица, которая преобразует квадрат в трапецию?
Ответ 1
a, b, c, d - четыре угла вашего 2D-квадрата.
a, b, c, d выражаются в однородной координате, и поэтому они являются матрицами 3x1.
alpha, beta, gamma, delta - четыре угла вашей 2D трапеции.
альфа, бета, гамма, дельта выражаются в однородной координате, и поэтому они являются матрицами 3x1.
H - матрица 3x3, которую вы ищете, ее также называют гомографией
h1 h2 h3
H = h4 h5 h6
h7 h8 h9
H отображает a, b, c, d в альфа, бета, гамма, дельта и поэтому у вас есть следующие четыре уравнения:
alpha=H*a
beta=H*b
gamma=H*c
delta=H*d
Предполагая, что вы знаете a, b, c, d и alpha, beta, gamma, delta, вы можете решить предыдущие четыре системы уравнений для девяти неизвестных h1, h2, h3, h4, h5, h6, h7, h8, h9,
Здесь я только что описал "сырое" решение проблемы, которое в принципе может работать; для подробного объяснения вышеупомянутого метода вы можете увидеть, например, эту страницу http://www.corrmap.com/features/homography_transformation.php, где они помещают h9=1
(так как H
можно выразить только с помощью 8 параметров), а затем решить линейную систему из восьми уравнений в восьми неизвестных. Вы можете найти аналогичное объяснение в разделе 2 диссертации Оценка гомографии Элана Дубровского.
Другим объяснением является использование проективной геометрии для исправления камеры Дэвидом Остином в мартском выпуске 2013 года Feature Feature Column из AMS.
Вышеупомянутый метод с его недостатками описан в главе 4 "Оценка - 2D проективная трансформация" во втором издании "Множественная геометрия зрения" в компьютерном видении Ричарда Хартли и Эндрю Зиссермана, где они также описывают разные и лучшие алгоритмы; вы можете проверить эту ссылку http://www.cse.iitd.ac.in/~suban/vision/geometry/node24.html, которая, похоже, следует за той же книгой.
Вы можете найти другое объяснение гомографии в разделе 15.1.4 "Модель проективной трансформации" книги Компьютерное зрение: модели, обучение и выводы Саймона Дж. Д. Принца. Алгоритм Алгоритм 15.4: максимальное правдоподобие проективного преобразования (гомография) изложено в его буквенном алгоритме: проблема решена с помощью нелинейной минимизации.
Ответ 2
Возможно, вы могли бы использовать четырехугольник? См. Мой ответ здесь:
fooobar.com/questions/6640/...
Затем вы получите полный контроль над каждой точкой и можете легко сделать любую форму с четырьмя углами.:)
Ответ 3
реализация Java с минимальными зависимостями
Для тех, у кого ограниченное знание и время для поиска быстрого и грязного решения, есть работающая и довольно надежная реализация Java в Wii-interact проект.
Транспортировка находится в исходном файле homography. Это сводится к построению и решению матрицы:
/**
* Please note that Dr. John Zelle assisted us in developing the code to
* handle the matrices involved in solving for the homography mapping.
*
**/
Matrix A = new Matrix(new double[][]{
{x1, y1, 1, 0, 0, 0, -xp1*x1, -xp1*y1},
{0, 0, 0, x1, y1, 1, -yp1*x1, -yp1*y1},
{x2, y2, 1, 0, 0, 0, -xp2*x2, -xp2*y2},
{0, 0, 0, x2, y2, 1, -yp2*x2, -yp2*y2},
{x3, y3, 1, 0, 0, 0, -xp3*x3, -xp3*y3},
{0, 0, 0, x3, y3, 1, -yp3*x3, -yp3*y3},
{x4, y4, 1, 0, 0, 0, -xp4*x4, -xp4*y4},
{0, 0, 0, x4, y4, 1, -yp4*x4, -yp4*y4}
});
Matrix XP = new Matrix(new double[][]
{{xp1}, {yp1}, {xp2}, {yp2}, {xp3}, {yp3}, {xp4}, {yp4}});
Matrix P = A.solve(XP);
transformation = new Matrix(new double[][]{
{P.get(0, 0), P.get(1, 0), P.get(2,0)},
{P.get(3, 0), P.get(4, 0), P.get(5,0)},
{P.get(6, 0), P.get(7, 0), 1}
});
Использование: следующий метод выполняет окончательное преобразование:
public Point2D.Double transform(Point2D.Double point) {
Matrix p = new Matrix(new double[][]{{point.getX()}, {point.getY()}, {1}});
Matrix result = transformation.times(p);
double z = result.get(2, 0);
return new Point2D.Double(result.get(0, 0) / z, result.get(1, 0) / z);
}
Зависимость класса Matrix
происходит от JAMA: пакет Java Matrix
Лицензия