Learn OpenCV之Heatmap

article/2025/10/30 21:22:22

本文是利用热图(Heatmap)分析视频序列的标定。
注意,这里目的不是标定而是分析标定好的数据,或者也可以是检测的结果数据

文章结构是这样的,先详细的解释一下热图分析有什么用,根据一些具体的应用实例给出相应的教程和Python实现代码。

为什么要用热图对Logo检测结果进行分析

在计算机视觉中,经常会有将视频帧中的物体用四边形、多边形或者掩码(masks)标定出来的工作。标定的工作可以是人工手动的对一些训练数据,也可以是为了利用机器学习等方法对物体进行自动检查和跟踪得到的。

逐帧的分析上述得到的标定数据是不现实的,因为会有长视频的因素,有些几分钟有些几个小时,分析起来很费力。此外,虽然视频时长较短,但是视频个数很多,例如训练数据集。这时候使用热图分析会将分析任务变得很方便直观。

热图能有效的分析视频中物体的曝光位置和曝光量。视频帧中某些位置出现频率高(曝光量高),那么热图对应位置处是红色的(hot),相反的,视频帧中某些位置出现频率低(曝光量低),那么热图对应位置处是蓝色的(cool)。

使用热图分析各种logo的曝光量

Orpix公司利用DL的方法将数字媒体中的商标、logos检测出来,然后对赞助商进行估价,下面是该公司logo检测的一个例图。
在这里插入图片描述

赞助商会在他们赞助的活动上将他们的logo投放到数字板和衣服上。市场调查人员基于多种因素评估品牌的曝光质量,考虑的因素有如下:

  1. 曝光时间,在屏幕上曝光时间越长,广告投放的就越成功
  2. 曝光位置,logo的曝光位置越靠近下面几个位置上认为曝光质量越高:
    a. 视频帧的中间,因为视频帧的中间位置更能吸引观众的关注
    b. 著名球星的衣服上
  3. logo大小和清晰度,在广告中,广告大小对曝光质量影响很大。毫无疑问,一个广告占满整个屏幕会比没有占满整个屏幕的广告更有影响力。相似的,清晰的广告会比模糊的广告更有影响力。
  4. 独占曝光位置,广告商在为自己产品或者商标打广告时不喜欢和其他的商标分享曝光时间。他们通常喜欢在独占一定时间内的所有广告位置,如上图所示。

利用热图分析视频中logo的曝光情况,能提升曝光质量评价的速度。

2018世界杯决赛中的logo分析

2018世界杯是全世界上亿人的狂欢时段。甚至在某些国家,世界杯期间不用上班,非常的high。

当人们聚集在电视前讨论着他们喜欢的足球队时,还有很多数据分析师正在做着数据的分析工作,目的是为了分析比赛期间所展示的赞助活动的有效性。

Orpix公司利用一些logo的检测算法对美国直播的视频进行logo的检测。世界杯决赛时长为2小时26分钟13秒。该公司按照每秒一帧对视频进行抽样,总共抽取了8773帧图像。

Nike Logo检测分析

毋庸置疑,Nike(世界上最大的运动品牌公司)投放的logo,在运动员衣服上,出现了1221帧,以占比赛14%时长的成绩登顶为曝光最长的logo。下面是Nike的曝光热图。
在这里插入图片描述

虽然Nike在整场比赛中曝光时间最长,但是热图显示,曝光在整个图像的分布非常均匀。这点也很容易的从最长36s曝光时间的图像和整个1221曝光帧中看出。从热图上吸引人的是一小块红色的点是怎么来的。通过观察这个位置的原图,可以知道,当介绍球员时,Nike也跟着产生曝光量,如下图所示。

在这里插入图片描述

VISA Logo检测分析

除了分析球员衣服上的logo外,还可以分析数字板上的logo。信用卡处理公司VISA在数字板上曝光时间最长(769s),运动品牌巨头Adidas紧随其后。

VISA logo的热图如下图所示。下面红色区域是80帧的结果,其位置分布在图片的左上角。不同于Nike的热图均匀分布在整张图片,它的热图主要集中在一个特定的区域。原因是logo是在数字板上显示的,而不是和Nike一样出现在不断移动的运动员身上。

在这里插入图片描述

这里,Orpix给出了世界杯决赛的所有分析样例

Logo 热图生成的代码

下面是根据Orpix给出的VISA logo检测数据进行分析生成热图的代码。

在学习代码前需要的环境是

  • opencv-python
  • matplotlib
  • numpy
Code Overview
  • generate_heatmap.py 生成热图代码文件
  • 世界杯决赛Visa标定数据

下载好上面的数据,将数据加压后与代码文件放在同一个文件夹下即可运行。

输入

labels.txt - 里面包含了对应图片的VISA logo标定信息,文件里每行数据如下定义:
图片路径 图片中logo数量 x1 y1 x2 y2 x3 y3 x4 y4 …

注意:这里定义的框不是矩形所以不能使用x,y,width,height表示而是采用四个点的坐标表示

输出

高亮的帧 - 输出对应于每张输入的logo区域高亮(其实将非logo区域加一个蒙层,为了大家容易理解,也为了方便调试)图片
热图 - 输出一张名为"heatmap.png"的热图,热图的生成用的是matplotlib包里的函数

代码细节

首先,初始化一个空的numpy array数组,用来存储生成heatmap的数据。

#keeps track of exposure time per pixel.  Accumulates for each image
#gets initialized when we process the first image
accumulated_exposures = None
#frames were sampled at one second per frame.  If you sampled frames from a 
#video at a different rate, change this value.
#
#if you sampled frames at 10 frames per second, this value would be 0.1
#
seconds_per_frame = 1.0

然后读取labels.txt获取每张图片的logo位置,为每张图片生成一个mask,mask中logo区域值为seconds_per_frame,非logo区域值为0。最后将所有的mask相加就可以得到产生热图的数据了。

#parse the line using helper function
frame_path, labels = parse_line(line)print "processing %s" % frame_path#load the image
frame = cv2.imread(frame_path)#this is where the highlighted images will go
if not os.path.exists('output'):os.mkdir('output')#if the heatmap is None we create it with same size as frame, single channel
if type(accumulated_exposures) == type(None):accumulated_exposures = np.zeros((frame.shape[0], frame.shape[1]), dtype=np.float)#we create a mask where all pixels inside each label are set to number 
#of seconds per frame that the video was sampled at.
#So as we accumulate the exposure heatmap counts, each pixel contained 
#inside a label contributes the seconds_per_frame to the overall 
#accumulated exposure values
maskimg = np.zeros(accumulated_exposures.shape, dtype=np.float)
for label in labels:cv2.fillConvexPoly(maskimg, label, (seconds_per_frame))#highlight the labels on the image and save.
#comment out the 2 lines below if you only want to compute the heatmap
highlighted_image = highlight_labels(frame, labels, maskimg)
cv2.imwrite('output/%s' % os.path.basename(frame_path), highlighted_image)#accumulate the heatmap object exposure time
accumulated_exposures = accumulated_exposures + maskimg

最后,利用matplotlib画出热图

#
#create final heatmap using matplotlib
# 
data = np.array(accumulated_exposures)
#create the figure
fig, axis = plt.subplots()
#set the colormap - there are many options for colormaps - see documentation
#we will use cm.jet
hm = axis.pcolor(data, cmap=plt.cm.jet)
#set axis ranges
axis.set(xlim=[0, data.shape[1]], ylim=[0, data.shape[0]], aspect = 1)
#need to invert coordinate for images
axis.invert_yaxis()
#remove the ticks
axis.set_xticks([])
axis.set_yticks([])#fit the colorbar to the height
shrink_scale = 1.0
aspect = data.shape[0]/float(data.shape[1])
if aspect < 1.0:shrink_scale = aspect
clb = plt.colorbar(hm, shrink=shrink_scale)
#set title
clb.ax.set_title('Exposure (seconds)', fontsize = 10)
#saves image to same directory that the script is located in (our working directory)
plt.savefig('heatmap.png', bbox_inches='tight')
#close objects
plt.close('all')

代码下载
原博客-Heapmap for Logo Detection using OpenCV (Python)


http://chatgpt.dhexx.cn/article/jSAyIUwP.shtml

相关文章

python heatmap画法

任务描述 将一个归一化的分数以热图的形式显示出来&#xff0c;分数高的地方颜色深&#xff0c;分数小的地方颜色浅 注意&#xff1a;使用单一颜色无法实现这种渐变过程 原理 将单通道的0-1之间的score值映射到三通道的颜色空间 原料 一个单通道的score矩阵颜色空间列表&a…

python heatmap总结

基础使用 import seaborn as sns; sns.set_theme(color_codesTrue) iris sns.load_dataset("iris") species iris.pop("species") g sns.clustermap(iris)取消行列分类树 import seaborn as sns; sns.set_theme(color_codesTrue) import matplotlib.p…

seaborn绘制heatmap

【seaborn.heatmap整理】 用处&#xff1a;将数据绘制为颜色方格&#xff08;编码矩阵&#xff09;。 引用形式&#xff1a; seaborn.heatmap(data, vminNone, vmaxNone, cmapNone, centerNone, robustFalse, annotNone, fmt’.2g’, annot_kwsNone, linewidths0, linecolor‘…

Heatmap

前言 目前所说的模型可视化或者模型可解释说到是对某一类别具有可解释性&#xff0c;直接画出来特征图并不能说明模型学到了某种特征&#xff0c;对一个深层的卷积神经网络而言&#xff0c;通过多次卷积和池化以后&#xff0c;它的最后一层卷积层包含了最丰富的空间和语义信息…

R | 可视化 | 热图(Heatmap)

1 基础绘制 R绘制热图时&#xff0c;数据需要输入一个矩阵&#xff0c;可以用as.matrix()把它转换成矩阵。这里利用R自带的数据集绘制热图。 > # 数据 > data <- as.matrix(mtcars) > > # 绘制热图 > heatmap(data) OUTPUT: 热图的每一列是一个变量&…

科研作图-heatmap(一)

1.简介 在科研中有很多地方为了可解释给审稿人提供了热图,便于知道深度学习中到底是哪部分在起作用,或者是在机器学习中分析不同的特征之间是否存在相关性?存在多大的相关性;或者是直观的展示场景热力图…总之,用处很多,我正好现在也需要用,就先总结下:绘制HeatMap的库有很多,…

「C#」生成HeatMap(热度图)的实现

1、什么是Heatmap 其实不用多言&#xff0c;需要这个的人自然知道这是什么。基于一系列点生成的热度图&#xff0c;放张图感受一下&#xff1a; ma...大概就是这种样子。 2、生成&#xff08;计算&#xff09;原理 实现方式实际上是在每个点上叠加高斯矩阵。高斯矩阵就是在二…

关键点检测的heatmap介绍

开始学关键点检测的时候&#xff0c;到处找找不到heatmap的解释。现在大概有些懂了&#xff0c;干脆自己写一个。部分转载。 关键点定位任务两种做法&#xff1a;heatmap和fully connected回归&#xff08;Heapmap-based和Regression-Based&#xff09; heatmap得到一张类似热…

python绘制热度图(heatmap)

1、简单的代码 from matplotlib import pyplot as plt import seaborn as sns import numpy as np import pandas as pd#练习的数据&#xff1a; datanp.arange(25).reshape(5,5) datapd.DataFrame(data)#绘制热度图&#xff1a; plotsns.heatmap(data)plt.show() 查看效果&a…

热图(Heatmap)绘制(matplotlib与seaborn)

热图是数据统计中经常使用的一种数据表示方法&#xff0c;它能够直观地反映数据特征&#xff0c;查看数据总体情况&#xff0c;在诸多领域具有广泛应用。 一&#xff1a;matplotlib绘制方法 1.基础绘制 热图用以表示的是矩阵数据&#xff0c;例如相关阵、协差阵等方阵&#…

‘0’ 和 '\0'

48是0对应的ascii值。

KEIL/MDK编译优化optimization选项注意事项

KEIL编译器C语言编译选项优化等级说明 -Onum Specifies the level of optimization to be used when compiling source files. Syntax -Onum Where num is one of the following: 0 Minimum optimization. Turns off most optimizations. When debugging is enabled, this opt…

0,'\0','0'

#include <iostream> using namespace std; int main(void) { cout<<__FILE__<<\t<<__LINE__<<endl;cout<<"内 容:\t"<<"0"<<\t<<"\\\0\"<<\t<<"\0\"<<…

Odoo

狭路相逢 勇者胜 Odoo 是用于经营公司的最好的管理软件。 数百万用户使用我们的集成应用可以更好地开展工作 现在开始。免费的。 重新定义可扩展性 一个需求&#xff0c;一个应用程式。整合从来没有那么顺畅 促进销售量 客户关系管理POS销售 整合您的服务 项目工时表帮助…

0 、 '0' 、 0 、 ’\0’ 区别

转载自&#xff1a;https://blog.csdn.net/qnavy123/article/details/93901631 ① ‘0’ 代表 字符0 &#xff0c;对应ASCII码值为 0x30 (也就是十进制 48) ② ‘\0’ 代表 空字符(转义字符)【输出为空】 &#xff0c;对应ASCII码值为 0x00(也就是十进制 0)&#xff0c; …

Linux的内核编译用O0是编译不过的

最近在ATF的升级过程中遇到了一个编译问题&#xff0c;最后是通过编译优化解决的&#xff0c;然后一百度这个优化全是在Linux中的。于是就借着Linux编译优化来学学。 内容来自 宋宝华老师&#xff1a; 关于Linux编译优化几个必须掌握的姿势 1、编译选项和内核编译 首先我们都…

alert uuid does not exits. Dropping to a shell!

ALERT&#xff01;UUID does not exit. Dropping to a shell&#xff01; 服务器系统ubuntu16.04server&#xff0c;非自然断电后开机进入initramfs模式&#xff0c;服务器磁盘阵列是raid1和raid5。初步分析是硬盘坏道或掉盘&#xff0c;进入raid卡里看到硬盘一切正常&#xf…

跟着团子学SAP PS:如何查询PS模块中的user exits以及相关BAdIs SE80/SMOD/CNEX006/CNEX007/CNEX008

在PS很多标准字段或功能无法满足客户需求的时候往往需要通过SAP标准的user exits或者BAdI进行开发以满足业务需要&#xff0c;所以今天介绍下如何查询PS模块中的用户出口以及BAdIs&#xff1a; &#xff08;1&#xff09;查询PS模块中的user exits: 执行SE80&#xff0c;在菜…

EXT

ext的核心是store&#xff0c;存储数据用的。调试时可以先把store这块先屏蔽掉&#xff0c;先看页面的&#xff0c;页面出来了再调试store。这样会调试起来很快。 init: function () { var view this.getView(), // var store Global.getStore(app.store.L…

IDEA|class path resource XXX cannot be opened because it does not exits

IDEA|class path resource XXX cannot be opened because it does not exits 问题截图&#xff1a; 原因&#xff1a;没有设置好各个文件夹。我的理解是&#xff0c;当把文件夹设置好具体的功能才能被IDEA自动识别。 解决方法&#xff1a; 转发链接&#xff1a;https://bl…