Nodes/ComfyUI CV/cv2.drawMarker
ComfyUI Node

cv2.drawMarker

Mark a point so you can actually see it

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
cv2.drawMarker
  • source
  • position
  • result
◄color(0, 0, 0, 0)►
◄markerTypeMARKER_CROSS►
◄markerSize20►
◄thickness1►
◄line_typeLINE_AA►

Keypoints, corners, centroids, detections - half the nodes in an OpenCV-flavoured pack produce coordinates, and coordinates are invisible. drawMarker puts a small glyph at one: a crosshair, a star, a diamond, a filled triangle. It's the "where exactly did the detector think the eye was" node, and it's the difference between debugging and guessing.

The one thing that makes people think it's broken

color defaults to the literal "(0, 0, 0, 0)" - black, fully transparent-ish, i.e. invisible on the black image most people test with. You run the node, the preview comes back identical, and you conclude it does nothing. It's drawing. It's just drawing in black.

Type a real Scalar literal: "(0, 255, 0)" is green, and the format is BGR, so red is "(0, 0, 255)". A bare number broadcasts to every component, so "255" means white. Components past the target's channel count are ignored by OpenCV, per the tooltip.

The inputs

source is what you draw on and, as with every drawing wrapper here, you can hand it an IMAGE, a MASK or an NPARRAY - the result output echoes the same format back, so an IMAGE batch stays an IMAGE batch (each frame gets its own marker drawn and the results restack).

position is a CV_TUPLE of two components, (x, y), default (0, 0) - top-left corner, which is also why a marker you "can't see" sometimes is there, half off-frame. It travels as a unit, so you can type it or wire it from CV Tuple/its split components; it can't arrive half-connected.

color as above. These three are the required ones.

Then the glyph, which is the fun part:

  • markerType is a dropdown of OpenCV's whole MARKER_* family, defaulting to MARKER_CROSS - a plain crosshair. MARKER_TILTED_CROSS is an X, MARKER_STAR a six-point asterisk, and there are filled shapes (MARKER_DIAMOND, MARKER_SQUARE, MARKER_TRIANGLE_UP) for something that reads at a glance.
  • markerSize is the axis length in pixels, default 20.
  • thickness default 1. Push it to 2 or 3 if the marker is going onto a busy photograph.
  • line_type defaults to LINE_AA - anti-aliased, which is why your marker looks slightly soft if you zoom in. LINE_8 gives you hard pixels.

Where it fits

Anywhere you've got points and want eyes on them. The pack's detector nodes - blobs, keypoints, chessboard corners, feature matches - all hand back arrays; drawMarker is the cheap overlay for one of them. It's also the honest way to check that a transform did what you think: mark where a point lands after a warp, before and after.

Against alternatives: OpenCV's own drawKeypoints exists as a wrapper in this pack too, but it draws the detector's whole keypoint set with its own idea of colour and size. drawMarker is the one you use when you want to annotate specific coordinates you chose - a click point, a centroid, a known landmark - rather than everything the algorithm found. For a batch of points, the pack's CV Draw Path (ordered) draws sequences where direction matters.

Being a drawing primitive, it's also in the family the pack treats carefully: cv2 drawing functions mutate their target image in place, so the wrapper passes a private copy of every array across the call boundary - your upstream cached IMAGE doesn't get scribbled on because a downstream node drew a crosshair. Nothing to configure, just a thing that would otherwise be a very confusing bug.

Installing comfyui_cv

Part of bmad4ever/comfyui_cv: roughly 470 auto-generated raw cv2.* wrappers plus curated nodes, a GPL-3.0 fork of Gerold Meisinger's opencv-comfyui, curated against OpenCV 5.0.0.93. Manager: search ComfyUI CV. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv

Restart after. Python ≥ 3.12 and a recent ComfyUI on the V3 node API; the only dependency is opencv-contrib-python-headless~=5.0.0.93. Install the contrib wheel specifically - all four OpenCV distributions share one site-packages/cv2 and the last one installed wins, so a plain opencv-python quietly empties the contrib submodules and their nodes (tools/repair_opencv_contrib.py --check / --apply).

Common issues

Nothing visible. Almost always the black default color, or a position that's off-frame. Both are one widget away from fixed.

Marker in the wrong place. Remember the frame is (x, y) with y increasing downward, and position is the marker's centre, not its top-left.

Marker looks blurred. LINE_AA. Switch to LINE_8 for crisp pixels, or accept the softness - anti-aliased is usually what you want when you're compositing on top of a photo.

Same marker on every frame. That's the design, not a bug: the node draws one marker at one position. Loop the position values yourself, or use a node that takes a point list.

Categoryimage/CV/low-level/cv2 D

Inputs (7)

NameTypeDefaultDescription
sourceCOMFY_MATCHTYPE_V3 The image output(s) echo this input's format. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size.
positionCV_TUPLE0,0The point where the crosshair is positioned. One value with 2 components (x, y) - it travels as a whole, so it cannot arrive half-connected. Wire it from 'CV Tuple' or type the components in place.
colorSTRING(0, 0, 0, 0)Line color. cv2 Scalar as a literal, e.g. "(0, 255, 0)" (BGR) or "(0, 255, 0, 64)" (BGRA). A bare number broadcasts to every component, so "255" means (255, 255, 255, 255). Components past the target's channel count are ignored by OpenCV.
markerTypeoptCOMBOMARKER_CROSSThe specific type of marker you want to use, see #MarkerTypes
markerSizeoptINT20-2147483648–2147483647The length of the marker axis [default = 20 pixels] Preset to the OpenCV default (20).
thicknessoptINT1-2147483648–2147483647Line thickness. Preset to the OpenCV default (1).
line_typeoptCOMBOLINE_AAType of the line, See #LineTypes

Outputs (1)

NameTypeDescription
resultCOMFY_MATCHTYPE_V3Echoes the 'source' input's format: an IMAGE link comes back as IMAGE, MASK as MASK, NPARRAY stays NPARRAY.