|
| 1 | +import cv2 |
| 2 | +import filters |
| 3 | +import numpy as np |
| 4 | + |
| 5 | +# Based on the blog post of Benjamin Elder |
| 6 | +# https://elder.dev/posts/open-source-virtual-background/ |
| 7 | +# License: CC-BY 4.0 |
| 8 | + |
| 9 | +def shift_image(input_img, dx, dy): |
| 10 | + img = np.roll(input_img, dy, axis=0) |
| 11 | + img = np.roll(img, dx, axis=1) |
| 12 | + if dy>0: |
| 13 | + img[:dy, :] = 0 |
| 14 | + elif dy<0: |
| 15 | + img[dy:, :] = 0 |
| 16 | + if dx>0: |
| 17 | + img[:, :dx] = 0 |
| 18 | + elif dx<0: |
| 19 | + img[:, dx:] = 0 |
| 20 | + return img |
| 21 | + |
| 22 | +class Hologram: |
| 23 | + def __init__(self, *args, **kwargs): |
| 24 | + pass |
| 25 | + |
| 26 | + def apply(self, *args, **kwargs): |
| 27 | + frame = kwargs['frame'].astype(np.uint8) |
| 28 | + frame[:,:,:3] = cv2.applyColorMap(frame[:,:,:3], cv2.COLORMAP_WINTER) |
| 29 | + frame[:,:,:3] = cv2.cvtColor(frame[:,:,:3], cv2.COLOR_BGR2RGB) |
| 30 | + # add a halftone effect |
| 31 | + bandLength, bandGap = 2, 3 |
| 32 | + for y in range(frame.shape[0]): |
| 33 | + if y % (bandLength+bandGap) < bandLength: |
| 34 | + frame[y,:,:3] = frame[y,:,:3] * np.random.uniform(0.1, 0.3) |
| 35 | + # add some ghosting |
| 36 | + holo_blur = cv2.addWeighted(frame[:,:,:3], 0.2, |
| 37 | + shift_image(frame[:,:,:3], 5, 5), 0.8, 0) |
| 38 | + holo_blur = cv2.addWeighted(holo_blur, 0.4, |
| 39 | + shift_image(frame[:,:,:3], -5, -5), 0.6, 0) |
| 40 | + # combine with the original color, oversaturated |
| 41 | + frame[:,:,:3] = cv2.addWeighted(frame[:,:,:3], 0.5, holo_blur, 0.6, 0) |
| 42 | + return frame.astype(np.float) |
| 43 | + |
| 44 | + |
| 45 | +filters.register_filter("hologram", Hologram) |
0 commit comments