File size: 3,567 Bytes
8f76218
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
"""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()