【CV】计算两个向量的夹角,并使用 OpenCV 可视化弧线

背景

基于人体/动物,骨骼点数据,计算关节角度

1. 原理

计算两个向量的夹角,我们已三个点为例,BA 向量和BC向量,求 B 的角度。若为四个点,延长交叉即可。
在这里插入图片描述

2. 效果

效果图如下

请添加图片描述

3. 核心代码

def compute_vector_angle(a, b, c):"""计算两个向量 ba 和 bc 向量的夹角@params a , 点 a@params b , 点 b@params c , 点 c"""# 我这里为了好理解使用三个点数据,也可以用四个点triangle_data = [a, b, c]# 向量夹角ba_angle = math.atan2(a[1] - b[1], a[0] - b[0]) * 180 / math.pibc_angle = math.atan2(c[1] - b[1], c[0] - b[0]) * 180 / math.pib_angle = 0if ba_angle * bc_angle >= 0:# 第1,4象限b_angle = abs(ba_angle - bc_angle)else:# 第2,3象限b_angle = abs(ba_angle) + abs(bc_angle)if b_angle > 180:b_angle = 360 - b_angleprint("\nba_angle:", ba_angle, "bc_angle:", bc_angle, "angle:", b_angle)start_angle = ba_angleend_angle = bc_anglereturn start_angle, end_angle, b_angle, triangle_data

4. 可视化

图像可视化,坐标和圆的坐标系如下,

  • 坐标系,相反
  • 圆坐标系,逆时针,如图所示
    在这里插入图片描述

5. 全部代码

实现 Python 代码,可直接执行,C++ 同理实现

#!/usr/bin/env python
# -*- encoding: utf-8 -*-"""
@Create  :   2024/01/09 15:03:33
@Author  :   Yuan Mingzhuo
"""import numpy as np
import cv2
import mathdef compute_vector_angle(a, b, c):"""计算两个向量 ba 和 bc 向量的夹角@params a , 点 a@params b , 点 b@params c , 点 c"""# 我这里为了好理解使用三个点数据,也可以用四个点triangle_data = [a, b, c]# 向量夹角ba_angle = math.atan2(a[1] - b[1], a[0] - b[0]) * 180 / math.pibc_angle = math.atan2(c[1] - b[1], c[0] - b[0]) * 180 / math.pib_angle = 0if ba_angle * bc_angle >= 0:# 第1,4象限b_angle = abs(ba_angle - bc_angle)else:# 第2,3象限b_angle = abs(ba_angle) + abs(bc_angle)if b_angle > 180:b_angle = 360 - b_angleprint("\nba_angle:", ba_angle, "bc_angle:", bc_angle, "angle:", b_angle)start_angle = ba_angleend_angle = bc_anglereturn start_angle, end_angle, b_angle, triangle_datadef draw_image_vector_angle(image, triangle_data, start_angle, end_angle, angle):"""可视化显示@params image , 图@params triangle_data , 向量点数据@start_angle , ba 向量角度@end_angle   , bc 向量角度@angle       , ba 与 bc 向量夹角"""# 点point_a = (int(triangle_data[0][0]), int(triangle_data[0][1]))point_b = (int(triangle_data[1][0]), int(triangle_data[1][1]))point_c = (int(triangle_data[2][0]), int(triangle_data[2][1]))for point in triangle_data:cv2.circle(img=image,center=(int(point[0]), int(point[1])),radius=2,color=(255, 255, 255),thickness=1,lineType=cv2.LINE_AA,)# 线lines = [(point_b, point_a), (point_b, point_c), (point_a, point_c)]for line in lines:cv2.line(img=image,pt1=line[0],pt2=line[1],color=(0, 0, 255),thickness=1,lineType=cv2.LINE_AA,)# 弧线startAngle = start_angleendAngle = end_angleif start_angle * end_angle < 0:angle_data = abs(start_angle) + abs(end_angle)if angle_data > 180:# 取反弧度结束角if end_angle > 0:endAngle = end_angle - 360else:endAngle = end_angle + 360print("DRAW : ", "startAngle", startAngle, "endAngle", endAngle)cv2.ellipse(img=image,center=point_b,axes=(16, 16),angle=360,startAngle=startAngle,endAngle=endAngle,color=(255, 255, 255),thickness=1,lineType=cv2.LINE_AA,)# 角 Bangle_b_point = [int(((point_a[0] + point_b[0] + point_c[0]) / 3)),int(((point_a[1] + point_b[1] + point_c[1]) / 3)),]cv2.putText(img=image,text=f"{int(abs(angle))}",org=angle_b_point,fontFace=cv2.FONT_HERSHEY_SIMPLEX,fontScale=0.3,color=(200, 200, 200),thickness=1,lineType=cv2.LINE_AA,)return imageif __name__ == "__main__":"""可视化测试"""# 测试点a, b, c = (70, 100), (100, 150), (170, 70)# 图像image = np.full((300, 300, 3), 0, dtype=np.uint8)# 计算start_angle, end_angle, angle, triangle_data = compute_vector_angle(a, b, c)# 绘制image = draw_image_vector_angle(image=image,triangle_data=triangle_data,start_angle=start_angle,end_angle=end_angle,angle=angle,)# 显示cv2.imshow("test", image)cv2.waitKey(3000)

6. 应用

骨骼点角度计算和可视化

在这里插入图片描述

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

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

相关文章

【服务器数据恢复】FreeNAS+ESXi数据恢复案例

服务器数据恢复环境&#xff1a; 一台服务器&#xff0c;虚拟化系统为esxi&#xff0c;上层使用iSCSI的方式实现FC SAN功能&#xff0c;iSCSI通过FreeNAS构建。 FreeNAS采用了UFS2文件系统&#xff0c;esxi虚拟化系统里有3台虚拟机&#xff1a;其中一台虚拟机安装FreeBSD系统&a…

redis的高可用(主从复制、哨兵、群集)

redis的高可用&#xff08;主从复制、哨兵、群集&#xff09; 主从复制&#xff1a;主从复制是高可用Redis的基础&#xff0c;哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份&#xff0c;以及对于读操作的负载均衡和简单的故障恢复。缺陷&…

【python】爬取豆瓣电影排行榜Top250存储到Excel文件中【附源码】

英杰社区https://bbs.csdn.net/topics/617804998 一、背景 近年来&#xff0c;Python在数据爬取和处理方面的应用越来越广泛。本文将介绍一个基于Python的爬虫程 序&#xff0c;用于抓取豆瓣电影Top250的相关信息&#xff0c;并将其保存为Excel文件。 程序包含以下几个部…

[游戏开发] 两向量夹角计算(0-360度)

上图是Unity左手坐标系&#xff0c;红轴是右&#xff0c;蓝轴是前&#xff0c;绿轴是上 测试目标是黑(3.54,0,4)、黄(-3.85,0,4.8)、灰(0.46,0,-2.6)三个向量&#xff0c;且三个向量都再XZ平面上&#xff0c;Y的值为0 以黑色为起始轴&#xff0c;和其他两周做角度计算 计算角…

微信小程序如何自定义导航栏,怎么确定导航栏及状态栏的高度?导航栏被刘海、信号图标给覆盖了怎么办?

声明&#xff1a;本文为了演示效果&#xff0c;颜色采用的比较显眼&#xff0c;可根据实际情况修改颜色 问题描述 当我们在JSON中将navigationStyle设置成custom后&#xff0c;当前页面的顶部导航栏就需要我们制作了&#xff0c;但出现了一下几个问题&#xff1a; 导航栏的高…

【Scala】——流程控制

1 if-else 分支控制 让程序有选择的的执行&#xff0c;分支控制有三种&#xff1a;单分支、双分支、多分支 1.1单分支 if (条件表达式) {执行代码块 }1.2 双分支 if (条件表达式) {执行代码块 1 } else {执行代码块 2 }1.3 多分支 if (条件表达式1) {执行代码块 1 } else …

初学者的基本 Python 面试问题和答案

文章目录 专栏导读1、什么是Python&#xff1f;列出 Python 在技术领域的一些流行应用。2、在目前场景下使用Python语言作为工具有什么好处&#xff1f;3、Python是编译型语言还是解释型语言&#xff1f;4、Python 中的“#”符号有什么作用&#xff1f;5、可变数据类型和不可变…

CMake入门教程【核心篇】设置和使用缓存变量

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 概述设置缓存变量使用缓存变量更改缓存变量完整代码示例实战使用技巧注意事项总结与分析

锂电池制造设备中分布式IO模块优势

在“碳达峰、碳中和”目标推动下&#xff0c;新能源汽车当下发展势头正盛&#xff0c;而纯电动车的核心部件则是&#xff1a;锂电池。动力型锂电池作为新能源汽车核心零部件&#xff0c;其发展与新能源汽车行业息息相关&#xff0c;迎来广阔的市场空间。 为何采用I/O模块&#…

Linux中快速搭建RocketMQ测试环境

必要的文件下载 为什么选择RocketMQ | RocketMQ x86_64位JDK下载0jdk/8u391-b13 rocketmq二进制包下载-rocketmq-all-5.1.4-bin-release.zip 编译好的直接可用的dashboard【rocketmq-dashboard-1.0.0.jar】请在文章顶部下载 dashboard配套的配置文件【application.propert…

ECMAScript6历史-前端开发+ECMAScript+基础语法+入门教程

ECMAScript6详解 ECMAScript 历史 我们首先来看 ECMA 是什么。ECMA&#xff0c;读音类似“埃科妈”&#xff0c;是欧洲计算机制造商协会&#xff08;European Computer Manufacturers Association&#xff09;的简称&#xff0c;是一家国际性会员制度的信息和电信标准组织。19…

AcWing 203. 同余方程(扩展欧几里得算法)

题目链接 203. 同余方程 - AcWing题库高质量的算法题库https://www.acwing.com/problem/content/205/ 来源 《算法竞赛进阶指南》, NOIP2012提高组 题解 本题中的同余方程可以转化为ax by 1的形式&#xff0c;利用扩展欧几里得算法可以求得特解为&#xff0c;则通解为。 代…

网站建设网络设计营销类网站模板

★安装环境要求★ 服务器&#xff1a;Linux / Apache / IIS PHP版本&#xff1a;5.4及5.4以上&#xff0c;完美支持php7.4 MYSQL版本&#xff1a;5.0以上 PS&#xff1a;php版本推荐5.6&#xff0c;mysql推荐使用5.7 ★模板安装步骤★ 1、请将源码包里面的所有文件和文件夹上…

【每日一题】删除子串后的字符串最小长度

文章目录 Tag题目来源解题思路方法一&#xff1a;栈 写在最后 Tag 【栈】【字符串】【2024-01-10】 题目来源 2696. 删除子串后的字符串最小长度 解题思路 方法一&#xff1a;栈 思路 按照题目要求需要移除字符串中的 “AB” 和 “CD” 子字符串&#xff0c;并且移除这两种…

Helix QAC 2023.4 新版支持C++20语言,带来更多性能提升!

Helix QAC 2023.4 新增功能 Helix QAC 2023.4全面支持MISRA C:2023规则&#xff0c;涵盖100%的指南。此版本还加强了对C20语言的支持&#xff0c;改进了数据流分析性能&#xff0c;并在整个产品中增加了多项用户体验改进。 增强的C20支持 此版本新增了对以下语言特性的支持&a…

vscode设置python脚本运行参数

1 添加配置文件 点击到你要配置的python文件&#xff0c;然后右上角点击 运行 &#xff0c;再点击 添加配置 再点击 “Pyhton文件” 选项&#xff08;其实就是在选择 当前的python文件 进行配置&#xff09; 接着就生成了配置文件 lanunch.json 2 参数配置 再上面代码的基础上…

Guava:Cache强大的本地缓存框架

Guava Cache是一款非常优秀的本地缓存框架。 一、 经典配置 Guava Cache 的数据结构跟 JDK1.7 的 ConcurrentHashMap 类似&#xff0c;提供了基于时间、容量、引用三种回收策略&#xff0c;以及自动加载、访问统计等功能。 基本的配置 Testpublic void testLoadingCache() th…

6 - 数据备份与恢复|innobackupex

数据备份与恢复&#xff5c;innobackupex 数据备份与恢复数据备份相关概念物理备份与恢复逻辑备份&#xff08;推荐&#xff09;使用binlog日志文件实现对数据的时时备份‘使用日志 恢复数据 innobackupex 对数据做备份和恢复增量备份与恢复 数据备份与恢复 数据备份相关概念 …

【Docker】Docker基础

文章目录 安装使用帮助启动命令镜像命令容器命令 安装 # 卸载旧版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine # 设置存储库 sudo yum install -y yum-utils …

关于git使用的tips

前言 这里是一些git指令使用的tips&#xff0c;如果你作为初学者的话&#xff0c;我认为它将对你有所帮助。 常见指令 常见问题处理 1、使用git clone下载【huggingface.co】资源超时或无法请求问题 绝大多数情况是网络问题&#xff0c;首先如果是比较大的资源&#xff0c;你需…