primerz commited on
Commit
091ba99
·
verified ·
1 Parent(s): 8a3467f

Update generator.py

Browse files
Files changed (1) hide show
  1. generator.py +50 -44
generator.py CHANGED
@@ -7,23 +7,31 @@ class Generator:
7
  def __init__(self, model_handler):
8
  self.mh = model_handler
9
 
10
- def prepare_control_images(self, image, width, height):
11
  """
12
- Generates conditioning maps, ensuring they are resized
13
- to the exact target dimensions (width, height).
 
 
 
14
  """
15
- print(f"Generating control maps for {width}x{height}...")
 
16
 
17
- # Generate depth map
18
- depth_map_raw = self.mh.leres_detector(image)
 
 
 
19
 
20
- # Generate lineart map
 
 
 
 
21
  lineart_map_raw = self.mh.lineart_anime_detector(image)
22
-
23
- # Manually resize maps to match the exact output resolution
24
  depth_map = depth_map_raw.resize((width, height), Image.LANCZOS)
25
  lineart_map = lineart_map_raw.resize((width, height), Image.LANCZOS)
26
-
27
  return depth_map, lineart_map
28
 
29
  def predict(
@@ -46,41 +54,40 @@ class Generator:
46
  # 2. Get Face Info
47
  face_info = self.mh.get_face_info(processed_image)
48
 
49
- # --- START ADAPTIVE PARAMETER LOGIC ---
 
50
  adaptive_cfg = guidance_scale
51
  adaptive_strength = img2img_strength
52
 
53
  if face_info is not None:
54
- # Calculate Face Coverage Ratio
55
  bbox = face_info['bbox']
56
  face_area = (bbox[2] - bbox[0]) * (bbox[3] - bbox[1])
57
  total_area = target_width * target_height
58
- coverage_ratio = face_area / total_area
59
 
60
- print(f"Face Coverage: {coverage_ratio:.2f} ({int(coverage_ratio * 12)}/12)")
61
 
62
- # Apply variance logic based on your requested thresholds
63
- if coverage_ratio >= (8/12): # > 0.66 (High Coverage)
64
- # Lower CFG by 5-15% (avg 10%), keep strength same
65
- adaptive_cfg = guidance_scale * 0.90
66
- adaptive_strength = img2img_strength * 1.0
67
- print("-> High Coverage: Applying slight CFG reduction (-10%)")
68
-
69
- elif coverage_ratio >= (4/12): # 0.33 to 0.66 (Medium Coverage)
70
- # CFG lower 20-30% (avg 25%), strength lower 5-10% (avg 7.5%)
71
- adaptive_cfg = guidance_scale * 0.75
72
- adaptive_strength = img2img_strength * 0.925
73
- print("-> Medium Coverage: Lowering CFG (-25%) and Strength (-7.5%)")
74
-
75
- else: # < 0.33 (Low Coverage)
76
- # CFG lower 30-40% (avg 35%), strength lower 10-15% (avg 12.5%)
77
- adaptive_cfg = guidance_scale * 0.65
78
- adaptive_strength = img2img_strength * 0.875
79
- print("-> Low Coverage: Significantly lowering CFG (-35%) and Strength (-12.5%)")
80
 
81
- print(f"Adaptive CFG: {guidance_scale} -> {adaptive_cfg:.2f}")
82
- print(f"Adaptive Strength: {img2img_strength} -> {adaptive_strength:.2f}")
83
- # --- END ADAPTIVE PARAMETER LOGIC ---
 
 
 
 
84
 
85
  # 3. Generate Prompt
86
  if not user_prompt.strip():
@@ -95,15 +102,15 @@ class Generator:
95
 
96
  print(f"Prompt: {final_prompt}")
97
 
98
- # 4. Generate OTHER Control Maps
99
- print("Generating Control Maps (Depth, LineArt)...")
100
  depth_map, lineart_map = self.prepare_control_images(processed_image, target_width, target_height)
101
 
102
- # 5. Logic for Face vs No-Face
103
  if face_info is not None:
104
  print("Face detected: Applying InstantID with keypoints.")
105
 
106
- # Corrected Raw Embedding Usage
107
  face_emb = torch.tensor(
108
  face_info['embedding'],
109
  dtype=Config.DTYPE,
@@ -124,7 +131,6 @@ class Generator:
124
 
125
  control_guidance_end = [0.3, 0.6, 0.6]
126
 
127
- # --- Seed/Generator Logic ---
128
  if seed == -1 or seed is None:
129
  seed = torch.Generator().seed()
130
  generator = torch.Generator(device=Config.DEVICE).manual_seed(int(seed))
@@ -140,11 +146,11 @@ class Generator:
140
  image_embeds=face_emb,
141
  generator=generator,
142
 
143
- # --- UPDATED: Use Adaptive Parameters ---
144
- strength=adaptive_strength, # <-- Uses calculated strength
145
- guidance_scale=adaptive_cfg, # <-- Uses calculated CFG
146
  num_inference_steps=num_inference_steps,
147
- # --------------------------------------
148
 
149
  controlnet_conditioning_scale=controlnet_conditioning_scale,
150
  control_guidance_end=control_guidance_end,
 
7
  def __init__(self, model_handler):
8
  self.mh = model_handler
9
 
10
+ def solve_bezier(self, t, p0, p1, p2, p3):
11
  """
12
+ Calculates a point on a cubic Bezier curve for a given t (0 to 1).
13
+ Formula: B(t) = (1-t)^3*P0 + 3*(1-t)^2*t*P1 + 3*(1-t)*t^2*P2 + t^3*P3
14
+
15
+ Here, 't' is the Face Coverage Ratio.
16
+ The output is the Multiplier for CFG or Strength.
17
  """
18
+ # Clamp t between 0 and 1 just in case
19
+ t = max(0.0, min(1.0, t))
20
 
21
+ # Bernstein polynomials
22
+ term0 = (1 - t)**3 * p0
23
+ term1 = 3 * (1 - t)**2 * t * p1
24
+ term2 = 3 * (1 - t) * t**2 * p2
25
+ term3 = t**3 * p3
26
 
27
+ return term0 + term1 + term2 + term3
28
+
29
+ def prepare_control_images(self, image, width, height):
30
+ print(f"Generating control maps for {width}x{height}...")
31
+ depth_map_raw = self.mh.leres_detector(image)
32
  lineart_map_raw = self.mh.lineart_anime_detector(image)
 
 
33
  depth_map = depth_map_raw.resize((width, height), Image.LANCZOS)
34
  lineart_map = lineart_map_raw.resize((width, height), Image.LANCZOS)
 
35
  return depth_map, lineart_map
36
 
37
  def predict(
 
54
  # 2. Get Face Info
55
  face_info = self.mh.get_face_info(processed_image)
56
 
57
+ # --- CUBIC BEZIER ADAPTIVE LOGIC ---
58
+ # Defaults (if no face detected)
59
  adaptive_cfg = guidance_scale
60
  adaptive_strength = img2img_strength
61
 
62
  if face_info is not None:
63
+ # 1. Calculate Face Coverage (t)
64
  bbox = face_info['bbox']
65
  face_area = (bbox[2] - bbox[0]) * (bbox[3] - bbox[1])
66
  total_area = target_width * target_height
67
+ coverage_ratio = face_area / total_area # This is our 't'
68
 
69
+ print(f"Face Coverage: {coverage_ratio:.3f} ({int(coverage_ratio * 12)}/12)")
70
 
71
+ # 2. Define Control Points based on your requirements
72
+
73
+ # CFG CURVE:
74
+ # P0 (t=0.0): Lower by 35% (Multiplier 0.65)
75
+ # P3 (t=1.0): No change (Multiplier 1.0)
76
+ # P1, P2: Control handles to smooth the transition (Ease-In-Out)
77
+ cfg_mult = self.solve_bezier(coverage_ratio, 0.65, 0.70, 0.90, 1.0)
78
+
79
+ # STRENGTH CURVE:
80
+ # P0 (t=0.0): Lower by 12.5% (Multiplier 0.875)
81
+ # P3 (t=1.0): No change (Multiplier 1.0)
82
+ str_mult = self.solve_bezier(coverage_ratio, 0.875, 0.90, 0.98, 1.0)
 
 
 
 
 
 
83
 
84
+ # 3. Apply Multipliers
85
+ adaptive_cfg = guidance_scale * cfg_mult
86
+ adaptive_strength = img2img_strength * str_mult
87
+
88
+ print(f"-> CFG Multiplier: {cfg_mult:.3f} | New CFG: {adaptive_cfg:.2f}")
89
+ print(f"-> Str Multiplier: {str_mult:.3f} | New Strength: {adaptive_strength:.2f}")
90
+ # --- END ADAPTIVE LOGIC ---
91
 
92
  # 3. Generate Prompt
93
  if not user_prompt.strip():
 
102
 
103
  print(f"Prompt: {final_prompt}")
104
 
105
+ # 4. Generate Control Maps
106
+ print("Generating Control Maps...")
107
  depth_map, lineart_map = self.prepare_control_images(processed_image, target_width, target_height)
108
 
109
+ # 5. Face vs No-Face Setup
110
  if face_info is not None:
111
  print("Face detected: Applying InstantID with keypoints.")
112
 
113
+ # Use Raw Embedding (Fix)
114
  face_emb = torch.tensor(
115
  face_info['embedding'],
116
  dtype=Config.DTYPE,
 
131
 
132
  control_guidance_end = [0.3, 0.6, 0.6]
133
 
 
134
  if seed == -1 or seed is None:
135
  seed = torch.Generator().seed()
136
  generator = torch.Generator(device=Config.DEVICE).manual_seed(int(seed))
 
146
  image_embeds=face_emb,
147
  generator=generator,
148
 
149
+ # --- Using Adaptive Values ---
150
+ strength=adaptive_strength,
151
+ guidance_scale=adaptive_cfg,
152
  num_inference_steps=num_inference_steps,
153
+ # ---------------------------
154
 
155
  controlnet_conditioning_scale=controlnet_conditioning_scale,
156
  control_guidance_end=control_guidance_end,