MATLAB | 如何从热图中提取数据

news2025/1/21 12:01:08

这期做了个可能有用的小工具,一般论文中热图很少给出数据,于是就想写个小工具通过热图上的颜色估计出数据值来,目前写了个初版的工具分享给大家!

工具函数

由于只是初版,要手动改的地方还是不少的,要设置好要提取数据的图片地址,结果存储地址,数据热图行数、列数以及colorbar的范围。

function getHeatmapData
% 要提取的图像地址
picPath='1.png';
% 提取结果存储路径
HMPath='data1.mat';
% 热图行数、列数
heatMapSize=[8,8];
% colorbar所表示范围
climColorbar=[-1,1];
% 提取colorbar上颜色点数量
pntNumColorBar=20;
% 数据计算所用点数(数值越大越精确)
pntNumInterp=1000;



% figure窗口初始化
pic=imread(picPath);
figure()
ax=gca;hold on
ax.XLim=[0,size(pic,2)];
ax.YLim=[0,size(pic,1)];
imshow(pic)
% 绘制红蓝色点的句柄
baHdl=plot(ax,0,0,'b+','MarkerSize',12,'LineWidth',1.5);
rxHdl=plot(ax,0,0,'rx','MarkerSize',12,'LineWidth',1.5);
pntSet=zeros(0,2);
colorSet=zeros(4,3);
set(gcf,'WindowButtonDownFcn',@buttondown)

    function buttondown(~,~)
        xy=get(gca,'CurrentPoint');
        xp=xy(1,2);yp=xy(1,1);pos=[yp,xp];
        if strcmp(get(gcf,'SelectionType'),'normal')
            pntSet=[pntSet;pos];
        elseif size(pntSet,1)>0
            pntSet(end,:)=[];
        end
        pntSet=round(pntSet);
        pntSet(pntSet<1)=1;
        if size(pntSet,1)>4
            set(gcf,'WindowButtonDownFcn',[])
            saveColor();
            close all
        else
        % 标记采样点位置和数值
        baHdl.XData=pntSet(:,1);baHdl.YData=pntSet(:,2);
        rxHdl.XData=pntSet(:,1);rxHdl.YData=pntSet(:,2);
        delete(findobj('type','text'))
        for i=1:size(pntSet,1)
            colorSet(i,:)=[pic(pntSet(i,2),pntSet(i,1),1),...
                           pic(pntSet(i,2),pntSet(i,1),2),...
                           pic(pntSet(i,2),pntSet(i,1),3)];
            text(ax,pntSet(i,1),pntSet(i,2),['    ',num2str(i),':[',num2str(colorSet(i,1)),',',...
                 num2str(colorSet(i,2)),',',num2str(colorSet(i,3)),']'])
        end
        end
    end
    function saveColor(~,~)
        % 获取colorbar上颜色
        cbPntSet=pntSet(1:2,:);
        cbPntSetdiff=abs(cbPntSet(1,:)-cbPntSet(2,:));
        if cbPntSetdiff(1)>cbPntSetdiff(2)
            tPntSet=cbPntSet(1,1)+linspace(0,1,pntNumColorBar)'.*(cbPntSet(2,1)-cbPntSet(1,1));
            tPntSet=round(tPntSet);
            CMap=[pic(round((cbPntSet(1,2)+cbPntSet(2,2))/2),tPntSet,1)',...
            pic(round((cbPntSet(1,2)+cbPntSet(2,2))/2),tPntSet,2)',...
            pic(round((cbPntSet(1,2)+cbPntSet(2,2))/2),tPntSet,3)'];
        else
            tPntSet=cbPntSet(1,2)+linspace(0,1,pntNumColorBar)'.*(cbPntSet(2,2)-cbPntSet(1,2));
            tPntSet=round(tPntSet);
            CMap=[pic(tPntSet,round((cbPntSet(1,1)+cbPntSet(2,1))/2),1),...
            pic(tPntSet,round((cbPntSet(1,1)+cbPntSet(2,1))/2),2),...
            pic(tPntSet,round((cbPntSet(1,1)+cbPntSet(2,1))/2),3)];
        end
        CMap=double(CMap);
        % -----------------------------------------------------------------
        % 提取heatmap上颜色
        hmPntSet=pntSet(3:4,:);
        hmXLim=[min(hmPntSet(:,1)),max(hmPntSet(:,1))];
        hmYLim=[min(hmPntSet(:,2)),max(hmPntSet(:,2))];
        YList=linspace(hmYLim(1),hmYLim(2),heatMapSize(1));
        XList=linspace(hmXLim(1),hmXLim(2),heatMapSize(2));
        [XMesh,YMesh]=meshgrid(round(XList),round(YList));
        CMesh=zeros(heatMapSize);
        for i=1:heatMapSize(1)
            for j=1:heatMapSize(2)
                CMesh(i,j,1)=pic(YMesh(i,j),XMesh(i,j),1);
                CMesh(i,j,2)=pic(YMesh(i,j),XMesh(i,j),2);
                CMesh(i,j,3)=pic(YMesh(i,j),XMesh(i,j),3);
            end
        end
        % 计算heatmap数值范围
        CMesh=double(CMesh);
        t1=linspace(climColorbar(1),climColorbar(2),pntNumColorBar)';
        t2=linspace(climColorbar(1),climColorbar(2),pntNumInterp)';
        CMapInterp=[interp1(t1,CMap(:,1),t2,'linear'),interp1(t1,CMap(:,2),t2,'linear'),interp1(t1,CMap(:,3),t2,'linear')];
        Data=zeros(heatMapSize);
        for i=1:heatMapSize(1)
            for j=1:heatMapSize(2)
                tRGB=[CMesh(i,j,1),CMesh(i,j,2),CMesh(i,j,3)];
                tnorm2=sum((CMapInterp-tRGB).^2,2);
                [ind,~]=find(tnorm2==min(tnorm2),1);
                Data(i,j)=t2(ind);
            end
        end
        % 存储数值
%         timestr=char(datetime('now'));
%         timestr(timestr==' ')='_';
%         timestr(timestr==':')='_';
%         nowStr=[timestr,'.mat'];
        CMapInterp=CMapInterp./255;
        CMap=CMap./255;
        save(HMPath,'Data','CMap','CMapInterp','climColorbar')
    end
end

基本使用

假设有这么一张图(压缩包内提供的示例图7)

要提取的数据8行8列,colorbar范围-1到1,因此将工具函数最前面的代码做出如此改动:

% 要提取的图像地址
picPath='7.png';
% 提取结果存储路径
HMPath='data7.mat';
% 热图行数、列数
heatMapSize=[8,8];
% colorbar所表示范围
climColorbar=[-1,1];
% 提取colorbar上颜色点数量
pntNumColorBar=20;
% 数据计算所用点数(数值越大越精确)
pntNumInterp=1000;

依次点击colorbar最小值处,最大值处,以及热图的对角线两个点处,之后随便点击图片任意处(共点击五次),就能将数据存储在mat文件中:

大概这样取四个点,并随便点击图像某处(若是点错了可鼠标右键撤回):

之后查看mat文件:

其中:

  • Data 提取的热图数据
  • CMap colormap
  • CMapInterp 插值后colormap
  • climColor colorbar范围

获取了这些数据后,可以很轻松的靠以下代码复刻出来图像:

HM=load('data7.mat');
HMHdl=heatmap(HM.Data);
colormap(HM.CMapInterp)
% 新版本可以将caxis换为clim
caxis(HM.climColorbar)

% 不显示数值
HMHdl.CellLabelColor='none';

看起来提取的很完美,虽然肯定有误差,但是对于一般的论文复现已经足够了:


行列数不相同

几乎完全相同的处理手段,比如此图是15行20列,colorbar范围是-0.6到0.8,将最前面的代码修改为:

% 要提取的图像地址
picPath='6.png';
% 提取结果存储路径
HMPath='data6.mat';
% 热图行数、列数
heatMapSize=[15,20];
% colorbar所表示范围
climColorbar=[-.6,.8];
% 提取colorbar上颜色点数量
pntNumColorBar=20;
% 数据计算所用点数(数值越大越精确)
pntNumInterp=1000;

运行后进行取点:

之后还是运行绘图代码:

HM=load('data6.mat');
HMHdl=heatmap(HM.Data);
colormap(HM.CMapInterp)
% 新版本可以将caxis换为clim
caxis(HM.climColorbar)

% 不显示数值
HMHdl.CellLabelColor='none';

数据提取结果:


非方形色块热图

依旧依据热图性质修改一下参数:

% 要提取的图像地址
picPath='4.png';
% 提取结果存储路径
HMPath='data4.mat';
% 热图行数、列数
heatMapSize=[11,11];
% colorbar所表示范围
climColorbar=[-1,1];
% 提取colorbar上颜色点数量
pntNumColorBar=20;
% 数据计算所用点数(数值越大越精确)
pntNumInterp=1000;

这种圆点形状的尽量要取点时取在正中央

数据提取结果:


色块上有文本

依旧依据热图性质修改一下参数:

% 要提取的图像地址
picPath='8.png';
% 提取结果存储路径
HMPath='data8.mat';
% 热图行数、列数
heatMapSize=[8,8];
% colorbar所表示范围
climColorbar=[-1,1];
% 提取colorbar上颜色点数量
pntNumColorBar=20;
% 数据计算所用点数(数值越大越精确)
pntNumInterp=1000;

有文本的热图,在热图色块上点击时,尽量俩点点击在同一位置且不要碰到文字,比如俩色块都点击同一边角(下图所示即为点击两个色块左下角):

提取效果:


以上已给出完整代码,想要更多例子练练手:

【热图数据提取】

更新时会跟进更新以下连接:
【链接】:
https://pan.baidu.com/s/1zoStpQ54LqmR7fSXMWWyOA?pwd=slan

【提取码】:slan

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/151827.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PHP多商户AI智能在线客服系统源码 机器人自动回复 即时通讯聊天系统源码

一套智能在线客服系统源码 多商户网页客服系统源码 支持二十种国际语言 带机器人自动回复。 框架&#xff1a;Thinkphp5workerman&#xff0c; 环境&#xff1a;nginxphp7.3mysql5.6 支持H5公众号APP小程序 了解更多可私信我&#xff01; 系统功能&#xff1a; 1、支持国际…

编写程序时调用第三方程序时使用的是相对路径而不是绝对路径会造成什么严重后果(Windows Linux)

简介 在编写程序时&#xff0c;有很多人调用第三方程序使用的是相对路径&#xff0c;而不是绝对路径&#xff0c;如下&#xff1a; #!/bin/python3import osos.system("whoami") #调用whoami程序&#xff0c;查看当前用户名#!/bin/bashfind / -name "hellowor…

day10|239. 滑动窗口最大值、347.前 K 个高频元素

239. 滑动窗口最大值 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值 。 示例 1&#xff1a; 输入&#xff1a;nums [1,3…

如何修改视频MD5的格式?这些方法值得你收藏

MD5实际上是计算机安全领域中广泛使用的一种散列函数&#xff0c;可以用来保护消息的完整性&#xff0c;简单来说就是类似于我们的指纹&#xff0c;可以说MD5是每个文件的“数字指纹”。比如&#xff1a;我们在平台上传一些热门视频&#xff0c;平台会自动识别视频的MD5值&…

嵌入式 LINUX 驱动开发 day01 第一个内核模块程序 多文件编译为一个程序, 内核模块参数, 内核模块依赖

1.第一个内核模块程序 ( 记得配置自己的交叉编译的工具,) 首先两个文件 vser.c Makefile (记得大写的M) vser.c #include <linux/init.h> //内核初始化头文件 #include <linux/module.h> //内核模块文件 #include <linux/kernel.h> //&…

Java基础算法每日5道详解(6)

112. Path Sum 路径总和 Given the root of a binary tree and an integer targetSum, return true if the tree has a root-to-leaf path such that adding up all the values along the path equals targetSum. A leaf is a node with no children. Example 1: Input: ro…

html+css实现一个响应式管理平台架构模板

文本将会带你使用htmlcss实现一个响应式的管理平台架构模板&#xff0c;目前来说市面上的管理平台架构模板大同小异&#xff0c;文本的知识点都会符合场景所需。 目录 1、管理平台的架构内容 2、顶部的布局 3、下半部分布局 4、左侧菜单区域实现 5、右侧主体区域实现 …

前端重新部署如何通知用户刷新网页?

我把我掘金的文章同步一份给CSDN 1.目标场景 有时候上完线&#xff0c;用户还停留在老的页面&#xff0c;用户不知道网页重新部署了&#xff0c;跳转页面的时候有时候js连接hash变了导致报错跳不过去&#xff0c;并且用户体验不到新功能。 2.思考解决方案 如何去解决这个问…

顶象助力绿球金科打造App低碳出行场景

“低碳出行”、“碳中和”、“碳惠普”正在成为近几年的科技热词之一。 自2020年9月&#xff0c;中国向世界许下“力争2030年前实现碳达峰&#xff0c;2060年前实现碳中和”的承诺以来&#xff0c;一场围绕绿色节能、低碳减排的变革正在席卷各行各业。 “碳中和”已经成为时代…

如何让SCI期刊审稿人,理解你的文章? - 易智编译EaseEditing

首先需要对论文进行全文润色 对于发表论文来说&#xff0c;进行润色是必须的&#xff0c;正因为SCI论文翻译要求高难度大&#xff0c;无论笔译还是口译都一定要有过硬的基本功&#xff0c;知识面要足够宽广&#xff0c;专业综合能力要求高。 所以当一篇论文的整体结构不到位&…

凯恩帝机床联网

一、设备信息确认 1、确认型号 数控面板拍照确认&#xff1a; 此系统为&#xff1a;K1TCi 注&#xff1a;凡是系统中带i的&#xff0c;基本上都含网口。 2、确认通讯接口 网口常见位置&#xff0c;XS92&#xff08;丝印标号&#xff09;&#xff0c;可通过这个确认&#x…

PnetLab模拟器安装锐捷镜像

安装准备&#xff1a; 1.安装完成pnetlab&#xff0c;这里不过多叙述&#xff1b; 2.在锐捷的网站下载好模拟器镜像&#xff08;目前只支持Switch和Router&#xff09;&#xff0c;下载地址&#xff1a;https://www.ruijie.com.cn/fw/wd/88899/ 官网下载后的内容包括下面几个…

Linux umount报错:device is busy

执行nfs卸载命令umount /mnt&#xff0c;报错target is busy. 或device is busy可以按以下步骤检查&#xff1a;退出要卸载挂载的目录&#xff0c;再执行卸载挂载cd ../umount /mnt找出占用目录的端口&#xff0c;kill端口fuser -m /mnt/kill -9 端口umount /mnt停止nfs服务&am…

计算机基础——操作系统

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.操作系统 1.操作系统简介 2.操作系统的主要功能 &#xff08;1&#xff…

【Kotlin】字符串操作 ② ( 字符串替换函数 replace | 字符串比较操作符 == 和 === | 字符串遍历 forEach )

文章目录一、字符串替换函数 replace二、字符串比较操作符 和 三、字符串遍历 forEach一、字符串替换函数 replace 字符串替换函数 replace 函数原型如下 : /*** 返回一个新字符串&#xff0c;通过替换此字符序列中匹配给定正则表达式的每个子字符串获得* 用给定的[替换]。**…

一个芯片工程师的ADC学习笔记 (二)

众所周知&#xff0c;ADC主要用于对模拟信号进行数字采集&#xff0c;以进行数据处理。我们周围的信号一般都是不断变化的模拟量&#xff0c;如光、温度、速度、压力、声音等。然而&#xff0c;我们大多数人都使用数字设备。如果我们想方便地使用和处理信息&#xff0c;就需要将…

【机器学习】关联规则挖掘算法 + 三大案例实战 + Apriori算法 + Python代码实现

文章目录一、关联规则概述1.1 关联规则引入1.2 关联规则相关概念介绍1.2.1 样本、事务、项集、规则1.2.2 支持度、置信度1.2.3 提升度1.2.4 所有指标的公式二、Python实战关联规则2.1 使用 mlxtend 工具包得出频繁项集与规则2.1.1 安装 mlxtend 工具包2.1.2 引入相关库2.1.3 自…

MP3解码算法原理解析

一&#xff1a;MP3编解码整体结构介绍 看懵逼了是吧。这里面有很多概念需要一一讲解。 比特流&#xff1a;比特流是一种内容分发协议。它采用高效的软件分发系统和点对点技术共享大体积文件&#xff08;如一部电影或电视节目&#xff09;&#xff0c;并使每个用户像网络重新分配…

记录--微信调用jssdk--Invalid Signature, updateAppMessageShareData: denied等问题

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 最近在做安卓内嵌入H5活动页拉新活动&#xff0c;遇到的棘手问题记录下&#xff0c; 一是为了日后遇到同样问题好回顾&#xff0c;二是希望能帮到有同样问题的兄弟。 废话不多说&#xff0c;先从最棘手…

【高阶数据结构】封装Map和Set

&#x1f308;欢迎来到数据结构专栏~~封装Map和Set (꒪ꇴ꒪(꒪ꇴ꒪ )&#x1f423;,我是Scort目前状态&#xff1a;大三非科班啃C中&#x1f30d;博客主页&#xff1a;张小姐的猫~江湖背景快上车&#x1f698;&#xff0c;握好方向盘跟我有一起打天下嘞&#xff01;送给自己的一…