cv2.getFontScaleFromHeight
\"Make this label 40 pixels tall\" — the number putText never gave you
- float
cv2.putText takes a fontScale - a unitless multiplier on the font's own baseline geometry - which means "0.8" is not a size, it's a guess you tune by eye until the text looks about right. cv2.getFontScaleFromHeight converts a real measurement into that guess. Tell it you want glyphs 40 pixels tall and it tells you the scale to pass.
I ran it on a 4.8 build to be sure of the numbers: FONT_HERSHEY_SIMPLEX, height 40, thickness 2 → 1.833. So a label you want 40 px tall goes into putText with fontScale = 1.833, and it comes out 40 px tall instead of "sort of 30-something".
The inputs
fontFace- a dropdown of the Hershey faces, defaulting toFONT_HERSHEY_SIMPLEX. It must match the face you'll actually draw with, because each one has different baseline geometry.pixelHeight- the target height, in pixels. It opens at 0, and 0 gives you a negative fontScale (I measured about-0.048), which draws invisible or mirrored text rather than erroring. That's the trap in this node: no message, just a blank label.thickness- optional, defaults to 1. The height calculation accounts for stroke width, so pass the same thickness you'll handputText. Otherwise you're a couple of pixels off, which matters when you're aligning text to something.
One output, float - the fontScale. Wire it straight into the fontScale input of the cv2.putText wrapper, and put the same fontFace and thickness there too.
Why you'd bother
Any time a graph draws on its own images and the images aren't a fixed size. Bake fontScale = 1 into an annotation node and your labels are fine on a 1024px preview and unreadable on a 4K one - or comically large on a 256px thumbnail. Compute the height from the frame instead (~3% of image height) and every diagnostic overlay the pack draws - keypoint ids, box labels, pose annotations, matrix readouts - stays legible regardless of what resolution flows through.
The second case is legibility after downscaling. A 12 px label is fine until the image gets resized for a contact sheet, at which point it's a smudge. Knowing the actual pixel height lets you decide "minimum 18 px" and enforce it.
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. Python ≥ 3.12, recent ComfyUI on the V3 node API. Nothing to download, and this function has been in OpenCV for years.
Where people get burned
- Leaving
pixelHeightat 0. Negative fontScale, invisible text, no error. Set a real number. - Mismatched faces. The scale is computed for the
fontFaceyou selected, not for text you draw with a different one. Same for thickness. - Expecting it to reserve space. This returns a scale, not a bounding box; if you're laying out a text on a canvas you still need
cv2.getTextSizeto know the width and baseline. The pack wraps that too. - Treating it as a hard promise. The returned scale is about the font's cap/baseline geometry, so a string with descenders or accents on a different face lands a pixel or two off what you asked for. For overlays, that's irrelevant. For pixel-perfect typography, you're using the wrong library.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| fontFace | COMBO | FONT_HERSHEY_SIMPLEX | Font to use, see cv::HersheyFonts. |
| pixelHeight | INT | 0-2147483648–2147483647 | Pixel height to compute the fontScale for |
| thicknessopt | INT | 1-2147483648–2147483647 | Thickness of lines used to render the text.See putText for details. Preset to the OpenCV default (1). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| float | FLOAT | — |