从给定枢轴点缩放图像的算法

发布于 2024-09-16 08:32:44 字数 78 浏览 7 评论 0原文

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

standard scaling using the center of an image as the pivot point and is uniform in all dimensions. I'd like to figure out a way to scale an image from an arbitrary pivot point such that points closer to the pivot point scale less than points away from that point.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

涫野音 2024-09-23 08:32:44

好吧,我不知道你正在使用什么框架/库,但你可以将其视为:

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

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

  • T = 变换
  • S = 缩放
  • T' = 相反变换

如果您应用 Tx 作为 xa 点向量,它会给您新的坐标。对于 Sx 也是如此

,所以如果你想执行该操作,你必须执行:T'。 (S.(Tx))

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

如果您使用框架,则应用三个操作(或组合操作并应用)。
如果您使用粗略的数学...请采用矩阵方式:)

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

Well, I don't know what framework/library you're using but you can think of it as:

  • translation to make your pivot point the center point
  • standard scaling
  • opposite transalation to make the center point the original pivot point

Translation and scaling are isomorphismes so you can represent them as matrix. Each transformation is a matrix and you can multiply them for find the combined transformation matrix. So:

  • T = transformation
  • S = scalling
  • T' = opposite transformation

If you apply T.x being x a point vector it gives you the new coordinates. The same for S.x.

So if you want to do that operations you have to do: T'. (S. (T.x))

I think you can associate operations so it's the same as (T'.S.T).x

If you are using a framework apply three operations (or combine operations and apply).
If you are using crude math... go the matrix way :)

PS: If you are doing this by hand. I know that if you are scaling you will want to find the coordinates of the original point given a transformed point. So you can iterate over the resulting points (each of the pixels) and see what coordinates (or point in between) from the original image you have to use. In that case what you need is the inverse matrix. So instead of using S you want to use S^(-1). If you know that you want to apply T'.S.T you can find this resulting matrix and next find (T'.S.T)^(-1). Then you have your inverse matrix to find original points given the resulting points.

何时共饮酒 2024-09-23 08:32:44

这过于简单化了,但应该可以帮助您入门。其一,由于标准重采样是统一的,因此实际上并不存在枢轴点的概念。如果有的话,它们通常只是从一个角落开始,因为这样更容易运行 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 大小到 srcImg 大小的 x 和 y 的简单缩放。它返回浮点坐标,该坐标被传递给 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。也许最简单的事情是对数缩放到边缘的距离。

This is an oversimplification, but should help you get started. For one, since standard resampling is uniform, there isn't really a concept of a pivot-point. If anything, they usually just start from a corner, as it's easier to run the for loops that way.

Generally the algorithm is something like this pseudo-code

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
} 

For uniform resampling, getResampleLoc is just a simple scale of x and y from the dstImg size to the srcImg size. It returns float coordinates, which are passed to getColor. The implementation of getColor is what determines the various resampling algorithms. Basically, it blends the pixels surrounding the coordinate in some ratio. In reality, there are optimizations that can be done to make information generated inside of getColor shared between calls, but don't worry about that.

For you, you would need something like:

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
} 

And then you just need to implement getResampleLoc to take pivotPt into account. Probably the simplest thing is to log-scale the distance to the edge.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文