|
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
addimage.py
|
|
|
|
Add a PNG image to a frame
|
|
|
|
History:
|
|
--------
|
|
25.05.20/KQ Initial (modularized) version
|
|
27.05.20/KQ Variable naming corrected
|
|
"""
|
|
|
|
import numpy as np
|
|
import cv2
|
|
import sys
|
|
|
|
# My own new version w/ transparency effect (& reasonable performance)
|
|
def overlay_png(frame, x_offset, y_offset, png, alpha_mask):
|
|
"""Overlay a png on an OpenCV frame @x_offset/y_offset w/ transparency effect based on png alpha channel
|
|
"""
|
|
|
|
_scr_height = png.shape[0]
|
|
_scr_width = png.shape[1]
|
|
|
|
_frame_roi = frame[y_offset:y_offset+_scr_height, x_offset:x_offset+_scr_width, 0:3] # Source original region
|
|
_all_square_bg_fg = cv2.bitwise_or(_frame_roi >> 2, png, mask=alpha_mask) # Both added, background somewhat reduced ...
|
|
_mask_inv = cv2.bitwise_not(alpha_mask) # Negate mask (inverse)
|
|
_surrounding_bg = cv2.bitwise_or(_frame_roi, png, mask=_mask_inv) # This yields the original background at transparent regions
|
|
frame[y_offset:y_offset+_scr_height, x_offset:x_offset+_scr_width, 0:3] = _all_square_bg_fg + _surrounding_bg # Now add both: Transparent add achieved!
|
|
|
|
# Ref.: https://stackoverflow.com/questions/14063070/overlay-a-smaller-image-on-a-larger-image-python-opencv
|
|
def overlay_image_alpha(img, img_overlay, pos, alpha_mask):
|
|
"""Overlay img_overlay on top of img at the position specified by
|
|
pos and blend using alpha_mask.
|
|
Alpha mask must contain values within the range [0, 1] and be the
|
|
same size as img_overlay.
|
|
"""
|
|
|
|
x, y = pos
|
|
|
|
# Image ranges
|
|
y1, y2 = max(0, y), min(img.shape[0], y + img_overlay.shape[0])
|
|
x1, x2 = max(0, x), min(img.shape[1], x + img_overlay.shape[1])
|
|
|
|
# Overlay ranges
|
|
y1o, y2o = max(0, -y), min(img_overlay.shape[0], img.shape[0] - y)
|
|
x1o, x2o = max(0, -x), min(img_overlay.shape[1], img.shape[1] - x)
|
|
|
|
# Exit if nothing to do
|
|
if y1 >= y2 or x1 >= x2 or y1o >= y2o or x1o >= x2o:
|
|
return
|
|
|
|
channels = img.shape[2]
|
|
|
|
alpha = alpha_mask[y1o:y2o, x1o:x2o] # Alpha channel only: 0..1 where <>0 means NOT transparent!
|
|
alpha_inv = 1.0 - alpha
|
|
|
|
for c in range(channels):
|
|
img[y1:y2, x1:x2, c] = (alpha * img_overlay[y1o:y2o, x1o:x2o, c] +
|
|
alpha_inv * img[y1:y2, x1:x2, c])
|
|
|