Tutorial: ControlNet preprocessors¶
Use NovelAI’s ControlNet preprocessors to extract a structural map from a reference image — depth, line art, semantic segmentation. In v0.1.0 the extracted annotation is returned as a standalone image you can save or inspect; feeding it back into a generation is a v0.2 feature.
Workflow overview¶
graph LR
A[Reference image] --> B[annotate_image]
B --> C[Annotation<br/>depth / line art]
C --> D[Save or display]
1. Extract a depth map¶
import base64
from pathlib import Path
photo_b64 = base64.b64encode(Path("photo.png").read_bytes()).decode("ascii")
depth_result = await ctx.session.call_tool("annotate_image", {
"image": photo_b64,
"model": "midas",
})
# depth_result[0] is an Image content block with the depth map;
# depth_result[1] is the saved file path.
2. Try different preprocessors¶
Preprocessor |
Best for |
|---|---|
|
Pose, volumetric composition. |
|
Anime, painterly line preservation. |
|
Loose sketch → coherent line art. |
|
Architecture, interiors, straight lines. |
|
Scene composition, palette transfer. |
for model in ("midas", "hed", "fake_scribble"):
annotation = await ctx.session.call_tool("annotate_image", {
"image": photo_b64,
"model": model,
})
# Save each annotation for inspection
3. CLI equivalent¶
# Extract a depth map
uv run python -m novelai_image_mcp annotate ./photo.png --model midas
4. Limitations in v0.1.0¶
Warning
Generation does not consume annotations yet. generate_image accepts
text prompts, character prompts, and vibe references — but not a
ControlNet condition. The controlnet_condition / controlnet_model
parameters planned for v0.2 will let generate_image use an extracted
annotation as a structural condition.
Tip
Workaround: For now, combine annotate_image with director_tool to
produce a stylized line-art output from a photo, then optionally use
image_to_image to refine. See Director tools.
What’s next?¶
Vibe transfer — alternate style-transfer workflow