Python实现AR增强现实:从姿态估计到3D模型投影实战

落日邮差
落日邮差
发布时间:2026-10-13| 5人浏览过
原创

本文详解如何利用Python实现增强现实(AR)基础功能。通过SIFT算法提取图像特征并计算单应性矩阵,完成参考平面到目标图像的映射。结合相机标定与RANSAC算法推导空间变换,最终使用PyOpenGL将3D立方体或茶壶模型实时投影叠加至真实场景,并解决常见依赖库冲突问题。

Python AR基础与姿态估计概述

首先掌握如何使用Python语言进行基于平面和标记物的姿态估计。

本实验旨在实现一个基础示例:首先识别图像中的参考平面,随后拍摄目标图像,并将参考平面上方的3D模型投影至目标图像中。

主要实施步骤如下:

参考平面识别与单应性矩阵计算

识别参考平面

此步骤的核心任务是提取参考图像与目标图像的SIFT特征,随后利用RANSAC算法稳健地估算单应性矩阵。

具体实现代码如下:


#计算特征
sift.process_image('D:输入图片/book_frontal.JPG', 'im0.sift')
l0, d0 = sift.read_features_from_file('im0.sift')

sift.process_image('D:输入图片/book_per.JPG', 'im1.sift')
l1, d1 = sift.read_features_from_file('im1.sift')

#匹配特征,并计算单应性矩阵
matches = sift.match_twosided(d0, d1)
ndx = matches.nonzero()[0]
fp = homography.make_homog(l0[ndx, :2].T)
ndx2 = [int(matches[i]) for i in ndx]
tp = homography.make_homog(l1[ndx2, :2].T)

model = homography.RansacModel()
H, inliers = homography.H_from_ransac(fp, tp, model)

上述代码输出的单应性矩阵,负责将一幅图像中标记物的点映射至另一幅图像的对应点。同时需建立X-Y(Z=0)三维坐标系,设定标记物位于Z=0平面,原点置于标记物的特定位置。

坐标系转换与3D模型投影验证

从单应性矩阵推导参考面坐标系至目标图像坐标系的转换关系

在实施坐标转换前,为验证单应性矩阵结果的准确性,需在目标图像上放置若干三维物体,本实验选用立方体作为验证对象。生成该立方体的代码示例如下:


def cube_points(c, wid):

  p = []
  p.append([c[0]-wid, c[1]-wid, c[2]-wid])
  p.append([c[0]-wid, c[1]+wid, c[2]-wid])
  p.append([c[0]+wid, c[1]+wid, c[2]-wid])
  p.append([c[0]+wid, c[1]-wid, c[2]-wid])
  p.append([c[0]-wid, c[1]-wid, c[2]-wid])

  p.append([c[0]-wid, c[1]-wid, c[2]+wid])
  p.append([c[0]-wid, c[1]+wid, c[2]+wid])
  p.append([c[0]+wid, c[1]+wid, c[2]+wid])
  p.append([c[0]+wid, c[1]-wid, c[2]+wid])
  p.append([c[0]-wid, c[1]-wid, c[2]+wid])

  p.append([c[0]-wid, c[1]-wid, c[2]+wid])
  p.append([c[0]-wid, c[1]+wid, c[2]+wid])
  p.append([c[0]-wid, c[1]+wid, c[2]-wid])
  p.append([c[0]+wid, c[1]+wid, c[2]-wid])
  p.append([c[0]+wid, c[1]+wid, c[2]+wid])
  p.append([c[0]+wid, c[1]-wid, c[2]+wid])
  p.append([c[0]+wid, c[1]-wid, c[2]-wid]

 return array(p).T

计算出相机标定矩阵后,即可得出两个视图间的相对变换关系。

相关代码如下:


#计算照相机标定矩阵,使用图像的分辨率为747*1000
K = my_calibration((747, 1000))

#位于边长为0.2,Z=0平面上的三维点
box = cube_points([0, 0, 0.1], 0.1)

#投影第一幅图像上底部的正方形
cam1 = camera.Camera(hstack((K, dot(K, array([[0], [0], [-1]])))))
#底部正方形上的点
box_cam1 = cam1.project(homography.make_homog(box[:, :5]))

#使用H将点变换到第二幅图像上
box_trans = homography.normalize(dot(H,box_cam1))

#从cam1和H中计算第二个照相机矩阵
cam2 = camera.Camera(dot(H, cam1.P))
A = dot(linalg.inv(K), cam2.P[:, :3])
A = array([A[:, 0], A[:, 1], cross(A[:, 0], A[:, 1])]).T
cam2.P[:, :3] = dot(K, A)

#使用第二个照相机矩阵投影
box_cam2 = cam2.project(homography.make_homog(box))

在图像(像素空间)中对3D模型进行投影并绘制显示。


#底部正方形的二维投影
figure()
imshow(im0)
plot(box_cam1[0, :], box_cam1[1, :], linewidth=3)
title('2D projection of bottom square')
axis('off')

#使用H对二维投影进行变换
figure()
imshow(im1)
plot(box_trans[0, :], box_trans[1, :], linewidth=3)
title('2D projection transfered with H')
axis('off')

#三维立方体
figure()
imshow(im1)
plot(box_cam2[0, :], box_cam2[1, :], linewidth=3)
title('3D points projected in second image')
axis('off')

实验最终效果如图所示。

增强现实(AR)技术原理

什么是AR

AR全称为Augmented Reality,即增强现实技术。

该技术是一种将真实世界信息与虚拟世界信息“无缝”集成的新技术。它通过计算机科学技术,对现实世界中难以直接体验的实体信息(如视觉、声音、味道、触觉等)进行模拟仿真,再将虚拟信息叠加到真实世界中,通过人类感官感知,从而获得超越现实的体验。真实环境与虚拟物体在同一画面或空间中实时共存。

增强现实技术不仅展示真实世界信息,还同时显示虚拟信息,两者相互补充、叠加。在视觉化增强现实中,用户利用头盔显示器,将真实世界与计算机图形多重合成,即可看到被虚拟物体环绕的真实世界。

增强现实技术融合了多媒体、三维建模、实时视频显示及控制、多传感器融合、实时跟踪及注册、场景融合等多项新技术与新手段,提供了常规情况下人类无法直接感知的信息。

Python实现AR的完整流程与报错处理

如何利用Python实现AR

其步骤与姿态估计的实现差异不大。基于前述内容计算出相机的位置和姿态后,利用这些信息放置计算机图形学模型。在本例中,我们放置了一个红色的小茶壶。

在运行代码前,需安装PyGame和PyOpenGL库,下载链接为(https://www.lfd.uci.edu/~gohlke/pythonlibs/)。

核心实现代码如下:


def set_projection_from_camera(K): 
#从照相机标定矩阵中获得视图

 glMatrixMode(GL_PROJECTION) 
 glLoadIdentity()
 fx = K[0,0] 
 fy = K[1,1] 
 fovy = 2*math.atan(0.5*height/fy)*180/math.pi 
 aspect = (width*fy)/(height*fx)
 near = 0.1 
 far = 100.0
 gluPerspective(fovy,aspect,near,far) 
 glViewport(0,0,width,height)

def set_modelview_from_camera(Rt): 
#从照相机姿态中获取模拟视图矩阵

 glMatrixMode(GL_MODELVIEW) 
 glLoadIdentity()
 Rx = np.array([[1,0,0],[0,0,-1],[0,1,0]])
 R = Rt[:,:3] 
 U,S,V = np.linalg.svd(R) 
 R = np.dot(U,V) 
 R[0,:] = -R[0,:]
 t = Rt[:,3]
 M = np.eye(4) 
 M[:3,:3] = np.dot(R,Rx) 
 M[:3,3] = t
 M = M.T
 m = M.flatten()
 glLoadMatrixf(m)

def draw_background(imname):
#使用四边形绘制背景图像

 bg_image = pygame.image.load(imname).convert() 
 bg_data = pygame.image.tostring(bg_image,"RGBX",1)
 glMatrixMode(GL_MODELVIEW) 
 glLoadIdentity()

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
 glEnable(GL_TEXTURE_2D) 
 glBindTexture(GL_TEXTURE_2D,glGenTextures(1)) 
 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,bg_data) 
 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST) 
 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST)
 glBegin(GL_QUADS) 
 glTexCoord2f(0.0,0.0); glVertex3f(-1.0,-1.0,-1.0) 
 glTexCoord2f(1.0,0.0); glVertex3f( 1.0,-1.0,-1.0) 
 glTexCoord2f(1.0,1.0); glVertex3f( 1.0, 1.0,-1.0) 
 glTexCoord2f(0.0,1.0); glVertex3f(-1.0, 1.0,-1.0) 
 glEnd()
 glDeleteTextures(1)

def draw_teapot(size):
#在原点处绘制红色茶壶

 glEnable(GL_LIGHTING) 
 glEnable(GL_LIGHT0) 
 glEnable(GL_DEPTH_TEST) 
 glClear(GL_DEPTH_BUFFER_BIT)
 glMaterialfv(GL_FRONT,GL_AMBIENT,[0,0,0,0]) 
 glMaterialfv(GL_FRONT,GL_DIFFUSE,[0.5,0.0,0.0,0.0]) 
 glMaterialfv(GL_FRONT,GL_SPECULAR,[0.7,0.6,0.6,0.0]) 
 glMaterialf(GL_FRONT,GL_SHININESS,0.25*128.0) 
 glutSolidTeapot(size)

width,height = 1000,747
def setup():
 pygame.init() 
 pygame.display.set_mode((width,height),OPENGL | DOUBLEBUF) 
 pygame.display.set_caption("OpenGL AR demo")  

实验运行结果如图所示:

运行代码时可能遇到的错误及解决方案

可能出现的错误如下:An error ocurred while starting the kernelfreeglut ERROR: Function called without first calling ‘glutInit'.

原因分析:经专家指点,该错误源于freeglut与glut共存导致的动态链接库重叠问题,两者定义了相同的方法。该冲突文件位于ana\Lib\site-packages\OpenGL\DLLS文件夹内。

解决方法:需删除freeglut.vc15.dll文件。删除后的文件状态如图所示。

以上即为利用Python实现AR的完整教程,希望能为读者提供参考,并欢迎大家继续支持本站。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。