基于图像切割计算轨迹相似度

news2024/11/28 16:46:26

目录

  • 背景
  • 思路与核心代码
  • 数值实验
  • 优缺点分析
  • 参考文献

背景

在前面2文,我们分别讨论了利用夹角余弦来计算轨迹相似度和利用缓冲原理来计算轨迹相似度两种方法,前者可以作为一个baseline提供参考,后者的计算更符合人们的感官和事实,今天,我们要从计算机视觉出发,考察两条轨迹的相似度。

思路与核心代码

可以这么去想,首先,分别将两条轨迹点“串点连线”画出两条轨迹,同时控制画布的大小和渲染颜色,比如都是400*400像素的画布和轨迹都是黑色线段串连,其余都是白色的,如下图所示,

图1 轨迹1
图2 轨迹2

这样比较两条轨迹的相似度就转化为比较两张图片的相似度,而在计算机视觉领域,就有很多方法来比较两张图片相似度,这里采用图像切割法。图像切割法也比较好理解,就是用同样大小的网格去按照同样的方式去切割这两张图片,将图片分成相同数目的子图,相当于建立了一个网格坐标系,轨迹1的子图和轨迹2的子图在位置上可以建立起一一对应关系,也就是他们在网格坐标的位置一一对应,如果切割出来的位于网格坐标相同位置的某个子图恰好有轨迹1的一部分,又有轨迹2的一部分,那么就可以认为这个子图是这两条轨迹共同经过的区域,可以设计出一个Kronecker函数,对于任意的相同坐标相同尺寸的2个子图 i m g i img_i imgi i m g i ′ img_i' imgi

K ( i m g i , i m g i ′ ) = { 1 , i m g i ∩ i m g i ′ ≠ ∅ 0 , i m g i ∩ i m g i ′ = ∅ K(img_i, img_i')=\left\{ \begin{aligned} 1 & , img_i \cap img_i' \neq \emptyset\\ 0 &, img_i \cap img_i' = \emptyset \end{aligned} \right. K(imgi,imgi)={10,imgiimgi=,imgiimgi=
其中, i m g i img_i imgi表示轨迹1的第i个子图, i m g i ′ img_i' imgi表示轨迹2的第i个子图。然后,去统计轨迹1经过多少个子图,轨迹2经过多少个子图,其中,轨迹1和轨迹2共同经过的子图有多少个,从而就能计算出这两条轨迹的相似度了。

def trajectoryLine(trajectory, fig_name, grid_num): #轨迹连线绘图并网络切割
    fig = plt.figure(figsize= (4, 4)) #dpi=300
    ax = plt.subplot(111)
    ax.plot(trajectory['lng'], trajectory['lat'], color = 'k') #轨迹图,  marker ='.',  color = 'k', linewidth = 0.0002
    ax.set_axis_off()
    plt.savefig(r"D:\钢联物流\中交轨迹与手机轨迹相似度\图片\{}.png".format(fig_name)) #保存本地
    buffer_ = io.BytesIO() #开辟新的缓存
    plt.savefig(buffer_, format = 'png')
    buffer_.seek(0)
    image = Image.open(buffer_)
    image_parts = [] #用来存放切割后的局部图片PIL.Image.Image
    weight = int(image.size[0] // grid_num)
    height = int(image.size[1] // grid_num)
    for j in range(grid_num):
        for i in range(grid_num):
            box = (weight * i, height * j, weight * (i + 1), height * (j + 1))
            part = image.crop(box)
            image_parts.append(part)
    buffer_.close() #释放缓存
    return image_parts

def whetherBlank(image): #判断一张图片是否纯白,如果是返回0,反之,返回1
    # image_array = np.int8(image)
    if np.mean(image)==255: #纯白
        result = 0
    else:
        result = 1
    return result

def cvSimilarity(traj1, traj2): #两个轨迹绘制并网格切分
    traj1_parts = trajectoryLine(traj1, "traj1_line", grid_num = 40)
    traj2_parts = trajectoryLine(traj2, "traj2_line", grid_num = 40)
    traj1_list = [whetherBlank(part) for part in traj1_parts]
    traj2_list = [whetherBlank(part) for part in traj2_parts]
    print(len(traj1_list))
    intersection_cnt = 0
    for i in range(len(traj1_list)):
        if traj1_list[i]==1 and traj2_list[i]==1:
            intersection_cnt +=1
    cv_sim_value = intersection_cnt/(np.sum(traj1_list)+np.sum(traj2_list)-intersection_cnt)
    print(intersection_cnt, np.sum(traj1_list), np.sum(traj2_list))
    print("网格相似度", cv_sim_value)
    return cv_sim_value

数值实验

下面是对不同运单计算出来的相似度对比,整体还不错,前者是基于缓冲的相似度,后者是图像切割相似度,两者具有高度的一致性,但是在相似度高的轨迹,图像切割法会更高,在相似度本来就很低的对比情况下,图像切割法也会略微高出一些。

trajectory

优缺点分析

1,图像切割法直观形象好理解;
2,操作简便,无需做过多的考虑;
3,未考虑小图中各自轨迹点的密集程度的对相似度的影响;
4,网眼尺寸不好把握,其实也可以像缓冲相似度那样设计一个toleranceTest来决定网眼大小,也可以当作一个超参数,设计一个metric来进行调优。

参考文献

1,计算机视觉 - 图像相似度
https://blog.51cto.com/u_15668366/5412298
2,轨迹路线相似度计算
https://blog.csdn.net/weixin_39459401/article/details/129157653
3,Python-Opencv中用compareHist函数进行直方图比较进行对比图片
https://blog.csdn.net/qq_44262417/article/details/89217011
4,计算两幅图像的相似度(PSNR、SSIM、MSE、余弦相似度、MD5、直方图、互信息、Hash)& 代码实现 与举例
https://blog.csdn.net/m0_61899108/article/details/127715737

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

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

相关文章

1. 企业大数据开发流程

文章目录 1. 数据建设流程1.1 业务需求(占40%)1.2 需求调研1.3 概要设计1.4 详细设计1.5 数据开发(占20%)1.6 数据交付 学习链接 1. 数据建设流程 即当我们接到一个新的需求后(需求文档),我们应…

vmware 16增加硬盘容量并在Ubuntu 18.04上边格式化并挂载

参考了《增加 VM虚拟机硬盘容量》 《Linux学习之分区挂载》中有给VMWare 16虚拟机添加一块硬盘的内容,需要先参考添加硬盘。 sudo mkfs.ext4 /dev/sda4给/dev/sda4进行ext4格式化。 sudo mkdir /mountsda4新建一个挂载目录。 sudo mount -t ext4 /dev/sda4 /mo…

羊城杯-2023-Crypto

文章目录 Danger_RSA题目描述:题目分析: Easy_3L题目描述:题目分析: XOR贯穿始终题目描述:题目分析: MCeorpkpleer题目描述:题目分析: SigninCrypto题目描述:题目分析&am…

项目——群英阁(galaxyHub)

目录 一、项目概述二、设计思路三、项目流程四、项目代码头文件:👇server端:👇client端:👇 五、运行效果 一、项目概述 项目中文名称:群英阁 项目英文名称:galaxyHub 利用UDP通信实现…

HikariCP源码修改,使其连接池支持Kerberos认证

HikariCP-4.0.3 修改HikariCP源码,使其连接池支持Kerberos认证 修改后的Hikari源码地址:https://github.com/Raray-chuan/HikariCP-4.0.3 Springboot使用hikari连接池并进行Kerberos认证访问Impala的demo地址:https://github.com/Raray-chuan/springboot-kerberos-hikari-im…

Lambda表达式第三版,从3个方面分析。(①抽象方法无参数无返回值,②抽象方法带参数无返回值,③抽象方法带参数有返回值)

1、函数式编程思想概述 在数学中,函数就是有输入量、输出量的一套计算方案,也就是”拿数据做操作“面向对象思想强调”必须通过对象的形式来做事情“函数式思想则尽量忽略面向对象的复杂语法:”强调做什么,而不是以什么形式去做&a…

【javaweb】学习日记Day8 - Mybatis入门 Mysql 多表查询 事务 索引

之前学习过的SQL语句笔记总结戳这里→【数据库原理与应用 - 第六章】T-SQL 在SQL Server的使用_Roye_ack的博客-CSDN博客 【数据库原理与应用 - 第八章】数据库的事务管理与并发控制_一级封锁协议_Roye_ack的博客-CSDN博客 目录 一、多表查询 1、概述 (1&#…

性能测试(测试系列10)

目录 前言: 1.什么是性能测试 1.1生活中遇到的软件问题 1.2性能测试的定义 1.3性能测试和功能测试有什么区别 1.4性能的好坏的区分 1.5影响一个软件性能的因素 2.为什么要进行性能测试 3.性能测试常见的术语以及衡量指标 3.1并发 3.2用户数 3.3响应时间 …

Jmeter如何设置中文版

第一步:找到 apache-jmeter-5.4.3\bin目录下的 jmeter.properties 第二步:打开 三,ctrf 输入languageen,注释掉,增加以行修改如下 四,ctrs 保存修改内容,重新打开jmeter就可以了

golang-bufio 缓冲写

1. 缓冲写 在阅读这篇博客之前,请先阅读上一篇:golang-bufio 缓冲读 // buffered output// Writer implements buffering for an io.Writer object. // If an error occurs writing to a Writer, no more data will be // accepted and all subsequent…

5.0: Dubbo服务导出源码解析

#Dubbo# 文章内容 Dubbo服务导出基本原理分析Dubbo服务注册流程源码分析Dubbo服务暴露流程源码分析服务导出的入口方法为ServiceBean.export(),此方法会调用ServiceConfig.export()方法,进行真正的服务导出。 1. 服务导出大概原理 服务导出的入口方法为ServiceBean.export…

stm32之28.ADC

须看原理图(引脚、电压值、ADC几号通道)配置 。 若对比值0~4096 模拟电压/参考电压4096/x 假设模拟电压2.1V,参考电压3.3v,4096/x3.3/2.1 ->3.3x2.1x4096 ->x2,606.5 也可反推出模拟电压 ADC转换时间 ADC时钟来源于…

leetcode645. 错误的集合(java)

错误的集合 题目描述优化空间代码演示 题目描述 难度 - 简单 LC645 - 错误的集合 集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数…

时序预测 | MATLAB实现CNN-GRU卷积门控循环单元时间序列预测(风电功率预测)

时序预测 | MATLAB实现CNN-GRU卷积门控循环单元时间序列预测(风电功率预测) 目录 时序预测 | MATLAB实现CNN-GRU卷积门控循环单元时间序列预测(风电功率预测)预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.时序预测 | MA…

Python中的绝对和相对导入

在本文中,我们将看到Python中的绝对和相对导入。 Python中导入的工作 Python中的import类似于C/C中的#include header_file。Python模块可以通过使用import导入文件/函数来访问其他模块的代码。import语句是调用import机制的最常见方式,但它不是唯一的…

常见数学名词的物理意义(更新中)

BetterExplained – Math lessons that click 一、复数 i 的物理意义就是旋转,i 就是逆时针旋转90,i*i 就是逆时针旋转180 加法:实部相加,虚部相加 乘法: 复数zxyi控制了函数的放缩和旋转 ——x 放缩,…

Shell开发实践:服务器的磁盘、CPU、内存的占用监控

🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师…

基于vue-cli创建后台管理系统前端页面——element-ui,axios,跨域配置,布局初步,导航栏

目录 引出安装npm install安装element-ui安装axios 进行配置main.js中引入添加jwt前端跨域配置 进行初始布局HomeView.vueApp.vue 新增页面和引入home页面导航栏总结 引出 1.vue-cli创建前端工程,安装element-ui,axios和配置; 2.前端跨域的配…

SQL查询本年每月的数据

--一、以一行数据的形式,显示本年的12月的数据,本示例以2017年为例,根据统计日期字段判断,计算总和,查询语句如下:selectsum(case when datepart(month,统计日期)1 then 支付金额 else 0 end) as 1月, sum…

UE4 春节鞭炮

先搞个基类,一个鞭炮的 搞个鞭炮类,存多个鞭炮 在构造函数的位置先生成对应的鞭炮数 将鞭炮绑定到绳子上,随绳子摆动而一起摆动 在基类里面写爆炸事件 最后用Timer去调用