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)