Nodes/ComfyUI CV/cv2.PCAProject
ComfyUI Node

cv2.PCAProject

Turn your data into its principal components

By bmad4ever·Created 4 months ago·Updated 15 days ago· 1
cv2.PCAProject
  • data
  • mean
  • eigenvectors
  • nparray

Half of a compression round trip. cv2.PCACompute finds the axes; this node expresses your data in those axes - subtract the mean, rotate onto the eigenvectors, and you're left with a matrix whose first column carries the most variance, second column the next most, and so on. Truncate those columns and you've compressed your feature matrix.

Three inputs, all required, all NPARRAY: data, mean, eigenvectors. One output: nparray, N x K where K is however many eigenvectors you handed it.

The wiring that matters

The mean and eigenvectors you pass in must be the pair that came out of the same PCACompute / PCACompute2 run that your data belongs to. This is the entire discipline of the family, and it's why the pack makes mean a socket instead of computing it behind your back - the project/back-project nodes need the exact same centroid, and Python's cv2 has the same requirement.

So the pattern is:

PCACompute (data) ── mean ────────┬──> PCAProject (mean)
                  └─ eigenvectors ─┴──> PCAProject (eigenvectors)
                        data ──────────> PCAProject (data)

Wire it the other way - data into a project node on one branch and a different compute node's mean on the other - and nothing errors. cv2 draws lines through the wrong origin and hands you plausible numbers. That's the trap in this family, and the reason Inspect CV Data earns its place in the graph while you're learning it.

There's a second, quieter trap: mean here is not the same argument as mean on PCACompute. On compute it's the output the mean is written through; on project it's an input it reads. Same name, opposite direction, same socket type. The good news is that if you drew the wire from compute to project, you've already got it right.

What you do with the output

The projected matrix is your reduced feature set. Practical uses inside ComfyUI land:

  • Train on fewer dimensions. If a classifier is being fed HOG or deep features from CV HOG Features / CV Deep Features, projecting to 10-30 components first is the standard move. What you do with the projected matrix afterwards is the pack's cv2.ml corner (CV Train Classifier) or your own thing downstream.
  • Drop the tail. A lot of the time the useful work is exactly this: components past the third are mostly noise, and you get the rest of the graph to be cheaper and less noisy for free. There's no truncation node here - cv2's PCAProject returns as many components as there are eigenvectors, so you control K by setting maxComponents on the way in.
  • Round-trip sanity check. PCAProject then PCABackProject gets you back to the original space. Compare with the input (CV Array Statistic on both is enough) and you have your reconstruction error, which is the answer to "was 0.95 enough?".

Also worth knowing: PCA is a rotation, so PCAProject is not a lossy step - the loss happens when you cut eigenvectors. Projecting with the full set is a reversible change of basis, and for point clouds that alone is often the goal: rotate the cloud into its own frame so a later operation can assume axis-aligned structure.

Requirements and failure modes

cv2 wants float32 or float64 everywhere - data and the two model arrays. Mixed dtypes get you an opaque "Overload resolution failed" from the Python binding, so CV Cast Array before the compute node (the cast propagates automatically if you're consistent, because the outputs of that compute run carry the same dtype through).

Shapes have to line up: data is N x M, mean is 1 x M, eigenvectors is K x M. CV Array Shape and Inspect CV Data are the diagnostic pair when a mismatch raises, and Parse Matrix is how you type a mean in by hand if you're reconstructing a pipeline you ran elsewhere.

And like every raw wrapper in this pack, it's a matrix node with no batch awareness: link an image in and you get frame 0, one array out.

Installing

ComfyUI Manager → search ComfyUI CV → Install → restart. Manual:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"

Python ≥ 3.12, recent ComfyUI (V3 node API). PCAProject is core cv2 - no contrib, no models, no downloads. You'll find it under image/CV/low-level/cv2 P as cv2.PCAProject.

Categoryimage/CV/low-level/cv2 P

Inputs (3)

NameTypeDefaultDescription
dataNPARRAY - - - A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
meanNPARRAY - - - A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
eigenvectorsNPARRAY - - - A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.

Outputs (1)

NameTypeDescription
nparrayNPARRAY—