marketing-campaign / videostream.py
analytics-jiten's picture
Upload 5 files
8f76218
"""The VideoStreamInterface provides an easy way to apply transforms to a video stream"""
import numpy as np
import panel as pn
import param
import skimage
from PIL import Image, ImageFilter
from skimage import data, filters
from skimage.color.adapt_rgb import adapt_rgb, each_channel
from skimage.draw import rectangle
from skimage.exposure import rescale_intensity
from skimage.feature import Cascade
from videostream_utils import PILImageTransform, NumpyImageTransform, VideoStreamInterface
pn.extension("terminal", sizing_mode="stretch_width")
ACCENT = "#fef3c7"
class GaussianBlur(PILImageTransform):
"""Gaussian Blur
https://pillow.readthedocs.io/en/stable/reference/ImageFilter.html#PIL.ImageFilter.GaussianBlur
"""
radius = param.Integer(default=2, bounds=(0, 10))
def transform(self, image: Image):
return image.filter(ImageFilter.GaussianBlur(radius=self.radius))
class GrayscaleTransform(NumpyImageTransform):
"""GrayScale transform
https://scikit-image.org/docs/0.15.x/auto_examples/color_exposure/plot_rgb_to_gray.html
"""
def transform(self, image: np.ndarray):
grayscale = skimage.color.rgb2gray(image[:, :, :3])
return skimage.color.gray2rgb(grayscale)
class SobelTransform(NumpyImageTransform):
"""Sobel Transform
https://scikit-image.org/docs/0.15.x/auto_examples/color_exposure/plot_adapt_rgb.html
"""
def transform(self, image):
@adapt_rgb(each_channel)
def sobel_each(image):
return filters.sobel(image)
return rescale_intensity(1 - sobel_each(image))
@pn.cache()
def get_detector():
"""Returns the Cascade detector"""
trained_file = data.lbp_frontal_face_cascade_filename()
return Cascade(trained_file)
class FaceDetectionTransform(NumpyImageTransform):
"""Face detection using a cascade classifier.
https://scikit-image.org/docs/0.15.x/auto_examples/applications/plot_face_detection.html
"""
scale_factor = param.Number(1.4, bounds=(1.0, 2.0), step=0.1)
step_ratio = param.Integer(1, bounds=(1, 10))
size_x = param.Range(default=(60, 322), bounds=(10, 500))
size_y = param.Range(default=(60, 322), bounds=(10, 500))
def transform(self, image):
detector = get_detector()
detected = detector.detect_multi_scale(
img=image,
scale_factor=self.scale_factor,
step_ratio=self.step_ratio,
min_size=(self.size_x[0], self.size_y[0]),
max_size=(self.size_x[1], self.size_y[1]),
)
for patch in detected:
rrr, ccc = rectangle(
start=(patch["r"], patch["c"]),
extent=(patch["height"], patch["width"]),
shape=image.shape[:2],
)
image[rrr, ccc, 0] = 200
return image
component = VideoStreamInterface(
transforms=[
GaussianBlur,
GrayscaleTransform,
SobelTransform,
FaceDetectionTransform,
]
)
component.video_stream.timeout=1000
component.video_stream.param.timeout.bounds=(250, 2000)
pn.template.FastListTemplate(
site="Awesome Panel 🤗",
title="VideoStream with transforms",
sidebar=[component.settings],
main=[
"""Try a much, much faster version <a href="https://sharing.awesome-panel.org/MarcSkovMadsen/videostream-interface/app.html" target="_blank">here</a> powered by Webassembly.""",
component],
favicon="https://sharing.awesome-panel.org/favicon.ico",
accent=ACCENT,
header_color="#4b5563"
).servable()