Превратить четырехугольник в прямоугольник?
У меня есть сцена, состоящая из одного произвольного четырехугольника. Я должен быть в состоянии превратить этот четырехугольник в прямоугольник. Каждый квад находится в двухмерных координатах, поэтому они имеют 4 вершины (x_i, y_i)
,
Преобразование должно иметь обратное, потому что идея состоит в том, чтобы вернуться к исходному четырехугольнику после манипулирования прямоугольником.
Какой самый простой способ выполнить эту операцию? Я слышал, что это называется перспективным преобразованием, но я нашел несколько небольших подсказок, которые заставляют меня думать, что это может быть довольно легко сделать.
3 ответа
Вы знаете, каков размер желаемого прямоугольника? Вы можете отобразить любой выпуклый четырехугольник на прямоугольник с обратимым преобразованием с перспективным преобразованием, если это так. Все, что вам нужно сделать, это получить 4 соответствующие точки (между четырехугольником и прямоугольником), скажем, (X 1, Y 1), (X 2, Y 2), (X 3, Y 3), (X 4, Y 4) для четырехугольника и соответственно (x 1, y 1), (x 2, y 2), (x 3, y 3), (x 4, y 4) для прямоугольника. Затем включите его в окончательное уравнение в ссылке Бореалида, и все готово:
Решение вышеприведенного уравнения (где n = 4) даст вам элементы (a,b,c,d,e,...,h) матрицы обратимого преобразования перспективы,
Это позволит вам преобразовать точки на прямоугольнике в точки на четырехугольнике. Для обратного преобразования просто инвертируйте матрицу преобразования.
Также обратите внимание, что как только вы получите вектор [XW YW W] T преобразованных координат, вам нужно его нормализовать так, чтобы W = 1. Т.е., ваш окончательный ответ был [XW / W YW / WW / W] T, который равен [XY 1] T, желаемый ответ.
Не все четырехугольники являются прямоугольниками. По этой причине нет обратимого преобразования из квадрата в прямоугольник; существует больше квадраторов, чем канатов, поэтому вы не можете создать обратимое отображение квадратов на каналы.
Однако вы можете создать обратимое преобразование для конкретного четырехугольника. Как вы предполагаете, речь идет о повороте перспективы, поэтому четырехугольник "выглядит" как прямоугольник в вашем новом координатном пространстве. См. http://alumni.media.mit.edu/~cwren/interpolator/, который содержит исходный код Matlab для этой проблемы.
Это решение использует 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){}
Надеюсь, это поможет вам.:)