# 全景图区域批量切图工具 ## 项目简介 这是一个用于处理全景图(360° 全景图片)的命令行工具,可以根据 JSON 配置文件中定义的区域坐标,批量裁剪出多个 Pinhole(普通视角)图片。 ## 核心功能 - 从 URL 下载全景图片 - 根据给定的四个角点坐标,将全景图裁剪为普通视角图片 - 支持全景图跨边界处理(当坐标跨越 360° 边界时自动校正) - 批量处理多个场景和多个区域 - 自动创建分层输出目录 ## 代码运行流程 ### 1. 启动流程 ``` 命令行执行 → argparse 解析参数 → main() 函数 ``` 执行命令: ```bash 基础用法: 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 文件格式示例: ```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` 参数调整 ## 依赖安装 ```bash pip install -r requirements.txt ``` 需要的主要依赖: - `opencv-python`: 图片读取和保存 - `numpy`: 数组运算 - `py360convert`: 全景图转普通视角转换 - `requests`: HTTP 下载图片 ## 使用示例 ```bash # 基本用法 python process_pano.py --json config.json # 自定义输出目录和尺寸 python process_pano.py --json config.json --output my_results --width 1920 --height 1080 ``` ## 关键算法说明 ### 全景图跨边界处理 当全景图坐标跨越 0°/360°边界时,代码自动进行坐标校正: ```python 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% 的边距