增强现实之开源AR库——AR.js

AR.js是一个web端的AR库,它完全开源免费,获得了很高的热度。我们要实现的效果如下:

首先去github下载AR.js库:

AR.js下载

建议顺带看下作者给出的介绍。介绍里给出一个示例,我们在此示例的源码进行分析并尝试修改示例中的三维模型。

解压缩后目录如下:

示例存three.js目录的example目录下。只有在服务器环境内才可以访问。我们可以将AR.js拷贝至Apache服务器中访问,最简单的方法是:将AR.js用集成开发工具(webstorm,hbuilder等)打开,然后在开发环境中打开three.js/example,找到dev.html将其打开,点击运行即可。

我们会看到以下效果:

(由于是晚上拍的,可能效果不是很好)

我们将dev.html进行修改,改变显示的三维模型。

首先我们在example文件夹中创建一个class文件夹,存放我们自己写的实例。在class文件夹中新建一个Charactor.html文件。

路径如图:

在Charactor.html文件中编辑代码:

1.引入three.js库 及帧数查看组件

<script src='vendor/three.js/build/three.js'></script>
<script src='vendor/three.js/examples/js/libs/stats.min.js'></script>

three.js是前端实现三维显示的库,我们用它来创建的三维模型并添加页面(场景)中显示。

stats是帧数查看组件,它用来检测前端动画的运行状态。AR.js能够达到60帧以上,它足够优秀。

2.引入jsartoolkit

<script src='../vendor/jsartoolkit5/build/artoolkit.min.js'></script>
<script src='../vendor/jsartoolkit5/js/artoolkit.api.js'></script>

three.js的作用是实现三维显示,jsartoolkit则是实现摄像头的调用以及摄像头所获取影像的分析(AR的核心功能正是在此)。(此处注意一下,谷歌浏览器已经不允许http开头网址访问摄像头(本地调试除外),但火狐支持仍然支持,如果你是网站开发者,而又没有https的网址,可以推荐你的用户使用火狐浏览器。)

3.引入threex.artoolkit

<script src='../src/threex/threex-artoolkitsource.js'></script>
<script src='../src/threex/threex-artoolkitcontext.js'></script>
<script src='../src/threex/threex-artoolkitprofile.js'></script>
<script src='../src/threex/threex-arbasecontrols.js'></script>
<script src='../src/threex/threex-armarkercontrols.js'></script>
<script src='../src/threex/threex-arsmoothedcontrols.js'></script>
<script>THREEx.ArToolkitContext.baseURL = '../'</script>

three.js与jsartoolkit本来毫无关系,而threex.artoolkit将他们联系到一起,事实上,这才是AR.js库的精髓所在。

4.three.js要素初始化

//
//    Init
//

// init renderer
var renderer   = new THREE.WebGLRenderer({
   // antialias   : true,
   alpha: true
});
renderer.setClearColor(new THREE.Color('lightgrey'), 0)
// renderer.setPixelRatio( 2 );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.domElement.style.position = 'absolute'
renderer.domElement.style.top = '0px'
renderer.domElement.style.left = '0px'
document.body.appendChild( renderer.domElement );

// array of functions for the rendering loop
var onRenderFcts= [];

// init scene and camera
var scene  = new THREE.Scene();

var ambient = new THREE.AmbientLight( 0x666666 );
scene.add( ambient );

var directionalLight = new THREE.DirectionalLight( 0x887766 );
directionalLight.position.set( -1, 1, 1 ).normalize();
scene.add( directionalLight );

这是基本的three.js的知识,如果你接触过three.js,那么你会发现这与three.js创建要素别无二致。

5.开启摄像头

//
//    Initialize a basic camera
//

// Create a camera
var camera = new THREE.Camera();
scene.add(camera);


//          handle arToolkitSource


var arToolkitSource = new THREEx.ArToolkitSource({
   // to read from the webcam 
   sourceType : 'webcam',

   // // to read from an image
   // sourceType : 'image',
   // sourceUrl : THREEx.ArToolkitContext.baseURL + '../data/images/img.jpg',    
   // sourceUrl : THREEx.ArToolkitContext.baseURL + '../data/images/armchair.jpg',       

   // to read from a video
   // sourceType : 'video',
   // sourceUrl : THREEx.ArToolkitContext.baseURL + '../data/videos/headtracking.mp4',       
})

arToolkitSource.init(function onReady(){
   onResize()
})

// handle resize
window.addEventListener('resize', function(){
   onResize()
})
function onResize(){
   arToolkitSource.onResizeElement()  
   arToolkitSource.copyElementSizeTo(renderer.domElement) 
   if( arToolkitContext.arController !== null ){
      arToolkitSource.copyElementSizeTo(arToolkitContext.arController.canvas)    
   }  
}

分析源码发现,此处还有其他识别模式,可以选择从照片或是从视频中识别要素。

6.初始化arToolKitContext


//          initialize arToolkitContext
   

// create atToolkitContext
var arToolkitContext = new THREEx.ArToolkitContext({
   cameraParametersUrl: THREEx.ArToolkitContext.baseURL + '../data/data/camera_para.dat',
   // debug: true,
   // detectionMode: 'mono_and_matrix',
   detectionMode: 'mono',
   // detectionMode: 'color_and_matrix',
   // matrixCodeType: '3x3',

   canvasWidth: 80*3,
   canvasHeight: 60*3,

   maxDetectionRate: 30,
})
// initialize it
arToolkitContext.init(function onCompleted(){
   // copy projection matrix to camera
   camera.projectionMatrix.copy( arToolkitContext.getProjectionMatrix() );
})

// update artoolkit on every frame
onRenderFcts.push(function(){
   if( arToolkitSource.ready === false )  return

   arToolkitContext.update( arToolkitSource.domElement )
})

这一步的作用是通过Canvas来联系摄像头与three.js,即在摄像界面上添加画板,以实现在摄像界面中作图的目的。

6.创建识别标记(ArMarker)


//          Create a ArMarkerControls


var markerRoot = new THREE.Group
scene.add(markerRoot)
var markerControls = new THREEx.ArMarkerControls(arToolkitContext, markerRoot, {
   // type: 'barcode',
   // barcodeValue: 5,
   
   type : 'pattern',
   patternUrl : THREEx.ArToolkitContext.baseURL + 'examples/marker-training/examples/pattern-files/pattern-marker.patt',
})


// build a smoothedControls
var smoothedRoot = new THREE.Group()
scene.add(smoothedRoot)
var smoothedControls = new THREEx.ArSmoothedControls(smoothedRoot, {
   lerpPosition: 0.4,
   lerpQuaternion: 0.3,
   lerpScale: 1,
   // minVisibleDelay: 1,
   // minUnvisibleDelay: 1,
})
onRenderFcts.push(function(delta){
   smoothedControls.update(markerRoot)
}) 

// smoothedControls.addEventListener('becameVisible', function(){
//     console.log('becameVisible event notified')
// })
// smoothedControls.addEventListener('becameUnVisible', function(){
//     console.log('becameUnVisible event notified')
// })

此处我们用到的带黑框的图片标记是ArToolKit的第一代标记,之后发展到可以直接识别图片,如果有兴趣,可以到github上专门下载ArtoolKit。

7.将物体添加到场景

var arWorldRoot=smoothedRoot

var mesh=new THREE.AxisHelper();
//markerRoot.add(mesh)
arWorldRoot.add(mesh);

var loadingManager = new THREE.LoadingManager( function() {
    arWorldRoot.add( elf );
} );

var loader = new THREE.ColladaLoader( loadingManager );
loader.load( '../examples/models/collada/elf/elf.dae', function ( collada ) {
    elf = collada.scene;
} );

我们在此修改了添加到场景当中的模型,并添加到场中当中。

8.渲染整个three.js画面

//
//    render the whole thing on the page
//
var stats = new Stats();
document.body.appendChild( stats.dom );
// render the scene
onRenderFcts.push(function(){
   renderer.render( scene, camera );
   stats.update();
})

// run the rendering loop
var lastTimeMsec= null
requestAnimationFrame(function animate(nowMsec){
   // keep looping
   requestAnimationFrame( animate );
   // measure time
   lastTimeMsec   = lastTimeMsec || nowMsec-1000/60
   var deltaMsec  = Math.min(200, nowMsec - lastTimeMsec)
   lastTimeMsec   = nowMsec
   // call each update function
   onRenderFcts.forEach(function(onRenderFct){
      onRenderFct(deltaMsec/1000, nowMsec/1000)
   })
})

场景的动态效果都通过onRenderFct函数数组来实现。若要实现动画效果,我们要把实现动态的方法添加到数组中。

 

完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Charactor</title>
    <!-- three.js library -->
    <script src='../examples/vendor/three.js/build/three.js'></script>
    <script src='../examples/vendor/three.js/examples/js/libs/stats.min.js'></script>
    <!-- jsartookit -->
    <script src='../vendor/jsartoolkit5/build/artoolkit.min.js'></script>
    <script src='../vendor/jsartoolkit5/js/artoolkit.api.js'></script>
    <!-- include threex.artoolkit -->
    <script src='../src/threex/threex-artoolkitsource.js'></script>
    <script src='../src/threex/threex-artoolkitcontext.js'></script>
    <script src='../src/threex/threex-artoolkitprofile.js'></script>
    <script src='../src/threex/threex-arbasecontrols.js'></script>
    <script src='../src/threex/threex-armarkercontrols.js'></script>
    <script src='../src/threex/threex-arsmoothedcontrols.js'></script>
    <script>THREEx.ArToolkitContext.baseURL = '../'</script>
</head>
<body>
<script src="../examples/js/loaders/ColladaLoader.js"></script>
<script src="../examples/js/controls/OrbitControls.js"></script>
<script src="../examples/js/Detector.js"></script>
<script src="../examples/js/libs/stats.min.js"></script>
<script>
    //init renderer(初始化渲染器)
    var renderer=new THREE.WebGLRenderer({
        alpha:true
    });
    renderer.setClearColor(new THREE.Color('lightgrey'),0);
    //renderer setPiexRatio(2);
    renderer.setSize(window.innerWidth,window.innerHeight);
    renderer.domElement.style.position='absolute';
    renderer.domElement.style.top='0px';
    renderer.domElement.style.left='0px';
    document.body.appendChild(renderer.domElement);

    //array of  functions for the rendering loop(渲染处理函数组初始化)
    var onRenderFcts=[];

    //init scene and camera
    var scene=new THREE.Scene();//初始化场景和环境

    var ambient=new THREE.AmbientLight(0x666666);
    scene.add(ambient);

    var directctionalLight=new THREE.DirectionalLight(0x887766);
    directctionalLight.position.set(-1,1,1).normalize();
    scene.add(directctionalLight);

    //Initialize a basic camera

    //Create a camera(初始化相机添加到场景)
    var camera=new THREE.Camera();
    scene.add(camera);

    //handle arToolkitSource(调用打开相机事件,由THREEx提供)
    var arToolkitSource=new THREEx.ArToolkitSource({
        //to read from the webcam
        sourceType:'webcam'

        // // to read from an image
        // sourceType : 'image',
        // sourceUrl : THREEx.ArToolkitContext.baseURL + '../data/images/img.jpg',
        // sourceUrl : THREEx.ArToolkitContext.baseURL + '../data/images/armchair.jpg',

        // to read from a video
        // sourceType : 'video',
        // sourceUrl : THREEx.ArToolkitContext.baseURL + '../data/videos/headtracking.mp4',
    })

    arToolkitSource.init(function onReady() {
        onResize();
    })

    //handle resize(处理重新调整大小后正常显示)
    window.addEventListener('resize',function () {
        onResize();
    })
    function onResize() {
        arToolkitSource.onResizeElement()
        arToolkitSource.copyElementSizeTo(renderer.domElement)
        if(arToolkitContext.arController!==null){
            arToolkitSource.copyElementSizeTo(arToolkitContext.arController.canvas);
        }
    }

    //初始化 ArcToolkit环境, 相机内部场景
    //initialize arToolkitContext

    //create acToolkitContext
    var arToolkitContext=new THREEx.ArToolkitContext({
        //相机参数设置
        cameraParametersUrl:THREEx.ArToolkitContext.baseURL+'../data/data/camera_para.dat',
        //debug:true,
        //detectionMode:'mono_and_matrix',
        detectionMode:'mono',
//        detectionMode:'color_and_matrix',
//        matrixCodeType:'3x3',
        canvasWidth:80*3,
        canvasHeight:60*3,
        maxDetectionRate:30, //最大旋转角度还是什么滴
    })
    //initialize it
    arToolkitContext.init(function onCompleted() {
        //copy projection matrix to camera
        camera.projectionMatrix.copy(arToolkitContext.getProjectionMatrix());
    });
    //update artoolkit on every frame
    onRenderFcts.push(function () {
        if(arToolkitSource.ready==false) return;

        arToolkitContext.update(arToolkitSource.domElement)
    })

    //Create a ArMakerControls
    //创建一个Ar标记
    var markerRoot=new THREE.Group(); //用threejs的点集合初始化。
    scene.add(markerRoot);

    var markerControls=new THREEx.ArMarkerControls(arToolkitContext,markerRoot,{
        //type:'barcode',
        //barcodeValue:5,
        type:'pattern',
        patternUrl:THREEx.ArToolkitContext.baseURL+'./examples/marker-training/examples/pattern-files/pattern-marker.patt',
    })
    //build a smoothedControls
    var smoothedRoot=new  THREE.Group();
    scene.add(smoothedRoot);
    var smoothedControls=new THREEx.ArSmoothedControls(smoothedRoot,{
        lerpPosition:0.4,
        lerpQuaternion:0.3,
        lerpScale:1,
        //minVisibleDaly:1,
        //minUnvisibleDely:1,
    })
    onRenderFcts.push(function (delta) {
        smoothedControls.update(markerRoot)
    })
    smoothedControls.addEventListener('becameVisible',function () {
        console.log('becameVisible event notified')
    })

    //add Object in the scene
    //添加物体
    var arWorldRoot=smoothedRoot

    var mesh=new THREE.AxisHelper();
    //markerRoot.add(mesh)
    arWorldRoot.add(mesh);

    //add a torus knot创建物体
    // collada

    var loader = new THREE.ColladaLoader();
    loader.load( '../examples/models/collada/stormtrooper/stormtrooper.dae', function ( collada ) {
        var animations = collada.animations;

        //调整对象状态
        var avatar = collada.scene;
        avatar.rotation.x=Math.PI;
        avatar.rotation.z=Math.PI;
        avatar.scale.set(0.5,0.5,0.5);
        mixer = new THREE.AnimationMixer( avatar );

        arWorldRoot.add( avatar );
        var action = mixer.clipAction( animations[ 0 ] ).play();
        onRenderFcts.push(function () {
            avatar.rotation.z+=0.02*Math.PI;
        })
    } );

    //renderer the Whole thing on the page
    //渲染场景到页面中
    //渲染率查看器
    var stats=new Stats();
    document.body.appendChild(stats.dom);

    //renderer the scene
    onRenderFcts.push(function () {
        renderer.render(scene,camera);
        stats.update();
    })

    //行程渲染事件环路
    //run the rendering loop
    var lastTimeMsec=null;
    requestAnimationFrame(function animate(nowMsec){
        //keep looping
        requestAnimationFrame(animate);
        //measure time
        lastTimeMsec=lastTimeMsec||nowMsec-1000/60;
        var deltaMsec=Math.min(200,nowMsec-lastTimeMsec)
        //call all each update function
        onRenderFcts.forEach(function (onRenderFct) {
            onRenderFct(deltaMsec/1000,nowMsec/1000)
        })
    })
</script>
</body>
</html>

源码文件:

百度网盘:https://pan.baidu.com/s/1YTZAB6o12docx1JN-qopuw

密码:t6vp

Marker图片:

百度网盘:https://pan.baidu.com/s/1-UOpqfTtBBfyZKy7W0oowg

  • 16
    点赞
  • 106
    收藏
    觉得还不错? 一键收藏
  • 94
    评论
### 回答1: AR室内导航是利用增强现实AR)技术结合Three.js开发的一种应用。AR技术能够将虚拟的三维图像在现实环境中展示出来,而Three.js是一种用于在Web浏览器中创建和展示三维图形的JavaScriptAR室内导航基于用户所在的位置和目标位置,通过设备摄像头获取实时图像,并将虚拟导航信息叠加在图像上,为用户提供导航的帮助。利用Three.js的技术,可以实现将建筑、室内设施等三维模型与实际场景相结合,使用户能够直观地了解周围环境和导航路径。 开发AR室内导航需要进行以下步骤:首先,利用AR技术获取实时的摄像头图像。其次,借助Three.js创建和加载三维模型,包括建筑和室内设施的模型。然后,通过算法将虚拟模型与实际场景对齐,确保其在图像中的正确展示。最后,根据用户的位置和目标位置,计算出导航路径并在图像上显示出来。 AR室内导航在现实生活中具有广泛的应用前景。比如,可以应用于商场、机场等大型室内空间,帮助用户快速找到目标位置;也可以用于导览系统,为用户提供关于展览品的信息和导览路径;甚至可以应用于室内导航机器人,帮助机器人自主地完成室内导航任务。 总之,AR室内导航结合了增强现实和Three.js技术,可以有效利用虚拟的三维图像为用户提供室内导航的帮助,具有广泛的应用前景。AR技术和Three.js技术的不断发展将进一步推动AR室内导航的创新和应用。 ### 回答2: AR室内导航是一种利用增强现实技术为用户提供室内导航服务的应用。而Three.js是一款基于WebGL的开源JavaScript 3D,可以在网页上创建并展示3D图形和动画。 通过结合AR技术和Three.js,可以实现AR室内导航服务。首先,我们需要收集室内的地图数据,并将其转换为Three.js可以处理的格式。这些地图数据包括建筑物的结构、房间的位置、通道、门窗等信息。 接下来,利用AR技术,我们可以在用户的手机或者其他设备的摄像头画面上叠加虚拟信息,如地图、导航路径等。用户可以通过观看屏幕上的现实场景,同时看到与现实世界相结合的虚拟导航信息,以指导其在室内进行导航。 在AR室内导航中,利用Three.js可以创建虚拟的建筑物模型和导航路径。借助于Three.js的3D渲染功能,我们可以根据地图数据绘制建筑物的3D模型,并在模型上标记房间名称、导航路径等信息。用户可以通过观察屏幕上的AR场景,准确地了解自己当前所处的位置和前进方向。 另外,AR室内导航还可以结合其他功能,如语音导航、路径规划等。通过结合语音识别技术,用户可以通过语音指令告诉设备他们想去的目的地,然后AR导航系统可以为用户提供路径规划并进行语音导航指引。 总体而言,AR室内导航结合了增强现实技术和Three.js的优势,为用户提供了更直观、沉浸式的室内导航体验。通过利用现有技术的结合,我们可以帮助用户更轻松地找到目的地,并提升室内导航的效率和准确性。 ### 回答3: AR室内导航是一种利用增强现实技术和Three.js实现的室内导航系统。AR增强现实)技术是指通过手机相机或其他设备的摄像头捕捉现实世界的图像,并在图像上叠加虚拟对象或信息的技术。Three.js是一个基于WebGL的开源JavaScript,可以用于创建和显示三维图形和动画。 AR室内导航系统利用摄像头捕捉室内环境的图像,通过图像处理和计算机视觉技术,识别出室内场景中的相关特征,如墙壁、楼梯、门等。然后,通过Three.js创建虚拟的导航界面,将用户当前位置和目标位置在AR视图中显示出来。 用户只需要将手机摄像头对准室内环境,系统会通过AR技术识别出当前位置,并在屏幕上叠加导航界面。导航界面可以显示当前位置的平面示意图,以及路径指示标记,指引用户前往目标位置。用户可以通过手机屏幕上的虚拟按钮或手势交互,进行导航的操作,如放大和缩小地图、切换楼层、选择目标位置等。 AR室内导航系统的优势在于可以提供更直观、准确的室内导航体验。用户只需要通过手机摄像头观察现实场景,并在屏幕上看到导航界面,就可以轻松地找到目标位置,不再需要依赖图纸或标识牌。同时,Three.js的强大功能也为导航界面的设计和交互提供了灵活性和自定义性。 总而言之,AR室内导航系统结合了增强现实技术和Three.js,为用户提供了更直观、准确的室内导航体验,使得在复杂的室内环境中找到目标位置变得更加简单和便捷。
评论 94
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值