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

文章目录

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

前言

  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)

三、结果

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HCIA-Datacom题库(自己整理分类的)_09_Telent协议【13道题】

一、单选 1.某公司网络管理员希望能够远程管理分支机构的网络设备,则下面哪个协议会被用到? RSTP CIDR Telnet VLSM 2.以下哪种远程登录方式最安全? Telnet Stelnet v100 Stelnet v2 Stelnet v1 解析: Telnet 明文传输…

cocos uuid 相关问题一

暂时记录 1.9.x 通过UUID搜索资源 uuid压缩 Editor.UuidUtils.compressUuid uuid解压 Editor.UuidUtils.decompressUuid 新版本 uuid 压缩 Editor.Utils.UuidUtils.compressUuid uuid 解压 Editor.Utils.UuidUtils.decompressUuid 算法: decompressUui…

【卡方检验(Chi-Squared Test)的原理简介】

文章目录 卡方检验(Chi-Squared Test)的原理简介1. 卡方检验的流程借助scipy进行卡方检验3 连续变量的卡方检验4 借助sklearn进行卡方检验特征筛选 卡方检验(Chi-Squared Test)的原理简介 在一般情况下,卡方检验是针对…

数控开料机对比木工雕刻机的优势

数控开料机和木工雕刻机都属于木工机械加工设备,都可以用来开料和雕刻,但在市场价格、床体结构、技术要求等方面二者存在不小的差异,那么全自动数控开料机对比普通木工雕刻机有什么优势呢。 首先我们都知道,木工雕刻机主要应用于…

从优化设计到智能制造:生成式AI在可持续性3D打印中的潜力和应用

可持续性是现代工业中一个紧迫的问题,包括 3D 打印领域。为了满足环保制造实践日益增长的需求,3D 打印已成为一种有前景的解决方案。然而,要使 3D 打印更具可持续性,还存在一些需要解决的挑战。生成式人工智能作为一股强大的力量&…

计算机网络面试八股复习:常见的7/5/4层网络模型、各层协议以及键入网址到显示页面的流程

七层/五层/四层 网络模型 名称 OSI七层模型 TCP/IP四层模型 五层模型 关系图 常见协议 精简部分,完整版见上图 应用层 : TFTP(简单文件传输协议),HTTP,DNS,RIP(路由信息协议) 表…

阿里云实时计算企业级状态存储引擎 Gemini 技术解读

本文整理自阿里云 Flink 存储引擎团队李晋忠,兰兆千,梅源关于阿里云实时计算企业级状态存储引擎 Gemini 的研究,内容主要分为以下五部分: 流计算状态访问的痛点企业级状态存储引擎GeminiGemini 性能评测&线上表现结语参考 一、…

原型模式

为什么要使用原型模式 不用重新初始化对象,而是动态地获得对象运行时的状态。适用于当创建对象的成本较高时,如需进行复杂的数据库操作或复杂计算才能获得初始数据。 优点是可以隐藏对象创建的细节,减少重复的初始化代码;可以在…

DataFrame详解

清洗相关的API 清洗相关的API: 1.去重API: dropDupilcates 2.删除缺失值API: dropna 3.替换缺失值API: fillna 去重API: dropDupilcates dropDuplicates(subset):删除重复数据 1.用来删除重复数据,如果没有指定参数subset,比对行中所有字段内容,如果全部相同,则认为是重复数据,…

分布式数据库原理及技术题目汇总(上)

题目汇总 选择 1.(单选题,3.0分)以下说法中不正确的是(B )。 A.HIVE中create table命令使用时,表类型可以存储为ORC。 B.HIVE中create table命令使用时,必须包含row format delimited。 C.HIVE中create table命令使用时若含r…

儿童护眼台灯什么品牌好?儿童护眼台灯品牌排行

台灯大家都不陌生,但使用它的人有多少呢,准确使用的人又有多少呢,我们就是为了照明才会去买台灯,而时间久了,你就会眼睛刺痛,那就是没有选对台灯和没有正确使用台灯,还是建议大家买具有护眼功能…

首次落地零担快运!商用车自动驾驶跑出交付加速度

即将迈入2024年,还活着的自动驾驶玩家,身上有两个显著标签:选对了细分赛道、会玩。 10月以来,Cruise宣布在美国德州奥斯汀、休斯顿、亚利桑那州凤凰城和加州旧金山全面停止所有自动驾驶出租车队运营服务,通用汽车计划…

OSS 上传的操作

OSS 上传的操作&#xff1a; 依赖包&#xff1a; <!-- 阿里云OSS --><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.15.1</version></dependency> 配置文…

基于Java SSM框架实现音乐推荐网站项目【项目源码+论文说明】

基于java的SSM框架实现音乐推荐网站演示 摘要 中国风音乐推介网站近年来已成为风靡全球的新兴艺术形式。国内涌现出了大批优秀、有才华的爱好者和许多经久不衰的经典作品。中国风音乐推介网站的兴起打破了音乐界格局,也突破了原有分类唱法发展中的瓶颈,为声乐艺术的发展开辟了…

为啥领导都爱说“我只看结果”?

点击下方“JavaEdge”&#xff0c;选择“设为星标” 第一时间关注技术干货&#xff01; 免责声明~ 任何文章不要过度深思&#xff01; 万事万物都经不起审视&#xff0c;因为世上没有同样的成长环境&#xff0c;也没有同样的认知水平&#xff0c;更「没有适用于所有人的解决方案…

SpringCloud 之HttpClient、HttpURLConnection、OkHttpClient切换源码

承接上文&#xff0c;之前已经分析过OpenFegin 的创建、发送请求源码了&#xff0c;接下来&#xff0c;分析下底层的HttpClient、HttpURLConnection、OkHttpClient切换从源码级别来看是如何做到的。 Spring Cloud OpenFegin&#xff08;创建、发送请求&#xff09;源码 Http…

创建mysql普通用户

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

浮动和定位

目录​​​​​​​ &#x1f333;浮动 &#x1f340;去浮动 &#x1f343;方法一 &#x1f343;方法二 &#x1f343;方法三 &#x1f333;定位 &#x1f340;相对定位 &#x1f340;绝对定位 &#x1f340;固定定位 &#x1f333;转义字符 浮动 浮动会脱离文档流.导…

部署vue项目的常见问题汇总--许锅锅

文章目录 vue项目的常见问题版本问题/控制台指令识别问题【node和npm的版本要对应】加载慢的问题【设置镜像即可】设置淘宝镜像cmd窗口内容 npm/cnpm install的问题 npm WARN deprecated core-js3.6.5: core-js&#xff1c;3.23.3 is no longer maintained and not recommended…

计算机毕业设计------SSH宿舍管理系统

项目介绍 本项目分为三种角色&#xff1a;系统管理员、楼宇管理员、学生&#xff1b; 系统管理员主要功能如下&#xff1a; 楼宇管理员管理、学生管理、楼宇管理、宿舍管理、学生入住登记、学生寝室调换、学生迁出登记、学生缺勤记录、修改密码、退出登录 楼宇管理员主要功能…