iljung1106 commited on
Commit ยท
4ccf22e
1
Parent(s): d9b727e
cv2.CacadeClassifier error fix attempt
Browse files- 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
|
| 462 |
-
self._extractor =
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
| 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 =
|
| 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 =
|
| 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
|
| 635 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 636 |
if full_image is None:
|
| 637 |
return None, None, "โ ์ ์ฒด ์ด๋ฏธ์ง๋ฅผ ๋จผ์ ์
๋ก๋ํด์ฃผ์ธ์."
|
| 638 |
|
| 639 |
try:
|
| 640 |
-
|
|
|
|
| 641 |
eye = None
|
| 642 |
if face is not None:
|
| 643 |
-
eye =
|
| 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,
|