【问题标题】:algorithm for scaling an image from a given pivot point从给定枢轴点缩放图像的算法
【发布时间】:2010-08-30 07:12:46
【问题描述】:

使用图像中心作为轴心点的标准缩放比例,并且在所有维度上都是统一的。我想找出一种从任意枢轴点缩放图像的方法,使得靠近枢轴点的点比远离该点的点更小。

【问题讨论】:

    标签: image image-manipulation 2d scaling


    【解决方案1】:

    好吧,我不知道您使用的是什么框架/库,但您可以将其视为:

    • 翻译以使您的枢轴点成为中心点
    • 标准缩放
    • 反向平移以使中心点成为原始枢轴点

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

    • T = 转换
    • S = 缩放
    • 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)。然后你有你的逆矩阵来找到给定结果点的原始点。

    【讨论】:

    • 这会使离枢轴刻度更远的点比靠近枢轴的点更多吗?
    • 将像固定点一样缩放是您选择的枢轴点(坐标点 T')
    【解决方案2】:

    这过于简单化了,但应该可以帮助您入门。一方面,由于标准重采样是统一的,因此实际上并没有枢轴点的概念。如果有的话,它们通常只是从一个角落开始,因为这样运行 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 考虑在内。可能最简单的方法是对到边缘的距离进行对数缩放。

    【讨论】:

    • 这是一个很好的答案,谢谢。我想澄清一下,我只是缩放点位置而不是像素信息。所以想象一个点位置的网络,我想对它们进行缩放,使靠近枢轴点的点比远离的点缩放更少。
    • 那就更简单了。您只需要 getResampleLoc 然后遍历坐标对而不是有两个 for 循环。从您的枢轴点计算极向量,对其进行非线性缩放(例如平方),然后转换回笛卡尔。
    猜你喜欢
    • 2015-02-06
    • 2013-06-06
    • 2018-11-01
    • 2015-10-22
    • 2016-05-16
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多