Files
Bird_detect_cascade_service_V2/app/image_pipeline.py
T
2026-08-21 14:19:14 +08:00

121 lines
3.4 KiB
Python

from pathlib import Path
from typing import Dict
import cv2
import numpy as np
from app.config import settings
from app.utils import (
draw_results,
now_timestamp_minute,
safe_stem,
save_json,
write_image_xml,
)
def make_unique_result_dir(parent_dir: Path, timestamp: str, original_filename: str) -> tuple[Path, str, str]:
"""
创建单次图片识别结果目录。
目录名:
时间戳_原文件名stem
例如:
runs/images/202605181431_DJI_20250820151801_0006_Z/
返回:
result_dir, result_base_name, original_stem
"""
original_stem = safe_stem(original_filename)
base_name = f"{timestamp}_{original_stem}"
result_dir = parent_dir / base_name
if not result_dir.exists():
result_dir.mkdir(parents=True, exist_ok=True)
return result_dir, base_name, original_stem
idx = 1
while True:
candidate_base = f"{base_name}_{idx:02d}"
candidate_dir = parent_dir / candidate_base
if not candidate_dir.exists():
candidate_dir.mkdir(parents=True, exist_ok=True)
return candidate_dir, candidate_base, original_stem
idx += 1
def save_image_outputs(
img_bgr: np.ndarray,
original_filename: str,
predict_output: Dict,
) -> Dict:
"""
图片结果自动保存到:
runs/images/时间戳_原图片名/
目录内部生成:
原图片名.jpg
时间戳_原图片名.json
时间戳_原图片名.xml
示例:
runs/images/202605181431_DJI_20250820151801_0006_Z/
├── DJI_20250820151801_0006_Z.jpg
├── 202605181431_DJI_20250820151801_0006_Z.json
└── 202605181431_DJI_20250820151801_0006_Z.xml
"""
images_root = Path(settings.output_dir) / settings.image_output_subdir
images_root.mkdir(parents=True, exist_ok=True)
timestamp = now_timestamp_minute()
result_dir, result_base_name, original_stem = make_unique_result_dir(
parent_dir=images_root,
timestamp=timestamp,
original_filename=original_filename,
)
# 图片文件名不带时间戳,按你的要求保留原图片名 stem
image_path = result_dir / f"{original_stem}.jpg"
# JSON 和 XML 带时间戳
json_path = result_dir / f"{result_base_name}.json"
xml_path = result_dir / f"{result_base_name}.xml"
results = predict_output.get("results", [])
annotated = draw_results(img_bgr, results)
cv2.imwrite(str(image_path), annotated)
json_data = {
"success": True,
"type": "image",
"original_filename": original_filename,
"result_dir": str(result_dir),
"saved_image": str(image_path),
"saved_json": str(json_path),
"saved_xml": str(xml_path),
"image_width": predict_output.get("image_width"),
"image_height": predict_output.get("image_height"),
"num_objects": predict_output.get("num_objects"),
"results": results,
}
save_json(json_path, json_data)
write_image_xml(
xml_path=xml_path,
image_filename=image_path.name,
image_path=str(image_path),
width=int(predict_output.get("image_width", img_bgr.shape[1])),
height=int(predict_output.get("image_height", img_bgr.shape[0])),
results=results,
)
return {
"result_dir": str(result_dir),
"image": str(image_path),
"json": str(json_path),
"xml": str(xml_path),
}