title: Alpha blending two images with OpenCV and/or Numpy
body: <p>I would like to add a semi-transparent rectangle filled with a solid colour to an already loaded semi-transparent PNG. Here's an example input image I am using:</p>
  <p><a href="https://i.stack.imgur.com/IuQ0H.png" rel="noreferrer"><img src="https://i.stack.imgur.com/IuQ0H.png" alt="enter image description here" /></a></p>
  <p>That image is loaded with a standard <code>cv2.IMREAD_UNCHANGED</code> flag so that alpha channel is perfectly preserved. That input image is stored in the <code>image</code> variable.</p>
  <p>Here's my code that I have so far:</p>
  <pre><code># get image dimensions
  imgHeight, imgWidth = image.shape[:2]
  
  # create empty overlay layer with 4 channels
  overlay = np.zeros((imgHeight, imgWidth, 4), dtype = &quot;uint8&quot;)
  
  # draw semi-transparent red rectangle
  overlay[200:300, 0:imgWidth] = (0, 0, 255, 200)
  
  # extract alpha channel from overlay
  alpha = cv2.split(overlay)[3]
  
  # compute mask
  mask = (np.multiply(alpha, 1.0 / 255))[:, :, np.newaxis]
  
  # blend input image and overlay
  output = cv2.convertScaleAbs(overlay * mask + image * (1 - mask))
  </code></pre>
  <p>And here's the result that I am getting:</p>
  <p><a href="https://i.stack.imgur.com/MruIQ.png" rel="noreferrer"><img src="https://i.stack.imgur.com/MruIQ.png" alt="enter image description here" /></a></p>
  <p>At first glance it looks <em>acceptable</em>. We have our input image with a semi-transparent rectangle in the middle. However, upon closer inspection, we can observe strange behaviour when mixing alpha channels (marked with arrows):</p>
  <p><a href="https://i.stack.imgur.com/aNWBN.png" rel="noreferrer"><img src="https://i.stack.imgur.com/aNWBN.png" alt="enter image description here" /></a></p>
  <p>It seems that alpha is not blended at all which results in original image pixels being only fully opaque or fully transparent.</p>
  <p>Perhaps my method of blending transparent PNG with semi-transparent shapes is far from ideal. As a side note, I did try the <code>cv2.addWeighted</code> method but that yielded even worse results.</p>
  <p>I would like the solution to be limited to OpenCV and/or Numpy. Any help would be greatly appreciated.</p>