Astridkraft commited on
Commit
83f1ff4
·
verified ·
1 Parent(s): d18cc2e

Update controlnet_module.py

Browse files
Files changed (1) hide show
  1. controlnet_module.py +81 -31
controlnet_module.py CHANGED
@@ -35,6 +35,7 @@ class ControlNetProcessor:
35
  self.controlnet_canny = None
36
  self.pipe_openpose = None
37
  self.pipe_canny = None
 
38
 
39
  def load_pose_detector(self):
40
  """Lädt nur den Pose-Detector"""
@@ -76,9 +77,9 @@ class ControlNetProcessor:
76
  try:
77
  img_array = np.array(image.convert("RGB"))
78
 
79
- # Canny Edge Detection
80
  gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
81
- edges = cv2.Canny(gray, 100, 200)
82
 
83
  # Zu 3-Kanal Bild konvertieren
84
  edges_rgb = cv2.cvtColor(edges, cv2.COLOR_GRAY2RGB)
@@ -142,6 +143,38 @@ class ControlNetProcessor:
142
  raise
143
  return self.pipe_canny
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  def generate_with_controlnet(
146
  self, image, prompt, negative_prompt,
147
  steps, guidance_scale, controlnet_strength,
@@ -149,28 +182,30 @@ class ControlNetProcessor:
149
  ):
150
  """Generiert Bild mit ControlNet und Fortschrittsanzeige"""
151
  try:
152
- # --- KORREKTE LOGIK ---
153
  if keep_environment:
154
- # UMGEBUNG BEIBEHALTEN, PERSON ÄNDERN → KOMBINIERTE STRATEGIE
155
- print("🎯 ControlNet Modus: Umgebung beibehalten (OpenPose + Canny Kombination)")
156
 
157
- # Schritt 1: OpenPose für Grundpose
158
  pose_image = self.extract_pose(image)
159
- print("✅ OpenPose für Grundpose erstellt")
160
-
161
- # Schritt 2: Canny für Silhouette + Umgebung
162
  canny_image = self.extract_canny_edges(image)
163
- print("✅ Canny für Silhouette + Umgebung erstellt")
164
 
165
- # Kombinierte Conditioning - zuerst mit OpenPose arbeiten
166
- conditioning_image = pose_image
167
- controlnet_type = "openpose"
 
 
 
 
168
 
169
  else:
170
- # PERSON BEIBEHALTEN, UMGEBUNG ÄNDERN → NUR OPENPOSE (wie bisher)
171
  controlnet_type = "openpose"
172
  print("🎯 ControlNet Modus: Person beibehalten (OpenPose)")
173
- conditioning_image = self.extract_pose(image)
 
174
 
175
  pipe = self.load_controlnet_pipeline(controlnet_type)
176
 
@@ -185,25 +220,40 @@ class ControlNetProcessor:
185
  print("🔄 ControlNet: Starte Pipeline...")
186
 
187
  # ControlNet Generierung
188
- result = pipe(
189
- prompt=prompt,
190
- image=conditioning_image,
191
- negative_prompt=negative_prompt,
192
- num_inference_steps=int(steps),
193
- guidance_scale=guidance_scale,
194
- generator=generator,
195
- controlnet_conditioning_scale=controlnet_strength,
196
- height=512,
197
- width=512,
198
- output_type="pil",
199
- callback_on_step_end=callback,
200
- callback_on_step_end_tensor_inputs=[],
201
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
  print("✅ ControlNet abgeschlossen!")
204
 
205
- # ZWEI Werte zurückgeben: ControlNet-Output + ORIGINALBILD für Inpaint
206
- return result.images[0], image # ← IMMER Originalbild für Inpaint!
207
 
208
  except Exception as e:
209
  print(f"❌ Fehler in ControlNet: {e}")
 
35
  self.controlnet_canny = None
36
  self.pipe_openpose = None
37
  self.pipe_canny = None
38
+ self.pipe_multi = None
39
 
40
  def load_pose_detector(self):
41
  """Lädt nur den Pose-Detector"""
 
77
  try:
78
  img_array = np.array(image.convert("RGB"))
79
 
80
+ # Canny Edge Detection mit besseren Parametern für Gesichter
81
  gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
82
+ edges = cv2.Canny(gray, 50, 150) # Bessere Kantenerkennung
83
 
84
  # Zu 3-Kanal Bild konvertieren
85
  edges_rgb = cv2.cvtColor(edges, cv2.COLOR_GRAY2RGB)
 
143
  raise
144
  return self.pipe_canny
145
 
146
+ elif controlnet_type == "multi":
147
+ if self.pipe_multi is None:
148
+ print("Loading Multi-ControlNet pipeline...")
149
+ try:
150
+ # Beide ControlNet-Modelle laden
151
+ self.controlnet_openpose = ControlNetModel.from_pretrained(
152
+ "lllyasviel/sd-controlnet-openpose",
153
+ torch_dtype=self.torch_dtype
154
+ )
155
+ self.controlnet_canny = ControlNetModel.from_pretrained(
156
+ "lllyasviel/sd-controlnet-canny",
157
+ torch_dtype=self.torch_dtype
158
+ )
159
+
160
+ # Multi-ControlNet Pipeline
161
+ self.pipe_multi = StableDiffusionControlNetPipeline.from_pretrained(
162
+ "runwayml/stable-diffusion-v1-5",
163
+ controlnet=[self.controlnet_openpose, self.controlnet_canny],
164
+ torch_dtype=self.torch_dtype,
165
+ safety_checker=None,
166
+ requires_safety_checker=False
167
+ ).to(self.device)
168
+
169
+ from diffusers import EulerAncestralDiscreteScheduler
170
+ self.pipe_multi.scheduler = EulerAncestralDiscreteScheduler.from_config(self.pipe_multi.scheduler.config)
171
+ self.pipe_multi.enable_attention_slicing()
172
+ print("✅ Multi-ControlNet pipeline loaded successfully!")
173
+ except Exception as e:
174
+ print(f"Fehler beim Laden von Multi-ControlNet: {e}")
175
+ raise
176
+ return self.pipe_multi
177
+
178
  def generate_with_controlnet(
179
  self, image, prompt, negative_prompt,
180
  steps, guidance_scale, controlnet_strength,
 
182
  ):
183
  """Generiert Bild mit ControlNet und Fortschrittsanzeige"""
184
  try:
185
+ # --- MULTI-CONTROLNET LOGIK ---
186
  if keep_environment:
187
+ # UMGEBUNG BEIBEHALTEN, PERSON ÄNDERN → MULTI-CONTROLNET
188
+ print("🎯 ControlNet Modus: Umgebung beibehalten (Multi-ControlNet: OpenPose + Canny)")
189
 
190
+ # Beide Conditioning Maps erstellen
191
  pose_image = self.extract_pose(image)
 
 
 
192
  canny_image = self.extract_canny_edges(image)
193
+ print("✅ OpenPose + Canny Maps erstellt")
194
 
195
+ # Multi-ControlNet verwenden
196
+ conditioning_images = [pose_image, canny_image]
197
+ controlnet_type = "multi"
198
+
199
+ # Unterschiedliche Strengths für Pose und Canny
200
+ controlnet_conditioning_scale = [controlnet_strength * 0.7, # OpenPose: 70%
201
+ controlnet_strength * 0.3] # Canny: 30%
202
 
203
  else:
204
+ # PERSON BEIBEHALTEN, UMGEBUNG ÄNDERN → NUR OPENPOSE
205
  controlnet_type = "openpose"
206
  print("🎯 ControlNet Modus: Person beibehalten (OpenPose)")
207
+ conditioning_images = self.extract_pose(image)
208
+ controlnet_conditioning_scale = controlnet_strength
209
 
210
  pipe = self.load_controlnet_pipeline(controlnet_type)
211
 
 
220
  print("🔄 ControlNet: Starte Pipeline...")
221
 
222
  # ControlNet Generierung
223
+ if controlnet_type == "multi":
224
+ result = pipe(
225
+ prompt=prompt,
226
+ image=conditioning_images,
227
+ negative_prompt=negative_prompt,
228
+ num_inference_steps=int(steps),
229
+ guidance_scale=guidance_scale,
230
+ generator=generator,
231
+ controlnet_conditioning_scale=controlnet_conditioning_scale,
232
+ height=512,
233
+ width=512,
234
+ output_type="pil",
235
+ callback_on_step_end=callback,
236
+ callback_on_step_end_tensor_inputs=[],
237
+ )
238
+ else:
239
+ result = pipe(
240
+ prompt=prompt,
241
+ image=conditioning_images,
242
+ negative_prompt=negative_prompt,
243
+ num_inference_steps=int(steps),
244
+ guidance_scale=guidance_scale,
245
+ generator=generator,
246
+ controlnet_conditioning_scale=controlnet_conditioning_scale,
247
+ height=512,
248
+ width=512,
249
+ output_type="pil",
250
+ callback_on_step_end=callback,
251
+ callback_on_step_end_tensor_inputs=[],
252
+ )
253
 
254
  print("✅ ControlNet abgeschlossen!")
255
 
256
+ return result.images[0], image # ControlNet-Output + Originalbild
 
257
 
258
  except Exception as e:
259
  print(f"❌ Fehler in ControlNet: {e}")