OpenCV getOptimalNewCameraMatrix_0
The Node That Makes Undistortion Actually Work
- cameraMatrix
- distCoeffs
- nparray
- literal
OpenCV getOptimalNewCameraMatrix_0 is the workhorse of this pack's camera-calibration corner. It wraps cv2.getOptimalNewCameraMatrix(), which takes your camera matrix and distortion coefficients and computes two things you need before you undistort anything: an adjusted camera matrix and a rectangle (ROI) telling you which pixels of the result are valid. Run this first, feed its outputs into undistort, and you get clean, undistorted images with the black borders cropped away. Skip it and you'll be fighting black edges and wasted resolution.
The mechanism
Distortion correction is a two-stage act. undistort uses the camera matrix + distortion coefficients to remap pixels - but a naive remap leaves dead zones around the edges where no source pixel maps, and it throws away the resolution those zones represent. getOptimalNewCameraMatrix solves that by computing a tuned camera matrix (a zoom and recenter of your original) and the ROI of pixels that actually carry image data under that tuning. The alpha slider is the whole game:
- alpha = 0 - maximally zoom in and crop to only valid pixels. No black borders, maximum resolution, but the frame edges get cut.
- alpha = 1 - keep all original pixels, accept black borders around the result.
- Anything between - a trade-off;
0.5is a common "crop the worst of it but don't eat my corners" choice.
The inputs and outputs
- cameraMatrix (
NPARRAY) and distCoeffs (NPARRAY) - your calibration data, as OpenCV numpy arrays. The 3×3 matrix and the distortion coefficient vector (5 or 8 elements depending on model). - imageSize (
STRING) - source image size as a literal, e.g.[1920, 1080]. Brackets required. - alpha (
FLOAT) - the free-scaling parameter above. - newImgSize (
STRING) - optional output size as a literal (e.g.[1280, 720]); leave as[]to match the source. - centerPrincipalPoint (
BOOLEAN) - setTrueif you want the principal point forced to center (usually you don't here). - Output nparray - the new 3×3 camera matrix, feed it to
undistort's cameraMatrix input. - Output literal (
STRING) - the valid-pixels ROI, serialized as text like(x, y, w, h).
The pain point
That second output is where this pack's design bites. The ROI is a Rect, a composite type, so the generator hands it back as a string literal rather than structured coordinates. There's no node here that natively consumes it - you'll end up parsing (x, y, w, h) back into numbers for a crop node by hand. It's clunky, but the ROI is genuinely optional: undistortion works with just the new camera matrix; the ROI just tells you the honest crop. For most users, setting alpha=0 and cropping to the ROI is the difference between a clean result and a bordered one.
Install
ComfyUI Manager, search opencv-comfyui (display "OpenCV"), or:
cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui
pip install opencv-contrib-python
Restart. No models. Usual pack rules: everything image-side is NPARRAY with batch size 1, and imageSize/newImgSize need bracket literals. The _1 variant is an identical duplicate - the generator numbered two overloads that collapsed to the same signature. Pick either.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| cameraMatrix | NPARRAY | — | |
| distCoeffs | NPARRAY | — | |
| imageSize | STRING | — | |
| alpha | FLOAT | — | |
| newImgSize | STRING | — | |
| centerPrincipalPoint | BOOLEAN | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |
| literal | STRING | — |