在拍照文件时,假如手机和待拍照的文件不是正对时,拍照的文件会发生扭曲。能够运用 ARKit 对拍照的图形进行纠正,获取到笔直拍照的作用。

下面是完成的思路和进程。

前提条件

在拍照的进程中,默认待拍照的图画在一个水平面或许笔直平面上(由于 ARKit 目前只能检测到水平面或许笔直平面)。

思路

  1. 经过 ARKit 获取到待拍照的平面,推导出表达平面的方程式
  2. 依据相机内参,相机当前的方位,取拍照图片上的左上、左下、右上、右下四个点,推算出这四个点所拍照的三维国际中的线
  3. 核算进程 2 中的四条线和进程 1 中的平面的四个交点,相机所拍照的图画即是这四个交点内的内容
  4. 依据投影变换,将拍照图片的左上、左下、右上、右下四个点和进程 3 中的四个交点进行对应变换,得出纠正后的图片

核算进程

获取待拍照的平面的方程式

能够经过一个平面上的三个点(不在一条直线上),核算一个平面的方程表达式。

ARKit 能够提供的才能:

  1. 识别出国际空间中的水平、笔直的平面
  2. 射线检测:能够测试手机图画上的点和特征点的交点

平面的一般式为:Ax+By+Cz+D=0Ax + By + Cz + D = 0

能够选取手机平面正中间相邻的、不再一条直线上的三个点,依据射线检测,看是否在同一个平面上。假如在同一个平面上,则获取到对应的三个点,来核算平面公式。

假定三个交点为 P1(x1,y1,z1)P_1(x_1, y_1, z_1) P2(x2,y2,z2)P_2(x_2, y_2, z_2) P3(x3,y3,z3)P_3(x_3, y_3, z_3) ,依据三点坐标别离求得 A、B、C、DA、B、C、D的值,推到公式为:

A=(y3−y1)∗(z3−z1)−(z2−z1)∗(y3−y1)B=(x3−x1)∗(z2−z1)−(x2−x1)∗(z3−z1)C=(x2−x1)∗(y3−y1)−(x3−x1)∗(y2−y1)D=−(Ax1+By1+Cz1)A = (y_3 – y_1)*(z_3 – z_1) – (z_2 -z_1)*(y_3 – y_1) \\ B = (x_3 – x_1)*(z_2 – z_1) – (x_2 – x_1)*(z_3 – z_1) \\ C = (x_2 – x_1)*(y_3 – y_1) – (x_3 – x_1)*(y_2 – y_1) \\ D = -(Ax_1 + By_1 + Cz_1)

相机图片坐标和国际坐标之间的对应联系

经过相机内参获取平面上点和相机坐标的三维点

能够经过相机内参,推到出图画上的点和相机左面空间的点的对应联系。

假定:平面上的点的坐标为 P(xphoto,yphoto)P(x_{photo}, y_{photo}),相机空间的对应的点为:P(xcamera,ycamera,zcamera)P(x_{camera}, y_{camera}, z_{camera}),相机内参为:[fx0ox0fyoy001]\begin{bmatrix}fx&0 &ox\\0&fy&oy\\0&0&1\\ \end{bmatrix} ,则:

[fx0ox0fyoy001][xcameraycamerazcamera]=[xphoto′yphoto′zphoto′]→[xphoto′yphoto′zphoto′]/zphoto′=[xphotoyphoto1]\begin{bmatrix}f_x&0 &o_x\\0&f_y&o_y\\0&0&1\\ \end{bmatrix}\begin{bmatrix}x_{camera}\\y_{camera}\\z_{camera}\\ \end{bmatrix}=\begin{bmatrix}x’_{photo}\\y’_{photo}\\z’_{photo}\\ \end{bmatrix} \to\begin{bmatrix}x’_{photo}\\y’_{photo}\\z’_{photo}\\ \end{bmatrix} / z’_{photo} = \begin{bmatrix}x_{photo}\\y_{photo}\\1\\ \end{bmatrix}

所以 P(xphoto,yphoto)P(x_{photo}, y_{photo})P(xcamera,ycamera,zcamera)P(x_{camera}, y_{camera}, z_{camera}) 的联系为:

xphoto=fxxcamera/zcamera+oxyphoto=fyycamera/zcamera+oyx_{photo} = f_xx_{camera}/z_{camera} + o_x \\ y_{photo} = f_yy_{camera}/z_{camera} + o_y

核算国际坐标和相机坐标的对应联系

经过相机的位姿(transform),能够获取相机坐标和国际坐标之间的联系。
即:(P相机坐标,1)=T相加位姿−1(P国际坐标,w)(P_{相机坐标}, 1) = {T_{相加位姿}}^{-1}(P_{国际坐标}, w)

假定相机的坐标点为:P(xcamera,ycamera,zcamera)P(x_{camera}, y_{camera}, z_{camera}),对应的国际的坐标为 P(xworld,yworld,zworld)P(x_{world}, y_{world}, z_{world}),相机的位姿(transform)为 T相机位姿T_{相机位姿},相机的位姿的逆矩阵T−1{T}^{-1},即[t00′t10′t20′t30′t01′t11′t21′t31′t02′t12′t22′t32′t03′t13′t23′t33′]\begin{bmatrix}
t’_{00}&t’_{10} &t’_{20}&t’_{30}
\\t’_{01}&t’_{11} &t’_{21}&t’_{31}
\\t’_{02}&t’_{12} &t’_{22}&t’_{32}
\\t’_{03}&t’_{13} &t’_{23}&t’_{33}\\ \end{bmatrix}

则:

[xcameraycamerazcamera1]=[t00′t10′t20′t30′t01′t11′t21′t31′t02′t12′t22′t32′t03′t13′t23′t33′][xworldyworldzworldw]\begin{bmatrix}x_{camera}\\y_{camera}\\z_{camera}\\1\\ \end{bmatrix}=\begin{bmatrix} t’_{00}&t’_{10} &t’_{20}&t’_{30} \\t’_{01}&t’_{11} &t’_{21}&t’_{31} \\t’_{02}&t’_{12} &t’_{22}&t’_{32} \\t’_{03}&t’_{13} &t’_{23}&t’_{33}\\ \end{bmatrix} \begin{bmatrix}x_{world}\\y_{world}\\z_{world}\\w\\ \end{bmatrix}

综上条件,能够得出相机图片坐标P(xphoto,yphoto)P({x_{photo}, y_{photo}})和国际坐标P(xworld,yworld,zworld)P({x_{world}, y_{world}, z_{world}})之间的对应联系:

{[xcameraycamerazcamera1]=[t00′t10′t20′t30′t01′t11′t21′t31′t02′t12′t22′t32′t03′t13′t23′t33′][xworldyworldzworldw]xphoto=fxxcamera/zcamera+oxyphoto=fyycamera/zcamera+oy\left\{ \begin{array}{c} \begin{bmatrix}x_{camera}\\y_{camera}\\z_{camera}\\1\\ \end{bmatrix}= \begin{bmatrix} t’_{00}&t’_{10} &t’_{20}&t’_{30} \\t’_{01}&t’_{11} &t’_{21}&t’_{31} \\t’_{02}&t’_{12} &t’_{22}&t’_{32} \\t’_{03}&t’_{13} &t’_{23}&t’_{33}\\ \end{bmatrix} \begin{bmatrix}x_{world}\\y_{world}\\z_{world}\\w\\ \end{bmatrix} \\ x_{photo} = f_xx_{camera}/z_{camera} + o_x \\ y_{photo} = f_yy_{camera}/z_{camera} + o_y \end{array} \right.

能够推导出:
{(fxt00′+fxt02′−xphotot02′)xworld+(fxt10′+oxt12′−xphotot12′)yworld+(t20′fx+oxt22′−xcameratxx)zworld+t30′fx+oxt32′−xphotot32′=0(fyt01′+oyt02′−yphotot02′)xworld+(fyt11′+oyt12′−yphotot12′)yworld+(fyt21′+oyt22′−yphotot22′)zworld+fyt31′+oyt32′−yphotot32′=0\left\{ \begin{array}{c} (f_xt’_{00}+f_xt’_{02}-x_{photo}t’_{02})x_{world} + (f_xt’_{10}+o_xt’_{12}-x_{photo}t’_{12})y_{world}+(t’_{20}f_x+o_xt’_{22}-x_{camera}txx)z_{world}+t’_{30}f_x+o_xt’_{32}-x_{photo}t’_{32}=0 \\ (f_yt’_{01}+o_yt’_{02}-y_{photo}t’_{02})x_{world}+(f_yt’_{11}+o_yt’_{12}-y_{photo}t’_{12})y_{world}+(f_yt’_{21}+o_yt’_{22}-y_{photo}t’_{22})z_{world}+f_yt’_{31}+o_yt’_{32}-y_{photo}t’_{32}=0 \end{array} \right.

核算 ARKit 拍照图片上的四个点平和面的焦点

有了相机拍照图片的坐标和国际坐标的联系,再加上平面方程式,则能够核算出,相机拍照的图片坐标在指定平面上的交点。

相机拍照的图片上的一点对应国际中的一条射线,即求:这条射线平和面的焦点。

假定平面为:Ax+By+Cz+D=0Ax + By + Cz + D = 0,则能够得出一个三元一次方程组:
{(fxt00′+fxt02′−xphotot02′)xworld+(fxt10′+oxt12′−xphotot12′)yworld+(t20′fx+oxt22′−xcameratxx)zworld+t30′fx+oxt32′−xphotot32′=0(fyt01′+oyt02′−yphotot02′)xworld+(fyt11′+oyt12′−yphotot12′)yworld+(fyt21′+oyt22′−yphotot22′)zworld+fyt31′+oyt32′−yphotot32′=0Axworld+Byworld+Czworld+D=0\left\{ \begin{array}{c} (f_xt’_{00}+f_xt’_{02}-x_{photo}t’_{02})x_{world} + (f_xt’_{10}+o_xt’_{12}-x_{photo}t’_{12})y_{world}+(t’_{20}f_x+o_xt’_{22}-x_{camera}txx)z_{world}+t’_{30}f_x+o_xt’_{32}-x_{photo}t’_{32}=0 \\ (f_yt’_{01}+o_yt’_{02}-y_{photo}t’_{02})x_{world}+(f_yt’_{11}+o_yt’_{12}-y_{photo}t’_{12})y_{world}+(f_yt’_{21}+o_yt’_{22}-y_{photo}t’_{22})z_{world}+f_yt’_{31}+o_yt’_{32}-y_{photo}t’_{32}=0\\Ax_{world} + By_{world} + Cz_{world} + D = 0\end{array}\right.

当确认相机拍照的图片上一个点之后,带入上面的方程组,便是确认平面上的一点P(xworld,yworld,zworld)P(x_{world}, y_{world},z_{world})的三个方程组,

{A1xworld+B1yworld+C1zworld+D1=0A2xworld+B2yworld+C2zworld+D2=0Axworld+Byworld+Czworld+D=0\left\{ \begin{array}{c} A_1x_{world} + B_1y_{world} + C_1z_{world} + D_1 = 0\\A_2x_{world} + B_2y_{world} + C_2z_{world} + D_2 = 0\\Ax_{world} + By_{world} + Cz_{world} + D = 0\end{array}\right.

依据克莱姆规律,能够核算得出 P(xworld,yworld,zworld)P(x_{world}, y_{world},z_{world}) 的值。

运用相同的进程,我们就能够获得相机相片上的4的点对应的国际坐标。

投影变换

获取到相片拍照的图片上四个极点的国际坐标之后,就能够应用投影变换,对图片进行纠正。