从给定的中心点缩放图像的算法

5

标准缩放使用图像中心作为枢轴点,并在所有维度上均匀。我想找出一种方法,从任意枢轴点缩放图像,使得距离枢轴点更近的点比远离该点的点缩放更少。

2个回答

4

嗯,我不知道你使用的是哪个框架/库,但你可以这样考虑:

  • 平移以使你的中心点成为中心点
  • 标准缩放
  • 相反的平移以使中心点成为原始枢轴点

翻译和缩放是同构,因此您可以将它们表示为矩阵。每个转换都是一个矩阵,您可以将它们相乘以找到组合转换矩阵。所以:

  • T = 转换
  • S = 缩放
  • T' = 相反的转换

如果您应用了 T.x,其中 x 是点向量,则会给出新坐标。对于 S.x 也是如此。

因此,如果要执行这些操作,您必须执行:T'.(S.(T.x))

我认为您可以关联操作,因此与 (T'.S.T).x 相同

如果您正在使用框架,请应用三个操作(或组合操作并应用)。 如果您使用的是原始数学...那就走矩阵的路线吧 :)

PS:如果您手动执行此操作。我知道如果您进行缩放,您将希望在给定变换后找到原始点的坐标。因此,您可以迭代结果点(每个像素)并查看必须使用原始图像中的哪些坐标(或点之间的点)。在这种情况下,您需要逆矩阵。因此,您要使用 S^(-1) 而不是 S。如果您知道要应用 T'.S.T,则可以找到此结果矩阵,然后找到 (T'.S.T)^(-1)。然后,您就有了逆矩阵以查找给定结果点的原始点。


这会使得离枢轴较远的点比靠近枢轴的点更加分散吗? - user257543
将会按照您选择的固定点作为枢轴点进行缩放(即坐标T'点)。 - helios

-1

这只是一个过于简化的描述,但应该能帮助您入门。首先,由于标准重采样是均匀的,实际上并没有枢轴点的概念。如果有什么的话,它们通常只是从一个角落开始,因为这样更容易运行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只是将dstImg大小的x和y简单缩放到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。最简单的方法可能是对到边缘的距离进行对数缩放。


非常好的答案,谢谢。我想澄清一下,我只是在缩放点位置而不是像素信息。所以想象一下一个点位置的网络,我想将它们缩放,使得靠近枢轴点的点比远离枢轴点的点缩放得更少。 - user257543
比那还要简单。你只需要获取getResampleLoc,然后迭代坐标对,而不是使用两个for循环。从枢轴点计算极向量,进行非线性缩放(例如平方),再转换回笛卡尔坐标系。 - Lou Franco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接