将四边形变换为矩形?

时间:2010-07-06 21:46:22

标签: opengl computer-vision linear-algebra graphics

我有一个任意四边形组成的场景。我需要能够将四边形转换成矩形。每个四边形都是2d坐标,因此它们有4个顶点(x_i, y_i)

转换需要反转,因为想法是在操作矩形后返回原始四边形。

执行此操作的最简单方法是什么?我听说它被称为透视转换,但我发现一些小线索让我觉得这很容易做到。

3 个答案:

答案 0 :(得分:12)

你知道所需矩形的大小是多少吗?如果是这种情况,您可以使用透视变换将任何凸四边形映射到具有可逆变换的矩形。所有你需要做的就是获得4个对应点(在四边形和矩形之间),比方说,(X 1 ,Y 1 ),(X 2 < / sub>,Y 2 ),(X 3 ,Y 3 ),(X 4 ,Y < sub> 4 )对于四边形并相应地(x 1 ,y 1 ),(x 2 ,y 2 ),(x 3 ,y 3 ),(x 4 ,y 4 )对于矩形。然后将其插入Borealid's链接中的最终等式中,然后设置:

alt text

上述等式(其中n = 4)的解将给出可逆透视变换矩阵的元素(a,b,c,d,e,...,h),

alt text

这将允许您将矩形上的点转换为四边形上的点。对于逆向变换,只需反转变换矩阵。

另请注意,一旦获得变换坐标的向量[XW YW W] T ,您需要将其标准化,使得W = 1.即,您的最终答案是[XW / W YW / WW / W] T 等于[XY 1] T ,即期望的答案。

答案 1 :(得分:1)

并非所有四边形都是矩形。因此,没有从四边形到矩形的可逆变换;存在更多四边形而非rects,因此您无法从四边形到rects生成可逆映射。

但是,您可以为特定四边形生成可逆转换。正如你猜测的那样,它是关于旋转透视,所以四边形“出现”为新坐标空间中的矩形。请参阅http://alumni.media.mit.edu/~cwren/interpolator/,其中包含此问题的Matlab源代码。

答案 2 :(得分:0)

此解决方案使用JAI(Java Advance Image)API 所有的魔力都在QuadToQuad方法中。这是代码示例。

try
     {
      BufferedImage img = UtilImageIO.loadImage(picName);
      ParameterBlock params = new ParameterBlock();
      params.addSource(img); //source is the input image
        int w = img.getWidth(); //Set to the original width of the image
        int h = img.getHeight(); //Set to the original height of image
        Point tl = new Point(x,y); //The new top left corner
        Point tr = new Point((x1,y1); //The new top right corner
        Point bl = new Point(x2,y2); //The new bottom left corner
        Point br = new Point(x3,y3); //The new bottom right corner
        PerspectiveTransform p = PerspectiveTransform.getQuadToQuad(0,0, 0, h, w, h, w, 0, tl.x, tl.y, bl.x, bl.y, br.x, br.y, tr.x, tr.y).createInverse();
        WarpPerspective wa = new WarpPerspective(p);
        params.add(wa);
        params.add(Interpolation.getInstance(Interpolation.INTERP_BICUBIC)); //Change the interpolation if you need more speed
        RenderedOp dest = JAI.create("warp", params); //dest is now the output
        File outputfile = new File(picName);
        ImageIO.write(dest, "jpg", outputfile); 

    }
    catch(Exception e){}

希望它会对你有所帮助。 :)