chawin.chen commited on
Commit
9a7c81e
·
1 Parent(s): 2919cc4
Files changed (2) hide show
  1. api_routes.py +32 -7
  2. face_analyzer.py +3 -3
api_routes.py CHANGED
@@ -1497,7 +1497,7 @@ async def analyze_face(
1497
  return JSONResponse(
1498
  content={
1499
  "success": False,
1500
- "message": "请尝试上传清晰、无遮挡的正面照片",
1501
  "face_count": 0,
1502
  "faces": [],
1503
  }
@@ -1559,6 +1559,31 @@ async def analyze_face(
1559
  raise HTTPException(status_code=500, detail=f"分析过程中出现内部错误: {str(e)}")
1560
 
1561
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1562
  @api_router.post("/image_search", response_model=ImageFileList, tags=["图像搜索"])
1563
  @log_api_params
1564
  async def search_by_image(
@@ -1741,7 +1766,7 @@ async def list_outputs(
1741
  None) else ""
1742
  nickname_filter = request.nickname.strip() if getattr(request, "nickname",
1743
  None) else None
1744
-
1745
  # 业务逻辑:如果 search_type 为空,默认只显示非裁剪的人脸图
1746
  is_cropped_filter = 0 if not search_type else None
1747
 
@@ -1786,7 +1811,7 @@ async def list_outputs(
1786
  if category not in (
1787
  None, "all") and record_category != category:
1788
  continue
1789
-
1790
  # 向量搜索结果也根据 is_cropped_filter 进行过滤
1791
  record_is_cropped = bool(record.get("is_cropped_face")) if record else "_face" in file_path
1792
  if is_cropped_filter is not None and record_is_cropped != bool(is_cropped_filter):
@@ -3626,7 +3651,7 @@ async def compress_image(
3626
  # 异步执行图片向量化并入库,不阻塞主流程
3627
  if CLIP_AVAILABLE:
3628
  asyncio.create_task(handle_image_vector_async(compressed_path, compressed_filename))
3629
-
3630
  await _record_output_file(
3631
  file_path=compressed_path,
3632
  nickname=nickname,
@@ -4599,10 +4624,10 @@ async def face_similarity_verification(
4599
  h = region.get("h", 0)
4600
  x_end = min(source_image.shape[1], x + w)
4601
  y_end = min(source_image.shape[0], y + h)
4602
-
4603
  if x_end <= x or y_end <= y:
4604
  return source_image.copy(), False
4605
-
4606
  result_img = source_image.copy()
4607
  # 绘制绿色矩形框,厚度根据图片尺寸动态调整
4608
  thickness = max(2, int(round(min(source_image.shape[:2]) / 200)))
@@ -4656,7 +4681,7 @@ async def face_similarity_verification(
4656
  face_img2 = image2[y2:y2_end, x2:x2_end]
4657
 
4658
  # face_path1 和 face_path2 已经通过 _get_save_path 生成
4659
-
4660
  # 直接保存裁剪图,不进行特征点绘制
4661
  if save_image_high_quality(face_img1, face_path1, quality=SAVE_QUALITY):
4662
  await _record_output_file(
 
1497
  return JSONResponse(
1498
  content={
1499
  "success": False,
1500
+ "message": "Please upload a clear front-facing photo without any obstructions.",
1501
  "face_count": 0,
1502
  "faces": [],
1503
  }
 
1559
  raise HTTPException(status_code=500, detail=f"分析过程中出现内部错误: {str(e)}")
1560
 
1561
 
1562
+ @api_router.post(path="/app/analyze", tags=["App专用"])
1563
+ @log_api_params
1564
+ async def app_analyze_face(
1565
+ request: Request,
1566
+ file: UploadFile = File(None),
1567
+ files: list[UploadFile] = File(None),
1568
+ images: str = Form(None),
1569
+ nickname: str = Form(None, description="操作者昵称"),
1570
+ model: ModelType = Query(
1571
+ ModelType.HYBRID, description="选择使用的模型: howcuteami, deepface 或 hybrid"
1572
+ ),
1573
+ ):
1574
+ """
1575
+ App专用人脸分析接口,参数与原 /analyze 保持完全一致并透传。
1576
+ """
1577
+ return await analyze_face(
1578
+ request=request,
1579
+ file=file,
1580
+ files=files,
1581
+ images=images,
1582
+ nickname=nickname,
1583
+ model=model
1584
+ )
1585
+
1586
+
1587
  @api_router.post("/image_search", response_model=ImageFileList, tags=["图像搜索"])
1588
  @log_api_params
1589
  async def search_by_image(
 
1766
  None) else ""
1767
  nickname_filter = request.nickname.strip() if getattr(request, "nickname",
1768
  None) else None
1769
+
1770
  # 业务逻辑:如果 search_type 为空,默认只显示非裁剪的人脸图
1771
  is_cropped_filter = 0 if not search_type else None
1772
 
 
1811
  if category not in (
1812
  None, "all") and record_category != category:
1813
  continue
1814
+
1815
  # 向量搜索结果也根据 is_cropped_filter 进行过滤
1816
  record_is_cropped = bool(record.get("is_cropped_face")) if record else "_face" in file_path
1817
  if is_cropped_filter is not None and record_is_cropped != bool(is_cropped_filter):
 
3651
  # 异步执行图片向量化并入库,不阻塞主流程
3652
  if CLIP_AVAILABLE:
3653
  asyncio.create_task(handle_image_vector_async(compressed_path, compressed_filename))
3654
+
3655
  await _record_output_file(
3656
  file_path=compressed_path,
3657
  nickname=nickname,
 
4624
  h = region.get("h", 0)
4625
  x_end = min(source_image.shape[1], x + w)
4626
  y_end = min(source_image.shape[0], y + h)
4627
+
4628
  if x_end <= x or y_end <= y:
4629
  return source_image.copy(), False
4630
+
4631
  result_img = source_image.copy()
4632
  # 绘制绿色矩形框,厚度根据图片尺寸动态调整
4633
  thickness = max(2, int(round(min(source_image.shape[:2]) / 200)))
 
4681
  face_img2 = image2[y2:y2_end, x2:x2_end]
4682
 
4683
  # face_path1 和 face_path2 已经通过 _get_save_path 生成
4684
+
4685
  # 直接保存裁剪图,不进行特征点绘制
4686
  if save_image_high_quality(face_img1, face_path1, quality=SAVE_QUALITY):
4687
  await _record_output_file(
face_analyzer.py CHANGED
@@ -817,7 +817,7 @@ class EnhancedFaceAnalyzer:
817
  :return: 分析结果
818
  """
819
  if image is None:
820
- raise ValueError("无效的图像输入")
821
 
822
  # 检测人脸
823
  face_boxes = self._detect_faces(image)
@@ -825,7 +825,7 @@ class EnhancedFaceAnalyzer:
825
  if not face_boxes:
826
  return {
827
  "success": False,
828
- "message": "请尝试上传清晰、无遮挡的正面照片",
829
  "face_count": 0,
830
  "faces": [],
831
  "annotated_image": None,
@@ -834,7 +834,7 @@ class EnhancedFaceAnalyzer:
834
 
835
  results = {
836
  "success": True,
837
- "message": f"成功检测到 {len(face_boxes)} 张人脸",
838
  "face_count": len(face_boxes),
839
  "faces": [],
840
  "model_used": model_type.value,
 
817
  :return: 分析结果
818
  """
819
  if image is None:
820
+ raise ValueError("invalid image input")
821
 
822
  # 检测人脸
823
  face_boxes = self._detect_faces(image)
 
825
  if not face_boxes:
826
  return {
827
  "success": False,
828
+ "message": "Please upload a clear front-facing photo without any obstructions.",
829
  "face_count": 0,
830
  "faces": [],
831
  "annotated_image": None,
 
834
 
835
  results = {
836
  "success": True,
837
+ "message": f"success detected {len(face_boxes)} faces",
838
  "face_count": len(face_boxes),
839
  "faces": [],
840
  "model_used": model_type.value,