开源项目SUSTechPOINTS的点云数据加载过程

作者:Kinglong    发表时间:2024-02-06 22:01   

关键词:  

1.程序启动

依次安装requirement.txt中的以下相关库:

tensorflow>=2.1

jinja2

cherrypy

filterpy

cheroot != 8.4.4

安装方法:

例如执行pip3 install tensorflow安装 tensorflow

如果安装速度慢,可以使用镜像,执行以下命令安装:

pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple/ tensorflow

执行命令:python main.py,启动程序。

2.editor.js

    // 监听帧变化事件

    this.frame_changed= function(event){

        var sceneName = this.editorUi.querySelector("#scene-selector").value;

        if (sceneName.length == 0 && this.data.world)

        {

            sceneName = this.data.world.frameInfo.scene;

        }

        if (sceneName.length == 0){

            return;

        }

        var frame =  event.currentTarget.value;

        // 加载当前帧

        this.load_world(sceneName, frame);   

        event.currentTarget.blur();

    };

 

    // 加载当前帧数据

    this.load_world = async function(sceneName, frame, onFinished){

       var world = await this.data.getWorld(sceneName, frame);

       // 渲染

       this.data.activate_world(

                world,

                function(){

                    self.on_load_world_finished(world);

                    if (onFinished)

                        onFinished();

                }

            );

   }

 

    // 渲染过程

    this.on_load_world_finished= function(world){

        this.moveAxisHelper(world);

        this.moveRangeCircle(world);

        this.lookAtWorld(world);

        this.unselectBox(null, true);

        this.render();

        this.imageContextManager.attachWorld(world);

        this.imageContextManager.render_2d_image();

        this.render2dLabels(world);

        

        // 刷新当前帧信息

        this.update_frame_info(world.frameInfo.scene, world.frameInfo.frame);

 

        this.select_locked_object();

        

        //load_obj_ids_of_scene(world.frameInfo.scene);

        objIdManager.setCurrentScene(world.frameInfo.scene);

 

        // preload after the first world loaded

        // otherwise the loading of the first world would be too slow

        this.data.preloadScene(world.frameInfo.scene, world);

    };

 

3.data.js 

// 加载当前帧数据

getWorld(sceneName, frame, on_preload_finished){

     world = this._createWorld(sceneName, frame, on_preload_finished);

}

 

_createWorld(sceneName, frame, on_preload_finished){

    ........

    let world = new World(this, sceneName, frame, [this.worldGap*x, this.worldGap*y, this.worldGap*z], on_preload_finished);    

    ........

}

 

4.world.js 一帧的数据处理

function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){  

    ......

    // 相机数据

    this.cameras = new Images(this.sceneMeta, sceneName, frame);

    // 雷达数据

    this.radars = new RadarManager(this.sceneMeta, this, this.frameInfo);

    // 激光雷达数据

    this.lidar = new Lidar(this.sceneMeta, this, this.frameInfo);

    // 标注数据

    this.annotation = new Annotation(this.sceneMeta, this, this.frameInfo);

    ......

}

 

this.go=function(){

    if (this.everythingDone){
        //console.error("re-activate world?");

        //however we still call on_finished
        if (this.on_finished){
            this.on_finished();
        }
        return;
    }

    if (this.preloaded()){

        //this.points.material.size = data.cfg.point_size;
        
        if (this.destroy_old_world){
            this.destroy_old_world();
        }

        if (this.destroyed){
            console.log("go after destroyed.");
            this.unload();
            return;
        }

        this.scene.add(this.webglGroup);
        
        this.lidar.go(this.scene);
        this.annotation.go(this.scene);
        this.radars.go(this.scene);            
        this.aux_lidars.go(this.scene);

 

-----lidar.js 激光雷达点云数据-----

this.preload=function(on_preload_finished){
    this.on_preload_finished = on_preload_finished;
    var loader = new PCDLoader();
    var _self = this;
    loader.load( this.frameInfo.get_pcd_path(),
        //ok
        function ( pcd ) {
            _self.points_parse_time = new Date().getTime();
            console.log(_self.points_load_time, _self.frameInfo.scene, _self.frameInfo.frame, "parse pionts ", _self.points_parse_time - _self.create_time, "ms");
            
            if (_self.data.cfg.enableFilterPoints)// do some filtering work here
            {
                pcd = _self.remove_high_ponts(pcd, _self.data.cfg.filterPointsZ);
            }

            let position = pcd.position;

            // build geometry
            _self.world.data.dbg.alloc();
            var geometry = new THREE.BufferGeometry();
            if ( position.length > 0 )
                geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) );

            let normal = pcd.normal;
            // normal and colore are note used in av scenes.
            if ( normal.length > 0 )
                geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normal, 3 ) );
            
            let color = pcd.color;
            if ( color.length == 0 ) {
                color = []

                // by default we set all points to same color
                for (let i =0; i< position.length; ++i){                                
                    color.push(_self.data.cfg.point_brightness);                                
                }


                // if enabled intensity we color points by intensity.
                if(_self.data.cfg.color_points=="intensity" && pcd.intensity.length>0){
                    // map intensity to color
                    for (var i =0; i< pcd.intensity.length; ++i){
                        let intensity = pcd.intensity[i];
                        intensity *= 8;
                        
                        if (intensity > 1)
                            intensity = 1.0;
                        
                        
                        //color.push( 2 * Math.abs(0.5-intensity));
                        
                        color[i*3] =  intensity;
                        color[i*3+1] = intensity;
                        color[i*3+2] = 1 - intensity;
                    }
                }

                // save color, in case color needs to be restored.
                pcd.color = color;
            }

            geometry.setAttribute( 'color', new THREE.Float32BufferAttribute(color, 3 ) );

            geometry.computeBoundingSphere();
            // build material
            var material = new THREE.PointsMaterial( { size: _self.data.cfg.point_size, vertexColors: THREE.VertexColors } );

            /*
            if ( color.length > 0 ) {
                material.vertexColors = color;
            } else {
                //material.color.setHex(0xffffff);
                material.color.r = 0.6;
                material.color.g = 0.6;
                material.color.b = 0.6;
            }
            */

            //material.size = 2;
            material.sizeAttenuation = false;

            // build mesh

            var mesh = new THREE.Points( geometry, material );                        
            mesh.name = "pcd";

            //return mesh;
            // add to parent.
            _self.world.webglGroup.add(mesh);
            
            _self.points = mesh;
            _self.pcd = pcd;
            //_self.points_backup = mesh;

            _self.build_points_index();
            _self.points_load_time = new Date().getTime();

            console.log(_self.points_load_time, _self.frameInfo.scene, _self.frameInfo.frame, "loaded pionts ", _self.points_load_time - _self.create_time, "ms");

            _self._afterPreload();
        },

        // on progress,
        function(){

        },

        // on error
        function(){
            //error
            console.log("load pcd failed.");
            _self._afterPreload();
        },

        // on file loaded
        function(){
            _self.points_readfile_time = new Date().getTime();
            console.log(_self.points_load_time, _self.frameInfo.scene, _self.frameInfo.frame, "read file ", _self.points_readfile_time - _self.create_time, "ms");
        }
    );
};

 

5.annotation.js 标注数据

function Annotation(sceneMeta, world, frameInfo)

    this.world = world

    

    this.load_annotation((boxes)=>this.proc_annotation(boxes))

    

    // 加载标注数据

    this.load_annotation=function(on_load){

        debugger

        if (this.data.cfg.disableLabels){

            on_load([]);

        }else {

            var xhr = new XMLHttpRequest();

            // we defined the xhr

            var _self = this;

            xhr.onreadystatechange = function () {

                if (this.readyState != 4) return;

                if (this.status == 200) {

                    let ann = _self.frameInfo.anno_to_boxes(this.responseText);

                    on_load(ann);

                }

                // end of state change: it can be after some time (async)

            };

            

            xhr.open('GET', "/load_annotation"+"?scene="+this.frameInfo.scene+"&frame="+this.frameInfo.frame, true);

            xhr.send();

        }

     };

 

    // 处理标注数据

    this.proc_annotation = function(boxes){

        // .......

        // by kinlong 参数boxes是标注数据,this.boxes是对象

        this.boxes = this.createBoxes(boxes);  //create in future world

 

        this.boxes.forEach(b=>this.webglGroup.add(b));

 

        this.world.webglGroup.add(this.webglGroup); // this.webglGroup.children

 

        //this.world.webglGroup.children[0].children-->this.boxes--> [LineSegments]

    }

 

this.createBoxes = function(annotations){

        return annotations.map((b)=>{

            return this.createOneBoxByAnn(b);

        });

    };

 

this.createOneBoxByAnn = function(annotation){

        let b = annotation;

        

        let mesh = this.createCuboid(b.psr.position,

            b.psr.scale,

            b.psr.rotation,

            b.obj_type,

            b.obj_id,

            b.obj_attr);

        

        if (b.annotator){

            mesh.annotator = b.annotator;

        }

 

        if (b.follows)

            mesh.follows = b.follows;

        

        return mesh;  

    };

 

 // 附加标注信息,创建长方体

 this.createCuboid = function(pos, scale, rotation, obj_type, track_id, obj_attr){

        let mesh = this.new_bbox_cube(parseInt("0x"+globalObjectCategory.get_obj_cfg_by_type(obj_type).color.slice(1)));

        mesh.position.x = pos.x;

        mesh.position.y = pos.y;

        mesh.position.z = pos.z;

 

        mesh.scale.x = scale.x;

        mesh.scale.y = scale.y;

        mesh.scale.z = scale.z;

 

        mesh.rotation.x = rotation.x;

        mesh.rotation.y = rotation.y;

        mesh.rotation.z = rotation.z;

 

        mesh.obj_track_id = track_id;  //tracking id

        mesh.obj_type = obj_type;

        mesh.obj_attr = obj_attr;

        mesh.obj_local_id =  this.get_new_box_local_id();

 

        mesh.world = this.world;

 

        return mesh;

    };

 

this.new_bbox_cube=function(color){

        var h = 0.5;

        var body = [

            //top

            -h,h,h,  h,h,h,

            h,h,h,   h,-h,h,

            h,-h,h,  -h,-h,h,

            -h,-h,h, -h, h, h,

 

            //botom

            -h,h,-h,  h,h,-h,

            h,h,-h,   h,-h,-h,

            h,-h,-h,  -h,-h,-h,

            -h,-h,-h, -h, h, -h,

 

            // vertical lines

            -h,h,h, -h,h,-h,

            h,h,h,   h,h,-h,

            h,-h,h,  h,-h,-h,

            -h,-h,h, -h,-h,-h,

 

            //direction

            h,   0,  h,  1.5*h, 0, h,

        ];

        

        this.world.data.dbg.alloc();

 

        var bbox = new THREE.BufferGeometry();

        bbox.setAttribute( 'position', new THREE.Float32BufferAttribute(body, 3 ) );

        

        if (!color){

            color = 0x00ff00;

        }

 

        /*

        https://threejs.org/docs/index.html#api/en/materials/LineBasicMaterial

        linewidth is 1, regardless of set value.

        */

        

        var material = new THREE.LineBasicMaterial( { color: color, linewidth: 1, opacity: this.data.cfg.box_opacity, transparent: true } );

        var box = new THREE.LineSegments( bbox, material );

        

        box.scale.x=1.8;

        box.scale.y=4.5;

        box.scale.z=1.5;

        box.name="bbox";

        box.obj_type="car";                

        return box;

    };