iljung1106 commited on
Commit
4ccf22e
ยท
1 Parent(s): d9b727e

cv2.CacadeClassifier error fix attempt

Browse files
Files changed (1) hide show
  1. inference_utils.py +30 -13
inference_utils.py CHANGED
@@ -458,13 +458,11 @@ class StyleEmbedderApp:
458
  self._artist_names = None
459
  self._embeddings = None
460
 
461
- # Face/Eye extractor (lazy load, uses CPU for detector to avoid CUDA init)
462
- self._extractor = FaceEyeExtractor(
463
- yolo_dir=_default_path('yolov5_anime') if yolo_dir is None else Path(yolo_dir),
464
- weights_path=_default_path('yolov5x_anime.pt') if yolo_weights is None else Path(yolo_weights),
465
- cascade_path=_default_path('anime-eyes-cascade.xml') if eyes_cascade is None else Path(eyes_cascade),
466
- device='cpu', # Always use CPU for detector to avoid CUDA init
467
- )
468
 
469
  # Transform (no CUDA needed)
470
  self.transform = transforms.Compose([
@@ -583,12 +581,13 @@ class StyleEmbedderApp:
583
 
584
  if auto_face_image is None or auto_eye_image is None:
585
  try:
 
586
  if auto_face_image is None:
587
- auto_face_image = self._extractor.extract_face(full_image)
588
  if auto_eye_image is None:
589
  # Prefer detecting eyes from face if available.
590
  if auto_face_image is not None:
591
- auto_eye_image = self._extractor.extract_eye_region(auto_face_image)
592
  except Exception as e:
593
  # If detector fails, proceed without branches.
594
  print(f"[WARN] Auto face/eye extraction failed: {e}")
@@ -631,16 +630,28 @@ class StyleEmbedderApp:
631
  top_indices = np.argsort(similarities)[::-1][:top_k]
632
  return [(self._artist_names[i], float(similarities[i])) for i in top_indices]
633
 
634
- def extract_crops(self, full_image: Image.Image) -> Tuple[Optional[Image.Image], Optional[Image.Image], str]:
635
- """์–ผ๊ตด๊ณผ ๋ˆˆ ์ž๋™ ์ถ”์ถœ"""
 
 
 
 
 
 
 
 
 
 
 
636
  if full_image is None:
637
  return None, None, "โŒ ์ „์ฒด ์ด๋ฏธ์ง€๋ฅผ ๋จผ์ € ์—…๋กœ๋“œํ•ด์ฃผ์„ธ์š”."
638
 
639
  try:
640
- face = self._extractor.extract_face(full_image)
 
641
  eye = None
642
  if face is not None:
643
- eye = self._extractor.extract_eye_region(face)
644
 
645
  status = "โœ… ์ถ”์ถœ ์™„๋ฃŒ:\n"
646
  status += f"- ์–ผ๊ตด: {'๋ฐœ๊ฒฌ๋จ' if face else '๋ฐœ๊ฒฌ๋˜์ง€ ์•Š์Œ'}\n"
@@ -654,6 +665,12 @@ class StyleEmbedderApp:
654
  except Exception as e:
655
  return None, None, f"โŒ ์ถ”์ถœ ์‹คํŒจ: {str(e)}"
656
 
 
 
 
 
 
 
657
  def search(
658
  self,
659
  full_image: Image.Image,
 
458
  self._artist_names = None
459
  self._embeddings = None
460
 
461
+ # Face/Eye extractor - lazy load to avoid pickle issues with cv2.CascadeClassifier
462
+ self._extractor = None
463
+ self._extractor_yolo_dir = yolo_dir
464
+ self._extractor_yolo_weights = yolo_weights
465
+ self._extractor_eyes_cascade = eyes_cascade
 
 
466
 
467
  # Transform (no CUDA needed)
468
  self.transform = transforms.Compose([
 
581
 
582
  if auto_face_image is None or auto_eye_image is None:
583
  try:
584
+ extractor = self._get_extractor()
585
  if auto_face_image is None:
586
+ auto_face_image = extractor.extract_face(full_image)
587
  if auto_eye_image is None:
588
  # Prefer detecting eyes from face if available.
589
  if auto_face_image is not None:
590
+ auto_eye_image = extractor.extract_eye_region(auto_face_image)
591
  except Exception as e:
592
  # If detector fails, proceed without branches.
593
  print(f"[WARN] Auto face/eye extraction failed: {e}")
 
630
  top_indices = np.argsort(similarities)[::-1][:top_k]
631
  return [(self._artist_names[i], float(similarities[i])) for i in top_indices]
632
 
633
+ def _get_extractor(self):
634
+ """Lazy load extractor to avoid pickle issues"""
635
+ if self._extractor is None:
636
+ self._extractor = FaceEyeExtractor(
637
+ yolo_dir=_default_path('yolov5_anime') if self._extractor_yolo_dir is None else Path(self._extractor_yolo_dir),
638
+ weights_path=_default_path('yolov5x_anime.pt') if self._extractor_yolo_weights is None else Path(self._extractor_yolo_weights),
639
+ cascade_path=_default_path('anime-eyes-cascade.xml') if self._extractor_eyes_cascade is None else Path(self._extractor_eyes_cascade),
640
+ device='cpu', # Always use CPU for detector to avoid CUDA init
641
+ )
642
+ return self._extractor
643
+
644
+ def _extract_crops_impl(self, full_image: Image.Image) -> Tuple[Optional[Image.Image], Optional[Image.Image], str]:
645
+ """์–ผ๊ตด๊ณผ ๋ˆˆ ์ž๋™ ์ถ”์ถœ - ๋‚ด๋ถ€ ๊ตฌํ˜„"""
646
  if full_image is None:
647
  return None, None, "โŒ ์ „์ฒด ์ด๋ฏธ์ง€๋ฅผ ๋จผ์ € ์—…๋กœ๋“œํ•ด์ฃผ์„ธ์š”."
648
 
649
  try:
650
+ extractor = self._get_extractor()
651
+ face = extractor.extract_face(full_image)
652
  eye = None
653
  if face is not None:
654
+ eye = extractor.extract_eye_region(face)
655
 
656
  status = "โœ… ์ถ”์ถœ ์™„๋ฃŒ:\n"
657
  status += f"- ์–ผ๊ตด: {'๋ฐœ๊ฒฌ๋จ' if face else '๋ฐœ๊ฒฌ๋˜์ง€ ์•Š์Œ'}\n"
 
665
  except Exception as e:
666
  return None, None, f"โŒ ์ถ”์ถœ ์‹คํŒจ: {str(e)}"
667
 
668
+ def extract_crops(self, full_image: Image.Image) -> Tuple[Optional[Image.Image], Optional[Image.Image], str]:
669
+ """์–ผ๊ตด๊ณผ ๋ˆˆ ์ž๋™ ์ถ”์ถœ - Gradio์šฉ ๋ž˜ํ•‘ ํ•จ์ˆ˜"""
670
+ # Create extractor on-demand to avoid pickle issues
671
+ # The extractor will be created fresh each time, but _ensure_ready() handles caching
672
+ return self._extract_crops_impl(full_image)
673
+
674
  def search(
675
  self,
676
  full_image: Image.Image,