通过kinect实现3d扫描建立打印模型(processing、skanect、ReconstructMe)

http://www.sigvc.org/bbs/thread-722-1-1.html


在本文中将详细梳理使用Kinect进行3d扫描的过程,一共包含3种实现方法:processing编程实现、skanect软件实现、ReconstructMe软件实现。RecontructMe只能基于32位系统的驱动与kinect连接,而skanect与processing不论是32位还是64位都可以较好的兼容。

Comparison of ReconstructMe, KinectFusion and Skanect:



我们首先来看ReconstructMe:
ReconstructMe是基于32位系统的,但是在64位操作系统下仍旧使用32位的kinect驱动以及ReconstructMe。
ReconstructMe官方网址:http://reconstructme.net/
官网中针对不同的用户,有免费版以及收费版两种软件,具体下载地址为:http://reconstructme.net/projects/reconstructme-console/
下载完成以后,先不要安装,在安装ReconstructMe之前我们首先需要安装Kinect的驱动,具体步骤如下:


  • 下载32位openni驱动包,下载地址:
Dropbox下载地址:
https://www.dropbox.com/s/n55mr8q1j0nzyru/Sensor%20Driver%20Package%
20×86%201.5.2.zip
坚果云下载地址:
https://jianguoyun.com/c/pubfile/uGqA8e_Y18lRqUluPrFMdXnCzq3o0ko9_Eh_5yDu-3U
2.解压驱动包,首先安装OpenNI,再然后是SensorKinect,然后是SensorPrimesense。(在安装之前,一定要把原来kinect的驱动卸载掉)
3.全部安装完成以后,重启
4.将你的Kinect连接上电脑,可以通过查看控制面板中的设备管理器,检查你的电脑是否已 经识别Kinect.
8351452160_ed770105d7_z.jpg  
5.确认Kinect已经能和电脑通信之后,安装下载好的ReconstructMe,安装完以后运行目录中的Start ReconstructMe Scan OpenNI.bat,注意不是ReconstructMe.exe。然后根据提示进行操作即可
附图:
8350394557_08557b1c61_z.jpg  


接下来是通过skanect进行3d扫描

Skanect官方网址: http://skanect.manctl.com
下载地址: http://manctl.com/products.html (页面中含有详细的安装步骤,但是一些链接已经失效,在后面的安装步骤中含有其他下载链接)
详细安装步骤:

  • 下载skanect
  • 下载kinect驱动包:
Dropbox下载地址:
https://www.dropbox.com/s/734160v5imqyd5d/kinect%20driver%20package%20for%2064bit.zip
坚果云下载地址:
https://jianguoyun.com/c/pubfile/sm_vNwOtndapU8ya3p46l6BXj-ujPkDmnt7JrTnhjoc
3. 下载完驱动包以后,首先安装OpenNI,然后是NITE,再然后是sensor(此文件也就是Primesense),最后是SensorKinect.
4.把kinect通过USB连接到电脑,检查控制面板中的设备管理器,判断是否已经连接成功。
5.安装skanect并运行skanect.exe
( 备注
1. 若基于32位操作系统,当使用skanect应下载之前ReconstructMe的所需的驱动,并附加NITE(具体安装顺序如上所示):
dropbox下载: https://www.dropbox.com/s/alvz98xzchlhlqj/NITE-Win32-1.5.2.21-Dev.zip
坚果云下载:
https://jianguoyun.com/c/pubfile/pw4suN5cAEsSIyTDyMGLaoAIw3Dfc6baECBR_1udBkY
2. 若运行skanect时,提示未查找到openni.dll则需根据你安装的目录找到openni.dll并复制到system32中!)
附图:
8350401023_e880009539_z.jpg  


最后一种方法是通过processing编程实现
,对于使用过Processing或者java的人比较适用。虽然自己之前没有接触过java,但还是尝试了一下,欢迎大家一起折腾,具体步骤:

  • 首先还是需要安装Kinect的驱动(本人亲测为安装64位的驱动,如果你使用的操作系统是32位的还需安装NITE,因为后面调用processing库是需使用到)
  • Processing的simple-openni库下载及安装:
http://code.google.com/p/simple-openni/downloads/list
(木有接触过processing的,百度一下即可找到,下载该软件并根据官网指示了解如何安装库文件)
3.Coding!
Processing代码:

普通浏览 复制代码
  1. import processing.opengl.* ;
  2. import SimpleOpenNI.* ;
  3. import kinectOrbit.* ;
  4. KinectOrbit myOrbit ;
  5. SimpleOpenNI kinect ;
  6. String turnTableAngle  =  "0" ;
  7. ArrayList scanPoints  =  new ArrayList ( ) ;  // PointCloud
  8. ArrayList scanColors  =  new ArrayList ( ) ;  // Object Colors
  9. ArrayList objectPoints  =  new ArrayList ( ) ;  // PointCloud
  10. ArrayList objectColors  =  new ArrayList ( ) ;  // Object Colors
  11. float baseHeight  =    ;  // Height of the Model's base//1
  12. float modelWidth  =     ; //2
  13. float modelHeight  =     ; //3
  14. PVector axis  =  new PVector ( 0, baseHeight,    ) ; //4
  15. int scanLines  =  200 ;
  16. int scanRes  =  1 ;
  17. float [ ] shotNumber  =  new  float [ 3 ] ;
  18. int currentShot  =  0 ;
  19. public  void setup ( )
  20. {
  21.   size ( 800600, OPENGL ) ;
  22.    // Orbit
  23.   myOrbit  =  new KinectOrbit ( this0"kinect" ) ;
  24.   myOrbit.drawCS ( true ) ;
  25.   myOrbit.drawGizmo ( true ) ;
  26.   myOrbit.setCSScale (   ) ; //5
  27.   myOrbit.drawGround ( true ) ;
  28.    // Simple-openni
  29.   kinect  =  new SimpleOpenNI ( this ) ;
  30.   kinect.setMirror ( false ) ;
  31.   kinect.enableDepth ( ) ;
  32.   kinect.enableRGB ( ) ;
  33.   kinect.alternativeViewPointDepthToImage ( ) ;
  34.    for  ( int i  =  0 ; i < shotNumber.length ; i++ ) 
  35.   {
  36.     shotNumber<i>  = i *  ( 2 * PI ) / shotNumber.length ;
  37.   }
  38. }
  39. public  void draw ( ) 
  40. {
  41.   kinect.update ( ) ;  // Update Kinect data
  42.   background ( 0 ) ;
  43.   myOrbit.pushOrbit ( this ) ;  // Start Orbiting
  44.   drawPointCloud ( 5 ) ;
  45.   updateObject (scanLines, scanRes ) ;
  46.    if (currentShot> 0&¤tShot< 4 )
  47.   {
  48.     scan ( ) ;
  49.   }
  50.   drawObjects ( ) ;
  51.   drawBoundingBox ( ) ;  // Draw Box Around Scanned Objects
  52.   kinect.drawCamFrustum ( ) ;  // Draw the Kinect cam
  53.   myOrbit.popOrbit ( this ) ;  // Stop Orbiting
  54. }
  55. void drawPointCloud ( int steps )
  56. {
  57.    // draw the 3D point depth map
  58.    int index ;
  59.   PVector realWorldPoint ;
  60.   stroke ( 255 ) ;
  61.    for  ( int y  =  0 ; y < kinect.depthHeight ( ) ; y + = steps )
  62.   {
  63.      for  ( int x  =  0 ; x < kinect.depthWidth ( ) ; x + = steps )
  64.     {
  65.       index  = x + y * kinect.depthWidth ( ) ;
  66.       realWorldPoint  = kinect.depthMapRealWorld ( ) [index ] ;
  67.       stroke ( 150 ) ;
  68.       point (realWorldPoint.x, realWorldPoint.y, realWorldPoint.z ) ;
  69.     }
  70.   }
  71. }
  72. void drawObjects ( )
  73. {
  74.   pushStyle ( ) ;
  75.   strokeWeight ( 4 ) ;
  76.    for  ( int i  =  1 ; i < objectPoints.size ( ) ; i++ )
  77.   {
  78.     stroke (objectColors.get (i ).x, objectColors.get (i ).y, objectColors.get (i ).z ) ;
  79.     point (objectPoints.get (i ).x, objectPoints.get (i ).y, objectPoints.get (i ).z + axis.z ) ;
  80.   }
  81.    for  ( int i  =  1 ; i < scanPoints.size ( ) ; i++ )
  82.   {
  83.     stroke (scanColors.get (i ).x, scanColors.get (i ).y, scanColors.get (i ).z ) ;
  84.     point (scanPoints.get (i ).x, scanPoints.get (i ).y, scanPoints.get (i ).z + axis.z ) ;
  85.   }
  86.   popStyle ( ) ;
  87. }
  88. void drawBoundingBox ( )
  89. {
  90.   stroke ( 25500 ) ;
  91.   line (axis.x, axis.y, axis.z, axis.x, axis.y +  100, axis.z ) ;
  92.   noFill ( ) ;
  93.   pushMatrix ( ) ;
  94.   translate (axis.x, axis.x + baseHeight + modelHeight /  2, axis.z ) ;
  95.   box (modelWidth, modelHeight, modelWidth ) ;
  96.   popMatrix ( ) ;
  97. }
  98. void scan ( )
  99. {
  100.    for  (PVector v : scanPoints )
  101.   {
  102.     boolean newPoint  =  true ;
  103.      for  (PVector w : objectPoints )
  104.     {
  105.        if  (v.dist (w ) <  1 )
  106.       newPoint  =  false ;
  107.     }
  108.      if  (newPoint )
  109.     {
  110.       objectPoints.add (v.get ( ) ) ;
  111.        int index  = scanPoints.indexOf (v ) ;
  112.       objectColors.add (scanColors.get (index ).get ( ) ) ;
  113.     }
  114.   }
  115. }
  116. void updateObject ( int scanWidth,  int step )
  117. {
  118.    int index ;
  119.   PVector realWorldPoint ;
  120.   scanPoints.clear ( ) ;
  121.   scanColors.clear ( ) ;
  122.    float angle = (currentShot-1 )*2*PI/ 3 ;
  123.   rotateY (angle ) ;
  124.   line ( 0, 0, 100, 0 ) ; //draw a line at the base of the bounding box to indicate the rotation
  125.    int xMin  =  ( int )  (kinect.depthWidth ( ) /  2 - scanWidth /  2 ) ;
  126.    int xMax  =  ( int )  (kinect.depthWidth ( ) /  2 + scanWidth /  2 ) ;
  127.    for  ( int y  =  0 ; y < kinect.depthHeight ( ) ; y + = step )
  128.   {
  129.      for  ( int x  = xMin ; x < xMax ; x + = step )
  130.     {
  131.       index  = x +  (y * kinect.depthWidth ( ) ) ;
  132.       realWorldPoint  = kinect.depthMapRealWorld ( ) [index ] ;
  133.       color pointCol  = kinect.rgbImage ( ).pixels [index ] ;
  134.        if  (realWorldPoint.y < modelHeight + baseHeight && realWorldPoint.y > baseHeight )
  135.       {
  136.          if  ( abs (realWorldPoint.x - axis.x ) < modelWidth /  2 )
  137.         {  // Check x
  138.            if  (realWorldPoint.z < axis.z + modelWidth /  2 && realWorldPoint.z > axis.z -modelWidth /  2 )
  139.           {  // Check z
  140.             PVector rotatedPoint ;
  141.             realWorldPoint.z - = axis.z ;
  142.             realWorldPoint.x - = axis.x ;
  143.             rotatedPoint  = vecRotY (realWorldPoint, angle ) ;
  144.             scanPoints.add (rotatedPoint.get ( ) ) ;
  145.             scanColors.add ( new PVector (red (pointCol ), green (pointCol ), blue (pointCol ) ) ) ;
  146.           }
  147.         }
  148.       }
  149.     }
  150.   }
  151. }
  152. PVector vecRotY (PVector vecIn,  float phi )
  153. {
  154.    // Rotate the vector around the y-axis
  155.   PVector rotatedVec  =  new PVector ( ) ;
  156.   rotatedVec.x  = vecIn.x *  cos (phi ) - vecIn.z *  sin (phi ) ;
  157.   rotatedVec.z  = vecIn.x *  sin (phi ) + vecIn.z *  cos (phi ) ;
  158.   rotatedVec.y  = vecIn.y ;
  159.    return rotatedVec ;
  160. }
  161. public  void keyPressed ( ) {
  162.    switch (key )
  163.   {
  164.      case  's':
  165.     currentShot++ ;
  166.      break ;
  167.      case  'c'// Clear the object points
  168.     objectPoints.clear ( ) ;
  169.     objectColors.clear ( ) ;
  170.     currentshot = 0 ;
  171.      break ;
  172.      case  'e'// Export the object points
  173.     exportPly ( '0' ) ;
  174.      break ;
  175.      case  '+'// Increment the number of scanned lines
  176.     scanLines++ ;
  177.     println (scanLines ) ;
  178.      break ;
  179.      case  '-'// Decrease the number of scanned lines
  180.     scanLines-- ;
  181.     println (scanLines ) ;
  182.      break ;
  183.   }
  184. }



代码下载地址:
Dropbox下载:https://www.dropbox.com/s/90fttmvheag2k2r/scan.pde
坚果云下载:https://jianguoyun.com/c/pubfile/GHAf-ZzTMjgr1KNNinHgpWf7QKdTmBu2Z-2SIU_YbE8
收工!
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值