[bevformer渲染可视化] 2d框可视化 并可视化出小目标

news2024/11/13 14:52:57

可视化代码:


代码使用方法:
1.复制代码全文到任意python文件中

2.下载nuscenes v1.0-mini数据集,修改数据集路径,保证能读取到数据集

3.按照需求修改代码(本文是2dbox面积的面积和整个图片的面积比小于0.03视为小目标)

if area_ratio < 0.03:

   label = "small target"

3.运行命令

 在bevfomer环境下运行此python文件

import os
import cv2
import numpy as np
from nuscenes.utils.geometry_utils import view_points
from pyquaternion import Quaternion
from nuscenes import NuScenes

# 初始化nuScenes
nusc = NuScenes(version='v1.0-mini', dataroot='/home/lyh/Documents/dataset/v1.0-mini/', verbose=True)

# 定义类别颜色映射
category_colors = {
    'vehicle': (255, 255, 0),    # Yellow
    'pedestrian': (0, 0, 255),   # Blue
    'bicycle': (0, 255, 0),      # Green
    'motorcycle': (255, 0, 255), # Magenta
    'bus': (0, 255, 255),        # Cyan
    'trailer': (255, 165, 0),    # Orange
    'truck': (255, 20, 147)      # Deep Pink
}

def get_color_for_category(category_name):
    """
    获取类别的颜色
    """
    for category, color in category_colors.items():
        if category in category_name:
            return color
    return (128, 128, 128)  # Default color: Gray

def draw_3d_box_on_image(image, corners_3d, camera_intrinsic, color, label=None):
    """
    在图像上绘制3D框
    """
    # 从相机坐标系->像素坐标系
    view = np.eye(4)
    view[:3, :3] = camera_intrinsic
    in_front = corners_3d[2, :] > 0.1
    if all(in_front) is False:
        return image
    points = corners_3d
    points = np.concatenate((points, np.ones((1, points.shape[1]))), axis=0)
    points = np.dot(view, points)[:3, :]
    points /= points[2, :]

    box_img = points.astype(np.int32)

    for i in range(4):
        j = (i + 1) % 4
        # 下底面
        cv2.line(image, (box_img[0, i], box_img[1, i]), (box_img[0, j], box_img[1, j]), color, thickness=2)
        # 上底面
        cv2.line(image, (box_img[0, i + 4], box_img[1, i + 4]), (box_img[0, j + 4], box_img[1, j + 4]), color, thickness=2)
        # 侧边线
        cv2.line(image, (box_img[0, i], box_img[1, i]), (box_img[0, i + 4], box_img[1, i + 4]), color, thickness=2)

    if label:
        # 在图像上绘制文本标签
        x_min = min(box_img[0])
        y_min = min(box_img[1])
        cv2.putText(image, label, (x_min, y_min - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
    
    return image

def calculate_2d_bbox(corners_3d, camera_intrinsic):
    """
    计算2D边界框
    """
    view = np.eye(4)
    view[:3, :3] = camera_intrinsic
    in_front = corners_3d[2, :] > 0.1
    if all(in_front) is False:
        return None
    points = corners_3d
    points = np.concatenate((points, np.ones((1, points.shape[1]))), axis=0)
    points = np.dot(view, points)[:3, :]
    points /= points[2, :]

    box_img = points.astype(np.int32)
    x_min, y_min = np.min(box_img[0]), np.min(box_img[1])
    x_max, y_max = np.max(box_img[0]), np.max(box_img[1])

    return x_min, y_min, x_max, y_max

def visualize_sample(nusc, sample_token, save_path):
    sample = nusc.get('sample', sample_token)
    sample_data_token = sample['data']['CAM_FRONT']

    sd_rec = nusc.get('sample_data', sample_data_token)
    filename = sd_rec['filename']
    img_path = os.path.join(nusc.dataroot, filename)
    img = cv2.imread(img_path)

    assert sd_rec['sensor_modality'] == 'camera', 'Error: This function only works for camera sample_data!'
    if not sd_rec['is_key_frame']:
        raise ValueError('The 2D re-projections are available only for keyframes.')

    cs_rec = nusc.get('calibrated_sensor', sd_rec['calibrated_sensor_token'])
    pose_rec = nusc.get('ego_pose', sd_rec['ego_pose_token'])
    camera_intrinsic = np.array(cs_rec['camera_intrinsic'])

    img_height, img_width = img.shape[:2]
    img_area = img_height * img_width

    ann_recs = [nusc.get('sample_annotation', token) for token in sample['anns']]
    for ann_rec in ann_recs:
        box = nusc.get_box(ann_rec['token'])

        # 从世界坐标系->车身坐标系
        box.translate(-np.array(pose_rec['translation']))
        box.rotate(Quaternion(pose_rec['rotation']).inverse)

        # 从车身坐标系->相机坐标系
        box.translate(-np.array(cs_rec['translation']))
        box.rotate(Quaternion(cs_rec['rotation']).inverse)

        corners_3d = box.corners()
        bbox_2d = calculate_2d_bbox(corners_3d, camera_intrinsic)

        if bbox_2d:
            x_min, y_min, x_max, y_max = bbox_2d
            box_area = (x_max - x_min) * (y_max - y_min)
            area_ratio = np.sqrt(box_area / img_area)

            label = None
            if area_ratio < 0.03:
                label = "small target"

            color = get_color_for_category(ann_rec['category_name'])
            img = draw_3d_box_on_image(img, corners_3d, camera_intrinsic, color, label)

    save_filename = os.path.join(save_path, f"{sample_token}.png")
    cv2.imwrite(save_filename, img)
    print(f"Saved {save_filename}")

def visualize_all_samples(nusc, save_path):
    if not os.path.exists(save_path):
        os.makedirs(save_path)

    for sample in nusc.sample:
        visualize_sample(nusc, sample['token'], save_path)


# 设置保存路径并可视化所有样本
save_path = '/home/lyh/Documents/small_target_Output/'
visualize_all_samples(nusc, save_path)

可视化效果:

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

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

相关文章

电流互感器的操作、类型和极性注意事项

了解电流互感器及其在将大电流转换为小电流方面的重要作用&#xff0c;包括绕组比、类型以及保持计量极性的重要性。 电流互感器 (CT) 主要用于改变电压值。第二个结果是它们也会改变当前值。 升压变压器减少次级绕组中的电流&#xff0c;降压变压器增加次级绕组中的电流&…

vscode Git代码版本回退

在项目文件夹右键打开git bash&#xff0c;输入命令git log 查看提交的历史 commit&#xff0c;git log --prettyoneline将版本信息压缩到一行 使用git log可能会显示不全&#xff0c;按enter逐行查看&#xff0c;按end跳至末尾查看完成后&#xff0c;按q即可退出 找到自己想…

云计算实训40——部署nmt、部署project_exam_system项目

NMT N指的是nginx M指的是mysql T指的是tomcat 一、环境准备 #使用基础的docker指令来创建镜像&#xff0c;实现项目的发布 #安装docker、编辑daemon.json文件、安装docker-compose编排容器、启动docker #拖拽docker.sh的脚本[rootdocker--1 ~]# rz -Erz waiting to rec…

Qt QPushButton 按钮右上角增加小红点

简述 在项目里有时候应用类按钮在模块上新时&#xff0c;需要增加小红点提示。 效果图&#xff1a; 实现 实现的方法有很多 &#xff0c;下面介绍超简单的一种。 直接在按钮上贴一个 QLabel 即可。 #pragma once#include <QtWidgets/QWidget> #include "ui_paf…

宁武县乡村e镇招商引资暨产品推介会在京举办

2024年8月26日&#xff0c;宁武县乡村e镇招商引资暨产品推介会在北京市朝阳区五洲皇冠国际酒店举办。此次活动由山西省宁武县委、县政府主办&#xff0c;中国联合国采购促进会、中国商业文化研究会乡村振兴工作委员会协办&#xff0c;旨在宣传推介宁武县丰富的自然资源和农特产…

“1X”家用人形机器人:NEO Beta人形机器人,专为家庭使用而设计

1X机器人是指挪威人形机器人初创企业1X公司推出的一款名为NEO Beta的双足人形机器人原型。这款机器人专为家庭使用而设计&#xff0c;身高约1米65&#xff0c;体重30公斤&#xff0c;具有仿生设计&#xff0c;能够在人与人之间安全工作。NEO Beta采用了OpenAI的技术支持&#x…

spotbugs问题描述汉化

1 支持多语言 spotbugs自身支持问题描述的国际化&#xff0c;默认支持了英语、日语和法语。 问题描述都配置在messages.xml文件中。 (在源码中的位置&#xff1a;/spotbugs//spotbugs/etc/messages.xml) 2 多语言文件名 如果需要支持中文可以将messages.xml中的英文翻译过来。将…

Chapter 08 Vue生命周期

欢迎大家订阅【Vue2Vue3】入门到实践 专栏&#xff0c;开启你的 Vue 学习之旅&#xff01; 文章目录 前言一、生命周期阶段二、生命周期钩子三、生命周期图示 前言 Vue.js 是一个渐进式的 JavaScript 框架&#xff0c;广泛用于构建用户界面。理解 Vue 的生命周期对于开发高效、…

基于springboot+vue的在线商城系统

基于springbootvue的商城系统 (源码L文ppt)4-056 4 系统设计 4.1 系统功能模块设计 经过分析本系统的实际需求&#xff0c;系统主要分为三个模块&#xff0c;用户、商家以及管理员&#xff0c;具体的功能模块如图4-1所示&#xff1a; 图4-1 功能模块设计图 4.2…

超声波清洗机什么牌子值得入手?好用的超声波清洗机推荐

即便身处快节奏的工作环境中&#xff0c;我们仍需重视个人卫生及日常用品的清洁维护&#xff0c;这不仅是生活质量的体现&#xff0c;更是关乎健康的基本原则。长期忽视清洁&#xff0c;灰尘积累则可能成为细菌滋生的温床&#xff0c;进而悄悄威胁我们的身体健康。因此&#xf…

使用BDT利率二叉树模型来计算期权的初始价值

Black-Derman-Toy (BDT) 模型是于1990年开发的一种用于金融市场的利率模型。这个模型是一个单因子短期利率模型&#xff0c;它假设利率遵循一个均值回归过程&#xff0c;即利率随时间趋向于回归到长期平均值。 BDT模型的关键特点包括&#xff1a; 它能够校准到初始的利率期限…

09-02 周一 Ubuntu上使用docker-compose部署elasticsearch和kibana服务

09-02 周一 Ubuntu上部署elasticsearch和kibana服务 时间版本修改人描述2024年9月2日11:13:54V0.1宋全恒新建文档 简介 由于组里需要提供一个简易的环境来部署一套服务&#xff0c;可以通过接口进行数据的存储和检索&#xff0c;因此&#xff0c;直接部署一套ES服务来充当这样…

[Linux网络]TCP三次握手和四次挥手的连接建立和断开

TCP的三次握手 第一次握手&#xff1a;客户端发送网络包&#xff0c;服务器端收到&#xff0c;证明客户端的发送能力、服务器的接收能力是正常的。第二次握手&#xff1a;服务器发送网络包&#xff0c;客户端收到&#xff0c;证明服务器端的发送能力是正常的&#xff0c;不过此…

每日一题,零基础入门FPGA——工程师在线精讲,直播预告

题目传送门&#xff1a;F学社 zzfpga.com/StudentPlatform/Sheet/QuestionBankhttp://zzfpga.com/StudentPlatform/Sheet/QuestionBank 【第Ⅰ期题目 * 5】 请使用D触发器和必要的逻辑门实现此同步时序电路&#xff0c;用Verilog语言描述。 【第Ⅰ期题目 * 4】 请设计一个0…

合宙低功耗4G模组Air780EP——产品规格书

Air780EP作为合宙通信推出的LTE Cat. 1 bis通信模块&#xff0c;基于移芯EC718P平台&#xff0c; 支持LTE 3GPP Release 14技术&#xff0c;确保数据传输的高效性和稳定性。 作为4G全网通模块&#xff0c;兼容各大运营商网络&#xff0c;提供广泛的网络覆盖和灵活性。 作为4…

驱动开发系列14 - Linux Graphics Wayland 详解

目录 一:概述 二:操作系统如何支持 Wayland 三:显卡驱动如何支持 Wayland 四:Wayland 协议介绍 一:概述 Wayland 是一种通信协议,规定了显示服务器与其客户端之间的通信,以及该协议的 C 语言库实现。使用 Wayland 协议的显示服务器称为 Wayland 合成器,因…

为什么单元测试在软件开发中很重要?

单元测试在软件开发过程中扮演着至关重要的角色&#xff0c;其重要性主要体现在以下几个方面&#xff1a; 保证代码质量&#xff1a;单元测试是对软件中的最小可测试单元——函数、方法或类进行检查和验证的过程。通过编写针对各个模块的独立测试用例&#xff0c;开发者能够确…

Python进阶之-加密库cryptography使用详解

✨前言 cryptography 库是一个强大的 Python 加密库&#xff0c;提供了对加密算法和协议的高层和低层访问。它是用来实现数据加密、签名、密钥管理等功能的。以下是一些常见用法的详解&#xff0c;帮助你理解如何使用这个库。 ✨安装 首先&#xff0c;你需要确保安装了 cryp…

经纬恒润半年报:净亏损超3亿元,研发支出增长/毛利下降

作为近年来为数不多成功IPO上市的汽车智能网联概念股&#xff0c;经纬恒润正处于「研发支出增长、毛利率下降」的阵痛期。这也反映出当下产业链的共性困难&#xff0c;车企降本、供应链白热化竞争。 本周&#xff0c;经纬恒润&#xff08;688326&#xff09;发布2024年半年报&a…

怎么才能快速提升网站在谷歌的收录?

​想让你的网站在谷歌快速收录&#xff0c;其实正常的方法都需要时间&#xff0c;无论是定期更新&#xff0c;提交网站地图&#xff0c;搞外链建设啥的&#xff0c;这些方法虽然有效&#xff0c;但见效慢。而且谷歌爬虫不会一下子抓取你所有页面&#xff0c;需要时间。如果真想…