#可视化# 如何根据权重着色

 

当我们遇到海量数据时,总是想将其可视化出来,容易观察数据的特点,也易于分析。这二天,没事,细细的研究了一下生成上图的工作,借此机会熟悉QT和已经没有碰的OpenGL。不过,还好,很多东西都还没有忘记,只是不那么熟练了,可是openGL核心的东西还是没有忘记。细细从下往上看图,我们会发现其颜色从红色逐渐到蓝色。容易看出,其着色的依据是根据其点云数据中点的高度,高度越低,其颜色偏向红色,高度越高,其颜色偏向蓝色,也就说我们很容易看出来哪些点偏低,哪些点偏高。

 

上图的树完全是由大量的三维点构成,由激光扫描而成,其大量的三维点一起就成为点云数据了。我是根据其高度为其中的点着色的,当然这里看不出什么优势,如果我们换一个思维时,如果我们对有权重的数据按照同样的思路可视化时,就可以看出其优点了,因为我们在模式识别中,很多数据有其权重,比如对于二维数据:

特征 权重
(2, 3) 1
(5, 6) 5
(1, 4) 10

如果我们按照其权重按照大小画出来的话,见上图,这也是我们比较直观的思维,容易想出来,可是当数据越愈来愈多的时候,这些圈就易重合,就不能突出数据本身了,如下图

这是之前研究Joint Boost分类器,将其数据可视化的过程,可见数据大了,就不易看出其数据分布特征了。

其实,类似的库都有实现根据其权重在RGB空间中着色的函数,但是一直不知道其如何实现的,由于网上也没有类似的介绍,我也在实习空余期间研究了起来,这到底是如何实现的呢。

PCL库源代码的误解

看了一下PCL库源代码,太大,没有细看,只是初略的看了一下可视化相关的代码,然后就推测是如下的规则,先看float 的二进制

我的猜测是先将权重正规化到0—-1空间。然后根据其指数(因为是负数),移动后面的尾数部分,因为加上尾数部分省略的bit位,其值是1(细看计算机如何存储float),可以将尾数的24bit位右移指数-127的绝对值后,然后把24bit位按照每8bit位分给RGB即可,可是得到的效果并不是很好,例如

0.567 RGB = (116, 147, 72)
0.5009 RGB = (125, 29, 64)

本来相近的数字,竟然的出来的RGB值也相差如此之大,看来有点曲解了,由于PCL库的巨大,最终没有找到相应的源代码。不过后来细想,这可能是由于没有分配好0 1bit位导致的,如果能充分利用这一点,其实也是能做到的,但是目前没有什么想法。

自食其力

在借鉴上面的思路,自己分析了如下的规则(还是将数据将先正规化后)

0 RGB = (255, 0, 0)
0.5 RGB = (0, 255, 0)
1 RGB = (0, 0, 255)

到底是什么函数能将其值映射到RGB这样的三维数据呢,让我一下想到了Sin 和 Cos函数。

后面经过进一步分析,得到了如下函数:

// 给每一个点赋颜色 v是权重 已经正规化
if( v < 0.500000){
    x = v * 3.14;
    glColor3f( cos(x), sin(x), 0 );

}else{
    x = (v - 0.5) * 3.14;
    glColor3f(0, cos(x), sin(x));
}

glVertex3f(pos.x(), pos.y(), pos.z());

 

最主要的还是将数据通过0.5这个临界值分段着色,后面又细想,其实在这里,我们并不需要Sin Cos函数,直接一个线性函数即可

Y = 1 – X

那么得到的就是 (x, 1-x, 0)也能得到想要的结果,具体可以修改一下参数或者映射函数,比如你想要颜色变的快的话,你可以对其进行平方。

算法流程

  • 对权重进行正规化;
  • 根据0.5这个临界值着色,选择需要的映射函数;

【注】 没有解决什么大问题,只是在乎一些技术细节,多思考一些简单的问题,一定会有回报。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。