Fits small cameras

This commit is contained in:
Ankle committed 2026-07-29 16:25:16 +08:00
1 parent a773166c91
commit 98ed2576c6
7 files changed
+526 -96

No files matched your search

+7 -5
View File
@@ -50,21 +50,23 @@ find /userdata/data/scan -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | sort
指定扫描目录名进行拼图:
```bash
./stitch.sh 2026-07-22_18-25-09 --mount desktop
./stitch.sh 2026-07-22_18-25-09 --mount desktop --pan-direction increasing
```
必须用`--mount`声明球机安装方式:
```bash
# 办公室测试:球机正放桌面,摄像头后台将画面旋转180度
./stitch.sh 2026-07-22_18-25-09 --mount desktop
./stitch.sh 2026-07-22_18-25-09 --mount desktop --pan-direction increasing
# 野外部署:球机物理倒挂
./stitch.sh 2026-07-22_18-25-09 --mount hanging
./stitch.sh 2026-07-22_18-25-09 --mount hanging --pan-direction increasing
```
- `desktop`同时反转网格行顺序和列顺序;
- `hanging`按`meta.json`原始row/col顺序排列;
- `desktop`反转上下行顺序,`hanging`保持上下行顺序;
- `--pan-direction increasing`表示画面左到右时pan递增,列保持正序;
- `--pan-direction decreasing`表示画面左到右时pan递减,列反序;
- pan方向由交互式标定第④步自动识别,不能根据desktop/hanging猜测;
- 两种模式都不会旋转或镜像单张图片,只改变图片在大图中的位置。
目录名会自动解析为:
+35 -5
View File
@@ -105,11 +105,23 @@ def identify_dimensions(images: list[Path]) -> tuple[int, int]:
return dimensions.pop()
def build_mosaic(scan_dir: Path, tile_width: int, quality: int, mount: str) -> Path:
def build_mosaic(
scan_dir: Path,
tile_width: int,
quality: int,
mount: str,
pan_direction: str,
) -> Path:
# Office testing: the dome stands on a desk and the camera firmware rotates
# the encoded picture by 180 degrees. Field deployment: the dome is hung.
# the encoded picture by 180 degrees, which reverses the vertical grid.
# Horizontal ordering is camera/firmware-specific and is measured during
# calibration; it must not be inferred from the physical mount.
reverse_rows = mount == "desktop"
reverse_cols = mount == "desktop"
if pan_direction == "auto":
# Backward-compatible behavior for scans made before calibration began
# recording the actual signed pan direction.
pan_direction = "decreasing" if mount == "desktop" else "increasing"
reverse_cols = pan_direction == "decreasing"
scan_id, rows, cols, images = load_grid(scan_dir, reverse_rows, reverse_cols)
source_width, source_height = identify_dimensions(images)
if tile_width <= 0:
@@ -150,7 +162,10 @@ def build_mosaic(scan_dir: Path, tile_width: int, quality: int, mount: str) -> P
print(f"扫描目录:{scan_dir}")
print(f"网格:{cols}列 × {rows}行,共{len(images)}张")
print(f"安装方式:{mount}(行={'反向' if reverse_rows else '正向'},列={'反向' if reverse_cols else '正向'})")
print(
f"安装方式:{mount}(行={'反向' if reverse_rows else '正向'})"
f",实测pan方向:{pan_direction}(列={'反向' if reverse_cols else '正向'})"
)
print(f"小图:{source_width}×{source_height}")
if tile_width != requested_tile_width:
print(f"尺寸保护:单格宽度由{requested_tile_width}自动缩小到{tile_width},避免超过ImageMagick限制")
@@ -173,6 +188,15 @@ def main() -> None:
required=True,
help="desktop=办公室桌面正放且后台旋转180度;hanging=野外倒挂",
)
parser.add_argument(
"--pan-direction",
choices=["auto", "increasing", "decreasing"],
default="auto",
help=(
"画面左到右时pan数值方向;交互式向导会自动传入。"
"旧扫描未记录方向时默认auto沿用历史mount规则"
),
)
parser.add_argument(
"--tile-width",
type=int,
@@ -188,7 +212,13 @@ def main() -> None:
help="输出JPEG质量,默认92",
)
args = parser.parse_args()
build_mosaic(resolve_scan_dir(args.scan_dir), args.tile_width, args.quality, args.mount)
build_mosaic(
resolve_scan_dir(args.scan_dir),
args.tile_width,
args.quality,
args.mount,
args.pan_direction,
)
if __name__ == "__main__":