【第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()
相关推荐
PHOSKEY1 天前
具身机器人行星滚柱丝杠核心尺寸测量与光子精密QM系列闪测仪应用
数码相机
就是个名称2 天前
cesium 地球地固转地惯
数码相机
AttosTek2 天前
-80℃深度制冷短波红外相机选型指南
数码相机
落苜蓿蓝2 天前
多张覆盖视场的平面棋盘图片; 、对每张图片用 OpenCV 的 findChessboardCorners 检测内角点并用 corn ...
数码相机·opencv·平面
取个名字太难了~3 天前
最新手机外接相机实时传输 + 动态美颜完整项目源码
android·数码相机·智能手机·美颜·相机连接·demu
取个名字太难了~4 天前
安卓相机连接手机实时预览+美颜特效完整源码
android·数码相机·智能手机·美颜·相机连接·demu
ueotek4 天前
Ansys Speos丨面向航空航天与国防的杂散光分析——红外相机中的冷反射(Narcissus)效应
数码相机
美狐美颜SDK开放平台4 天前
直播APP开发,美颜SDK和相机SDK有什么区别?
android·深度学习·数码相机·ios·直播美颜sdk·视频美颜sdk
巧克力味的桃子4 天前
尼康Z30|P/A/S/M四大档位完整详解
数码相机
code_pgf5 天前
鱼眼相机模型
数码相机