Перспектива и билинейные преобразования - PullRequest
2 голосов
/ 18 июля 2010

Я делаю приложение для векторного рисования и заметил, что у Anti Grain Geometry есть пример, который делает именно то, что я хочу.http://www.antigrain.com/demo/index.html, ниже приведен пример перспективы для Win32.Я не понимаю их файл cpp.На основании этого примера.Если у меня есть несколько вершин для формирования объекта, таких как их лев, и тогда у меня есть 4 вершины в качестве контрольных точек, как я могу достичь их эффекта?Например, какое преобразование я применяю к каждой точке?

Спасибо

Ответы [ 2 ]

1 голос
/ 18 июля 2010

На той самой странице, которую вы разместили, есть ссылка на источник код. Я объясню билинейное преобразование в

http://www.antigrain.com/__code/include/agg_trans_bilinear.h.html

Идея состоит в том, чтобы найти преобразование формы:

output_x = a * input_x + b * input_x * input_y + c * input_y + d
output_y = e * input_x + f * input_x * input_y + g * input_y + h

Термин "билинейный" происходит от того, что каждое из этих уравнений является линейным в любой из входных координат самостоятельно. Мы хотим решить для правильные значения a, b, c и d. Скажем, у вас есть ссылка прямоугольник r1, r2, r3, r4, который вы хотите отобразить на (0,0), (1,0), (0,1), (1,1) (или некоторая система координат изображения).

Для a, b, c, d:

0 = a * r1_x + b * r1_x * r1_y + c * r1_y + d
1 = a * r2_x + b * r2_x * r2_y + c * r2_y + d
0 = a * r3_x + b * r3_x * r3_y + c * r3_y + d
1 = a * r4_x + b * r4_x * r4_y + c * r4_y + d

Для e, f, g, h:

0 = e * r1_x + f * r1_x * r1_y + g * r1_y + h
0 = e * r2_x + f * r2_x * r2_y + g * r2_y + h
1 = e * r3_x + f * r3_x * r3_y + g * r3_y + h
1 = e * r4_x + f * r4_x * r4_y + g * r4_y + h

Вы можете решить это, как вам больше нравится. (Если вы знакомы с матричные обозначения, это два матричных уравнения, для которых матрица то же самое, и тогда вам просто нужно найти разложение LU один раз и решить два неизвестных вектора). Коэффициенты тогда применяется для сопоставления внутренней части прямоугольника с положением в прямоугольник.

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

Для a, b, c, d:

r1_x = a * 0 + b * 0 * 0 + c * 0 + d
r2_x = a * 1 + b * 1 * 0 + c * 0 + d
r3_x = a * 0 + b * 0 * 1 + c * 1 + d
r4_x = a * 1 + b * 1 * 1 + c * 1 + d

Для e, f, g, h:

r1_y = e * 0 + f * 0 * 0 + g * 0 + h
r2_y = e * 1 + f * 1 * 0 + g * 0 + h
r3_y = e * 0 + f * 0 * 1 + g * 1 + h
r4_y = e * 0 + f * 0 * 1 + g * 1 + h
1 голос
/ 18 июля 2010

Я думаю, вы говорите о преобразовании перспективы из 2D-плоскости в квадрат в пространстве.

Ну, это не так уж сложно. Математика объясняется в статье:

Хекберт, Пол, Основы Наложение текстур и деформация изображения, Магистерская работа, UCB / CSD 89/516, CS Отдел, США Беркли, июнь 1989 года.

(я не ссылаюсь на статью из-за авторских прав. Она доступна в сети, и у вас не должно возникнуть проблем с ее поиском)

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

Если вы ищете какой-нибудь «простой в копировании» код, я предлагаю загрузить справочную реализацию OpenVG и внимательно изучить функции «vguComputeWarpQuadToSquare», «vguComputeWarpSquareToQuad» и «vguComputeWarpQuadToQuad» :-) Они покрывают все, что вам нужно .

Скачать здесь: http://www.khronos.org/registry/vg/ri/openvg-1.1-ri.zip

Эти функции будут вычислять матрицу 3x3, которая выполняет преобразование. Чтобы использовать эту матрицу, вы должны расширить свои 2D координаты в 2D однородные координаты. Это не , что сложно, но выходит за рамки вопроса. Если вам нужна помощь для работы с ними, я предлагаю вам задать другой вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...