Files
2nd/10_Wiki/Topics/AI_and_ML/해부학적 오류 디버깅 워크플로우.md
T
2026-05-10 22:08:15 +09:00

226 lines
7.9 KiB
Markdown

---
id: wiki-2026-0508-해부학적-오류-디버깅-워크플로우
title: 해부학적 오류 디버깅 워크플로우
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Anatomy Error Debugging, Anatomy Fix Workflow]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [image-generation, stable-diffusion, flux, controlnet, inpainting, workflow]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: python
framework: comfyui
---
# 해부학적 오류 디버깅 워크플로우
## 매 한 줄
> **"매 anatomy 깨진 region 의 의 isolate → controlnet pose 의 enforce → low-denoise inpaint 의 surgical fix"**. 매 2026 image-gen 의 anatomy artifact (extra finger, fused limb, broken hand, twisted neck) 의 의 매 entire image 의 regenerate 의 X — 매 mask + ControlNet (OpenPose / DWPose / DensePose) + low-strength img2img 의 combine 의 의 fix 한 이후 매 surrounding pixel 의 preserve.
## 매 핵심
### 매 common anatomy failure
- **Hand**: 매 6 finger / 4 finger / fused / extra thumb — 매 most common.
- **Limb**: 매 missing arm / 3 leg / asymmetric.
- **Face**: 매 misaligned eye / 3 eye / merged feature.
- **Joint**: 매 inverted knee / impossible bend.
- **Topology**: 매 long neck / floating head / mid-body merge.
### 매 fix strategy ladder (cheap → expensive)
- **Step 0 — Prevent**: better prompt + negative + LoRA (RealHands, GoodHands).
- **Step 1 — Detail upscale**: face/hand detailer (ADetailer, FaceDetailer node).
- **Step 2 — Mask + inpaint**: 매 region only 의 redraw, denoise 0.4-0.6.
- **Step 3 — ControlNet pose**: 매 OpenPose skeleton 의 enforce — 매 limb count 의 lock.
- **Step 4 — Reference + IP-Adapter**: 매 good-anatomy reference 의 inject.
- **Step 5 — Manual sketch + ControlNet Scribble**: 매 hand-drawn skeleton overlay.
- **Step 6 — External tool (Photoshop Generative Fill, Krita AI)**: 매 brush-driven local edit.
### 매 응용
1. Portrait commission post-processing.
2. Comic / manga panel correction.
3. Product mockup hand fix.
4. Concept art iteration.
5. Batch dataset cleanup (매 1000 image 의 anatomy QC).
## 💻 패턴
### Prompt-level prevention
```text
Positive: "detailed hands, anatomically correct, five fingers, perfect anatomy"
Negative: "extra fingers, fused fingers, six fingers, missing fingers, deformed hand,
mutated, extra limb, malformed, bad anatomy, twisted, asymmetric"
LoRA: <lora:GoodHands-beta2:0.7>
```
### ComfyUI — automated hand detailer
```python
# pseudo-graph (ComfyUI workflow JSON)
# 1. Generate base image (FLUX.1-dev or SDXL)
# 2. UltralyticsDetectorProvider("hand_yolov8n.pt") → bbox of hands
# 3. SAMSegment → precise mask
# 4. DetailerForEach:
# - guide_size: 512, max_size: 768
# - denoise: 0.5
# - cfg: 7.0
# - prompt: "perfect hand, five fingers, detailed"
# 5. Composite back into original
```
### Manual mask + inpaint (Diffusers)
```python
from diffusers import StableDiffusionXLInpaintPipeline
import torch
from PIL import Image
pipe = StableDiffusionXLInpaintPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16
).to("cuda")
img = Image.open("broken_hand.png")
mask = Image.open("hand_mask.png") # white = inpaint, black = keep
fixed = pipe(
prompt="perfect human hand, five fingers, detailed knuckles, anatomically correct",
negative_prompt="extra fingers, fused fingers, deformed",
image=img,
mask_image=mask,
strength=0.55, # 매 low denoise — 매 surrounding 의 preserve
num_inference_steps=30,
guidance_scale=7.5
).images[0]
```
### ControlNet OpenPose enforcement
```python
from diffusers import StableDiffusionXLControlNetInpaintPipeline, ControlNetModel
from controlnet_aux import OpenposeDetector
pose_detector = OpenposeDetector.from_pretrained("lllyasviel/Annotators")
controlnet = ControlNetModel.from_pretrained(
"thibaud/controlnet-openpose-sdxl-1.0", torch_dtype=torch.float16
)
# 매 reference image (good pose) 의 의 pose extract
pose_map = pose_detector(reference_img, hand_and_face=True)
pipe = StableDiffusionXLControlNetInpaintPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
controlnet=controlnet, torch_dtype=torch.float16
).to("cuda")
fixed = pipe(
prompt=prompt, image=img, mask_image=mask,
control_image=pose_map,
controlnet_conditioning_scale=0.8,
strength=0.6
).images[0]
```
### IP-Adapter reference injection
```python
from diffusers import StableDiffusionXLPipeline
pipe.load_ip_adapter("h94/IP-Adapter", subfolder="sdxl_models",
weight_name="ip-adapter-plus_sdxl_vit-h.safetensors")
pipe.set_ip_adapter_scale(0.6)
reference = Image.open("good_anatomy_ref.png")
fixed = pipe(prompt=prompt, ip_adapter_image=reference, ...).images[0]
```
### YOLO-based hand detection mask
```python
from ultralytics import YOLO
import numpy as np
import cv2
model = YOLO('hand_yolov8n.pt')
results = model(img_np)
mask = np.zeros(img_np.shape[:2], dtype=np.uint8)
for box in results[0].boxes.xyxy:
x1, y1, x2, y2 = map(int, box)
# pad 의 inpaint context 의 give
pad = 20
mask[max(0,y1-pad):y2+pad, max(0,x1-pad):x2+pad] = 255
cv2.imwrite("hand_mask.png", mask)
```
### FLUX.1 Fill (2026 native inpaint)
```python
from diffusers import FluxFillPipeline
pipe = FluxFillPipeline.from_pretrained(
"black-forest-labs/FLUX.1-Fill-dev",
torch_dtype=torch.bfloat16
).to("cuda")
fixed = pipe(
prompt="perfect anatomically correct hand",
image=img, mask_image=mask,
height=1024, width=1024,
guidance_scale=30, # 매 FLUX 의 high CFG OK
num_inference_steps=50
).images[0]
```
### Batch anatomy QC pipeline
```python
def qc_pipeline(image_paths):
for p in image_paths:
img = Image.open(p)
# 1. detect anatomy issues
issues = anatomy_classifier(img) # custom CLIP-based or YOLO
if not issues: continue
# 2. mask offending region
mask = build_mask(img, issues)
# 3. inpaint with ControlNet pose
fixed = controlnet_inpaint(img, mask, pose_from_ref(img))
fixed.save(p.replace('.png', '_fixed.png'))
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Single hand artifact | ADetailer / FaceDetailer node |
| Pose 의 corrupt | ControlNet OpenPose + inpaint |
| 매 specific style 의 reference | IP-Adapter + low denoise |
| 매 fine detail (eye, finger) | Mask + denoise 0.3-0.5 |
| 매 entire pose 의 wrong | Re-generate with ControlNet from start |
| FLUX-based pipeline | FLUX.1 Fill native |
**기본값**: ADetailer (auto) + ControlNet OpenPose (manual fallback) + 0.5 denoise.
## 🔗 Graph
- 부모: [[Image-Generation]] · [[Inpainting]]
- 변형: [[Outpainting]] · [[Img2Img]] · [[Region-Prompting]]
- 응용: [[Stable Diffusion]] · [[FLUX]] · [[ComfyUI-Workflow]]
- Adjacent: [[ControlNet]] · [[IP-Adapter]] · [[ADetailer]] · [[LoRA]]
## 🤖 LLM 활용
**언제**: 매 prompt rewrite (anatomy negative 의 expand); 매 ComfyUI graph 의 LLM 의 emit; 매 batch QC 의 caption-based filter.
**언제 X**: 매 actual pixel 의 fix 의 X — 매 image model 의 job. LLM 의 의 graph orchestrate 만.
## ❌ 안티패턴
- **High denoise (>0.8)**: 매 surrounding 의 destroy — 매 seam 의 visible.
- **No mask padding**: 매 hard edge — context 의 lose.
- **Re-roll only**: 매 매 same prompt 의 의 broken anatomy 의 re-generate — 매 root cause 의 X fix.
- **Negative prompt overload**: 매 negative 의 50 token — model 의 confuse.
- **No ControlNet on bad pose**: 매 inpaint alone 의 의 같은 pose 의 same fail 의 재생산.
## 🧪 검증 / 중복
- Verified (Diffusers docs 0.30+; ComfyUI ADetailer extension; FLUX.1 Fill model card; Civitai workflows).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — ADetailer + ControlNet OpenPose + FLUX.1 Fill patterns 추가 |