我有一个由任意四边形组成的场景。我需要能够将该四边形转换为矩形。每个四边形都在2D坐标系中,因此它们有4个顶点(x_i, y_i)
。
变换需要有一个反演,因为想法是在操作矩形后回到原始四边形。
执行此操作的最简单方法是什么?我听说这被称为透视变换,但我发现了一些小线索,让我认为这可能很容易实现。
我有一个由任意四边形组成的场景。我需要能够将该四边形转换为矩形。每个四边形都在2D坐标系中,因此它们有4个顶点(x_i, y_i)
。
变换需要有一个反演,因为想法是在操作矩形后回到原始四边形。
执行此操作的最简单方法是什么?我听说这被称为透视变换,但我发现了一些小线索,让我认为这可能很容易实现。
你知道所需矩形的尺寸吗?如果是这样,您可以使用透视变换将任何凸四边形映射到矩形上,并进行可逆转换。您只需要获取4个相应点(在四边形和矩形之间),例如(X1,Y1),(X2,Y2),(X3,Y3),(X4,Y4)用于四边形,对应地(x1,y1),(x2,y2),(x3,y3),(x4,y4)用于矩形。然后将它们插入Borealid's链接中的最终方程式中即可:
上述方程的解(其中n=4)将给出可逆透视变换矩阵的元素(a、b、c、d、e、...、h)。 这将使您能够将矩形上的点转换为四边形上的点。要进行反向变换,只需反转变换矩阵即可。并非所有的四边形都是矩形。正因为如此,从四边形到矩形没有可逆变换;存在更多的四边形而不是矩形,因此您无法从四边形到矩形产生可逆映射。
然而,您可以为一个特定的四边形生成可逆变换。正如您所推测的那样,这涉及到旋转视角,使得四边形在您的新坐标空间中“看起来”像一个矩形。请参见https://web.archive.org/web/20100801071311/http://alumni.media.mit.edu/~cwren/interpolator/,其中包含了这个问题的Matlab源代码。
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){}