在作热度图的时候我们经常需要将热度图调整透明度后叠加在原图上达到更好的展示效果。比如检测人气密度的热度图:



(来自sensetime)

一般作图的时候会第一时间想到matplotlib,因为可以很方便作几乎任何图图,但是最近发现用opencv也很容易执行这个操作。

1. 获取人群密度

输入一张图片我们首先需要获取里面有多少人以及每个人所在的位置信息。这个工作比较复杂,这里不展开讲了,不过提一下集中模式:一种是人群密度不高的场景,可以利用行人检测识别图片中的人及其所在位置,这个方法有很多了,像MTCNN,RCNN,YOLO之类的方法都能用;另一种是广场高密度人群的场景,这样的话因为人与人之间的重叠度很高,大部分人是检测不到的,需要利用检测人头或者用这篇文章的方法来提高检测精度。

2. 热度图的梯度设置

热力图的颜色主要表现的就是这个点代表的人群密度,密度越高,颜色越深。之前我们获取的是检测到的人的bounding box的中心的坐标,那么获取每个点的热度有一下两种方法:1. 设定半径,计算每个像素点在此半径内所包含的人所在的点的数量,此数量即代表词典的热度;2. 设定半径,以每个人所在的点以此半径设定热度梯度,如果两个点有交叉将交叉区域的热度叠加。第一种方法如果图片比较大的时候会很慢,所以一般用第二种。

3. 根据热度分配像素颜色

所谓的热度图就是根据所在位置的值的大小从颜色梯度提取合适的颜色。获取颜色梯度可以通过matplotlib的get_cmap函数,也可以用colour包下的Color函数自己定义(当然也可以用matplotlib定义,就是有点麻烦)。

下面的例子就是用上述2里面第一种结合get_cmap/Color函数将每个像素的热度转换成相应的颜色:

def density_heatmap(image, box_centers, radias=100):
import matplotlib.pyplot as plt
from colour import Color
density_range = 100
gradient = np.linspace(0, 1, density_range)
img_width = image.shape[1]
img_height = image.shape[0]
density_map = np.zeros((img_height, img_width))
color_map = np.empty([img_height, img_width, 3], dtype=int)
# get gradient color using rainbow
cmap = plt.get_cmap("rainbow") # 使用matplotlib获取颜色梯度
blue = Color("blue") # 使用Color来生成颜色梯度
hex_colors = list(blue.range_to(Color("red"), density_range))
rgb_colors = [[rgb * 255 for rgb in color.rgb] for color in hex_colors][::-1]
for i in range(img_height):
for j in range(img_width):
for box in box_centers:
dist = distance.euclidean(box, (j, i))
if dist <= radias * 0.25:
density_map[i][j] += 10
elif dist <= radias:
density_map[i][j] += (radias - dist) / (radias * 0.75) * 10
ratio = min(density_range-1, int(density_map[i][j]))
for k in range(3):
# color_map[i][j][k] = int(cmap(gradient[ratio])[:3][k]*255)
color_map[i][j][k] = rgb_colors[ratio][k]
return color_map

但是利用heatmap包可以很方便用2里面的第二种方式画热度图:

def use_heatmap(image, box_centers):
import heatmap
hm = heatmap.Heatmap()
box_centers = [(i, image.shape[0] - j) for i, j in box_centers]
img = hm.heatmap(box_centers, dotsize=200, size=(image.shape[1], image.shape[0]), opacity=128, area=((0, 0), (image.shape[1], image.shape[0])))
return img

4. 将热度图调整透明度覆盖到原图上

利用opencv函数(opencv的安装可以参考这里)里面的addWeighted函数可以实现。

frame = cv2.imread(img) # origin image
heatmap = cv2.imread(hm) # heatmap image
overlay = frame.copy()
alpha = 0.5 # 设置覆盖图片的透明度
cv2.rectangle(overlay, (0, 0), (frame.shape[1], frame.shape[0]), (255, 0, 0), -1) # 设置蓝色为热度图基本色
cv2.addWeighted(overlay, alpha, frame, 1-alpha, 0, frame) # 将背景热度图覆盖到原图
cv2.addWeighted(heatmap, alpha, frame, 1-alpha, 0, frame) # 将热度图覆盖到原图
cv2.imshow('frame', frame)
cv2.waitKey(0)

cv2.addWeighted有6个参数(具体可以看这里):第一个为需要叠加的表层图片;第二个为叠加图片的透明度,越接近1越不透明;第三个为叠加的底层图片;第4个为底层图片的透明度,为1-alpha;第5个为一个标量直接加在两张图片的加权和上面,一般直接设为0就行;第6个为最后的加权和操作后的输出的目标图片。

通过上述操作就可以拿到所需的热度图了。

参考:

http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_core/py_image_arithmetics/py_image_arithmetics.html

http://jjguy.com/heatmap/

https://pypi.python.org/pypi/colour/

https://matplotlib.org/examples/color/colormaps_reference.html

http://www.pyimagesearch.com/2016/03/07/transparent-overlays-with-opencv/

http://bsou.io/posts/color-gradients-with-python

利用opencv作透明重叠人群密度热度图的更多相关文章

  1. 基于CNN的人群密度图估计方法简述

    人群计数的方法分为传统的视频和图像人群计数算法以及基于深度学习的人群计数算法,深度学习方法由于能够方便高效地提取高层特征而获得优越的性能是传统方法无法比拟的.本文简单了秒速了近几年,基于单张图像利用C ...

  2. 如何利用OpenCV自带的级联分类器训练程序训练分类器

    介绍 使用级联分类器工作包括两个阶段:训练和检测. 检测部分在OpenCVobjdetect 模块的文档中有介绍,在那个文档中给出了一些级联分类器的基本介绍.当前的指南描述了如何训练分类器:准备训练数 ...

  3. 利用OpenCV给图像添加中文标注

    利用OpenCV给图像添加中文标注 : 参考:http://blog.sina.com.cn/s/blog_6bbd2dd101012dbh.html  和https://blog.csdn.net/ ...

  4. 利用opencv源代码和vs编程序训练分类器haartraining.cpp

    如需转载请注明本博网址:http://blog.csdn.net/ding977921830/article/details/47733363. 一  训练框架 训练人脸检測分类器须要三个步骤: (1 ...

  5. php利用zookeeper作dispatcher服务器

    ===== https://blog.eood.cn/php_share_memory 最常见的apc 可以缓存php的opcode提高应用的性能,可以在同个php-fpm进程池间共享数据 常见功能: ...

  6. #利用openCV裁脸

    #利用openCV裁脸import cv2 def draw_rects(img, rects): for x, y, w, h in rects: cv2.rectangle(img, (x, y) ...

  7. python利用opencv去除水印方法

    OpenCV(Open Source Computer Vision Library)是一个跨平台计算机视觉库,实现了图像处理和计算机视觉方面的很多通用算法 在python中可以利用opencv来去除 ...

  8. 图像滑动窗口 利用opencv和matlab

    1.利用opencv实现图像滑动窗口操作 功能:利用opencv实现图像滑动窗口操作(即利用已知尺寸的窗口遍历整幅图像,形成许多子图像)  vs2015+opencv3.1  2016.10 函数实现 ...

  9. C# 利用 OpenCV 进行视频捕获 (笔记)

    原文:C# 利用 OpenCV 进行视频捕获 (笔记) 简介 这个项目是关于如何从网络摄像头或者视频文件(*.AVI)中捕获视频的,这个项目是用C#和OPENCV编写的. 这将有助于那些喜欢C#和Op ...

随机推荐

  1. Postgresql添加/删除触发器示例

    -- 定义触发器 CREATE TRIGGER "vss_after_insert_flow_201702" AFTER INSERT ON "public". ...

  2. OpenCV 图像处理的各种滤镜效果实现

    引自:https://blog.csdn.net/column/details/stylizefliter.html 学习OpenCV:滤镜系列(15)——羽化(模糊边缘) 在PHOTOSHOP里,羽 ...

  3. Java编程的逻辑 (39) - 剖析LinkedList

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  4. input 模糊搜索

    <html> <head> <title>test</title> <script type="text/javascript" ...

  5. Entity Framework应用:根据实体的EntityState状态实现增删改查

    在上一篇文章中,我们讲解了使用EF实现简单的增删改成,在这篇文章中我们使用实体的EntityState状态来优化数据的增删改查. 一.修改数据 上篇文章中的修改数据的方法是EF官方推荐的方式,即先查询 ...

  6. centos7配置kerberos服务,并使用JAAS登录

    准备两个虚拟机:192.168.1.101.192.168.1.102,101作为kerberos的server端,102作为kerberos的client端.开启88端口. 1.安装kerberos ...

  7. WebRTC源码分析(一):安卓相机采集实现分析

    WebRTC 的代码量不小,一次性看明白不太现实,在本系列中,我将试图搞清楚三个问题: 客户端之间如何建立连接? 客户端之间如何实现数据传输? 音视频数据的采集.预览.编码.传输.解码.渲染完整流程. ...

  8. Java线程状态及 wait、sleep、join、interrupt、yield等的区别

    Java中的线程状态(详见Java线程状态及转换-MarchOn): wait:Object类的实例方法,释放CPU执行权,进入等待状态,直到  被中断.被拥有该对象锁的线程唤醒(notify或not ...

  9. SQLite 日期 & 时间

    具体看http://www.runoob.com/sqlite/sqlite-date-time.html 不过实例介绍的不够详细,以下详细举例: SQLite包含了如下时间/日期函数:datetim ...

  10. 自然语言交流系统 phxnet团队 创新实训 项目博客 (三)

    语音转文本部分是调用的科大讯飞的在线语音,它的激发方式是按键,通过按钮触发开启安卓设备的录音,此部分需要在源码中写入关于安卓权限的要求,来调用安卓的录音权限,当按钮被激发,则开始进入语音录制阶段,将麦 ...