mastari commited on
Commit
db978c8
Β·
1 Parent(s): 7c16a09
Files changed (2) hide show
  1. handler.py +18 -21
  2. requirements.txt +3 -2
handler.py CHANGED
@@ -15,12 +15,10 @@ from gfpgan import GFPGANer
15
  logging.basicConfig(level=logging.DEBUG)
16
  logger = logging.getLogger(__name__)
17
  logger.setLevel(logging.DEBUG)
18
-
19
  logger.debug("πŸ“¦ [INIT] Importing GFPGAN handler module...")
20
 
21
-
22
  # ======================================================
23
- # GFPGAN MODEL DOWNLOAD CONFIG
24
  # ======================================================
25
  MODEL_URL = "https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.4.pth"
26
  MODEL_NAME = "GFPGANv1.4.pth"
@@ -39,34 +37,33 @@ class EndpointHandler:
39
  logger.debug(f"πŸ”— [MODEL] Expected model path: {model_path}")
40
 
41
  # ------------------------------------------------------
42
- # Download model if not found
43
  # ------------------------------------------------------
44
  if not os.path.exists(model_path):
45
  try:
46
- logger.debug(f"πŸ“₯ [DOWNLOAD] Model not found locally. Downloading from {MODEL_URL}")
47
  r = requests.get(MODEL_URL, stream=True)
48
  r.raise_for_status()
49
  with open(model_path, "wb") as f:
50
  for chunk in r.iter_content(chunk_size=8192):
51
  if chunk:
52
  f.write(chunk)
53
- logger.debug("βœ… [MODEL] Downloaded GFPGAN model successfully.")
54
  except Exception as e:
55
  logger.error(f"πŸ’₯ [ERROR] Failed to download GFPGAN weights: {e}")
56
  raise
57
 
58
  # ------------------------------------------------------
59
- # Initialize GFPGANer just like the official Gradio demo
60
  # ------------------------------------------------------
61
  try:
62
- logger.debug("🧠 [MODEL] Initializing GFPGANer (v1.4, upscale=2, no background upsampler)...")
63
  self.restorer = GFPGANer(
64
  model_path=model_path,
65
- upscale=2, # Matches Gradio demo β€œRescaling factor: 2”
66
  arch="clean",
67
  channel_multiplier=2,
68
- bg_upsampler=None,
69
- version="1.4",
70
  )
71
  logger.debug("βœ… [MODEL] GFPGAN model initialized successfully.")
72
  except Exception as e:
@@ -78,10 +75,10 @@ class EndpointHandler:
78
  # ======================================================
79
  def __call__(self, data):
80
  logger.debug("βš™οΈ [INFER] Starting inference...")
81
- logger.debug(f"πŸ“₯ Incoming data keys: {list(data.keys())}")
82
 
83
  # ------------------------------------------------------
84
- # Handle both raw bytes and JSON base64 inputs
85
  # ------------------------------------------------------
86
  try:
87
  if isinstance(data, dict) and "inputs" in data:
@@ -99,7 +96,7 @@ class EndpointHandler:
99
  return {"error": f"Invalid input: {e}"}
100
 
101
  # ------------------------------------------------------
102
- # Load and convert image
103
  # ------------------------------------------------------
104
  try:
105
  img_np = np.array(Image.open(io.BytesIO(image_bytes)).convert("RGB"))
@@ -109,29 +106,29 @@ class EndpointHandler:
109
  return {"error": f"Image loading failed: {e}"}
110
 
111
  # ------------------------------------------------------
112
- # Perform face restoration
113
  # ------------------------------------------------------
114
  try:
115
  cropped_faces, restored_faces, restored_img = self.restorer.enhance(
116
  img_np,
117
  has_aligned=False,
118
  only_center_face=False,
119
- paste_back=True, # ⬅️ Matches web demo behavior
120
  )
121
- logger.debug("βœ… [RESTORE] Face restoration complete.")
122
  except Exception as e:
123
  logger.error(f"πŸ’₯ [ERROR] GFPGAN enhancement failed: {e}")
124
  return {"error": f"Enhancement failed: {e}"}
125
 
126
  # ------------------------------------------------------
127
- # Encode restored image to base64 for response
128
  # ------------------------------------------------------
129
  try:
130
- _, buffer = cv2.imencode(".png", restored_img[:, :, ::-1]) # BGR β†’ RGB
131
  img_base64 = base64.b64encode(buffer).decode("utf-8")
132
- logger.debug("πŸ“€ [ENCODE] Successfully encoded restored image.")
133
  return {"image": img_base64}
134
  except Exception as e:
135
- logger.error(f"πŸ’₯ [ERROR] Failed to encode restored image: {e}")
136
  return {"error": f"Encoding failed: {e}"}
137
 
 
15
  logging.basicConfig(level=logging.DEBUG)
16
  logger = logging.getLogger(__name__)
17
  logger.setLevel(logging.DEBUG)
 
18
  logger.debug("πŸ“¦ [INIT] Importing GFPGAN handler module...")
19
 
 
20
  # ======================================================
21
+ # GFPGAN MODEL URL
22
  # ======================================================
23
  MODEL_URL = "https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.4.pth"
24
  MODEL_NAME = "GFPGANv1.4.pth"
 
37
  logger.debug(f"πŸ”— [MODEL] Expected model path: {model_path}")
38
 
39
  # ------------------------------------------------------
40
+ # Download model if missing
41
  # ------------------------------------------------------
42
  if not os.path.exists(model_path):
43
  try:
44
+ logger.debug(f"πŸ“₯ [DOWNLOAD] Model not found locally β€” fetching from {MODEL_URL}")
45
  r = requests.get(MODEL_URL, stream=True)
46
  r.raise_for_status()
47
  with open(model_path, "wb") as f:
48
  for chunk in r.iter_content(chunk_size=8192):
49
  if chunk:
50
  f.write(chunk)
51
+ logger.debug("βœ… [MODEL] Downloaded GFPGAN weights successfully.")
52
  except Exception as e:
53
  logger.error(f"πŸ’₯ [ERROR] Failed to download GFPGAN weights: {e}")
54
  raise
55
 
56
  # ------------------------------------------------------
57
+ # Initialize GFPGANer (same as official Gradio demo)
58
  # ------------------------------------------------------
59
  try:
60
+ logger.debug("🧠 [MODEL] Initializing GFPGANer (upscale=2, arch='clean')...")
61
  self.restorer = GFPGANer(
62
  model_path=model_path,
63
+ upscale=2, # Rescaling factor = 2
64
  arch="clean",
65
  channel_multiplier=2,
66
+ bg_upsampler=None
 
67
  )
68
  logger.debug("βœ… [MODEL] GFPGAN model initialized successfully.")
69
  except Exception as e:
 
75
  # ======================================================
76
  def __call__(self, data):
77
  logger.debug("βš™οΈ [INFER] Starting inference...")
78
+ logger.debug(f"πŸ“₯ Incoming data type: {type(data)}")
79
 
80
  # ------------------------------------------------------
81
+ # Handle both JSON base64 and raw bytes
82
  # ------------------------------------------------------
83
  try:
84
  if isinstance(data, dict) and "inputs" in data:
 
96
  return {"error": f"Invalid input: {e}"}
97
 
98
  # ------------------------------------------------------
99
+ # Decode image
100
  # ------------------------------------------------------
101
  try:
102
  img_np = np.array(Image.open(io.BytesIO(image_bytes)).convert("RGB"))
 
106
  return {"error": f"Image loading failed: {e}"}
107
 
108
  # ------------------------------------------------------
109
+ # Run GFPGAN restoration
110
  # ------------------------------------------------------
111
  try:
112
  cropped_faces, restored_faces, restored_img = self.restorer.enhance(
113
  img_np,
114
  has_aligned=False,
115
  only_center_face=False,
116
+ paste_back=True # Matches GFPGAN web demo
117
  )
118
+ logger.debug("βœ… [RESTORE] Face restoration completed successfully.")
119
  except Exception as e:
120
  logger.error(f"πŸ’₯ [ERROR] GFPGAN enhancement failed: {e}")
121
  return {"error": f"Enhancement failed: {e}"}
122
 
123
  # ------------------------------------------------------
124
+ # Encode result as base64 PNG
125
  # ------------------------------------------------------
126
  try:
127
+ _, buffer = cv2.imencode(".png", restored_img[:, :, ::-1]) # BGR→RGB
128
  img_base64 = base64.b64encode(buffer).decode("utf-8")
129
+ logger.debug("πŸ“€ [ENCODE] Encoded restored image successfully.")
130
  return {"image": img_base64}
131
  except Exception as e:
132
+ logger.error(f"πŸ’₯ [ERROR] Failed to encode image: {e}")
133
  return {"error": f"Encoding failed: {e}"}
134
 
requirements.txt CHANGED
@@ -2,8 +2,9 @@ torch==2.1.0
2
  torchvision==0.16.0
3
  gfpgan==1.3.8
4
  basicsr==1.4.2
5
- numpy==1.26.4
6
- Pillow>=10.0.0
7
  opencv-python
8
  requests
 
 
9
 
 
2
  torchvision==0.16.0
3
  gfpgan==1.3.8
4
  basicsr==1.4.2
5
+ facexlib==0.3.0
 
6
  opencv-python
7
  requests
8
+ numpy
9
+ Pillow
10