cv2.solveLP (1/2)
A Real Simplex Solver, Hiding in Your Node Menu
- Func
- Constr
- int
- nparray
Yes, that's really a linear-programming solver in the ComfyUI node menu. cv2.solveLP runs OpenCV's implementation of the simplex algorithm - the same routine that shows up in operations research, optimal transport and LP-based shape fitting - and ComfyUI CV (bmad4ever/comfyui_cv) exposes it because it auto-generates a wrapper for every top-level cv2.* function in the type stubs, including the numerics that have nothing to do with pixels.
So the honest framing: this node exists because a generator walked the OpenCV API. It works, it's real, and roughly nobody has shipped a workflow with it. If you're here, you're either curious or you have an actual constrained-optimization problem that you'd like to solve without leaving ComfyUI. Both are fine reasons.
Inputs
Func- the objective's coefficient vector,c. OpenCV wants a row vector here, but accepts a column vector too, reading it ascᵀ. Must be 32- or 64-bit floating point.Constr- the constraint matrix:mrows byn+1columns. The rightmost column isb; the remainingncolumns areA. Also float32/float64.constr_eps- the "allowed numeric disparity for constraints", as a float. This is the extra parameter that makes this the (1/2) variant of the node.
That last field is the difference between the two wrappers. OpenCV has two overloads of solveLP, so the pack generates two nodes, with the same display name and a (1/2) / (2/2) suffix: cv2.solveLP (2/2) is the plain two-argument call, and this one is the variant that also exposes constr_eps. Wire the same problem into either.
The constr_eps idea is a tolerance on feasibility: real systems are often feasible only up to floating-point slop, and a solver working at exact equality can report a well-posed problem as infeasible. A small positive tolerance is what the parameter is for. Its default is 0 - exact - which is the strictest setting, not a sensible one for noisy data.
Outputs
int- OpenCV'sSolveLPResultstatus code. You need this: it distinguishes a solved problem from "unbounded", "infeasible", and "one of several optima". Read it before you use the answer.nparray- the solution vector.
Two things I'd rather state plainly than dress up: OpenCV's own documentation is the authority on the exact inequality convention of the constraint rows (getting the sign convention backwards is the traditional first mistake with any LP, and this wrapper does not add guardrails), and the numeric values behind the status codes are OpenCV's enum - print the code once against a problem you know the answer to if you're going to branch on specific values.
Where it fits in a ComfyUI graph
LP shows up in vision work as the "respect these bounds while optimizing this" step: fitting a shape under feasibility constraints, choosing blend weights that sum to one and stay non-negative, allocating a crop or resolution budget across regions, optimal-transport-flavoured matching between point sets. In this pack the inputs are all NPARRAYs, so the assembly story is the usual one - Parse Matrix or CV Points to type the problem, CV Concat Arrays to glue rows, CV Array To Numbers to pull results back into scalar sockets, CV Scalar for constant vectors.
Install
Manager → search ComfyUI CV, or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
Restart ComfyUI. Python ≥ 3.12 and a recent V3-API ComfyUI are required - this pack will not register on an old install. No models, no downloads.
Where people get burned
Shape errors, not math errors. Constr is m×n+1 with b in the last column, and a matrix built the other way round produces a shape complaint rather than a wrong answer. Build one tiny problem you can solve on paper first - the pack's numeric nodes make that easy - and only then scale up.
Getting the inequality direction backwards. Every LP tutorial warns you; this node won't. If the optimum is obviously nonsense, flip the sign of a row and see.
Contrib wheel collisions. The four OpenCV distributions share one site-packages/cv2. Installing a non-contrib wheel over the contrib one leaves contrib-derived nodes out of the menu with no error. tools/repair_opencv_contrib.py --check diagnoses; --apply repairs.
Treating it as validated. The pack's README is unusually candid that it's a personal, AI-assisted project, that test-driven development left possible undetected mistakes, and that production use needs an independent code review. A simplex solver is exactly the kind of thing where you check the answer - plug the solution back into the constraints before anything downstream depends on it.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| Func | NPARRAY | This row-vector corresponds to $c$ in the LP problem formulation (see above). It should contain 32- or 64-bit floating point numbers. As a convenience, column-vector may be also submitted, in the latter case it is understood to correspond to $c^T$. A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here. | |
| Constr | NPARRAY | `m`-by-`n+1` matrix, whose rightmost column corresponds to $b$ in formulation above and the remaining to $A$. It should contain 32- or 64-bit floating point numbers. A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here. | |
| constr_eps | FLOAT | 0.0000-1e+38–1e+38 | allowed numeric disparity for constraints |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| int | INT | — |
| nparray | NPARRAY | — |