Perspective Correct
Keystone correction without a photo editor
- image
- mask
- image
Tilt a camera up to photograph a tall building and the walls converge - the tower leans back, the whole structure looks like it's falling over. Photographers call it keystoning, and fixing it used to mean Photoshop's perspective warp or a dedicated correction tool. Perspective Correct is the Darkroom pack's take: a three-slider node that straightens converging verticals and horizontals with proper keystone math, plus automatic cropping to clean up the mess the transform leaves behind.
How it works
A keystone transform is a projective warp - it maps the image onto a plane tilted in 3D, which is exactly what the camera did when it pointed up. The node computes that warp from three parameters:
vertical(−0.5 to +0.5) - the vertical keystone, and the one you'll use most. Positive corrects converging verticals (the building-lean-back case). Negative does the opposite, for when you want to exaggerate the lean or fix a shot where verticals splay outward.horizontal(−0.5 to +0.5) - the same for left-right convergence, for shooting buildings at an angle or correcting off-axis geometry.rotation(−15° to +15°) - a straight rotation correction for the "my horizon is crooked" problem. Handy that it lives in the same node.
The required input is vertical (it has no default-free path), with horizontal and rotation as optional extras.
The crop question
Any projective warp leaves empty triangles at the image corners. The node's auto_crop option (on by default) handles that automatically - it crops into the transformed image to remove the black borders. Leave it on and you get a clean, rectangular result at the cost of some edge pixels. Turn it off if you want to see the full transformed frame (useful for judging whether the correction is right before you commit).
That's a real design nicety: the standard workflow is turn off auto_crop, set vertical until the walls are plumb, then turn it back on - you get to see exactly what you're correcting, then let the node clean up.
Where it fits
It lives in AKURATE/Darkroom/Lens, alongside Lens Distortion, Chromatic Aberration, and Vignette. In a photography-realistic pipeline it pairs naturally with the pack's Lens Profile node: Perspective Correct handles the geometry from camera tilt, Lens Profile handles the lens's own optical flaws, and the two cover most of "why does this building photo look wrong."
It's a spatial operation, so it's on the README's not-in-LUT-bake-chain list - apply it after LUT extraction, never inside a bake chain. Output is a single image.
A couple of practical notes:
- Correct first, crop later. Perspective correction is a geometric op that eats edge pixels. Do it before any sharpening or grain, so you're not sharpening pixels you're about to throw away.
- Don't chase extreme values. Beyond roughly ±0.3 the perspective gets so stretched that the image starts to look warped rather than corrected. If you need more than that, the original shot is probably too tilted to save cleanly.
- On AI output it's a pose/composition fix. Generated "architecture" often has subtly wrong perspective baked in. This node is the cheap, controllable way to straighten it without regenerating.
Installing it
Part of the full ComfyUI-Darkroom pack:
cd ComfyUI/custom_nodes
git clone https://github.com/jeremieLouvaert/ComfyUI-Darkroom.git
pip install -r ComfyUI-Darkroom/requirements.txt
Or search "Darkroom" in ComfyUI Manager. Needs scipy, opensimplex, rawpy, exifread, Pillow. Restart and it's under AKURATE/Darkroom/Lens. No GPU, no models, no API - it's numpy warping math.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| vertical | FLOAT | 0.00-0.5–0.5 | Vertical keystone. Positive corrects converging verticals (building lean-back) |
| horizontalopt | FLOAT | 0.00-0.5–0.5 | Horizontal keystone. Corrects left-right convergence |
| rotationopt | FLOAT | 0.0-15–15 | Rotation correction in degrees |
| auto_cropopt | BOOLEAN | true | Automatically crop to remove black borders from the transform. Ignored when a mask is connected. |
| maskopt | MASK | Where the correction applies, 0 to 1. Partial values bend lines that cross the mask edge, and strong keystone bows long lines even without a mask. auto_crop is ignored while a mask is connected. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |