алгоритм масштабирования изображения из заданной точки поворота - PullRequest
5 голосов
/ 30 августа 2010

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

Ответы [ 2 ]

4 голосов
/ 30 августа 2010

Ну, я не знаю, какую платформу / библиотеку вы используете, но вы можете думать об этом как:

  • перевод, чтобы сделать вашу точку поворота центральной точкой
  • стандартное масштабирование
  • обратный перевод, чтобы сделать центральную точку исходной точкой поворота

Перевод и масштабирование являются изоморфизмами, поэтому вы можете представить их в виде матрицы. Каждое преобразование является матрицей, и вы можете умножить их, чтобы найти объединенную матрицу преобразований. Итак:

  • T = преобразование
  • S = scalling
  • T '= обратное преобразование

Если вы примените T.x как x точечный вектор, он даст вам новые координаты. То же самое для S.x.

Так что, если вы хотите сделать эти операции, вы должны сделать: T '. (S. (T.x))

Я думаю, что вы можете связать операции, так что это то же самое, что (T'.S.T) .x

Если вы используете платформу, примените три операции (или объедините операции и примените). Если вы используете грубую математику ... используйте матрицу:)

PS: Если вы делаете это вручную. Я знаю, что если вы масштабируете, вы захотите найти координаты исходной точки с учетом преобразованной точки. Таким образом, вы можете перебрать получившиеся точки (каждый из пикселей) и посмотреть, какие координаты (или точки между ними) исходного изображения вам нужно использовать. В этом случае вам нужна обратная матрица. Поэтому вместо использования S вы хотите использовать S ^ (- 1). Если вы знаете, что хотите применить T'.S.T, вы можете найти полученную матрицу и затем найти (T'.S.T) ^ (- 1). Затем у вас есть обратная матрица для поиска исходных точек по заданным точкам.

0 голосов
/ 30 августа 2010

Это упрощение, но оно должно помочь вам начать.С одной стороны, так как стандарт передискретизации однородна, не существует на самом деле понятие поворотной точки.Во всяком случае, они обычно начинаются с угла, так как таким образом проще запускать циклы for.

Обычно алгоритм выглядит примерно так: псевдокод

function resample (srcImg, dstSize) {
    dstImg = makeImage(dstSize)
    for (r = 0; r < dstSize.height; ++r) {
        for (c = 0; r < dstSize.width; ++c) {
            // getResampleLoc returns float coordinate
            resampleLoc = getResampleLoc(c, r, dstImg.size, srcImg.size)
            color = getColor(srcImg, resampleLoc)
            dstImg.setColor(c, r, color)
        }
    }
    return dstImage
} 

Для равномерной повторной выборкиgetResampleLoc - это просто простой масштаб x и y от размера dstImg до размера srcImg.Возвращает координаты с плавающей точкой, которые передаются в getColor.Реализация getColor - это то, что определяет различные алгоритмы передискретизации.В основном это смешивает пиксели, окружающие координату в некотором отношении.В действительности, существуют оптимизации, которые позволяют сделать информацию, генерируемую внутри getColor, общей для вызовов, но не беспокойтесь об этом.

Для вас вам понадобится что-то вроде:

function resample (srcImg, dstSize, pivotPt) {
    dstImg = makeImage(dstSize)
    for (r = 0; r < dstSize.height; ++r) {
        for (c = 0; r < dstSize.width; ++c) {
            // getResampleLoc returns float coordinate
            resampleLoc = getResampleLoc(c, r, dstImg.size, srcImg.size, pivotPt) 
            color = getColor(srcImg, resampleLoc)
            dstImg.setColor(c, r, color)
        }
    }
    return dstImage
} 

И тогда вам просто нужно реализовать getResampleLoc, чтобы принять во внимание pivotPt.Вероятно, самое простое - записать расстояние до края.

...