guqing b888f897fa 1)init 10 часов назад
..
README.md b888f897fa 1)init 10 часов назад
process_pano.py b888f897fa 1)init 10 часов назад
requirements.txt b888f897fa 1)init 10 часов назад

README.md

全景图区域批量切图工具

项目简介

这是一个用于处理全景图(360° 全景图片)的命令行工具,可以根据 JSON 配置文件中定义的区域坐标,批量裁剪出多个 Pinhole(普通视角)图片。

核心功能

  • 从 URL 下载全景图片
  • 根据给定的四个角点坐标,将全景图裁剪为普通视角图片
  • 支持全景图跨边界处理(当坐标跨越 360° 边界时自动校正)
  • 批量处理多个场景和多个区域
  • 自动创建分层输出目录

代码运行流程

1. 启动流程

命令行执行 → argparse 解析参数 → main() 函数

执行命令:

基础用法: python process_pano.py --json <输入 JSON 文件> 
可调参数:python process_pano.py --json <输入 JSON 文件> [--output 输出目录] [--width 宽度] [--height 高度]

2. 主要处理步骤

┌─────────────────────────────────────────────────────────────┐
│  步骤 1: 读取 JSON 配置文件                                  │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│  步骤 2: 解析 sceneCode,初始化图片缓存                       │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│  步骤 3: 遍历每个场景项 (list 数组)                           │
│     - 获取 tag.sid (场景 ID)                                 │
│     - 获取 snap[] 数组 (快照列表)                            │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│  步骤 4: 遍历每个快照 (snap)                                  │
│     - 获取 imageUrl, panoId, corners                         │
│     - 跳过无效数据 (无 URL 或少于 4 个角点)                     │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│  步骤 5: 下载全景图 (使用缓存避免重复下载)                     │
│     imread_url() → OpenCV 图片格式                           │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│  步骤 6: 生成 Pinhole 图片                                   │
│     generate_pinhole_from_array():                          │
│     - 处理全景图跨边界坐标                                   │
│     - 计算中心点 (u_deg, v_deg)                             │
│     - 计算视场角 (fov_h, fov_v)                             │
│     - 调用 py360convert.e2p() 转换                          │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│  步骤 7: 保存结果图片                                         │
│     路径:{output}/{sceneCode}/{sid}/pano_{panoId}_snap_{idx}.jpg │
└─────────────────────────────────────────────────────────────┘

输入格式

JSON 文件格式示例:

{
  "sceneCode": "场景编码",
  "list": [
    {
      "tag": {
        "sid": "场景 ID"
      },
      "snap": [
        {
          "imageUrl": "https://example.com/panorama.jpg",
          "panoId": "0",
          "corners": [
            {"x": 100, "y": 200},
            {"x": 500, "y": 200},
            {"x": 500, "y": 600},
            {"x": 100, "y": 600}
          ]
        }
      ]
    }
  ]
}

输出结果

保存位置

默认输出目录结构:

cropped_results/
└── {sceneCode}/
    └── {sid}/
        ├── pano_0_snap_0.jpg
        ├── pano_0_snap_1.jpg
        └── pano_1_snap_0.jpg
  • 根目录: 可通过 --output 参数自定义 (默认:cropped_results)
  • 场景目录: 以 sceneCode 命名
  • 子目录: 以 sid (场景 ID) 命名
  • 文件命名: pano_{panoId}_snap_{索引}.jpg

输出图片规格

  • 默认尺寸:5671 × 3186 像素
  • 可通过 --width--height 参数调整

依赖安装

pip install -r requirements.txt

需要的主要依赖:

  • opencv-python: 图片读取和保存
  • numpy: 数组运算
  • py360convert: 全景图转普通视角转换
  • requests: HTTP 下载图片

使用示例

# 基本用法
python process_pano.py --json config.json

# 自定义输出目录和尺寸
python process_pano.py --json config.json --output my_results --width 1920 --height 1080

关键算法说明

全景图跨边界处理

当全景图坐标跨越 0°/360°边界时,代码自动进行坐标校正:

if pts[1][0] < pts[0][0]:
    pts[1][0] += w  # 右边界点向左补偿
if pts[2][0] < pts[3][0]:
    pts[2][0] += w  # 下边界点向左补偿

视场角计算

  • 水平视场角:fov_h = (span_x / w) * 360 * 1.2 (最大 110°)
  • 垂直视场角:fov_v = (span_y / h) * 180 * 1.2 (最大 110°)
  • 乘以 1.2 是为了留 20% 的边距