Ответ 1
Гораздо лучший способ сделать это - обратное отображение.
По существу, вы хотите "деформировать" изображение, верно? Это означает, что каждый пиксель исходного изображения переходит в предопределенную точку - предварительное определение представляет собой матрицу преобразования, которая сообщает вам, как вращать, масштабировать, переводить, сдвигать и т.д. Изображение, которое по существу принимает некоторую координату (x,y)
на вашем изображении и говоря: "Хорошо, новая позиция для этого пикселя (f(x),g(y))
.
Это, по сути, то, что делает "деформирование".
Теперь подумайте о масштабировании изображения... скажем, в десять раз больше. Таким образом, пиксель в (1,1)
становится пикселем в (10,10)
, а затем следующий пиксель, (1,2)
становится пикселем (10,20)
в новом изображении. Но если вы продолжаете это делать, у вас не будет значений для пикселя, (13,13)
, потому что (1.3,1.3)
не определен в вашем исходном изображении, и у вас будет куча дыр в новом изображении - вам придется интерполировать для этого значения, используя четыре пикселя вокруг него в новом изображении, то есть (10,10) , (10,20), (20,10), (200,2)
- это называется билинейная интерполяция.
Но вот еще одна проблема: предположим, что ваше преобразование не было простым масштабированием и было аффинным (например, образ образца, который вы опубликовали) - тогда (1,1)
станет чем-то вроде (2.34,4.21)
, а затем вам придется округлить их на выходном изображении до (2,4)
и , а затем вам нужно будет выполнить билинейную интерполяцию на новом изображении, чтобы заполнить отверстия или более сложную интерполяцию - беспорядочно?
Теперь, не удастся выйти из интерполяции, но мы можем избежать билинейной интерполяции, просто один раз. Как? Простое обратное отображение.
Вместо того, чтобы смотреть на это как исходное изображение, идущее на новое изображение, подумайте, откуда будут получены данные для нового изображения в исходном изображении! Таким образом, (1,1)
в новом изображении будет происходить из некоторого обратного отображения в исходном изображении, скажем, (3.4, 2.1)
, а затем выполнить билинейную интерполяцию на исходном изображении, чтобы выяснить соответствующее значение!
Матрица преобразования
Итак, как вы определяете матрицу преобразования для аффинного преобразования? Этот веб-сайт рассказывает вам, как это сделать, путем компоновки различных матриц преобразования для вращения, сдвига и т.д.
Трансформация:
Compositing:
Окончательная матрица может быть достигнута путем компоновки каждой матрицы в порядке, и вы инвертируете, чтобы получить обратное сопоставление - используйте это вычисление позиций пикселей в исходном изображении и интерполируйте.