【目标跟踪】多相机多目标跟踪

news2025/1/13 13:45:43

文章目录

    • 前言
    • 一、计算思路
    • 二、代码
    • 三、结果

前言

  1. 相机目标跟踪之前博客已经有过基本介绍,本篇博客主要介绍一种多相机目标跟踪的计算方法
  2. 已知各相机内外参,如何计算共视区域像素投影?废话不多说,见下图。

同一时刻相机A与相机B的图

相机A

在这里插入图片描述

相机B

在这里插入图片描述

问:相机 A 检测出目标1 box位置,如何计算得出目标1在相机 B 中像素的位置?

在这里插入图片描述


一、计算思路

  1. 取相机 A 目标1中一个像素点 (Ua, Va)
  2. 计算改点在相机A中的相机坐标系坐标 (Xa,Ya,Za)
  3. 相机 A 坐标转化到相机 B 下的相机坐标 (Xb,Yb,Zb)
  4. (Xb,Yb,Zb) 转化到像素坐标 (Ub,Vb)

第2点与第3点中像素坐标转化到相机坐标。

在这里插入图片描述

其中Zcamera 可以近似求出。看过之前博客的朋友应该可以明白,具体计算方式,代码会全部给出。

第3点就是一个三维坐标系旋转平移变化。

在这里插入图片描述

二、代码

import yaml
import numpy as np
import cv2


def read_yaml(path):
    with open(path, 'r', encoding='utf-8') as f:
        result = yaml.load(f.read(), Loader=yaml.FullLoader)
    return result


def get_r_t_mtx(path, f_r_b_l):
    sensor_list = ["front_center", "right_center", "back_center", "left_center"]
    yaml_result = read_yaml(path)  # 读取yaml配置文件h
    res_pitch = yaml_result[sensor_list[f_r_b_l]]["pitch"]
    res_h = yaml_result[sensor_list[f_r_b_l]]["height"]
    res_r = np.array(yaml_result[sensor_list[f_r_b_l]]["rotation"]).reshape(3, 3)
    res_t = np.array(yaml_result[sensor_list[f_r_b_l]]["translation"]).reshape(3, 1)
    res_mtx = np.array(yaml_result[sensor_list[f_r_b_l]]["K"]).reshape(3, 3)
    return res_pitch, res_h, res_mtx, res_r, res_t


# 近似计算相机坐标系 Zcamera
def get_camera_z(children, pixe_y):
    pitch, h, K, *_ = children
    sigma = np.arctan((pixe_y - K[1][2]) / K[1][1])
    z = h * np.cos(sigma) / np.sin(sigma + pitch)  # 深度
    return z


def get_sensor_pixe(children, parent, x, y, distance):
    r, t = get_two_camera_r_t(children, parent)
    children_pitch, children_h, children_mtx, *c = children
    parent_pitch, parent_h, parent_mtx, *p = parent
    distance_init = distance
    x = (x - children_mtx[0][2]) / children_mtx[0][0]
    y = (y - children_mtx[1][2]) / children_mtx[1][1]
    coor = np.array([x, y, 1]).reshape(3, 1) * distance_init
    res_coor = r @ coor + t  # 车体坐标系
    res_x = (res_coor[0] / res_coor[2]) * parent_mtx[0][0] + parent_mtx[0][2]
    res_y = (res_coor[1] / res_coor[2]) * parent_mtx[1][1] + parent_mtx[1][2]
    return res_x, res_y


def show_img(img):
    cv2.namedWindow("show")
    cv2.imshow("show", img)
    cv2.waitKey(0)


def get_two_camera_r_t(children, parent):
    *children, children_mtx, children_r, children_t = children
    *parent, parent_mtx, parent_r, parent_t = parent
    res_r = np.array(parent_r).T @ np.array(children_r)
    res_t = np.array(parent_r).T @ (np.array(children_t) - np.array(parent_t)).reshape(3, 1)
    return res_r, res_t


def get_uv(point, param):
    *p, mtx, r, t = param
    coor_camera = r.T @ (np.array(point).reshape(3, 1) - t)
    coor_pixe = mtx @ coor_camera * (1 / coor_camera[2])
    return coor_pixe[0][0], coor_pixe[1][0]


if __name__ == '__main__':
    front_img = cv2.imread("front_img.jpg")
    left_img = cv2.imread("left_img.jpg")
    img = np.concatenate((left_img, front_img), axis=1)  # 横向拼接
    front_param = get_r_t_mtx("./sensor_param.yaml", 0)
    left_param = get_r_t_mtx("./sensor_param.yaml", 3)
    color = np.random.randint(0, 255, (3000, 3))  # 随机颜色

    car_coor = [5.41, 6.5, 1.3]
    camera1 = np.ravel(get_uv(car_coor, left_param))
    camera2 = np.ravel(get_uv(car_coor, front_param))
    print(camera1, camera2)
    cv2.circle(img, (int(camera1[0]), int(camera1[1])), 1, color[0].tolist(), 2)
    cv2.circle(img, (int(camera2[0]) + 1920, int(camera2[1])), 1, color[1].tolist(), 2)
    cv2.line(img, (int(camera1[0]), int(camera1[1])), (int(camera2[0] + 1920), int(camera2[1])), color[0].tolist(), 2)
    show_img(img)

    # print(get_two_camera_r_t(front_param, left_param))
    # print(front_to_left_r.reshape(-1), "\n", front_to_left_t)
    # distance = get_camera_z(left_param, 640)
    # x1, y1 = 1429, 488
    # x2, y2 = 1509, 637
    # for x in range(x1, x2, 20):
    #     for y in range(y1, y2, 20):
    #         res_x, res_y = get_sensor_pixe(left_param, front_param, x, y, distance)
    #         cv2.circle(img, (int(x), int(y)), 1, color[x].tolist(), 5)
    #         cv2.circle(img, (int(res_x) + 1920, int(res_y)), 1, color[x].tolist(), 5)
    # cv2.line(img, (int(x) , int(y)), (int(res_x)+ 1920, int(res_y)), color[x].tolist(), 2)
    # distance = get_camera_z(front_param, 649)
    # x1, y1 = 271, 469
    # x2, y2 = 353, 649
    # for x in range(x1, x2, 20):
    #     for y in range(y1, y2, 20):
    #         res_x, res_y = get_sensor_pixe(front_param, left_param, x, y, distance)
    #         cv2.circle(img, (int(x) + 1920, int(y)), 1, color[x].tolist(), 2)
    #         cv2.circle(img, (int(res_x), int(res_y)), 1, color[x].tolist(), 2)
    # cv2.line(img, (int(x) + 1920, int(y)), (int(res_x), int(res_y)), color[x].tolist(), 2)
    # show_img(img)

三、结果

在这里插入图片描述

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

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

相关文章

创建ROS模型与小机器人地图规划

1、打开自己的VM系统 2、安装小机器人的安装包,输入如下命令,回车输入密码(自己设的): sudo apt install ros-noetic-turtlebot3-simulations ros-noetic-turtlebot3-slam ros-noetic-turtlebot3-navigation 提示我之前安装过了 3、用rosla…

ansible:如何在centos 7上重新启动auditd服务得到关于依赖的错误

在我的剧本中,我有一个更新 audit.rules 的任务,然后通知应该重新启动 auditd 服务的处理程序。 task:- name: 6.6.7 - audit rules configurationtemplate: srcX/ansible/templates/auditd_rules.j2dest/etc/audit/rules.d/audit.rulesbackupyesownerr…

在线图表编辑工具Draw.io本地部署并结合内网穿透实现远程协作办公

前言 提到流程图,大家第一时间可能会想到Visio,不可否认,VIsio确实是功能强大,但是软件为收费,并且因为其功能强大,导致安装需要很多的系统内存,并且是不可跨平台使用。所以,今天给…

ChatGPT | Team套餐来了,每人 25美元,你怎么看?

最近,ChatGPT 在原有的plus会员的基础上 加了一个Team套餐 价格要更贵一些 收费 每人每月 25 美元 套餐包含 Plus 中的所有内容,以及: GPT-4 和 DALLE、浏览、高级数据分析等 创建 GPT 并将其与工作区共享 用于工作区管理的管理控制台 保证不…

shrio漏洞

sudo apt install tomcat9//安装tomcat9sudo systemctl status tomcat9//查看安装状态 编辑配置文件 sudo nano /etc/tomcat9/tomcat-users.xml 编辑配置文件,设置密码 sudo systemctl restart tomcat9 重启生效 访问 Tomcat 管理页面:在浏览器中输入…

网络安全B模块(笔记详解)- 网络爬虫渗透测试

ARP协议渗透测试 1.进入渗透机场景BT5中的/root目录,完善该目录下的arp_spoof.py文件,填写该文件当中空缺的Flag1字符串,将该字符串作为Flag值(形式:Flag1字符串)提交;(arp_spoof.py脚本功能见该任务第6题) 根据缺少的发现是要time模块 Flag:time 2.进入渗透机场景B…

独享静态代理IP在海外市场调研中的独特优势

独享静态代理IP在海外市场调研中扮演着至关重要的角色,提供了一系列无可比拟的优势。独享静态代理IP的稳定性和可靠性对于长期的市场调研至关重要,它保证了连接的持续性和数据的准确性。通过这些方面的综合优势,独享静态代理IP成为海外市场调…

生成学习全景:从基础理论到GANs技术实战

本文全面探讨了生成学习的理论与实践,包括对生成学习与判别学习的比较、详细解析GANs、VAEs及自回归模型的工作原理与结构,并通过实战案例展示了GAN模型在PyTorch中的实现。 关注TechLead,分享AI全维度知识。作者拥有10年互联网服务架构、AI产…

Visual Studio Code 连接远程服务器方法

1、输入用户名和服务器ip连接远程服务器 2、选择配置文件 配置文件路径:C:\Users\Administrator\.ssh\config config的内容大致如下: Host 192.168.134.3HostName 192.168.134.3User zhangshanHost 192.168.134.3HostName 192.168.134.3User lisiHost…

Open CASCADE学习|一种快速定位缺失的链接库的方法

OCCT代码中,缺少链接库一般报错LNK2019、LNK1120等,如下表所示。该错误说明中提供了类名及成员函数,这是找到缺少的链接库的线索。 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误 LNK2019 无法解析的外部符号 "p…

C/C++动态内存管理

文章目录 前言1.C/C内存分布2.C语言中动态内存管理方式:malloc/calloc/realloc/free3.C内存管理方式3.1 new/delete操作内置类型3.2 new和delete操作自定义类型 4. operator new与operator delete函数4.1 operator new与operator delete函数 5. new和delete的实现原…

Python实用小工具(4)——邮件轰炸机,给朋友搞点乐子(附源码+exe文件)

欢迎来到MatpyMaster!今天我们将使用Python来批量发送邮件,让你的邮件推送变得更加高效。废话不多说,直接开搞!使用声明: 请确保你的邮箱开启了SMTP服务,并获取了授权码。 选择合适的发送间隔,…

创建mysql普通用户

一、创建mysql普通用户的原因: 权限控制:MySQL的权限系统允许您为每个用户分配特定的权限。通过创建普通用户,您可以根据需要为每个用户分配特定的数据库和表权限,而不是将所有权限授予一个全局管理员用户。这有助于提高数据库的…

2024年华夏银行总行社会招聘公告

信息科技部自动化测试与开发类岗  工作地点:北京市 学历要求:本科及以上 工作职责 1、持续推进自动化测试的开展,提升自动化测试覆盖率,包括方案设计、测试分析、测试执行和总结等。 2、负责自动化测试工具和框架搭建,根据…

关于报错 curl: (56) Recv failure: Connection reset by peer

curl ip没问题 curl localhost 则报错 curl: (56) Recv failure: Connection reset by peer 出现这个报错有很多原因, 其中之一就是terminal代理 而关闭代理应用之后, 其实由于配置的终端都是 export指定的代理 所以导致还是一直报错. 通过 curl -v 可以发现 指向了代理ip和…

关于网络安全,你了解多少?

随着互联网技术的飞速发展,网络安全问题日益凸显。国际标准化组织(ISO)对计算机网络安全做出了明确定义:为保护数据处理系统而采取的技术和管理的安全措施,旨在保护计算机硬件、软件和数据免受偶然和故意原因造成的破坏…

Apipost IDEA插件,真的超好用

IDEA是一款功能强大的集成开发环境(IDE),它可以帮助开发人员更加高效地编写、调试和部署软件应用程序。我们在编写完接口代码后需要进行接口调试等操作,一般需要打开额外的调试工具。 今天给大家介绍一款IDEA插件:Api…

明年评职称,现在就要准备论文了吗?

明年评职称不仅需要提前补好继续教育课时,同样的还需要准备好论文和业绩材料,初级职称的相对来说对论文和业绩要求不高,但是中高级职称业绩和论文的质量代表着你的评审通过率,那为什么需要提前准备好呢?甘建二再给大家…

相机成像之图像传感器与ISP【四】

文章目录 1、图像传感器基础1.1 基础原理——光电效应1.2 基础的图像传感器设计1.3 衡量传感器效率的一个关键指标:光量子效率(QE)1.4 感光单元的响应1.5 像素的满阱容量1.6 像素尺寸和填充比例1.7 微透镜的作用1.8 光学低通滤波器简介1.9 传…

web开发学习笔记(1.html css)

css负责布局 js负责动作 2.磁盘路径 3.水平线标签 4.引入css 5.无语义标签 6.选择器 7.播放视频和音频 8.换行 <br> 9.段落标签 <p></p> 10.首行缩进 11.边距 12.盒子模型&#xff0c;居中显示&#xff0c; margin后面的四个值顺序为上右下左&#…