Maîtriser les nœuds de prétraitement d'image dans ComfyUI

L'un des défis majeurs de la génération d'images par IA réside dans l'imprévisibilité. Malgré des prompts détaillés, les résultats souffrent souvent de distorsions anatomiques ou d'une composition incohérente. L'introduction de ControlNet a révolutionné cette approche en permettant un guidage structurel précis. ComfyUI, par son architecture nodale, transforme cette puissance en un flux de travail visuel et modulaire où les nœuds de prétraitement jouent un rôle crucial.

Ces nœuds de prétraitement constituent le premier maillon de la chaîne de contrôle. Ils ne se contentent pas d'appliquer des filtres ; ils agissent comme des traducteurs convertissant les intentions humaines (croquis, poses, cartes de profondeur) en signaux compréhensibles par le modèle latent de Stable Diffusion.

Le fonctionnement interne : l'exemple de Canny

Contrairement aux interfaces "boîte noire", ComfyUI permet d'isoler chaque étape du pipeline. Prenons le nœud Canny Edge Detection. Derrière ce composant se cache une série d'opérations basées sur OpenCV :

  1. Conversion de l'image source en niveaux de gris.
  2. Application d'un flou gaussien pour réduire le bruit.
  3. Calcul du gradient d'intensité via des opérateurs de Sobel.
  4. Suppression des non-maxima pour affiner les contours.
  5. Hystérésis utilisant un double seuillage (Low/High Threshold) pour connecter les segments.

Si vous souhaitez étendre les fonctionnalités de ComfyUI, vous pouvez créer vos propres nœuds en Python. Voici une implémentation restructurée d'un processeur de contours :

import torch
import numpy as np
import cv2

class AdvancedCannyProcessor:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "image_data": ("IMAGE",),
                "threshold_min": ("INT", {"default": 80, "min": 0, "max": 255}),
                "threshold_max": ("INT", {"default": 180, "min": 0, "max": 255}),
            }
        }

    RETURN_TYPES = ("IMAGE",)
    FUNCTION = "apply_canny_filter"
    CATEGORY = "custom_preprocessors"

    def apply_canny_filter(self, image_data, threshold_min, threshold_max):
        processed_frames = []
        # Conversion du batch de tensors vers NumPy
        batch_np = image_data.cpu().numpy()

        for frame in batch_np:
            # Passage en format 8-bit et niveaux de gris
            pixel_buffer = (frame * 255).astype(np.uint8)
            gray_frame = cv2.cvtColor(pixel_buffer, cv2.COLOR_RGB2GRAY)
            
            # Détection des bords
            edges = cv2.Canny(gray_frame, threshold_min, threshold_max)
            
            # Reconstruction du canal RGB pour le pipeline ComfyUI
            rgb_edges = cv2.cvtColor(edges, cv2.COLOR_GRAY2RGB)
            final_tensor = torch.from_numpy(rgb_edges / 255.0).float()
            processed_frames.append(final_tensor)

        return (torch.stack(processed_frames, dim=0),)

Diversité des modalités de contrôle

Au-delà de Canny, le prétraitement englobe diverses méthodes de vision par ordinateur :

  • Estimation de Profondeur (Depth) : Utilise des modèles comme MiDaS pour déduire la distance des objets, créant une carte de disparité où la luminosité indique la proximité.
  • Extraction de Pose (OpenPose) : Identifie les articulations humaines via HRNet pour figer une posture sans contraindre l'apparence physique.
  • Segmentation Sémantique : Divise l'image en zones thématiques (ciel, bâtiment, herbe) pour un contrôle spatial global.

L'avantage de ComfyUI est la capacité de combiner ces flux. Vous pouvez injecter simultanément une structure Canny et une pose OpenPose dans le KSampler, en ajustant l'influence (strength) et la fenêtre temporelle d'activation de chaque condition.

Mécanisme d'intégration ControlNet

Techniquement, ControlNet n'écrase pas le processus de génération ; il injecte des résidus dans les couches d'attention croisée de l'UNet. Le nœud Apply ControlNet module ces poids dynamiquement à chaque étape de débruitage.

def inject_control_signal(model_target, cond_context, preprocessed_image, alpha=1.0, step_range=(0.0, 1.0)):
    # Simulation du chargement des paramètres de conditionnement
    start_step, end_step = step_range
    
    controlled_cond = model_target.apply_spatial_constraint(
        source_latent=preprocessed_image,
        text_context=cond_context,
        influence_scale=alpha,
        timing=(start_step, end_step)
    )
    
    return controlled_cond

Optimisation et bonnes pratiques

Pour garantir des résultats optimaux lors de l'utilisation des nœuds de prétraitement, plusieurs règles techniques s'appliquent :

  1. Alignement des résolutions : Les sorties des nœuds de prétraitement doivent idéalement être des multiples de 64 (ex: 512, 768, 1024) pour correspondre à la structure des blocs VAE et éviter les artefacts de redimensionnement.
  2. Gestion de la VRAM : L'accumulation de modèles de prétraitement (Depth + Canny + Pose) peut saturer la mémoire vidéo. Il est conseillé d'utiliser les versions FP16 des modèles et de désactiver les prévisualisations inutiles sur les gros flux.
  3. Ajustement des seuils : Pour des images sources complexes (photographies), des seuils Canny élevés (150/250) évitent de capturer trop de textures parasites, tandis que pour des croquis, des seuils bas (50/100) préservent les traits légers.
  4. Compatibilité des versions : Un modèle ControlNet conçu pour Stable Diffusion 1.5 ne fonctionnera pas avec un point de contrôle SDXL. Assurez-vous que le nœud de chargement pointe vers la version correcte correspondant à votre modèle de base.

En transformant une image de référence en un signal déterministe, les nœuds de prétraitement dans ComfyUI permettent de passer d'une exploration aléatoire à une production dirigée. Cete architecture modulaire offre une flexibilité totale, permettant aux ingénieurs et artistes de construire des pipelines de création visuelle robustes et reproductibles.

Étiquettes: ComfyUI ControlNet Stable-Diffusion Computer-Vision OpenCV

Publié le 27 octobre à 23h12