Navigation

    蓝鲸ROS机器人论坛

    • Register
    • Login
    • Search
    • Categories
    • Tags
    • Popular
    ROS交流群
    ROS Group
    产品服务
    Product Service
    开源代码库
    Github
    官网
    Official website
    技术交流
    Technological exchanges
    激光雷达
    LIDAR
    ROS教程
    ROS Tourials
    深度学习
    Deep Learning
    机器视觉
    Computer Vision

    用webgl来绘制二维点云吧

    技术交流
    webgl electron
    1
    1
    4216
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • weijiz
      weijiz last edited by

      做图形化程序web是非常方便的。最近做了一个项目就是用webgl来绘制二维点云,运行效果还是不错的。下面简单介绍一下webgl的使用方法和二维点云的绘制方法。

      首先什么是webgl?opengl大家一定都知道,就是 open graphic library. webgl 就相当于web中的opengl实现。利用webgl就可以充分利用显卡的性能绘制出很好的图形效果。

      webgl的基本概念
      三维图形在opengl中都是分割成三角形进行渲染的。比如一个正方形可以分成上下两个三角形。

      0_1467023401352_Screenshot from 2016-06-27 18:29:44.png

      这样一个正方形就有六个定点去确定下来。要利用webgl取画图就要指定两点就可以了,一个是所绘图形的所有定点,另一个是每个三角形的贴图。在webgl中这个是用 script type="x-shader/x-fragment"去指定的。
      下面就是画一个正方形的顶点计算script

      <script id="2d-vertex-shader" type="x-shader/x-vertex">
      attribute vec2 a_position;
      
      uniform vec2 u_resolution;
      uniform vec2 u_translation;
      uniform vec2 u_rotation;
      uniform vec2 u_scale;
      
      void main() {
        // Scale the positon
        vec2 scaledPosition = a_position * u_scale;
      
        // Rotate the position
        vec2 rotatedPosition = vec2(
           scaledPosition.x * u_rotation.y + scaledPosition.y * u_rotation.x,
           scaledPosition.y * u_rotation.y - scaledPosition.x * u_rotation.x);
      
        // Add in the translation.
        vec2 position = rotatedPosition + u_translation;
      
        // convert the position from pixels to 0.0 to 1.0
        vec2 zeroToOne = position / u_resolution;
      
        // convert from 0->1 to 0->2
        vec2 zeroToTwo = zeroToOne * 2.0;
      
        // convert from 0->2 to -1->+1 (clipspace)
        vec2 clipSpace = zeroToTwo - 1.0;
      
        gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
      }
      </script>
      

      首先定义了几个变量,然后根据转动,平移等坐标变换去计算应该绘制的坐标。gl_Position就是最后计算得出的坐标。整个计算过程由GPU去完成,因此运行效率也是很高的。

      定义贴图的script如下

      <script id="2d-fragment-shader" type="x-shader/x-fragment">
      precision mediump float;
      
      uniform vec4 u_color;
      
      void main() {
         gl_FragColor = u_color;
      }
      </script>
      

      这个脚本只是设置了填充的颜色,当然也可以填充图片之类的。

      变量的计算方式已经有了,怎么给这些变量设值呢?opengl提供了一些方法

        gl = canvas.getContext("webgl");
        if (!gl) {
          return;
        }
      
        // setup GLSL program
        var program = glUtils.createProgramFromScripts(gl, ["2d-vertex-shader", "2d-fragment-shader"]);
        gl.useProgram(program);
      
        // lookup uniforms
        resolutionLocation = gl.getUniformLocation(program, "u_resolution"); // 获取GPU中变量的地址
        colorLocation = gl.getUniformLocation(program, "u_color");
        translationLocation = gl.getUniformLocation(program, "u_translation");
        rotationLocation = gl.getUniformLocation(program, "u_rotation");
        scaleLocation = gl.getUniformLocation(program, "u_scale");
      
        var positionLocation = gl.getAttribLocation(program, "a_position");
        translation = [0, 0];
        rotation = [0, 1];
        scale = [1, 1];
        // set the resolution
        gl.uniform2f(resolutionLocation, canvas.width, canvas.height);  // 给GPU中的变量赋值
        // Set the translation.
        gl.uniform2fv(translationLocation, translation);
        // Set the rotation.
        gl.uniform2fv(rotationLocation, rotation);
        // Set the scale.
        gl.uniform2fv(scaleLocation, scale);
      

      执行 uniform2f 之后就会更改GPU内对应数据的值。

      通过

      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
           x1, y1,
           x2, y1,
           x1, y2,
           x1, y2,
           x2, y1,
           x2, y2]), gl.STATIC_DRAW);
      

      去设置所绘图形的端点坐标,这里是绘制正方形,所以是六个顶点。

          gl.drawArrays(gl.TRIANGLES, 0, 6);
      

      执行上面这句就可以开始绘图了,这里的参数指明了采用三角形进行绘图,共绘制六个顶点。这样我们就能看到一个正方形了
      完整的代码执行例子, 不涉及到坐标的计算
      完整的有坐标计算和拉伸的例子
      推荐一个学习webgl的好网站

      对于我们所要绘制的点云,只有画正方形是不够的。还有图像的放大,缩小,平移等等。这些就可以通过改变计算顶点坐标时的参数来实现。具体算起来会比较复杂,但是原理上就是如此。每个点就是一个非常小的正方形。

      来一个软件的最终效果图吧。

      0_1467025052651_Screenshot from 2016-06-27 18:57:02.png

      放大后的点云图
      0_1467025084561_Screenshot from 2016-06-27 18:57:17.png

      1 Reply Last reply Reply Quote 0
      • 1 / 1
      • First post
        Last post
      Copyright © 2015-2023 BlueWhale community