Distillation de Goût
Cette compétence autonome livre son implémentation dans scripts/ ; utilisez
taste-application pour le montage ultérieur généré ou local. Gardez chaque genre
nommé dans son propre pack. Les mesures de Flash Ethereal ne doivent pas être
réutilisées silencieusement pour Fluid Sketch ou 3D Cyber Glitch. Une mesure zéro
est une donnée valide ; distinguez-la d'un champ absent.
Les dépendances locales sont dans scripts/requirements.txt. Le travail de
fournisseur séparément autorisé a également besoin de
scripts/requirements-live.txt, d'identifiants et de
TASTE_FORGE_ALLOW_LIVE=1 explicite. --dry-run ne lit pas les identifiants ni
ne soumet de tâches. Ne déduisez jamais qu'un workflow a été sauvegardé à partir
d'un nom de point de terminaison local ; utilisez le workflow côté fournisseur ou
la preuve de la requête.
Transformez des vidéos de référence en un pack de style : un dossier de mesures et d'assets que les étapes ultérieures consomment de manière déterministe.
Quand Activer
- « capturer le look de ces clips » / « distiller l'ambiance » / « rendre cela reproductible »
- L'utilisateur a des images de référence et veut une LUT, un étalonnage ou un rythme correspondant
- Construire une bibliothèque de looks partitionnés par genre
- Toute requête où la réponse serait autrement « décrire le style dans un prompt »
La Découverte Fondamentale
Le prompt ne peut pas livrer un étalonnage. La mesure le peut.
Mesuré sur des images réelles : trois générations payées avec une direction de couleur croissante ont déplacé le a* des tons moyens de +1.9 → +2.8 → +0.3 par rapport à une cible de +24.9, et le contraste n'a jamais quitté ~19 contre une cible de 34.7. L'application d'un pack mesuré à la même séquence a touché une MAE chromatique de 1.88 et un contraste de 33.7 en un seul passage déterministe, gratuitement.
Donc la division est : le modèle fournit le contenu, le mouvement et la structure d'éclairage ; le pack fournit le look. Les mots de couleur dans un prompt de génération sont pire qu'inutiles — ils coûtent de l'argent et éloignent le rendu de la base neutre que la LUT souhaite. Dites-le explicitement dans le prompt : « Couleur : aucune. Rendu neutre. L'étalonnage est appliqué a posteriori. »
Contenu d'un Pack
stylepacks/<genre>/
grade.json statistiques de couleur mesurées (voir ci-dessous)
cadence.json chaque limite de plan détectée + la distribution dérivée
look.cube LUT 33^3, glissez directement dans Resolve comme LUT de nœud
spec.json description VLM, ancrée dans les mesures
grounding.txt les faits mesurés fournis au VLM
stills/ images plein format des plans les plus longs (images de conditionnement)
plates/ éléments de superposition de fusion d'écran extraits sur fond noir
props/ maillages GLB frappés
pack.json manifeste
Exécution
python mint.py --genre <nom> --refs a.mov b.mov c.mov # hors ligne, pas de clé API
python distill.py --genre <nom> # un appel VLM
mint.py est une analyse numérique pure — pas de réseau, pas de clé,
déterministe, donc un pack peut être regénéré plutôt que sauvegardé.
Les Mesures Qui Comptent
Chroma par zone de luminance, pas globalement
L'identité de couleur vit généralement dans une bande de luminance. Un
décalage global a*/b* ne peut mathématiquement pas représenter un
split-toning. Mesurez la chroma à l'intérieur de zones
(bords L* [0,15,35,55,75,100]).
Une vraie signature : violet à L25 (a +24.9, b* −17.5), quasi neutre aux deux extrémités. Ne rapporter que les zones les plus sombres et les plus claires appelle cela « dominante uniforme » — imprimez toujours la courbe entière.
Médiane + MAD, jamais moyenne + écart type
La chroma dans les ensembles de référence réels est fortement asymétrique à droite. Sur un rouleau mesuré, la chroma moyenne des tons moyens était de 36.9 contre une médiane de 17.5, donc une LUT basée sur la moyenne poussait la couleur ~3x plus fort que ce que le matériau justifiait.
Le contraste est std(L*), pas blanc moins noir
La plage blanc−noir est ~100 sur presque toutes les images réelles et ne discrimine rien.
La part d'arrière-plan est une statistique de première classe
Enregistrez la part des pixels en dessous de L*10. Aucun moment de la distribution ne peut la voir : un clip peut avoir la bonne moyenne, écart type et chroma alors que ses noirs ont été relevés en gris. C'est exactement comment un étalonnage a un jour obtenu un score MAE 1.88 / contraste 33.7 alors que l'image réelle était un désordre violet boueux.
Masquez l'interface avant de mesurer
Les références enregistrées d'écran portent des éléments d'interface statiques — barres de lettre-box, barre de statut, icône de like, texte de légende. Tout cela atterrit dans les statistiques comme s'il s'agissait du look : les barres noires gonflent le poids des ombres, un cœur rouge fausse a* vers le magenta. La variance temporelle les sépare proprement — l'image bouge, l'interface pas — donc aucun recadrage manuel n'est nécessaire. Sur du matériel réel, cela conserve ~65% des pixels.
Le rythme a besoin d'un seuil adaptatif
Le bon seuil de détection de contenu dépend du matériau : une référence d'action à haut contraste coupe assez fort pour 30, une référence moody cache ses coupes en dessous. Parcourez les seuils décroissants et prenez le plus élevé qui récupère encore ≥90% des plans que le réglage le plus sensible trouve — cela favorise les vraies coupes par rapport au bruit. Rejetez les seuils impliquant un taux de coupe absurde (>100/min) ; les mouvements de caméra continus déclenchent le détecteur à chaque image.
Effectuez tout le balayage en un seul passage de décodage avec un
StatsManager partagé. La version naïve re-décode par seuil, ce qui sur une
source 60fps est la différence entre secondes et minutes.
Plaques de Fusion : Assets, Pas Captures d'Écran
Une image fixe est une image entière — en composer une met juste une deuxième image par-dessus. Une plaque est le vocabulaire graphique de la référence (éblouissements, traînées, fragments de glitch) extrait sur fond noir de sorte qu'il se fonde avec un écran sans incrustation.
Deux pièges, tous deux rencontrés sur du matériel réel :
- Les seuils absolus échouent. Sur une référence lumineuse, une
sélection
L>55 ET chroma>12prend ~90% de l'image, et la « plaque » est l'image — y compris un visage reconnaissable. Sélectionnez par percentile (~top 3%) et rejetez toute plaque couvrant plus de ~22% de l'image. - Classez par séparation, pas par luminosité. « Part de pixels
lumineux saturés » classe une image délavée en tête et une image noire avec
un seul éblouissement intense — la véritable signature — près du bas.
Scorez
p99.5(énergie) / médiane(énergie).
Masquez aussi avant de noter : la typographie incrustée est lumineuse, saturée et à haut contraste, donc une exécution non masquée produit une plaque parfaite de la carte de titre de quelqu'un d'autre.
Ancrage du VLM
Introduisez les mesures dans le prompt système avant de demander une description. Non ancré, un VLM signalera « aucun étalonnage apparent, neutre » sur une image avec un a* à +24.9. Ancré, il décrit correctement la dominante et infère l'accent secondaire indépendamment.
Interdisez les mots d'hésitation (varié, mixte, dynamique, quelques,
souvent, neutre, ou) — un modèle ne peut pas rendre « éclairage
varié ». Appliquez l'interdiction dans le code, pas seulement dans le
prompt : elle était violée dans environ une exécution sur trois.
Redemandez par champ, gardez la réponse la moins hésitante après N tentatives
plutôt que d'échouer.
Avertissement à mentionner à l'utilisateur : une fois la spécification ancrée dans les mesures, elle n'est plus un contrôle indépendant sur celles-ci.
Pièges de la Cuisson de LUT
- Une LUT ne peut encoder qu'une fonction RVB par pixel. Tout ce qui dépend de la distribution (correspondance d'histogramme, ancres de percentile) doit être réduit à une constante avant la cuisson, sinon il mesure silencieusement la grille uniforme de la LUT au lieu de l'image.
cv2.cvtColor(LAB2RGB)sature en interne, donc un test hors gamut utilisant cela signale 0%. Convertissez Lab→sRGB linéaire à la main ; une mesure réelle était de 83.3% hors gamut.- Transfert de chroma par décalage, pas affine. L'affine divise par le σ de la source et dépasse — sur des images réelles, il a inversé b* à +11.6 contre une cible de −17.5. Le décalage a fait passer la MAE de 6.23 à 2.13.
- La compression de gamut coûtait 3.8x le temps d'exécution pour une MAE identique. Rendez-la optionnelle.
Anti-Patterns
| À ne pas faire | Pourquoi |
|---|---|
| Régler sur des séquences de test synthétiques | A coûté quatre conclusions erronées distinctes sur un projet ; les séquences réelles les ont toutes renversées |
| Faire confiance uniquement à la MAE | Une MAE de 1.88 semblait être un succès sur une image visiblement cassée |
| Utiliser moyenne/écart type pour la chroma | Asymétrique à droite ; pousse ~3x trop fort |
| Comparer uniquement les zones d'extrémité | Les deux extrémités sont quasi neutres par construction |
| Décrire le look et s'arrêter | La spécification est pour le contenu et la structure ; le pack est pour la couleur |
Passation
Le pack est l'interface. Une fois qu'il existe, utilisez la compétence
taste-application pour générer et assembler par rapport à lui, ou
remettez look.cube directement à un coloriste.
Code Fourni
scripts/ dans cette compétence est une implémentation fonctionnelle, pas du
pseudo-code. Elle n'a pas d'hypothèses spécifiques à un projet : pointez-la
vers n'importe quelles vidéos de référence et elle produit un pack.
pip install -r scripts/requirements.txt
export FAL_KEY=... # uniquement nécessaire pour les étapes qui appellent fal
Chaque appel réseau est simulé sous TASTE_FORGE_DRY_RUN=1 ou --dry-run,
donc le plan, les prompts, la disposition des pistes et le manifeste peuvent
être inspectés sans dépenser.