【第3篇】自定义飞机关键点标注数据获取

最终效果

  1. 导入fbx飞机模型,如air3、固定翼其他模型
  2. 为模型新建一个蓝图类,蓝图类里会有飞机的中心点(通常为几何中心,不一定是质心)
  3. blue蓝图类里新建scene component场景组件
  4. 将StaticMesh,也就是p51改为movable可移动的;就可以通过airsim的setObjectsPose给发送pose信息,pose(x,y,z,y,p,r)可以改变位置(location/position),也可以改变目标的ypr角度;
  5. 相机的ypr角度也可以更改;可以实现相机和目标的位姿都相对变化
  6. 写python脚本控制的时候,发送位姿变化的时候就保存org,show,points.txt等信息,就可以完成关键点数据的标注和获取。
  7. yolo-v8-pose预训练:
    存在问题:pose训练需要bbox和points一起,但是我只标记了5个关键点,在某些姿态下不足以覆盖目标的全部,所以还需要标记一些外轮廓的点,比如尾翼的上方,腹部的最下方等信息;还需要注意下飞机在不同姿态下载相机平面的投影,是否包含完毕。

下面是模型导入信息
python 复制代码
"""
读取 BP_P51 关键点,并演示位姿控制接口。

关键点顺序: C, N, T, WL, WR, CP
  C  = 机体中心
  N  = 机头
  T  = 机尾
  WL = 左翼尖
  WR = 右翼尖
  CP = 座舱

用法 (需 AirSim Play):
  python generate_fixed_wing_points.py
  python generate_fixed_wing_points.py --draw
  python generate_fixed_wing_points.py --set-pose 0 0 -2 5 0 30 --draw
  python generate_fixed_wing_points.py --set-position 10 0 -2 --set-attitude 5 0 30
  python generate_fixed_wing_points.py --draw --cam-pitch 50 --cam-yaw 30
"""

import argparse
import json
import os
import sys

_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
_PARENT_DIR = os.path.dirname(_SCRIPT_DIR)
if _PARENT_DIR not in sys.path:
    sys.path.insert(0, _PARENT_DIR)

from draw_fixed_wing_points import capture_and_draw
from fixed_wing_api import FixedWingInterface


def export_points_txt(fw: FixedWingInterface, txt_path: str):
    points = fw.get_key_points()
    lines = ["# label x y z  (NED world, meter)"]
    for label, point in points.items():
        x, y, z = point["position_ned_m"]
        lines.append(f"{label} {x:.6f} {y:.6f} {z:.6f}")
    with open(txt_path, "w", encoding="utf-8") as file:
        file.write("\n".join(lines) + "\n")


def apply_pose_from_args(fw: FixedWingInterface, args) -> None:
    if args.set_pose is not None:
        x, y, z, pitch, roll, yaw = args.set_pose
        print(
            f"\n=== 设置位姿: pos=({x}, {y}, {z}) m, "
            f"attitude=(pitch={pitch}, roll={roll}, yaw={yaw}) deg ==="
        )
        fw.set_pose(x=x, y=y, z=z, pitch_deg=pitch, roll_deg=roll, yaw_deg=yaw)
        fw.print_status()
        return

    if args.set_position is None and args.set_attitude is None:
        return

    pos_kwargs = {}
    if args.set_position is not None:
        x, y, z = args.set_position
        pos_kwargs = {"x": x, "y": y, "z": z}
        print(f"\n=== 设置位置: ({x}, {y}, {z}) m ===")

    att_kwargs = {}
    if args.set_attitude is not None:
        pitch, roll, yaw = args.set_attitude
        att_kwargs = {"pitch_deg": pitch, "roll_deg": roll, "yaw_deg": yaw}
        print(f"=== 设置姿态: pitch={pitch}, roll={roll}, yaw={yaw} deg ===")

    fw.set_pose(**pos_kwargs, **att_kwargs)
    fw.print_status()


def main():
    parser = argparse.ArgumentParser(description="BP_P51 关键点读取与位姿控制")
    parser.add_argument(
        "--set-pose",
        nargs=6,
        type=float,
        metavar=("X", "Y", "Z", "PITCH", "ROLL", "YAW"),
        help="同时设置位置(NED,m)和姿态(度),例如: --set-pose 0 0 -2 5 0 30",
    )
    parser.add_argument(
        "--set-position",
        nargs=3,
        type=float,
        metavar=("X", "Y", "Z"),
        help="只设置位置 (NED,m),可与 --set-attitude 组合",
    )
    parser.add_argument(
        "--set-attitude",
        nargs=3,
        type=float,
        metavar=("PITCH", "ROLL", "YAW"),
        help="只设置姿态 (度),可与 --set-position 组合",
    )
    parser.add_argument(
        "--export-txt",
        action="store_true",
        help="导出关键点到 fixed_wing_points_ned.txt",
    )
    parser.add_argument(
        "--draw",
        action="store_true",
        help="将关键点投影绘制到图像并保存 fixed_wing_org/show.jpg",
    )
    parser.add_argument("--cam-pitch", type=float, default=0.0, help="相机俯仰角 (度)")
    parser.add_argument("--cam-yaw", type=float, default=0.0, help="相机偏航角 (度)")
    parser.add_argument("--cam-roll", type=float, default=0.0, help="相机横滚角 (度)")
    parser.add_argument(
        "--show-imshow",
        action="store_true",
        help="弹窗显示原图与标注图",
    )
    args = parser.parse_args()

    fw = FixedWingInterface()
    fw.connect()

    print("=== 读取 BP_P51 位姿与关键点 ===")
    fw.print_status()

    apply_pose_from_args(fw, args)

    if args.export_txt:
        txt_path = os.path.join(_SCRIPT_DIR, "fixed_wing_points_ned.txt")
        export_points_txt(fw, txt_path)
        print(f"\n已导出: {txt_path}")

    if args.draw:
        draw_result = capture_and_draw(
            fw,
            output_dir=_SCRIPT_DIR,
            pitch_deg=args.cam_pitch,
            yaw_deg=args.cam_yaw,
            roll_deg=args.cam_roll,
            show_imshow=args.show_imshow,
            imshow_wait_ms=0,
        )
        snapshot_draw = {
            "camera": {
                "pitch_deg": args.cam_pitch,
                "yaw_deg": args.cam_yaw,
                "roll_deg": args.cam_roll,
            },
            "pixels": {
                label: (None if uv is None else [uv[0], uv[1]])
                for label, uv in draw_result["pixels"].items()
            },
            "images": {
                "org": draw_result["org_path"],
                "show": draw_result["show_path"],
                "pixels_txt": draw_result["txt_path"],
            },
        }
    else:
        snapshot_draw = None

    json_path = os.path.join(_SCRIPT_DIR, "fixed_wing_points_snapshot.json")
    snapshot = {
        "pose": {
            k: v for k, v in fw.get_pose().items() if k != "raw_pose"
        },
        "key_points": fw.get_key_points(),
        "draw": snapshot_draw,
    }
    with open(json_path, "w", encoding="utf-8") as file:
        json.dump(snapshot, file, indent=2, ensure_ascii=False)
    print(f"已保存快照: {json_path}")


if __name__ == "__main__":
    main()
相关推荐
中达瑞和-高光谱·多光谱2 小时前
跨越波段盲区,获取多维信息:全波段光谱相机能解决什么?
数码相机
蜕变的土豆5 小时前
Dalsa网口线扫相机配置以及排查问题全流程
数码相机
3DVisionary8 小时前
如何用单目高速DIC把“看不见“的振动变成“数得清“的数据
java·spring boot·python·数码相机·微小振动·精密件·单目高速dic
Helen_cai2 天前
OpenHarmony 权限动态申请封装(API Version23 + 适配版)
数码相机·华为·harmonyos
2601_957418802 天前
从 Demo 到商用:一个照片直播系统的 Android 相机连接实践
数码相机
取个名字太难了~3 天前
越用越便宜,越用越强大:影像 SDK 的边际成本递减与网络效应实践
android·数码相机·美颜·相机连接·demu
双翌视觉3 天前
晶圆光刻对准系统:半导体制造中的精准对位艺术
数码相机·制造
想要入门的程序猿3 天前
摄影测量学习()
数码相机·学习
ctrl_v助手3 天前
HALCON 学习笔记1
笔记·数码相机·学习·算法·计算机视觉