原文链接:https://blog.csdn.net/milli236/article/details/78671958

介绍

JSARToolKit5是一个WebAR库。这是我对JSARToolKit5的初次学习将其翻译了出来水平有限敬请斧正。

github:  https://github.com/artoolkit/jsartoolkit5

这篇文章简要的说明了如何用JSARToolKit5建虚拟现实WebAPP。我们讲学习什么是JSARToolKit5,什么类型的ARAPP你可以使用以及如果如果用ThreeJS 3D引擎去构建3D部件。我也将简要的阐述AR是什么以及我认为什么AR是酷炫的。

简要的说JSARToolKit5 是ARToolKit 库的JS部分。你可以使用JSARToolKit5 将对象加入图像或者影像之中,使其仿佛位于真实世界之中。不仅如此你可以让虚拟对象鲜活可交互(interactive and animated)。

为了证明这类应用是我们可以用JSARToolKit5制作出来的我们将写一个小的AR应用增加影像到摄像头上。这个应用可以讲一个小的盒子放在视频流中你可以点击盒子打开它然后可以看到盒子里面有什么。

JSARToolKit的基础

JSARToolKit 的工作原理是跟踪视频中的特殊的影像。这些特殊的影像叫做AR markers,JSARToolKit 能够分辨出他们在视频流中的位置以及他们指向哪那个方向。通过获得AR markers位置和方向你可以在影像的上面正确的画出3D的对象,让其仿佛就在其中。想要加载JSARToolKit将压缩的script放到网页中即可。

<script src="build/artoolkit.min.js"></script>

我们需要三样东西来构建AR应用。包括AR marker、一个摄像头以及一个将三维对象画到摄像头上的方式。针对marker我们将使用一个特别的嵌入式marker--"BarcodeMarker"。摄像头我们将使用设备摄像头(通过getUserMedia API实现)。对于三维部件将使用Three.js实现。首先我们将完成摄像头资源的设置。我们将使用getUserMedia API获得摄像头的URL之后这个URL将作为video对象的资源(video html标签)。通过这个我们将获得一个video元素来展示视频流。

这个实现的一个简单方式是使用一个JSARToolKit5的辅助函数ARController.getUserMedia(options). 成功回调将带回一个可以被使用的video元素。注意在Chrome for Android手机视频只有在与页面进行交互之后才会执行。ARController.getUserMedia 添加了一个窗口级别的触摸事件来操作视频元素。

我们要做的第一件事就是创建ARController。ARController保持着追踪已经注册的标记(markers )并且从数据中读取视频资源。我们现在来创建新奇的视频元素( video element)。同时我们应该明确的写出ARCameraParam 有助于复用。

var video = ARController.getUserMedia({maxARVideoSize: 320, // do AR processing on scaled down video of this sizefacing: "environment",onSuccess: function(video) {console.log('got video', video);}
});
var arController = new ARController(video, 'Data/camera_para.dat');
arController.onload = function() {console.log('ARController ready for use', arController);
};
var camera = new ARCameraParam('Data/camera_para.dat');
camera.onload = function() {var arController = new ARController(video.videoWidth, video.videoHeight, camera);console.log('ARController ready for use', arController);
};

通过JSARToolKit获得marker位置

现在我们有个视频钩子( video hooked)挂接到了管理器上我们也准备追踪AR markers摄像头中的AR markers。当我们看到AR markers我们想知道他的细节包括他在那里以及他的位置。

幸运的是ARToolKit 准备了所有的数学并给我们了一个可以重用的变化矩阵来找出摄像头中的marker。

// Set the ARController pattern detection mode to detect barcode markers.
arController.setPatternDetectionMode( artoolkit.AR_MATRIX_CODE_DETECTION );// Add an event listener to listen to getMarker events on the ARController.
// Whenever ARController#process detects a marker, it fires a getMarker event
// with the marker details.
//
var detectedBarcodeMarkers = {};
arController.addEventListener('getMarker', function(ev) {var barcodeId = ev.data.marker.idMatrix;if (barcodeId !== -1) {console.log("saw a barcode marker with id", barcodeId);// Note that you need to copy the values of the transformation matrix,// as the event transformation matrix is reused for each marker event// sent by an ARController.//var transform = ev.data.matrix;if (!detectedBarcodeMarkers[barcodeId]) {detectedBarcodeMarkers[barcodeId] = {visible: true,matrix: new Float32Array(16)}}detectedBarcodeMarkers[barcodeId].visible = true;detectedBarcodeMarkers[barcodeId].matrix.set(transform);}
});var cameraMatrix = arController.getCameraMatrix();for (var i in detectedBarcodeMarkers) {detectedBarcodeMarkers.visible = false;
}// Process a video frame to find markers in it.
// Each detected marker fires a getMarker event.
//
arController.process(video);

用Three.js配合JSARToolKit

通过JSARToolKit找到了标记为止,我们可以将其拷贝到应该被展示到marker上面的Three.js对象。注意如果逆向移动marker 出摄像头外追踪会消失并且Three.js不会获得更新。你可以让他待在原地,让他突然消失或者淡出。我更倾向于淡出失去跟踪的对象,但是他需要对于对象有着高精度的控制。

最酷的事情是Three.js object跟踪的marker是一个普通的Three.js object。所以我们可以用普通的技巧来处理现在的工作。在这个例子上我们使用一个接触时间来判断你什么时候敲这个对象以及处理。下面的代码是Three.js 鼠标光线跟踪代码。他从鼠标的位置投射出一个光线到3D场景并且检查投射到物体上的光线是否又被阻挡隔断的情况,如果找到了隔断也就是意味着鼠标在物体上面。这样就可以做出一个能够敲击的Three.js 场景。

我添加了一个小的渲染到了敲击时间上,这样当点击盒子对象时他会打开。为了检查,打开demo页并将摄像头打开。现在你的相机是一个平面的marker点击会出现效果。

代码方面,我用了Three.js 交互在JSARToolKit5中。他处理了上面所说的所有东西,并形成了一些简单的方法。把js/artoolkit.three.js加上就行。以上的示例Firefox Android or Chrome Android支持桌面也可以IOS可以完全不支持。

<script src="build/artoolkit.min.js"></script>
<script src="js/artoolkit.three.js"></script>
<script>
ARController.getUserMediaThreeScene(facing: 'environment',onSuccess: function(arScene, arController, arCameraParam) {arController.setPatternDetectionMode(artoolkit.AR_MATRIX_CODE_DETECTION);// Track the barcode marker with id 20.// markerRoot is a THREE.Object3D that tracks the marker position.//var markerRoot = arController.createThreeBarcodeMarker(20);// Add the openable box to the marker root.//var box = createOpenableBox();markerRoot.add(box);// Add the marker root to the AR scene.//arScene.scene.add(markerRoot);// Add event handlers to make the box open/close on tap.//window.addEventListener('touchend', function(ev) {if (box.hit( ev.touches[0], arScene.camera )) {box.toggleOpen();}}, false);window.addEventListener('mouseup', function(ev) {if (box.hit( ev, arScene.camera )) {box.toggleOpen();}}, false);// Create renderer and deal with mobile orientation.//var renderer = new THREE.WebGLRenderer({antialias: true});var f = Math.min(window.innerWidth / arScene.video.videoWidth,window.innerHeight / arScene.video.videoHeight);var w = f * arScene.video.videoWidth;var h = f * arScene.video.videoHeight;if (arController.orientation === 'portrait') {renderer.setSize(h,w);renderer.domElement.style.transformOrigin = '0 0';renderer.domElement.style.transform = 'rotate(-90deg) translateX(-100%)';} else {renderer.setSize(w,h);}document.body.appendChild(renderer.domElement);// Call arScene.renderOn on each frame,// it does marker detection, updates the Three.js scene and draws a new frame.//var tick = function() {requestAnimationFrame(tick);arScene.renderOn(renderer);};tick();}
);
</script>

没有帮助的JSARToolKit 和Three.js

也许你不想使用helpers。或者你想用JSARToolKit结合其他的绘制库,下面将介绍如何使用未集成JSARToolKit 库。

手动集成JSARToolKit 并不需要太多的工作。首先我需要跟踪markers通过getMarker时间。以下,我将跟踪ID 20的条形码标记的位置和可见性。

// Create a marker root object to keep track of the marker.
//
var markerRoot = new THREE.Object3D();// Make the marker root matrix manually managed.
//
markerRoot.matrixAutoUpdate = false;// Add a getMarker event listener that keeps track of barcode marker with id 20.
//
arController.addEventListener('getMarker', function(ev) {if (ev.data.marker.idMatrix === 20) {// The marker was found in this video frame, make it visible.markerRoot.visible = true;// Copy the marker transformation matrix to the markerRoot matrix.markerRoot.matrix.elements.set(ev.matrix);}
});// Add a cube to the marker root.
//
markerRoot.add( new THREE.Mesh(new THREE.BoxGeometry(1,1,1), new THREE.NormalGeometry()) );// Create renderer with a size that matches the video.
//
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(video.videoWidth, video.videoHeight);
document.body.appendChild(renderer.domElement);// Set up the scene and camera.
//
var scene = new THREE.Scene();
var camera = new THREE.Camera();
scene.add(camera);
scene.add(markerRoot);// Make the camera matrix manually managed.
//
camera.matrixAutoUpdate = false;// Set the camera matrix to the AR camera matrix.
//
camera.matrix.elements.set(arController.getCameraMatrix());// On each frame, detect markers, update their positions and
// render the frame on the renderer.
//
var tick = function() {requestAnimationFrame(tick);// Hide the marker, we don't know if it's visible in this frame.markerRoot.visible = false;// Process detects markers in the video frame and sends// getMarker events to the event listeners.arController.process(video);// Render the updated scene.renderer.render(scene, camera);
};
tick();

不要被上面的代码吓到。这些代码重点是渲染AR场景以及跟踪barcode marker。你可以在摄像头上面覆盖AR场景。只需要在摄像头的上卖弄叠加一个平面。

// To display the video, first create a texture from it.
var videoTex = new THREE.Texture(video);// Use linear downscaling for videoTex
// (otherwise it needs to be power-of-two sized and you
// need to generate mipmaps, which are kinda useless here)
videoTex.minFilter = THREE.LinearFilter;// And unflip the video Y-axis.
videoTex.flipY = false;// Then create a plane textured with the video.
var plane = new THREE.Mesh(new THREE.PlaneBufferGeometry(2, 2),new THREE.MeshBasicMaterial({map: videoTex, side: THREE.DoubleSide})
);// The video plane shouldn't care about the z-buffer.
plane.material.depthTest = false;
plane.material.depthWrite = false;// Create a scene and a camera to draw the video.
var videoScene = new THREE.Scene();
var videoCamera = new THREE.OrthographicCamera(-1, 1, -1, 1, -1, 1);
videoScene.add(videoCamera);
videoScene.add(plane);// Set the renderer autoClear to false, otherwise it
// clears the canvas before each render call.
renderer.autoClear = false;// Draw the videoScene before the AR scene.
var tick = function() {requestAnimationFrame(tick);markerRoot.visible = false;arController.process(video);// Clear the renderer before drawing the videoScene,// followed by the AR scene.renderer.clear();renderer.render(videoScene, videoCamera);renderer.render(scene, camera);
};
tick();
// Rotate the video plane and the renderer if the arController is in portrait mode.
if (arController.orientation === 'portrait') {plane.rotation.z = Math.PI/2;renderer.setSize(video.videoHeight, video.videoWidth);renderer.domElement.style.transformOrigin = '0 0';renderer.domElement.style.transform = 'rotate(-90deg) translateX(-100%)';
} else {renderer.setSize(video.videoWidth, video.videoHeight);
}

如何使用ARToolkit的方式来处理这些

如果你觉得这些事件回调不是你喜欢的。ARToolKit 还支持C方式进行API调用。 it's pretty neat(原文)。如果你看到了marker在之前的帧。我们可以用之前的marker矩阵作为输入进行矩阵计算。通过使用之前的矩阵作为基础来作计算我们可以达到基本的追踪。

Emscripten?如何调试?

JSARToolKit5 是JSARToolkit 库的一部分由Emscripten实现的。由于令人惊奇的C / C ++到ASM.js编译器。JSARToolKit5 运行了一个近乎本地的速度,在其他的浏览器也不是太笨重。并且更好的是,并且如果从上游库更新只需要一个编译。(也可能需要一些添加行用于绑定)

结果、JSARToolKit 有两个版本一个是调试版构建完整的所有调试符号,使生活便于调试代码库的C ++端。另外一个是压缩版用于加载和编译。

用 build/artoolkit.debug.js and js/artoolkit.api.js 就可以进行调试。artoolkit.api.js文件包含ARController和ARCameraParam的实现的C ++ < - > JS API绑定

我将继续推进。

JSARToolKit5文档翻译相关推荐

  1. 【iOS官方文档翻译】iOS蓝牙的基本概念

    之前写了[iOS官方文档翻译]iOS的蓝牙连接.数据接收及发送一文,介绍了怎样进行蓝牙通讯,但是很多基本概念没有进行解释,看起来可能有点吃力,所以现在再翻译一篇苹果对官方蓝牙4.0一些基本概念介绍的文 ...

  2. Sencha-概念-Layouts(布局)(官网文档翻译8)

    Sencha-概念-Layouts(布局)(官网文档翻译8) 介绍和HBox 布局描述了在您的应用程序的组件的大小和位置.例如,一个电子邮件客户端可能具有固定到左边的消息的列表,以说,可用的宽度的三分 ...

  3. 使用JSARToolKit5 开发AR应用 (2) Marker

    相关站点 jsartoolkit5 - ARToolkit.js Talkingdata - 用数据的心智去超越 three.js 系列教程 - 良心之作 JSARToolKit 支持多种标记 本文概 ...

  4. Laravel 5.6 中文文档翻译完成,译者 60 人,耗时 10 天

    图片来自 laravel-news.com Laravel 5.6 的文档地址: Laravel 5.6 文档页面 总结 Laravel 5.6 文档翻译完成,总共耗时 10 天,参与用户 60 人. ...

  5. python翻译程序-Python桌面应用案例:TXT文档翻译工具(源代码)

    搞定了Word文档和PDF文档翻译工具的案例,总觉得还差了一点,仔细想了下,明白了,原来差了一个TXT文本文件翻译工具案例.这个就更简单了--在PDF文档翻译工具基础上加了两个函数,就可以支持TXT文 ...

  6. TiDB 官方设计文档翻译(三)

    这个系列共三篇译文:  TiDB 官方设计文档翻译(一)  TiDB 官方设计文档翻译(二)  TiDB 官方设计文档翻译(三) 原文:  https://pingcap.github.io/blog ...

  7. TiDB 官方设计文档翻译(二)

    这个系列共三篇译文:  TiDB 官方设计文档翻译(一)  TiDB 官方设计文档翻译(二)  TiDB 官方设计文档翻译(三) 原文:  https://pingcap.github.io/blog ...

  8. TiDB 官方设计文档翻译(一)

    TiDB是新兴的NEWSQL数据库,由国内的PINGCAP团队研发.  有关于TiDB的架构.部署和运维,官方有中文的文档,链接是:  https://github.com/pingcap/docs- ...

  9. 欢迎参与 KubeVela 官方文档翻译活动

    来源 | 阿里巴巴云原生公众号 背景 KubeVela v1.0 启用了新的官网架构和文档维护方式,新增功能包括文档版本化控制.i18n 国际化以及自动化流程.但目前 KubeVela 官方文档只有英 ...

  10. Sencha-概念-Events(事件)(官网文档翻译10)

    Sencha-概念-Events(事件)(官网文档翻译10) 煎茶Touch 2的组件和类的触发广泛的事件,在其生命周期的不同点.活动让你的代码,它周围的变化作出反应,并在煎茶触摸是一个关键的概念. ...

最新文章

  1. cinder与ceph的区别_分布式存储基础、Ceph、cinder及华为软件定义的存储方案 -
  2. IOS初级:UIScrollView UIPageControl
  3. SAP Gateway service language determination
  4. ASP调用.Net dll
  5. 只需10分钟!就能用Flask,Docker和Jenkins部署机器学习模型
  6. JimStoneAjax如何跟DWR竞争?
  7. Mysql Data type
  8. MySQL源码—线程篇
  9. 【轨迹预测】基于matlab卡尔曼滤波运动轨迹预测【含Matlab源码 590期】
  10. 计算机交并符号,数学并集符号
  11. 如何解决ueditor乱码问题
  12. HTML 与 microsoftOffice word中字体对照表
  13. 摩托罗拉被曝裁员超一半 联想多品牌失败了吗?
  14. 英特尔显卡不支持自定义分辨率N卡解决办法
  15. 数据库监控 Prometheus + Grafana
  16. golang内幕之协程状态切换
  17. 利用企业微信免费发送各种信息,开发网页客服
  18. 区别主要在于服务器对带宽的分配:
  19. html怎么弄到excel里,html里导入excel表格数据-如何将网页中的表格快速复制到EXCEL中...
  20. iView的table表格购物车的使用案例

热门文章

  1. VirtualBox中安装Android-x86详解
  2. MySql的基本操作以及以后开发经常使用的常用指令
  3. 《C#高级编程(第六版)》泛型学习笔记(一):泛型优点和特性 (转载)
  4. jQuery动画的实现
  5. Linux网络设备驱动程序
  6. linux服务器的性能分析与优化(十三)
  7. 2012 定制化产品探讨(周金根).pdf
  8. Tomcat中Pipeline
  9. 39-java 输入输出总结
  10. PHP工具篇:PHPStorm IDE使用CodeSniffer代码规范化管理