查看完整版本: [-- 用 Qt 生成热图(heat map) --]

QTCN开发网 -> Qt 作品展 -> 用 Qt 生成热图(heat map) [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

pbe_sedm 2013-05-25 13:43

用 Qt 生成热图(heat map)

热图有时候叫热区图或者热力图,都是用于表现某种事物密集度的图形化显示。
我写的这个没有画底图,不然会更有趣,比如一个键盘,一张房屋平面图,或者一张Google地图,拿它做什么用,完全取决于你的需要。

一、主要用途
1、网站设计,可以帮助设计人员知道用户喜欢点哪些地方,对哪些东西感兴趣,以此来改良设计,改善用户体验,百度和腾讯都有提供此类有偿服务。 对位置不敏感,就比如有张全身照的美女图,通过统计就可以知道别人最喜欢看美女的哪个部位,是不是很有意思。
2、模拟分布,比如气象云图、无线射频信号的分布等等,都可以用这个来做。
3、众多例子:http://www.patrick-wied.at/static/heatmapjs/showcases.html

二、原理
1、首先可以参考下面几个链接
     JavaScript:  [一个用canvas画热力图的利器] http://www.cnblogs.com/bdqlaccp/archive/2012/09/12/2681518.html
            jQuery:  [浅谈Heatmap] http://huoding.com/2011/01/04/39
           Python:  [pyHeatMap : 使用Python绘制热图的库] http://oldj.net/article/python-heat-map/
2、基本原理:
      A、创建一个跟图片大小或者网页或者窗口一样大小的二维数组(可用一维实现),例如图片分辨率为1024x768,则你的二维数组为768行,1024列,数据所有元素均初始化为0。
      B、准备两张同样大小的画布(在Qt下可用QImage,在JavaScript下可用canvas,在Python下可用PIL库的Image),一张用于绘制灰度渐变圆圈(假设为 Alpha_Canvas),一张用于着色后显示输出(Output_Canvas)。
      C、准备一个调色板,调色板从0到255填充上线性渐变的颜色,这个颜色可根据需要自由指定,调色板主要用于着色操作中取颜色。
      D、我们假设在画布上点击一下算是采一个点,则点击一下对应的数组元素的值增加1,用于标识该位置(又)被点击了一次。
      E、我们保存一个整个数组中单个位置被点击次数最多的值(假设为:max),比如在整个画布中,(10,10)这个位置被点击了20次,而其他所有点均在该点的点击次数之下,则20被存储到该变量(max)中。这就意味着每点击一次都要拿当前坐标点的点击次数和最大点击次数相比,如果最大点击次数小于当前点击次数,则更新最大点击次数,并重新绘制整个图。
      F、选择Alpha_Canvas画布,在被点击的地方绘制一个径向渐变的圆,圆心为被点击的坐标,半径可根据需要自由设置,径向渐变圆的是灰度渐变圆圈,整个径向渐变圆圈是一个黑色圆圈,但圆心的颜色要比边界的深,而圆心的Alpha通道值是该点的被点击次数(假设为:current_count)与被点击次数最多的值之比乘以255(255要根据你的绘图环境来确定,在Qt中255表示完全不透明,0表示完全透明),即公式:current_count/max*255。
      G、选择Output_Canva画布,进行着色操作,根据上一步的圆心和半径可确定一个矩形区域,如果是重绘操作,则该矩形区域为整个图形区域。对该矩形区域进行遍历,取出Alpha_Canvas画布上每个颜色点的Alpha通道值,根据此值从调色板上取出对应的颜色,R、G、B三个值用从调色板取来的值,但Alpha通道值不能相同,在这里可以设置一个阈值,用于决定渐变开始的半径,也可以自由修改。将这四个值决定的颜色点绘制到Output_Canvas画布上,依此操作,直至遍历结束。
      H、完成着色操作后,整个绘图过程就完毕了。
3、开源项目
     JavaScript 版本:[heatmap.js]   http://www.patrick-wied.at/static/heatmapjs/index.html
     Python 版本:[pyHeatMap]  https://github.com/oldj/pyheatmap
     C++/Qt版本:[QHeatMap]   https://github.com/pbesedm/QHeatMap [本人实现]
4、JavaScript、Python、C++三种实现方法都有,相信你能明白原理,不明白请回复或联系我。

三、截图
[attachment=10591]
[attachment=10590]



























pxiao_xiao 2013-06-29 15:43
这是好贴啊 咋没人回复

XChinux 2013-06-29 16:14
需要用到这个的朋友自然有用,哈哈,大多数人碰不到这类需求.

zinsser 2013-06-29 20:58
对于这一类等值云图,用OpenGL实现似乎更为直接。但若要绘制等值线图,不知道有没有什么成熟的解决方案?

pbe_sedm 2013-06-30 12:44
如果把思路拓展一下,这种解决问题的方法可以在很多地方用得上,比如频谱分析的密度图,光谱图之类的,具体细节就不聊了,有心的朋友肯定能发现它的价值。

e730052 2013-07-01 20:14
这种程度,算完美了。

voidbroken 2013-07-03 12:52
好贴

pamxy 2013-07-25 19:36
果断收藏了 _  _

realfan 2013-07-26 11:36
很专业

似水流年 2013-07-27 17:48
引用楼主pbe_sedm于2013-05-25 13:43发表的 用 Qt 生成热图(heat map) :
热图有时候叫热区图或者热力图,都是用于表现某种事物密集度的图形化显示。
我写的这个没有画底图,不然会更有趣,比如一个键盘,一张房屋平面图,或者一张Google地图,拿它做什么用,完全取决于你的需要。
一、主要用途
1、网站设计,可以帮助设计人员知道用户喜欢点哪些地方,对哪些东西感兴趣,以此来改良设计,改善用户体验,百度和腾讯都有提供此类有偿服务。 对位置不敏感,就比如有张全身照的美女图,通过统计就可以知道别人最喜欢看美女的哪个部位,是不是很有意思。
.......



neil-wen 2013-08-08 14:38
不错  很好

kelvinyeah 2013-08-12 14:08
Professional,应该医疗领域用的比较多吧!好东西!

一去丶二三里 2013-12-20 15:41
好东西就是需要被顶。。。

量子飞跃 2013-12-21 19:15
高端 大气 让我想起了卫星云图

月亮加加加 2014-03-18 18:40
您好!我现在想通过很多点数据(包含经纬度),制作热力地图反映哪些区域的点分布比较密集。 了解了百度热力图API示例(http://developer.baidu.com/map/jsdemo.htm#c1_15),源代码中的point带有count属性,这里count是表达什么含义?另外,我的实验点数据仅仅包含经纬度信息,不知道能否通过百度API实现热力地图?

foxgod 2014-03-19 08:36
月亮加加加:您好!我现在想通过很多点数据(包含经纬度),制作热力地图反映哪些区域的点分布比较密集。 了解了百度热力图API示例(http://developer.baidu.com/map/jsdemo.htm#c1_15),源代码中的point带有count属性,这里count是表达什么含义?另外,我的实验点数据仅仅包含经纬度信息,不 .. (2014-03-18 18:40) 

你说我想写个程序,通过手机GPRS知道对方在百度地图上什么位置,应该怎么写??

woshizfs 2014-03-19 10:18
编译的时候怎么报错:
F:\opensource\QHeatMap-master\QHeatMap-master\test\mainwindow.cpp:36: 错误:no matching function for call to 'QImage::fill(QColor)'

pbe_sedm 2014-03-23 11:39
woshizfs:编译的时候怎么报错:
F:\opensource\QHeatMap-master\QHeatMap-master\test\mainwindow.cpp:36: 错误:no matching function for call to 'QImage::fill(QColor)' (2014-03-19 10:18) 

你Qt版本是不是太旧了?

hss2799 2014-06-16 15:45
很好,谢谢分享。

theotherone 2014-08-08 16:55
我想问的是,如果两个渐变圆圈重合的地方,alpha值怎么确定?

xubo6496918 2014-09-12 11:24
感谢楼主!

huangturen 2014-09-15 21:56
不能用啊!!!
C:\Users\biye\Downloads\QHeatMap-master\test\gradientpalette.cpp:22: error: C2614: “GradientPalette”: 非法的成员初始化:“gradient_”不是基或成员
C:\Users\biye\Downloads\QHeatMap-master\test\gradientpalette.cpp:42: error: C2065: “gradient_”: 未声明的标识符

等等!

nwnmrj 2015-06-07 18:30
好东西!

x85371169 2017-10-17 14:00
绘图速度比js版本慢了好多好多


查看完整版本: [-- 用 Qt 生成热图(heat map) --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled