opengl 将四边形转换为矩形?

pprl5pva  于 2023-01-20  发布在  其他
关注(0)|答案(3)|浏览(217)

我有一个由任意四边形组成的场景。我需要能够将四边形转换为矩形。每个四边形都是二维坐标,所以它们有4个顶点(x_i, y_i)
变换需要有一个逆变换,因为这个想法是在操作矩形后回到原始四边形。
执行此操作最简单的方法是什么?我听说它被称为透视变换,但我发现了一些小线索,使我认为这可能很容易做到。

vnzz0bqm

vnzz0bqm1#

你知道你想要的矩形的大小吗?如果是这样的话,你可以用透视变换把任何凸四边形Map成一个矩形。你所要做的就是得到4个对应的点(在四边形和矩形之间),比如说,(X1,Y1),(X2,Y2),(X3,Y3),(X4,Y 4)表示四边形,(x1,y1),(x2,y2),(x3,y3),(x4,y 4)表示矩形,然后将其代入Borealid's link中的最后一个方程,你就会得到:

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

这将允许你把矩形上的点变换成四边形上的点。对于逆变换,只需反转变换矩阵。
另请注意,一旦获得变换坐标的向量[XW YW W]T,就需要将其归一化,使W = 1。即,最终答案为[XW/W YW/W W/W]T,它等于所需答案[X Y 1]T。

k97glaaz

k97glaaz2#

不是所有的四边形都是矩形。因此,从四边形到矩形不存在可逆变换;存在的四边形比直边多,所以你不能产生一个从四边形到直边的可逆Map。
然而,你可以为一个特定的四边形生成一个可逆的变换。正如你所推测的,这是关于旋转透视图,使四边形在你的新坐标空间中“看起来”像一个矩形。参见https://web.archive.org/web/20100801071311/http://alumni.media.mit.edu/~cwren/interpolator/,其中包含了这个问题的Matlab源代码。

zfycwa2u

zfycwa2u3#

这个解决方案使用JAI(Java高级图像)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){}

希望对你有帮助。:)

相关问题