How to use opacity in drawKeypoints or drawMatches?

I’m using OpenCV 4.10 in python, but this should generalize to anyone using drawKeypoints or drawMatches. I want to draw the keypoints with less than 100% opacity over the image. I have tried:
img3 = cv2.drawKeypoints(img1,kp1,img3,color=(0,200,0, 128))
img3 = cv2.drawKeypoints(img1,kp1,img3,color=(0,200,0, 0.5))
I even threw in:
img3 = cv2.drawKeypoints(img1,kp1,img3,color=(0,200,0), alpha=0.5)

But none of the above work. Is this not possible?

an alpha channel on the color won’t do what you want it to do. it’s just a fourth color channel to all the drawing functions. the drawing functions in opencv are ancient and have no concept of transparency.

the LINE_AA mode lines kinda blend into the base, but also don’t take any alpha values into account, and the implementations and results are a disaster (thickness not correct in at least two different ways).

neither drawKeypoints nor drawMatches have any alpha parameter. why should that work? documentation:

if you want alpha blending, you’ll have to do that manually. draw onto a blank canvas, draw calls fully opaque, then blend that onto the real destination, with addWeighted()

opencv has no functions to actually alpha-blend with per-pixel alpha. to achieve that, you have to take the alpha channel and apply the blending equation to the involved matrices/arrays, making sure to keep the value ranges and data types in mind.

# alpha being an array with values ranged 0.0 .. 1.0
# if typed uint8, then products will need enough bits to be 16 bit, plus a sign, so everything must be int32

# simpler, two multiplications, no worries about underflow
composite = alpha * overlay + (1-alpha) * base

# one multiplication, but mind the subtraction will underflow an uint8
# so .astype() to int16 first (int16, not uint16) or do everything with floats
composite = base + alpha * (overlay - base)