最近做了一个摄像头定位的功能,这个摄像头安装在激光雕刻机的顶部,使用方法就是对着雕刻区域拍照,然后将照片覆盖在画布上,这样创作的元素就与雕刻区域形成一个映射。比如你忘雕刻区域放了一个小圆盘,如果手动定位的话,会非常麻烦,这个时候就可以使用摄像头定位。
废话就说到这里吧…
先看一下实现的页面。
分为两步,第一步是显示摄像头视频,雕刻用于定位的案例,然后拍照 第二步是进行透视变换,选取四个点,然后做一个透视变化。将斜的照片摆正,即使摄像头放斜了,也没关系。
这里用到了三个库,一个是fisheye,用于鱼眼矫正,另一个是paperjs,用于选取四个点位和视图缩放。还有一个是glfx库。
整个流程比较复杂,下面我简单描述一下。
首先通过js获取摄像头,选中摄像头名中有toocaa的摄像头,并显示它的视频流,使用video元素显示。然后拍照,拍照其实是将视频流的一帧渲染到canvas上,然后在通过canvas toDataURL 转成一个图片地址。
获取了图片后,需要进行鱼眼矫正,鱼眼矫正之前的文章有提到过,这里的矫正参数使用的调试好的参数。所以不需要用户介入。鱼眼矫正使用的是webgl,所以需要将图片渲染到webgl的canvas上进行矫正。
点击下一步时,需要获取矫正后的图片,这个时候就是从这个webgl的canvas上取照片,webgl的canvas。坐标系在左下角,所以需要做一层转换,翻转的都是像素点,imageData。
取到矫正后的图片后,需要再将其插入到paperjs的画布中,供用户标定四个点。
图片直接插入画布中显示不出来,可能是异步的问题,需要创建一个Image标签,然后再其load事件中 将其加载到paperjs画布中。
用户选完点后,将四个点的坐标传给glfx库,对图片进行透视变换,透视变换用的也是webgl,不同的是,这个库提供了toDataURL 并且不需要翻转像素。
在做这个需求前,我做了一个技术预研的 透视变换 demo,按照顺序,选取四个点,点击四点自动定位,就能将图片摆正,并且把四个点中的内容裁剪出来。最终结果与你选点有很大关系。
透视变换后,对图片进行截取,将工作区域部分截取出来。这个时候还需要借助canvas,将图片渲染到canvas 上然后使用drawImage方法,截取出激光雕刻机工作区域的图片。 最后再将 工作区域的图片 插入到画布中。
这其中还涉及到图片的缩放,标定点与工作区域点的坐标计算,以及paperjs画布工具的开发与切换。
总之就是很复杂。而且最后出来的图片,很模糊,勉强能看。
在前端并没像opencv那样强大的图片处理库,而且鱼眼矫正之能通过肉眼辨别是否正确。此外,glfx这个库也有鱼眼矫正的功能,不够有点复杂,参数也比较多,很难调,这也是一个优化点。
在第一次选点标定后,后续的流程会存储四个点,下次可以不再标定。大大简化了操作。
另外这个方案稍微一下就能使用手机拍照进行定位。随机带的摄像头并不是很清楚,而且很受环境影响。