基于glumpy点云可视化

本文介绍了如何使用glumpy库结合numpy处理三维点云数据,并将其实时渲染到OpenGL中,展示了从安装、配置到使用点云渲染和性能优化的过程。
摘要由CSDN通过智能技术生成

背景

最近在寻找将numpy中的点云,通过opengl实时渲染出来,因此,在github上面发现项目glumpy,此项目极大的简化opengl复杂的操作,并且和numpy相结合起来,极大的简化的numpy可视化操作

安装glumpy

pip install glumpy

在安装python项目中引入该包后,请注意glumpy需要引入opengl引擎,如glfw,pyqt5等,因此本文需安装

pip install PyQt5

本文以qt5为后台引擎来进行模型点云渲染。
通过:

from glumpy import app
app.use("qt5")

来选择不同的opengl引擎。

Demo

from glumpy import app

window = app.Window(512,512)

@window.event
def on_draw(dt):
    window.clear()

app.run()

官方的demo,打开一个空白窗口
在这里插入图片描述

采用collections容器渲染点云

import os
import numpy as np
from glumpy import app
from glumpy.graphics.collections import PointCollection

window = app.Window(1024,1024, color=(1,1,1,1))
points = PointCollection("agg", color="local", size="local")

@window.event
def on_draw(dt):
    window.clear()
    points.draw()
    if len(points) < 100000:
        points.append(np.random.normal(0.0,0.5,(1,3)),
                      color = np.random.uniform(0,1,4),
                      size  = np.random.uniform(1,24,1))

window.attach(points["transform"])
window.attach(points["viewport"])
app.run()

效果:
在这里插入图片描述
上述可以在渲染点云可增量渲染,但数据量大,容易卡顿。

采用gloo 渲染


import os
import numpy as np
from glumpy import app, gl, gloo, glm

vertex = """
#version 120

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform float linewidth;
uniform float antialias;

attribute vec4  fg_color;
attribute vec4  bg_color;
attribute float radius;
attribute vec3  position;

varying float v_pointsize;
varying float v_radius;
varying vec4  v_fg_color;
varying vec4  v_bg_color;
void main (void)
{
    v_radius = radius;
    v_fg_color = fg_color;
    v_bg_color = bg_color;

    gl_Position = projection * view * model * vec4(position,1.0);
    gl_PointSize = 2 * (v_radius + linewidth + 1.5*antialias);
}
"""

fragment = """
#version 120

uniform float linewidth;
uniform float antialias;

varying float v_radius;
varying vec4  v_fg_color;
varying vec4  v_bg_color;

float marker(vec2 P, float size)
{
   const float SQRT_2 = 1.4142135623730951;
   float x = SQRT_2/2 * (P.x - P.y);
   float y = SQRT_2/2 * (P.x + P.y);

   float r1 = max(abs(x)- size/2, abs(y)- size/10);
   float r2 = max(abs(y)- size/2, abs(x)- size/10);
   float r3 = max(abs(P.x)- size/2, abs(P.y)- size/10);
   float r4 = max(abs(P.y)- size/2, abs(P.x)- size/10);
   return min( min(r1,r2), min(r3,r4));
}


void main()
{
    float r = (v_radius + linewidth + 1.5*antialias);
    float t = linewidth/2.0 - antialias;
    float signed_distance = length(gl_PointCoord.xy - vec2(0.5,0.5)) * 2 * r - v_radius;
//    float signed_distance = marker((gl_PointCoord.xy - vec2(0.5,0.5))*r*2, 2*v_radius);
    float border_distance = abs(signed_distance) - t;
    float alpha = border_distance/antialias;
    alpha = exp(-alpha*alpha);

    // Inside shape
    if( signed_distance < 0 ) {
        // Fully within linestroke
        if( border_distance < 0 ) {
            gl_FragColor = v_fg_color;
        } else {
            gl_FragColor = mix(v_bg_color, v_fg_color, alpha);
        }
    // Outside shape
    } else {
        // Fully within linestroke
        if( border_distance < 0 ) {
            gl_FragColor = v_fg_color;
        } else if( abs(signed_distance) < (linewidth/2.0 + antialias) ) {
            gl_FragColor = vec4(v_fg_color.rgb, v_fg_color.a * alpha);
        } else {
            discard;
        }
    }
}
"""

theta, phi = 0,0
window = app.Window(width=800, height=800, color=(1,1,1,1))

n = 1000000
program = gloo.Program(vertex, fragment, count=n)
view = np.eye(4, dtype=np.float32)
glm.translate(view, 0, 0, -5)

program['position'] = 0.35 * np.random.randn(n,3)
program['radius']   = np.random.uniform(5,10,n)
program['fg_color'] = 0,0,0,1
colors = np.random.uniform(0.75, 1.00, (n, 4))
colors[:,3] = 1
program['bg_color'] = colors
program['linewidth'] = 1.0
program['antialias'] = 1.0
program['model'] = np.eye(4, dtype=np.float32)
program['projection'] = np.eye(4, dtype=np.float32)
program['view'] = view

@window.event
def on_draw(dt):
    global theta, phi, translate
    window.clear()
    program.draw(gl.GL_POINTS)
    theta += .5
    phi += .5
    model = np.eye(4, dtype=np.float32)
    glm.rotate(model, theta, 0, 0, 1)
    glm.rotate(model, phi, 0, 1, 0)
    program['model'] = model

@window.event
def on_resize(width,height):
    program['projection'] = glm.perspective(45.0, width / float(height), 1.0, 1000.0)

gl.glEnable(gl.GL_DEPTH_TEST)
app.run()

在这里插入图片描述
上述代码可以快速渲染大量点云,但是其点云的数量是确定的。

总结

通过glumpy可以快速将numpy中的三维点与opengl相结合起来,通过numpy对数据进行处理之后,在通过opengl进行渲染,可以快速并且直观的展示模型数据,以及处理能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

myenjoy_1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值