热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

三角测量计算三维坐标的代码_双目三维重建——层次化重建思考

双目三维重建——层次化重建思考FesianXu2020.7.22atANTFINANCIALintern前言本文是笔者阅读[1]第10章内容的笔记,本文从宏观的角度阐

双目三维重建——层次化重建思考

FesianXu 2020.7.22 at ANT FINANCIAL intern

前言

本文是笔者阅读[1]第10章内容的笔记,本文从宏观的角度阐述了双目三维重建的若干种层次化的方法,包括投影重建,仿射重建和相似性重建到最后的欧几里德重建等。本文作为介绍性质的文章,只提供了这些方法的思路,并没有太多的细节,细节将会由之后的博文继续展开。如有谬误,请联系作者指出,转载请注明出处。

联系方式:

e-mail: FesianXu@gmail.com

QQ: 973926198

github: https://github.com/FesianXu


: 在阅读本文之前,强烈推荐读者先阅读[4]和[5], 以了解[几何变换的层次——投影变换,仿射变换,度量变换和欧几里德变换的具体区别]和[conic圆锥线和quadric二次曲锥面的定义和应用],在本文中将会基于这些前置知识进行讨论。同时作为成像的基础知识,相机内外参数的知识[6]也是必须了解的。

双目三维重建简介

作为三维重建,我们希望能够得到被重建物体的结构(也就是三维世界中的点的位置信息)。在双目三维重建中,正如其“双目”所言,我们假设有两个摄像机对某个物体进行观测,得到了多视角对同一个物体描述的图片。通常,在三维重建任务中,我们通过一系列的前置算法,可以得到这些多视角图片之间的对应点关系,如Fig 1所示,点

和点
都是三维世界客体点
的投影,也就是说它们是一对
对应点(correspondence),通常我们用
表示一对对应点。笔者之前的博文[2,3]中曾经根据对极线约束和图像矫正对对应点的影响进行过介绍,读者有兴趣可自行查阅。
73e169474288aff3f16e96732e67fc62.png

Fig 1. 双目多视角图片之间的对应点,其都是对三维世界中客体点P的投影。

通常来说,在三维重建任务中,我们假设对应点对应的三维点

的位置是未知的,需要我们求出,并且我们也不知道相机的方向,位置和内参数校准矩阵等(也就是外参数和内参数都未知)。整个重建任务就是需要去计算相机矩阵
,使得对于三维点
有:

其中的

表示的是对应点的编号。当给定的对应点太少时,这个任务是显然不能完成的,但是如果给定了足够多的对应点,那么我们就有足够的约束去唯一确定出一个基础矩阵(Fundamental Matrix)[2] 出来,如式子(2)所示(当然,求解这个基础矩阵也并没有那么简单,这个并不在本文中进行阐述)。此时,整个三维重建将会存在一种称之为
投影歧义 (projective ambiguity)的现象,我们将会在下文进行介绍。作为无校准的相机来说,在不引入任何先验知识进行约束的情况下,这是双目三维重建能得到的最好结果。在添加了其他对场景的先验知识后(比如平行线约束,垂直线约束,摄像机内参数相同假设等),投影歧义可以被减少到仿射歧义甚至是相似歧义的程度。

总的来说,重建过程的三部曲可以分为:

  1. 根据对应点计算得到基础矩阵。
  2. 根据基础矩阵计算得到相机矩阵
  3. 对于每对对应点
    来说,通过三角测量法,计算其在空间上的三维点坐标位置。

注意到本文对这些重建方法的介绍只是一个概念性的方法,读者需要明晰的是,不要尝试单纯地实现本文介绍的方法去实现重建,对于真实场景的图片而言,重建过程存在着各种噪声(比如对应点对可能不准确,存在噪声等,需要鲁棒估计),这些具体的方法我们将会在之后的博文介绍。

这里需要单独拎出来提一下的是 三角测量法(Triangulation),如Fig 2所示,在计算得到了相机矩阵

之后,我们知道
满足对极约束
,换句话说,我们知道
在对极线
上,反过来这意味着从图像点
反向投影得到的射线共面,因此它们的反向射线将会交于一点
。通过三角测量的方法,我们可以测量除了基线上的任意一个三维空间点,原因在于基线上的点的反向射线是共线的,因此不能唯一确定其相交点。
56a94fbba6c1230a2fe6ec28d1c28731.png

Fig 2. 通过三角测量法去确定三维空间中的点。

重建歧义性

重建过程存在或多或少的歧义性,为了解决歧义性,我们需要引入额外的信息。

单纯地从对应点去进行场景,物体的三维重建必然是有一定的歧义性的,只是说引入了对场景一定的先验知识后,这种歧义性会得到缓解。举个例子,光从成对的对应点对(甚至可能是多个视角的点对),都不能计算出场景的绝对位置(指的是地球上的经纬度)和绝对朝向,这点很容易理解,例如Fig 3所示,即便是给定了相机内参数等,也不可能决定b和c这两个走廊的具体的东西走向,还是南北走向,亦或是其经纬度,这些涉及到地理位置的绝对信息无法光从相机重建得到。

e1d25e54675b66196fc7d519470ec8bb.png

Fig 3. 不引入其他任何知识,只从相机得到的照片,无法判断场景的绝对地理信息。

一般来说,基于相机的重建,我们称它最好的情况下,对于世界坐标系来说,都只能是欧几里德变换(包括这旋转和偏移)。当然,如果我们的相机没有标定,也就是内参数未知,就Fig 3的走廊为例子,我们无法确定走廊的宽度和长度,它可能是3米,也可能只是一个玩具走廊,只有30厘米,这些都有可能。在不引入对场景尺度的任何先验而且相机没有标定的情况下,我们称基于相片的场景重建只能最好到相似性变换(也就是是存在旋转,偏移和尺度缩放)。

如果用数学形式去解释这个现象,用

表示一系列场景中的三维点,
表示一对相机,其将三维点投影到
。假设我们有相似性变换

其中的

是旋转矩阵,
是偏移,
是尺度放缩。假设我们对三维点进行相似性变换,那么我们用
取代
,并且用
取代原来的相机参数
。我们发现,因为有
,因此在图像上的投影点位置是不会改变的。
通常来说,在不引入其他先验的情况下,我们会发现,在重建过程中,算法只会保证图像上的投影点的位置是投影正确的,没法保证三维空间的其他信息了。

相似歧义性

更进一步,我们对相机参数进行分解,有

,那么经过相似性变换之后,有:

一般情况下,我们不是很关心偏移

。我们会发现,相似性变换并不会改变其相机内参数,
是不会改变的,也就是说,即便是对于校准后的相机,最好的重建结果也会存在相似性歧义,我们称之为
相似性重建 (Similarity reconstruction, metric reconstruction)。 如Fig 4的图a所示,这就是相似性歧义的示意图,我们无法确定场景的绝对大小。
a7922b0f40920f3c8686e90c48c979d8.png

Fig 4. 重建的相似性歧义性和投影歧义性

如果两个相机的内参数中的焦距都是已知的,那么这个重建最好能到 相似性重建 (similarity reconstruction) 的程度,其重建过程引入的是 相似歧义性 (similarity ambiguity)。也就是说,重建出来的场景只会在尺度大小上和真实场景的有差别。

投影歧义性

如果我们对内参数一无所知,也不知道相机之间的相对位置关系,那么整个场景的重建将会陷入 投影歧义性 (projective ambiguity),如Fig 4的图b所示。同样我们可以假设一个不可逆的矩阵

作为投影矩阵,用我们在之前介绍的方法,我们会发现将投影矩阵同时作用在三维点和相机上时,不影响图像上的投影点位置。因此实际的重建三维点将会是投影歧义的。这个称之为
投影重建 (Projective reconstruction),投影重建和相似重建的不同之处在于,相似重建因为相机内参数已经知道,因此相机焦点位置是确定的,而投影重建因为没有校准机参数,因此焦点位置可能会变化,Fig 4示意图就明确了这一点。

仿射歧义性

如果两个相机只是存在位置偏移上的变化,而内参数完全相同(可以视为是同一个相机的在不同位置拍摄的相片),那么重建过程是最好能达到 仿射重建 (affine reconstruction)的程度,相对应的,这个重建过程会引入 仿射歧义性 (affine ambiguity)。举个例子,假如我们知道不同相机之间的焦距都是一样的(焦距是内参数的一部分),因此整个场景可能存在旋转,偏移和尺度放缩或者切变(Shear)[7]。但是不会存在如同Fig 4所示的投影歧义的那么严重的歧义性。

度量重建和欧几里德重建

一般来说,我们同样可以用 度量重建 (metric reconstruction) 去表述相似性重建,因为相似性重建过程中的某些量 比如 线与线的角度,线段比例等度量在重建场景和真实场景中应该是一致的。另外,当我们说到 欧几里德重建 (Euclidean reconstruction) 的时候,一般我们也是把它当做度量重建或者是相似性重建的别称,因为没有其他额外的知识,比如场景的世界坐标上的朝向,景深甚至是世界坐标经纬度等,我们是无法真正地实现欧几里德重建的,而这些额外知识已经脱离了基于相机的重建了。

理想点,无限远平面和IAC

我们曾经在博文[4,7]中提到过理想点(Ideal point),无限远平面(The plane at infinity)和IAC (Image of Absolute Conic)[8]。这些几何元素是用于描述投影空间中的一些性质,包括变换前后的不变性。这里进行知识回顾并且进一步的介绍。

简单来说,在投影变换过程中,平行线的平行性质将得不到保留,因此可能存在 透视 (perspective) 现象,具体体现出来如同Fig 5所示。这里的平行线交汇的无限远处的消失点我们称之为 理想点, 由所有理想点所组成的平面称之为 无限远平面 ,我们用符号

表示。
cbb9b7f5cb44d3a1dd04c629b89fb99a.png

Fig 5. 本来应该是平行的马路,在相机成像的时候,则变成了“不平行”,汇聚于无限远处的消失点(vanishing point)。

在谈到绝对圆锥曲线 (Absolute Conic, AC) 和 绝对圆锥曲线的投影 (Image of Absolute Conic, IAC) 之前,我们可以举个日常生活中的例子,我们都知道月亮离我们很远,可以视为是在无限远处的一个圆形(圆锥曲线的一种特例),想象你开车行驶在一条笔直的道路上,右侧空中高悬着圆月,你会发现不管你怎么疾驰,月亮仿佛都跟随着你,而且位置不变,大小也不变。

这个浪漫的“月亮跟着我”的例子,正是欧几里德变换对于处在无限远处平面上的绝对圆锥线的影响。 绝对圆锥曲线AC 是指的处在无限远平面上的圆锥曲线(圆锥曲面),而 绝对圆锥曲线的投影IAC 指的是绝对圆锥曲线在成像平面上的投影,如Fig 6所示,通常我们用

表示IAC,用
表示AC,其中
表示的是焦点。当距离足够远,可以视为无限远时,我们直观上会发现,只要成像平面是欧几里德变换的,那么AC将不会改变,原因很简单,因为任何的旋转,平移对于无限远而言,都太过渺小,因此可以视为没有任何欧式变换能够影响这些性质。因此,我们知道
欧几里德变换不影响IAC的形状大小
c8ae34883297cca957e3ab93473cf0ab.png

Fig 6. 在无限远平面上的AC和在成像平面上的IAC。

我们为什么要在这里讨论这些概念呢?原因在于,不管是几何变换也好,三维重建也好,都会涉及到“变”与“不变”的量,当需要对某些变化的量约束到不变的量时,我们需要添加条件,比如固定住无限远平面的位置,固定AC的形状大小等,从而可以减少歧义性,实现更精确的三维重建。

层次化三维重建

通过在投影重建的基础上,添加一系列的信息,我们可以分别得到场景的仿射重建,相似性重建。

我们考虑双目三维重建的层次化过程。首先作为基础的,假设我们的相机是没有校准的,我们需要基于对应的两张图像之间的对应点,求得场景的投影重建后,再添加若干信息,可以分别得到场景的仿射重建,相似性重建。

对于未校准的相机而言,假设给定了两张图片之间的对应点

,通过式子(2)我们可以计算出基础矩阵
。通过之前的分析,我们知道存在投影矩阵
可以使得场景重建存在投影歧义性,如Fig 5所示。

需要注意的是,我们这里提到的对应点对不能在两台相机的焦点连线上(也就是基线),这个我们之前也提到过。

d0a8fa43c8914d735830ec68ae5c1b97.png

Fig 5. 投影重建带来的投影歧义性,对于单次重建来说,投影重建的每个可能的场景都是投影一致性的。

仿射重建

从投影重建到仿射重建,回忆下我们在[4]中曾经讨论的:

仿射变换不会影响无限远平面的位置

也就是说,为了消除投影歧义性,我们需要添加约束 固定 无限远平面的位置。用数学形式化地表达我们整个过程,假设我们现在已经有了一个对场景的投影重建结果,包括一个三元组

,其中
是相机矩阵,
为场景坐标点集。进一步假设我们确定平面
作为真正的无限远平面,那么这个平面将会用一个齐次坐标下的向量表示,有
。我们需要把这个平面挪到
去,因此需要找到一个投影矩阵,将
映射到
,也就是有:
。有:

此时的

可以作用在所有的三维重建后的点集和两个相机矩阵上,注意到,公式(5)将会在
的情况下失效。 通过求得这个投影矩阵,我们得到了
仿射重建

然而,正如我们说的,除非我们添加一些额外的信息,否则无限远平面

是不能确定下来的,我们接下来给出几个例子,说明什么类型的信息是足够确定这个平面的。

偏移运动

偏移运动 (Translational motion) 指的是我们已知拍摄出来的两张照片来自于同一个相机,只不过是这两张照片来自于不同的视角下拍摄的,而且这个视角变化只是由于相机矩阵的

也即是偏移造成的。简单来说,就是如Fig 6 所示,黄色平面就是只是存在平移的相机,而灰色平面则同时存在平移和旋转。
526144ec4a03feaa24bd0706c302f13c.png

Fig 6. 绿色物体为成像客体,黄色平面是只存在偏移变化的相机,而灰色平面则存在着偏移和旋转。

回忆下我们刚才提到的“月亮跟着我”的例子,对于无限远处的物体来说,只是存在平移变化,是不会影响该物体的位置的(因为平移的距离对比他们之间的距离来说,实在是微不足道)。因此,相机的平移不会影响两张照片中的处在无限远处平面的点的位置,让我们用

表示这个处在无限远处平面的点。如Fig 7所示,两幅图像的对极点位置在图像中的相机坐标系是一致的,就是因为相机的平移大小对于走廊的深度来说是微不足道的,因此可以视为是无限远平面,因此对极点不变。我们可以知道,投影形成这些不变点的三维空间点,是处在无限远处的,通过匹配点和图片的像素位置(通过两个条件,既是匹配点又是图片上不变的点去筛选),我们可以寻找得到三组以上的这种无限远处的点,并且通过最小二乘法或者解析法求出这个无限远处平面
e1d25e54675b66196fc7d519470ec8bb.png

Fig 7. 纯平移运动不会改变远处(可以视为无限远处)的对极点位置。

虽然这样原理上是可行的,但是实际上计算过程中存在较大的数值问题,事实上我们这样计算出的基础矩阵是一个反对称(skew-symmetric)矩阵,这意味着我们还需要对基础矩阵进行约束。 事实上,在实际中最常用的约束还是下面谈到的平行线约束。

平行线约束

我们知道仿射变换不改变平行线的平行性,而投影变换则可能会改变,那么根据这个知识,我们可以从场景中寻找三组以上的本应该在实际三维空间中平行,却因为投影的透视现象在图像中相交的平行线,将它们的交点视为是无限远处的点,因此可以确定出无限远处平面

f3a9cfaff016caf432530ec7c25715b3.png

Fig 8. 寻找场景中三组本应该在实际三维空间中平行,却在图像中因为存在透视而相交的平行线,它们的交点作为无限远处的点,可以确定出无限远处平面。

这个过程听起来挺理想,然而因为存在噪声,多组不同的平行线在图片中不一定会交于一个点,这个时候我们需要鲁棒估计进行数值问题上的求解,我们之后再讨论。

我们如果在认真观察Fig 8我们会发现,虽然仿射重建保留了平行性,但是却不保证正交性,因此图(b)的右下图其实是不能保证的,我们一般只能得到(b)的左下图,为了保证场景的正交性,我们要到度量重建中才会考虑。

线段比例

我们知道仿射变换是不会改变变换前后线段之间的比例,见[4]中的具体描述。这为我们计算无限远处的消失点(vanishing point)又提供了一种思路:我们可以通过引入真实三维世界中某个直线上的线段比例长度去确定消失点的位置,如Fig 9和Fig 10所示。具体的计算过程我们之后的博文进行介绍。

40b67a39dfe0b11308dbda7fbff3a4e1.png

Fig 9. 根据实际世界中的线段比例去计算消失点位置。

d8600572a206c1c1625b5760430dd9ac.png

Fig 10. 通过引入线段比例的先验知识,从而将投影歧义性消除。

无限单应性矩阵

一旦无限远处平面被确定下来,我们就确定了仿射重建,随后我们就有一个被称之为“无限单应性矩阵”(The infinite homography)的特殊矩阵。这个矩阵负责把两个相机的图像中的无限远处的消失点进行映射,是一个2D的单应性矩阵。假设相机

对应的拍摄的图片的消失点
对应在无限远处平面的客体点是
,然后假设该客体点在另一个相机
对应拍摄的图片的投影为
。那么这个无限单应性矩阵存在有以下性质:

假设我们知道两个相机矩阵

他们是符合仿射重建的相机矩阵,那么我们有无限单应性矩阵

。这个并不难证明得到,留个读者自证。结合其(6),我们有:

也即是说,通过寻找两个图片的对应的消失点对,我们可以计算得到无限单应性矩阵

。我们接下来可以对相机矩阵中的某一个进行标准化,因此(7)变化为:

此时

,也就是说,通过计算得到无限单应性矩阵,我们可以恢复从仿射重建的相机矩阵。

其中一个相机是仿射相机

假设我们确定两个相机之中的其中一个是仿射相机[10],当然,仿射相机只是对投影相机的一种近似,其近似的基本假设就是被拍摄物体的表面纹理深度对于拍摄的距离来说可以忽略不计,也就是[11]中所说的弱深度纹理,low-relief。我们知道仿射相机进行的是仿射变换,因此不会移动无限远处平面的位置,而且我们知道仿射相机的主平面(principle plane)就是无限远处平面,并且它就可以用相机矩阵的第三行向量表示。那么假设最简单的情况,我们把这个仿射相机的相机矩阵

标准化为
,第三行为
,因此要把这个无限远处平面固定到
,只需要:
  1. 同时简单地交换两个相机矩阵的最后两列;
  2. 同时交换每个三维客体点
    的最后两个坐标即可。

相似性重建/度量重建

我们知道在仿射变换中,变换前后无限远处平面的位置不变;我们也知道在相似性变换/度量变换中,变换前后位于无限远处平面上的绝对圆锥曲线AC的位置不变。基于此,我们从仿射重建中消除仿射歧义性,将结果提升到度量重建的依据就在于,如何固定绝对圆锥线AC的位置。 与此同时,因为绝对圆锥线

位于无限远处平面上,因此确定了AC的位置也就意味着确定了无限远处平面的位置。

回忆下我们在博文[5]中,曾经讨论过圆锥曲线和二次圆锥面的数学表达式,简单来说,我们知道,描述一个圆锥线可以表达为:

其中曲线上的点为

,圆锥线
为:

在实践当中,最简单的方法是考虑其中一幅图像中的IAC。IAC是AC在图像上的成像投影,因此是一个圆锥曲线。根据焦点的位置对IAC进行反向投影,就形成了一个圆锥,如Fig 6所示,这个圆锥交于无限远处平面,就形成了AC。我们需要注意的是,IAC是图像本身的一个性质,就像图像中的点,线条一样,不取决于某个特定的重建,因此其对于重建中的变换来说是不变的。

假设已知了仿射重建,其中某个相机矩阵为

,用这个相机成像得到的图像中的IAC为
,那么,度量重建可以由这个仿射重建进行某个3D变换后得到,变换矩阵为:

其中的

可以由Cholesky分解得到,我们有
,当然前提要保证
是正定的,否则不能进行Cholesky矩阵分解。该证明具体可见[1]。

由此可知,为了从仿射重建中升级得到度量重建,我们需要得知IAC的表达。为了得到这个表达,就像在仿射重建中的一样,我们需要从场景中引入某些约束。

从场景的正交性中得到的约束

假设现在有一对消失点

,这对消失点来自于图像中的本身应该正交的场景,比如Fig 8中的三张图,都选自房子场景中本身应该垂直的部分,我们计算出其交点即为消失点,找出其中一对消失点,因为消失点处在无限远平面上,而且度量变换不会影响正交性,因此我们有:

根据此我们可以计算出IAC的表达。

从内参数标定中得到约束

假设我们知道了相机内参数并且假设内参数矩阵为

,我们有
。我们从[6]中知道:

如果有

,那么有

如果有

,那么有

Reference

[1]. Hartley R, Zisserman A. Multiple view geometry in computer vision[M]. Cambridge university press, 2003. Chapter 10

[2]. https://blog.csdn.net/LoseInVain/article/details/102665911

[3]. https://blog.csdn.net/LoseInVain/article/details/102775734

[4]. https://blog.csdn.net/LoseInVain/article/details/104533575

[5]. https://blog.csdn.net/LoseInVain/article/details/104515839

[6]. https://blog.csdn.net/LoseInVain/article/details/102632940

[7]. https://blog.csdn.net/LoseInVain/article/details/102756630

[8]. http://www.cs.unc.edu/~marc/tutorial/node87.html

[9]. https://blog.csdn.net/richardzjut/article/details/10473051

[10]. https://blog.csdn.net/LoseInVain/article/details/102883243

[11]. https://blog.csdn.net/LoseInVain/article/details/102739778



推荐阅读
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • Coursera ML 机器学习
    2019独角兽企业重金招聘Python工程师标准线性回归算法计算过程CostFunction梯度下降算法多变量回归![选择特征](https:static.oschina.n ... [详细]
  • yikesnews第11期:微软Office两个0day和一个提权0day
    点击阅读原文可点击链接根据法国大选被黑客干扰,发送了带漏洞的文档Trumps_Attack_on_Syria_English.docx而此漏洞与ESET&FireEy ... [详细]
  • 由二叉树到贪心算法
    二叉树很重要树是数据结构中的重中之重,尤其以各类二叉树为学习的难点。单就面试而言,在 ... [详细]
  • 本文探讨了随着并发需求的增长,MySQL数据库架构如何从简单的单一实例发展到复杂的分布式系统,以及每一步演进背后的原理和技术解决方案。 ... [详细]
  • 丽江客栈选择问题
    本文介绍了一道经典的算法题,题目涉及在丽江河边的n家特色客栈中选择住宿方案。两位游客希望住在色调相同的两家客栈,并在晚上选择一家最低消费不超过p元的咖啡店小聚。我们将详细探讨如何计算满足条件的住宿方案总数。 ... [详细]
  • 本教程详细介绍了如何使用 TensorFlow 2.0 构建和训练多层感知机(MLP)网络,涵盖回归和分类任务。通过具体示例和代码实现,帮助初学者快速掌握 TensorFlow 的核心概念和操作。 ... [详细]
  • 本题探讨了在大数据结构背景下,如何通过整体二分和CDQ分治等高级算法优化处理复杂的时间序列问题。题目设定包括节点数量、查询次数和权重限制,并详细分析了解决方案中的关键步骤。 ... [详细]
  • 2018-2019学年第六周《Java数据结构与算法》学习总结
    本文总结了2018-2019学年第六周在《Java数据结构与算法》课程中的学习内容,重点介绍了非线性数据结构——树的相关知识及其应用。 ... [详细]
  • 本文介绍了SVD(奇异值分解)和QR分解的基本原理及其在Python中的实现方法。通过具体代码示例,展示了如何使用这两种矩阵分解技术处理图像数据和计算特征值。 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 为了解决不同服务器间共享图片的需求,我们最初考虑建立一个FTP图片服务器。然而,考虑到项目是一个简单的CMS系统,为了简化流程,团队决定探索七牛云存储的解决方案。本文将详细介绍使用七牛云存储的过程和心得。 ... [详细]
  • MainActivityimportandroid.app.Activity;importandroid.os.Bundle;importandroid.os.Handler;im ... [详细]
  • 本文提供了一个详细的PHP用户认证和管理的代码示例,包括用户登录验证、数据库连接、错误处理等关键部分的实现。 ... [详细]
  • 收割机|篇幅_国内最牛逼的笔记,不接受反驳!!
    收割机|篇幅_国内最牛逼的笔记,不接受反驳!! ... [详细]
author-avatar
-_-小欢欢-_-
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有