delphi – 从3d透视图将图像重绘为2d
我需要用Pascal / Delphi / Lazarus写的逆透视变换.见下图:
我想我需要走过目标像素,然后计算源图像中的相应位置(避免四舍五入错误等). function redraw_3d_to_2d(sourcebitmap:tbitmap,sourceaspect:extended,point_a,point_b,point_c,point_d:tpoint,megapixelcount:integer):tbitmap; var destinationbitmap:tbitmap; x,y,sx,sy:integer; begin destinationbitmap:=tbitmap.create; destinationbitmap.width=megapixelcount*sourceaspect*???; // I dont how to calculate this destinationbitmap.height=megapixelcount*sourceaspect*???; // I dont how to calculate this for x:=0 to destinationbitmap.width-1 do for y:=0 to destinationbitmap.height-1 do begin sx:=??; sy:=??; destinationbitmap.canvas.pixels[x,y]=sourcebitmap.canvas.pixels[sx,sy]; end; result:=destinationbitmap; end; 我需要真正的公式…所以一个OpenGL解决方案不会是理想的… 解决方法
注意:在数学SE上有适合数学排版的
a version of this.
计算投影变革 一个透视是projective transformation的一个特殊情况,反过来又被四点定义. 步骤1:从源图像中的4个位置(名称为(x1,y1)到(x4,y4))开始,解决以下system of linear equations: [x1 x2 x3] [λ] [x4] [y1 y2 y3]?[μ] = [y4] [ 1 1 1] [τ] [ 1] 列为homogenous coordinates:一维更多,通过添加1作为最后一个条目创建.在随后的步骤中,这些向量的倍数将用于表示相同的点.有关如何将它们转回二维坐标的示例,请参阅最后一步. 步骤2:按照刚刚计算的系数缩放列: [λ?x1 μ?x2 τ?x3] A = [λ?y1 μ?y2 τ?y3] [λ μ τ ] 该矩阵将(1,0)映射到(x1,y1,1),(0,1,0)的倍数为(x2,y2,1)的倍数,(x3,y3,1)和(1,1)至(x4,y4,1)的倍数.因此,它将映射这四个特殊向量(在随后的说明中称为基本向量)到图像中的指定位置. 步骤3:对目标图像中的相应位置重复步骤1和2,以获得称为B的第二个矩阵. 这是从基础向量到目标位置的地图. 步骤4:Invert B得到B -1. B从基矢量映射到目标位置,因此逆矩阵沿相反方向映射. 步骤5:计算combined矩阵C = A?B -1. B – 1从目标位置映射到基向量,而A映射到源位置.因此,组合将目标位置映射到源位置. 步骤6:对于目标图像的每个像素(x,y),计算产品 [x'] [x] [y'] = C?[y] [z'] [1] 这些是您转换点的均匀坐标. 步骤7:计算源图像中的位置,如下所示: sx = x'/z' sy = y'/z' 这被称为坐标矢量的去谐波. 所有这些数学将是so much easier to read and write如果SO是support MathJax …? 选择图像大小 上面的aproach假设你知道你的角落在目的地图像中的位置.对于这些,您必须知道该图像的宽度和高度,它也由您的代码中的问号标记.所以我们假定输出图像的高度为1,宽度为sourceaspect.在这种情况下,整体面积也是源源不绝的.您必须以pixelcount / sourceaspect为因子来缩放该区域,以达到像素数的一个区域.这意味着您必须按照该因子的平方根来缩放每个边长.所以到最后,你有 pixelcount = 1000000.*megapixelcount; width = round(sqrt(pixelcount*sourceaspect)); height = round(sqrt(pixelcount/sourceaspect)); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |