save
This commit is contained in:
+4
-3
@@ -116,7 +116,7 @@ def _resolve_image_bytes(image_bytes: bytes = None, image_url: str = None) -> by
|
|||||||
|
|
||||||
|
|
||||||
def _local_face_shape(image_bytes: bytes = None, image_url: str = None) -> str:
|
def _local_face_shape(image_bytes: bytes = None, image_url: str = None) -> str:
|
||||||
"""MediaPipe 脸型分类,返回 display(含混合脸型描述)或主脸型。"""
|
"""MediaPipe 脸型分类,只返回主脸型(7 类之一),不含混合描述。"""
|
||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from face.face_shape_classifier import classify_from_image
|
from face.face_shape_classifier import classify_from_image
|
||||||
@@ -126,11 +126,12 @@ def _local_face_shape(image_bytes: bytes = None, image_url: str = None) -> str:
|
|||||||
if bgr is None:
|
if bgr is None:
|
||||||
raise ValueError("图片格式不支持,无法解码")
|
raise ValueError("图片格式不支持,无法解码")
|
||||||
result = classify_from_image(bgr, return_details=True, return_annotated=False)
|
result = classify_from_image(bgr, return_details=True, return_annotated=False)
|
||||||
shape = result.get("display") or result["face_shape"]
|
shape = result["face_shape"]
|
||||||
logger.info(
|
logger.info(
|
||||||
"local face_shape=%s conf=%.3f",
|
"local face_shape=%s conf=%.3f display=%s",
|
||||||
shape,
|
shape,
|
||||||
float(result.get("confidence") or 0),
|
float(result.get("confidence") or 0),
|
||||||
|
result.get("display") or shape,
|
||||||
)
|
)
|
||||||
return shape
|
return shape
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""把 static/annotations 根目录下的图片按创建时间(天)归入 YYYY-MM-DD 子目录。
|
||||||
|
|
||||||
|
用法:
|
||||||
|
python3 scripts/organize_annotations_by_day.py # 实际移动
|
||||||
|
python3 scripts/organize_annotations_by_day.py --dry-run # 只预览
|
||||||
|
python3 scripts/organize_annotations_by_day.py --dir /path # 指定目录
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
from collections import Counter
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
IMAGE_EXTS = {".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp"}
|
||||||
|
|
||||||
|
|
||||||
|
def file_day(path: Path) -> str:
|
||||||
|
"""取文件创建日(优先 birth time,否则 mtime),本地时区 YYYY-MM-DD。"""
|
||||||
|
st = path.stat()
|
||||||
|
ts = getattr(st, "st_birthtime", None) or st.st_mtime
|
||||||
|
return datetime.fromtimestamp(ts).strftime("%Y-%m-%d")
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
repo = Path(__file__).resolve().parent.parent
|
||||||
|
parser = argparse.ArgumentParser(description="按天整理 annotations 图片")
|
||||||
|
parser.add_argument(
|
||||||
|
"--dir",
|
||||||
|
type=Path,
|
||||||
|
default=repo / "static" / "annotations",
|
||||||
|
help="annotations 目录(默认 static/annotations)",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--dry-run",
|
||||||
|
action="store_true",
|
||||||
|
help="只打印将要执行的操作,不实际移动",
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
root: Path = args.dir.resolve()
|
||||||
|
|
||||||
|
if not root.is_dir():
|
||||||
|
print(f"目录不存在: {root}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
files = [
|
||||||
|
p
|
||||||
|
for p in root.iterdir()
|
||||||
|
if p.is_file() and p.suffix.lower() in IMAGE_EXTS
|
||||||
|
]
|
||||||
|
if not files:
|
||||||
|
print(f"根目录没有待整理图片: {root}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
by_day: Counter[str] = Counter()
|
||||||
|
moved = 0
|
||||||
|
skipped = 0
|
||||||
|
|
||||||
|
for src in sorted(files):
|
||||||
|
day = file_day(src)
|
||||||
|
dest_dir = root / day
|
||||||
|
dest = dest_dir / src.name
|
||||||
|
by_day[day] += 1
|
||||||
|
|
||||||
|
if dest.exists():
|
||||||
|
print(f"SKIP 目标已存在: {dest.relative_to(root)}")
|
||||||
|
skipped += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
if args.dry_run:
|
||||||
|
print(f"MOVE {src.name} -> {day}/")
|
||||||
|
else:
|
||||||
|
dest_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
shutil.move(str(src), str(dest))
|
||||||
|
moved += 1
|
||||||
|
|
||||||
|
print("---")
|
||||||
|
print(f"目录: {root}")
|
||||||
|
print(f"{'预览' if args.dry_run else '完成'}: {moved} 个文件"
|
||||||
|
+ (f", 跳过 {skipped}" if skipped else ""))
|
||||||
|
for day in sorted(by_day):
|
||||||
|
print(f" {day}: {by_day[day]}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Reference in New Issue
Block a user