Nodes/comfyui-segs-profile/SEGS Is Profile (eye_ratio)
ComfyUI Node

SEGS Is Profile (eye_ratio)

Is the face turned away? This node answers with two eye boxes

By tabisheva·Created 8 months ago·Updated 8 months ago· 0
SEGS Is Profile (eye_ratio)
  • segs
  • is_profile
  • eye_ratio
  • debug
threshold2.00

Every face-detailing setup has the same blind spot: the moment your subject turns sideways, the machinery that fixed frontal faces starts actively ruining them. A FaceDetailer tuned for two eyes and a straight-on jaw doesn't know what to do with a profile, and an IP-Adapter face reference or InstantID pass will happily map a frontal reference onto a cheekbone. SEGS Is Profile (eye_ratio) is a tiny gate for exactly that moment. You feed it the SEGS output of your existing detector, it looks at the eye bounding boxes, and tells you yes or no: is this face in profile?

What it actually does

The name undersells the trick. The node doesn't detect anything - no model, no weights, no API. It reads SEGS that your pipeline already produced and does pure geometry on it. That's the whole appeal: it's a decision node, not an inference node, which means it costs nothing and installs with zero dependencies.

Here's the insight it leans on. On a frontal face, the two eyes are roughly the same size, so the ratio of their bounding-box areas sits near 1.0. Turn the head sideways and one eye gets occluded or squashed by foreshortening - the visible eye's box balloons, the hidden one shrinks, and the ratio climbs. So the node:

  1. Unpacks the SEGS structure (the [(W,H), [SEG, SEG, ...]] shape Impact Pack produces).
  2. Picks the largest segment labeled left_eye and the largest labeled right_eye, by bbox area.
  3. Computes eye_ratio = max(area_left, area_right) / min(area_left, area_right).
  4. Returns is_profile = eye_ratio > threshold.

And the deliberate design decision worth knowing: if one eye is missing entirely, it assumes profile and returns True with eye_ratio = 0.0. A hidden eye is the profile signal, so missing is treated as the strongest version of it rather than an error.

The inputs and outputs that matter

The whole node is two inputs, three outputs - you'll touch about half of them.

  • segs (SEGS) - wire this from a Detector (SEGS) node in Impact Pack. It needs to contain left_eye / right_eye labels or the whole thing falls apart.
  • threshold (FLOAT, default 2.0, range 1.0–10.0) - the only knob. The ratio can't go below 1 by construction, so 1.0 means "any asymmetry is a profile" and 2.0 means "an eye must be visibly ~2x the other." Start at the default; nudge down if you're missing profiles.

Outputs: is_profile (BOOLEAN) is what you wire into a switch or If node to branch your graph. eye_ratio (FLOAT) is there if you want a smoother, continuous gate instead of a hard boolean. debug (STRING) dumps eye_ratio, both areas, and the threshold into a text node so you can see why it decided what it did - genuinely handy the first time a workflow misbehaves.

How to install

No dependencies, no model downloads - it's a ~150-line pure-Python file. Either search "comfyui-segs-profile" in ComfyUI Manager, or:

cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/tabisheva/comfyui-segs-profile.git

Restart ComfyUI. That's it. It'll show up in the node menu under utils/segs as "SEGS Is Profile (eye_ratio)".

Where people get burned

The one real trap: this only works if your detector emits eye labels. Many face bbox models output a single face class and nothing else - feed those into this node and both eyes come up missing, so every face is a "profile" and your gate is useless. The face models from the Bingsu/ADetailer family (like face_yolov8m.pt) and skytnt's face YOLO checkpoints do emit left_eye and right_eye; your Impact Pack detector needs to be running one of those. If you're seeing all-True output, that's your first suspect, and the debug output will confirm it in one run.

Second gotcha: threshold 2.0 assumes the visible eye is genuinely larger when occluded. A slightly-turned but still frontal face with noisy detection can spike past it. If your gate keeps misfiring, check eye_ratio on a few frames and set the threshold from what you actually see - that's exactly what the float output is for.

It's a niche utility, but if you're building any workflow where a head can rotate - video, multi-pose generations, character animation - it's the difference between your detail pass quietly melting profiles and it picking a sane branch. Cheap, no deps, one honest boolean. Hard to argue with that.

Categoryutils/segs

Inputs (2)

NameTypeDefaultDescription
segsSEGS
thresholdFLOAT2.001–10

Outputs (3)

NameTypeDescription
is_profileBOOLEAN
eye_ratioFLOAT
debugSTRING