最近在做双目视觉和三维重构,这是这段时间的劳动成果,放上来与大家分享,算是给大家新年的祝福,新年快乐!
这是一组工具,可以一步步实现一个不成熟的三维书写系统。
因为有一组视频数据,所以放到了Google Code,程序源码及样本数据都有。
项目地址:https://github.com/zhijie/3d-reconstruction-tools
最最终效果演示:http://v.youku.com/v_show/id_XMjMzNjk1ODAw.html
下面对几个工具做一个简单的介绍
0.TestImageGenerate
这个工具本意是用以产生三维视图中的简单物体图像,因为已知参数,可以检测标定处理的结果是否准确
但效果不好,仅当一个编程练习吧。mfc dialog+OpenGL
1.ChessboardImageGenerator
用于产生指定的棋盘图片,做标定时要用各种图像,棋盘是最常用的。有这个工具就不用去画了,棋盘虽然简单,但用画图画起来还是挺麻烦的
一个例子
2.ImageSampler
同时从两个摄像头采集图像并保存
3.VideoRecorder
同时从两个摄像头采集视频并保存为AVI
4.ChessboardCornerFinder
找到棋盘图像的各个角点,并产生画出角点的图像,而且保持角点位置到文件
右左
保存文件
%YAML:1.0 corners: !!opencv-matrix rows: 5 cols: 5 dt: "2f" data: [ 4.17272705e+002, 1.75255142e+002, 4.31500977e+002, 2.02935883e+002, 4.46574158e+002, 2.32363037e+002, 4.62359070e+002, 2.63098419e+002, 4.78908142e+002, 2.95410950e+002, 3.80886353e+002, 1.83497772e+002, 3.94665009e+002, 2.12001999e+002, 4.08767578e+002, 2.41773132e+002, 4.24090820e+002, 2.73374176e+002, 4.39639160e+002, 3.06546814e+002, 3.43771973e+002, 1.91936478e+002, 3.56431946e+002, 2.21002151e+002, 3.70125458e+002, 2.51641098e+002, 3.84296082e+002, 2.83781769e+002, 3.99276398e+002, 3.17960083e+002, 3.05803040e+002, 2.00590103e+002, 3.17759430e+002, 2.30394577e+002, 3.30348572e+002, 2.61634338e+002, 3.43624207e+002, 2.94604675e+002, 3.57753021e+002, 3.29424622e+002, 2.67154572e+002, 2.09574173e+002, 2.77988983e+002, 2.39880447e+002, 2.89649658e+002, 2.71787109e+002, 3.02015778e+002, 3.05513947e+002, 3.15142517e+002, 3.41069122e+002 ]
5.GetFingerPos
提取视频中每一帧图像的手指顶点的位置,并保存到文件
重要说明,目前,手指顶点的检测方法为肤色检测,找到手的区域后,假设y值最大的即为顶点。这个假设的基础是,在录制视频时,手的运动主要为平移,没有大的旋转。在视频中可以发现这个特点。这是目前简化处理的一个手段,但仍不失现实意义
看截图就知道了
为了增加手指定位的准确度,黄色的家用橡胶手套都用上了。这样效果更好,但在后期,还将提高裸手识别准确度,以代替别的辅助设备
6.CalibrateFromPoints
从棋盘角点数据文件进行标定,并保存结果
%YAML:1.0 intrinsic: !!opencv-matrix rows: 3 cols: 3 dt: f data: [ 2.07965546e+001, 0., 3.18873016e+002, 0., 1.62356453e+001, 2.39203979e+002, 0., 0., 1. ] distortion: !!opencv-matrix rows: 1 cols: 4 dt: f data: [ -8.27514123e-006, -1.16699221e-006, -2.67242605e-004, 4.39708587e-004 ] rotate0: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ 3.09123230e+000, -4.70028162e-001, 8.03785864e-003 ] translate0: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ -2.49148388e+001, 1.37777328e+002, 1.45024853e+001 ] rotate1: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ 3.09123230e+000, -4.70028162e-001, 8.03785864e-003 ] translate1: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ -2.49148388e+001, 1.37777328e+002, 1.45024853e+001 ] rotate2: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ 3.09123230e+000, -4.70028162e-001, 8.03785864e-003 ] translate2: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ -2.49148388e+001, 1.37777328e+002, 1.45024853e+001 ] rotate3: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ 3.09123230e+000, -4.70028162e-001, 8.03785864e-003 ] translate3: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ -2.49148388e+001, 1.37777328e+002, 1.45024853e+001 ] rotate4: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ 3.09123230e+000, -4.70028162e-001, 8.03785864e-003 ] translate4: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ -2.49148388e+001, 1.37777328e+002, 1.45024853e+001 ] rotate5: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ 3.09123230e+000, -4.70028162e-001, 8.03785864e-003 ] translate5: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ -2.49148388e+001, 1.37777328e+002, 1.45024853e+001 ] rotate6: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ 3.09123230e+000, -4.70028162e-001, 8.03785864e-003 ] translate6: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ -2.49148388e+001, 1.37777328e+002, 1.45024853e+001 ] rotate7: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ 3.09123230e+000, -4.70028162e-001, 8.03785864e-003 ] translate7: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ -2.49148388e+001, 1.37777328e+002, 1.45024853e+001 ] rotate8: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ 3.09123230e+000, -4.70028162e-001, 8.03785864e-003 ] translate8: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ -2.49148388e+001, 1.37777328e+002, 1.45024853e+001 ] rotate9: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ 3.09123230e+000, -4.70028162e-001, 8.03785864e-003 ] translate9: !!opencv-matrix rows: 1 cols: 3 dt: f data: [ -2.49148388e+001, 1.37777328e+002, 1.45024853e+001 ]
7.Show3dPoints
这是最后一步,也是演示视频中用到的工具
使用在两个视频中找到的手指顶点和之前保存的 标定参数,进行重构,并显示。
运行效果截图:
1.这是画的五角星重构后的不同视角截图
2.下面是我写的字“01s”,我的网名简写
同时这个工具可以把重构后的点还原到左右视图中
但目前有一个问题,就是还原后左右视图中有一个总是错误,如图
1.五角星的左右视图还原
2.“01s”的还原
我将在后续工作中改正之。
看这几张图像时注意,我画的时候是面对摄像头的,而这些图像是摄像头的视角,所以是反的
================================================================================
为了方便大家运行改程序,在程序源码的各个文件夹中都有简单的运行方法说明。在运行时请注意查看源码,几个工具的代码都有读入之前工具产生的数据文件或视频或图像,这就会有一个路径问题,可以根据自己的情况,只需修改路径即可。
你下载的程序都可直接运行,目录结构已经经过特意安排。在看到读入文件错误时,请查看源码,注意路径。
另外注意把下载的视频放到程序解压后文件夹的data/videos中
------------------------------------------------------------------------------------------------------------------------------------
这一组工具组成了完整的一个系统,也代表三维书写或相关系统的一个处理过程
简单重复一遍:
1.做标定板,放置摄像头(ChessboardImageGenerator)
2.采集棋盘图像用以标定(ImageSampler)
3.录制视频(VideoRecorder)(以后如果做成完整的系统,就不用录制了,可以进行实时处理,录制视频也是为了方便做试验)
4.找到棋盘图像的角点(ChessboardCornerFinder)
5.摄像头标定(CalibrateFromPoints)
6.找到视频中手指的位置(GetFingerPos)
7.重构并显示(Show3dPoints)
===============================================================================
我的试验环境
标定板,把产生的棋盘打印出来就成:
右左
相关文章链接:
手势控制鼠标进行操作的方法和源码
基于动态手势识别的酷狗音乐播放器控制
sift图像特征提取与匹配算法代码