利用python实现AR教程


Posted in Python onNovember 20, 2019

先了解如何利用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平面上,原点在标记物的某个位置上。

从单应性推导出从参考面坐标系到目标图像坐标系的转换

在进行坐标转换之前,为了检验单应性矩阵结果的正确性,需要将一些三维物体放置在目标图像上,本实验使用了一个立方体。产生立方体的代码如下:

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')

实验结果如下

利用python实现AR教程

什么是AR

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

它是一种将真实世界信息和虚拟世界信息“无缝”集成的新技术,是把原本在现实世界的一定时间空间范围内很难体验到的实体信息(视觉信息,声音,味道,触觉等),通过电脑等科学技术,模拟仿真后再叠加,将虚拟的信息应用到真实世界,被人类感官所感知,从而达到超越现实的感官体验。真实的环境和虚拟的物体实时地叠加到了同一个画面或空间同时存在。

增强现实技术,不仅展现了真实世界的信息,而且将虚拟的信息同时显示出来,两种信息相互补充、叠加。在视觉化的增强现实中,用户利用头盔显示器,把真实世界与电脑图形多重合成在一起,便可以看到真实的世界围绕着它。

增强现实技术包含了多媒体、三维建模、实时视频显示及控制、多传感器融合、实时跟踪及注册、场景融合等新技术与新手段。增强现实提供了在一般情况下,不同于人类可以感知的信息。

如何利用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")

实验结果如图:

利用python实现AR教程

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

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

原因:经大神指点得知这个错误是freeglut和glut共存的缘故,它们俩定义了相同的方法,这个是动态链接库的重叠问题,我的在ana\Lib\site-packages\OpenGL\DLLS文件夹里面。

利用python实现AR教程

你需要删除freeglut.vc15.dll这个文件。我这是已经删除完的样子。

以上这篇利用python实现AR教程就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
二种python发送邮件实例讲解(python发邮件附件可以使用email模块实现)
Dec 03 Python
python time模块用法实例详解
Sep 11 Python
Python 专题六 局部变量、全局变量global、导入模块变量
Mar 20 Python
python使用Flask操作mysql实现登录功能
May 14 Python
Python实用技巧之列表、字典、集合中根据条件筛选数据详解
Jul 11 Python
python并发和异步编程实例
Nov 15 Python
Python3调用百度AI识别图片中的文字功能示例【测试可用】
Mar 13 Python
python绘制地震散点图
Jun 18 Python
windows下python安装pip方法详解
Feb 10 Python
Python 统计位数为偶数的数字代码详解
Mar 15 Python
python3.6.8 + pycharm + PyQt5 环境搭建的图文教程
Jun 11 Python
Python中递归以及递归遍历目录详解
Oct 24 Python
使用python实现画AR模型时序图
Nov 20 #Python
Python笔记之工厂模式
Nov 20 #Python
Python常用模块logging——日志输出功能(示例代码)
Nov 20 #Python
将python2.7添加进64位系统的注册表方式
Nov 20 #Python
10个Python面试常问的问题(小结)
Nov 20 #Python
python使用pip安装SciPy、SymPy、matplotlib教程
Nov 20 #Python
Python笔记之facade模式
Nov 20 #Python
You might like
php正则过滤html标签、空格、换行符的代码(附说明)
2010/10/25 PHP
PHP获取当前所在目录位置的方法
2014/11/26 PHP
php实现粘贴截图并完成上传功能
2015/05/17 PHP
laravel自定义分页效果
2017/07/23 PHP
jquery zTree异步加载简单实例分享
2013/02/05 Javascript
JS中的prototype与面向对象的实例讲解
2013/05/22 Javascript
script不刷新页面的联动前后代码
2013/09/18 Javascript
基于jQuery的判断iPad、iPhone、Android是横屏还是竖屏的代码
2014/05/11 Javascript
Javascript动态引用CSS文件的2种方法介绍
2014/06/06 Javascript
jQuery实现锚点scoll效果实例分析
2015/03/10 Javascript
jQuery实现高亮显示网页关键词的方法
2015/08/07 Javascript
不能不知道的10个angularjs英文学习网站
2016/03/23 Javascript
对jquery的ajax进行二次封装以及ajax缓存代理组件:AjaxCache详解
2016/04/11 Javascript
微信小程序使用video组件播放视频功能示例【附源码下载】
2017/12/08 Javascript
JS求Number类型数组中最大元素方法
2018/04/08 Javascript
详解webpack 最简打包结果分析
2019/02/20 Javascript
利用Vconsole和Fillder进行移动端抓包调试方法
2019/03/05 Javascript
layer弹窗在键盘按回车将反复刷新的实现方法
2019/09/25 Javascript
Vue2.0 实现页面缓存和不缓存的方式
2019/11/12 Javascript
vue+vant 上传图片需要注意的地方
2021/01/03 Vue.js
Python socket C/S结构的聊天室应用实现
2014/11/30 Python
基于python(urlparse)模板的使用方法总结
2017/10/13 Python
PyQt5每天必学之创建窗口居中效果
2018/04/19 Python
Python开发网站目录扫描器的实现
2019/02/21 Python
python3.7 利用函数os pandas利用excel对文件名进行归类
2019/09/29 Python
python实现图片上添加图片
2019/11/26 Python
Tensorflow分批量读取数据教程
2020/02/07 Python
python库skimage给灰度图像染色的方法示例
2020/04/27 Python
keras实现theano和tensorflow训练的模型相互转换
2020/06/19 Python
用纯css3和html制作泡沫对话框实现代码
2013/03/21 HTML / CSS
CSS3图片旋转特效(360/60/-360度)
2013/10/10 HTML / CSS
中学教师岗位职责
2013/11/26 职场文书
办公室前台的岗位职责
2013/12/20 职场文书
html实现随机点名器的示例代码
2021/04/02 Javascript
如何用Node.js编写内存效率高的应用程序
2021/04/30 Javascript
Mongo服务重启异常问题的处理方法
2021/07/01 MongoDB