chenchaoyun
commited on
Commit
·
113c701
1
Parent(s):
9fd1066
fix
Browse files- api_routes.py +3 -4
- face_analyzer.py +2 -4
- utils.py +0 -49
api_routes.py
CHANGED
|
@@ -288,7 +288,6 @@ from models import (
|
|
| 288 |
|
| 289 |
from face_analyzer import EnhancedFaceAnalyzer
|
| 290 |
from utils import (
|
| 291 |
-
save_image_force_compress,
|
| 292 |
save_image_high_quality,
|
| 293 |
save_image_with_transparency,
|
| 294 |
human_readable_size,
|
|
@@ -1095,7 +1094,7 @@ async def analyze_face(
|
|
| 1095 |
original_md5_hash = str(uuid.uuid4()).replace('-', '')
|
| 1096 |
original_image_filename = f"{original_md5_hash}_original.webp"
|
| 1097 |
original_image_path = os.path.join(IMAGES_DIR, original_image_filename)
|
| 1098 |
-
|
| 1099 |
# 🔥 添加图片安全检测
|
| 1100 |
t1 = time.perf_counter()
|
| 1101 |
is_safe = await wx_access_token.check_image_security(contents)
|
|
@@ -1254,8 +1253,8 @@ async def analyze_face(
|
|
| 1254 |
if result.get("success") and annotated_image_np is not None:
|
| 1255 |
original_image_path = os.path.join(OUTPUT_DIR, original_image_filename)
|
| 1256 |
save_start = time.perf_counter()
|
| 1257 |
-
save_success =
|
| 1258 |
-
annotated_image_np, original_image_path,
|
| 1259 |
)
|
| 1260 |
_log_stage_duration(
|
| 1261 |
"标注图保存",
|
|
|
|
| 288 |
|
| 289 |
from face_analyzer import EnhancedFaceAnalyzer
|
| 290 |
from utils import (
|
|
|
|
| 291 |
save_image_high_quality,
|
| 292 |
save_image_with_transparency,
|
| 293 |
human_readable_size,
|
|
|
|
| 1094 |
original_md5_hash = str(uuid.uuid4()).replace('-', '')
|
| 1095 |
original_image_filename = f"{original_md5_hash}_original.webp"
|
| 1096 |
original_image_path = os.path.join(IMAGES_DIR, original_image_filename)
|
| 1097 |
+
save_image_high_quality(image, original_image_path, quality=SAVE_QUALITY)
|
| 1098 |
# 🔥 添加图片安全检测
|
| 1099 |
t1 = time.perf_counter()
|
| 1100 |
is_safe = await wx_access_token.check_image_security(contents)
|
|
|
|
| 1253 |
if result.get("success") and annotated_image_np is not None:
|
| 1254 |
original_image_path = os.path.join(OUTPUT_DIR, original_image_filename)
|
| 1255 |
save_start = time.perf_counter()
|
| 1256 |
+
save_success = save_image_high_quality(
|
| 1257 |
+
annotated_image_np, original_image_path, quality=SAVE_QUALITY
|
| 1258 |
)
|
| 1259 |
_log_stage_duration(
|
| 1260 |
"标注图保存",
|
face_analyzer.py
CHANGED
|
@@ -11,7 +11,7 @@ from config import logger, MODELS_PATH, OUTPUT_DIR, DEEPFACE_AVAILABLE, \
|
|
| 11 |
YOLO_AVAILABLE
|
| 12 |
from facial_analyzer import FacialFeatureAnalyzer
|
| 13 |
from models import ModelType
|
| 14 |
-
from utils import
|
| 15 |
|
| 16 |
if DEEPFACE_AVAILABLE:
|
| 17 |
from deepface import DeepFace
|
|
@@ -949,9 +949,7 @@ class EnhancedFaceAnalyzer:
|
|
| 949 |
cropped_face_filename = f"{original_image_hash}_face_{i + 1}.webp"
|
| 950 |
cropped_face_path = os.path.join(OUTPUT_DIR, cropped_face_filename)
|
| 951 |
try:
|
| 952 |
-
|
| 953 |
-
face_cropped, cropped_face_path, max_size_kb=100
|
| 954 |
-
)
|
| 955 |
logger.info(f"cropped face: {cropped_face_path}")
|
| 956 |
except Exception as e:
|
| 957 |
logger.error(f"Failed to save cropped face {cropped_face_path}: {e}")
|
|
|
|
| 11 |
YOLO_AVAILABLE
|
| 12 |
from facial_analyzer import FacialFeatureAnalyzer
|
| 13 |
from models import ModelType
|
| 14 |
+
from utils import save_image_high_quality
|
| 15 |
|
| 16 |
if DEEPFACE_AVAILABLE:
|
| 17 |
from deepface import DeepFace
|
|
|
|
| 949 |
cropped_face_filename = f"{original_image_hash}_face_{i + 1}.webp"
|
| 950 |
cropped_face_path = os.path.join(OUTPUT_DIR, cropped_face_filename)
|
| 951 |
try:
|
| 952 |
+
save_image_high_quality(face_cropped, cropped_face_path)
|
|
|
|
|
|
|
| 953 |
logger.info(f"cropped face: {cropped_face_path}")
|
| 954 |
except Exception as e:
|
| 955 |
logger.error(f"Failed to save cropped face {cropped_face_path}: {e}")
|
utils.py
CHANGED
|
@@ -22,7 +22,6 @@ except ImportError:
|
|
| 22 |
|
| 23 |
from config import (
|
| 24 |
IMAGES_DIR,
|
| 25 |
-
IMG_QUALITY,
|
| 26 |
logger,
|
| 27 |
SAVE_QUALITY,
|
| 28 |
MODELS_PATH,
|
|
@@ -611,54 +610,6 @@ def save_base64_to_unique_file(
|
|
| 611 |
return None
|
| 612 |
|
| 613 |
|
| 614 |
-
def save_image_force_compress(
|
| 615 |
-
image: np.ndarray,
|
| 616 |
-
output_path: str,
|
| 617 |
-
max_size_kb: int = 100,
|
| 618 |
-
min_scale: float = 0.1,
|
| 619 |
-
scale_step: float = 0.9,
|
| 620 |
-
initial_quality: int = 95,
|
| 621 |
-
min_quality: int = 10,
|
| 622 |
-
quality_step: int = 5,
|
| 623 |
-
) -> bool:
|
| 624 |
-
"""
|
| 625 |
-
强制压缩图像到 max_size_kb 以下,即使原图已小于该大小。
|
| 626 |
-
先缩小尺寸再压缩质量,直到满足要求或失败。
|
| 627 |
-
"""
|
| 628 |
-
max_bytes = max_size_kb * 1024
|
| 629 |
-
scale = IMG_QUALITY
|
| 630 |
-
height, width = image.shape[:2]
|
| 631 |
-
while scale >= min_scale:
|
| 632 |
-
resized_img = cv2.resize(
|
| 633 |
-
image,
|
| 634 |
-
(int(width * scale), int(height * scale)),
|
| 635 |
-
interpolation=cv2.INTER_AREA,
|
| 636 |
-
)
|
| 637 |
-
quality = initial_quality
|
| 638 |
-
|
| 639 |
-
while quality >= min_quality:
|
| 640 |
-
success, encoded_img = cv2.imencode(
|
| 641 |
-
".webp", resized_img, [cv2.IMWRITE_WEBP_QUALITY, quality]
|
| 642 |
-
)
|
| 643 |
-
if not success:
|
| 644 |
-
return False
|
| 645 |
-
|
| 646 |
-
if len(encoded_img) <= max_bytes:
|
| 647 |
-
with open(output_path, "wb") as f:
|
| 648 |
-
f.write(encoded_img)
|
| 649 |
-
logger.info(
|
| 650 |
-
f"压缩后图像大小: {len(encoded_img) / 1024:.2f} KB,scale={scale:.2f}, quality={quality}"
|
| 651 |
-
)
|
| 652 |
-
upload_file_to_bos(output_path)
|
| 653 |
-
return True
|
| 654 |
-
|
| 655 |
-
quality -= quality_step
|
| 656 |
-
|
| 657 |
-
scale *= scale_step
|
| 658 |
-
|
| 659 |
-
return False
|
| 660 |
-
|
| 661 |
-
|
| 662 |
def human_readable_size(size_bytes):
|
| 663 |
"""人性化文件大小展示"""
|
| 664 |
for unit in ["B", "KB", "MB", "GB"]:
|
|
|
|
| 22 |
|
| 23 |
from config import (
|
| 24 |
IMAGES_DIR,
|
|
|
|
| 25 |
logger,
|
| 26 |
SAVE_QUALITY,
|
| 27 |
MODELS_PATH,
|
|
|
|
| 610 |
return None
|
| 611 |
|
| 612 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 613 |
def human_readable_size(size_bytes):
|
| 614 |
"""人性化文件大小展示"""
|
| 615 |
for unit in ["B", "KB", "MB", "GB"]:
|