File size: 5,277 Bytes
d015578
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import os
import cv2
import copy
import time
import numpy as np

# Demo libs
import spiga.demo.visualize.plotter as plt


class Viewer:

    def __init__(self, window_title, width=None, height=None, fps=30):
        """
        Initialization of the viewer canvas using width and height in pixels
        :param window_title: The string with the window title to display.
        :param width: The given width in pixels of the window canvas.
        :param height: The given height in pixels of the window canvas.
        :param fps: Frames per second
        """
        # Visualizer parameters
        self.canvas = None
        self.width = width
        self.height = height
        self.window_title = window_title
        self.visualize = False

        # Time variables
        self.fps = fps
        self.fps_inference = 0
        self.fps_mean = 0
        self.fps_lifo = np.zeros(self.fps)
        self.timer = time.time()
        self.frame_cnt = -1

        # Video/Image writer
        self.write = False
        self.video_name = window_title  # Initial name
        self.video_path = None
        self.video_writer = None

        # Plots
        self.plotter = plt.Plotter()
        self.fps_draw_params = {'text_size': 0.75,
                                'text_thick': 2,
                                'coord': (10, 50),
                                'font': cv2.FONT_HERSHEY_SIMPLEX,
                                'color': (255, 255, 255)}

    def start_view(self):
        self._kill_window()
        cv2.namedWindow(self.window_title)
        self.visualize = True

    def record_video(self, video_path, video_name=None):
        self.write = True
        if video_name is not None:
            self.video_name = video_name
        self.video_path = video_path
        if not os.path.exists(video_path):
            os.makedirs(video_path)

        file_name = os.path.join(self.video_path, self.video_name + '.mp4')
        self.video_writer = cv2.VideoWriter(file_name, cv2.VideoWriter_fourcc(*'MP4V'),
                                            self.fps, (int(self.width), int(self.height)))

    def save_canvas(self, file_path=None):
        if file_path is None:
            if self.video_path is None:
                raise ValueError('Path not defined neither video_path is available')
            else:
                file_path = self.video_path

        file_name = os.path.join(file_path, '/%s_%i.jpg' % (self.video_name, self.frame_cnt))
        cv2.imwrite(file_path + file_name, self.canvas)

    def reset_params(self, width, height, window_title, fps=30):
        self.width = width
        self.height = height
        self._kill_window()
        if self.video_name == self.window_title:
            self.video_name = window_title
        self.window_title = window_title
        self.fps = fps

    def close(self):
        if self.write:
            self.video_writer.release()
        self._kill_window()

    def process_image(self, input_img, drawers=(), show_attributes=('fps')):

        # Variables
        image = copy.copy(input_img)
        img_h, img_w, img_ch = image.shape

        # Convert gray scale image to color if needed
        if img_ch == 1:
            image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)

        # Draw features on image
        image = self._draw_over_canvas(image, drawers, show_attributes)

        # Resize image if needed to canvas shape
        if img_w != self.width or img_h != self.height:
            image = cv2.resize(image, (self.width, self.height))

        # Update canvas
        self.canvas = image
        # Visualize FPS
        if 'fps' in show_attributes:
            self._plot_fps()

        # Write the resulting frame
        if self.write:
            self.video_writer.write(self.canvas)

        # Timing loop variables
        loop_time = self._update_timers()
        break_flag = False
        # Visualization
        if self.visualize:
            cv2.imshow(self.window_title, self.canvas)
            sleep_time = int(1000 * (1 / self.fps - loop_time))
            if sleep_time <= 0:
                sleep_time = 1
            if cv2.waitKey(sleep_time) & 0xFF == ord('q'):
                break_flag = True

        self.timer = time.time()
        return break_flag

    def _plot_fps(self):
        # Plot algorithm time
        params = self.fps_draw_params
        cv2.putText(self.canvas, ('FPS: %.2f' % self.fps_mean), params['coord'], params['font'], params['text_size'],
                    params['color'], params['text_thick'], cv2.LINE_AA)

    def _draw_over_canvas(self, image, drawers, show_attributes):
        for drawer in drawers:
            image = drawer.plot_features(image, self.plotter, show_attributes)
        return image

    def _kill_window(self):
        self.visualize = False
        try:
            cv2.destroyWindow(self.window_title)
        except:
            pass

    def _update_timers(self):
        self.frame_cnt += 1
        loop_time = time.time() - self.timer
        self.fps_inference = 1/loop_time
        lifo_idx = self.frame_cnt % self.fps
        self.fps_lifo[lifo_idx] = self.fps_inference
        if lifo_idx == 0:
            self.fps_mean = np.mean(self.fps_lifo)
        return loop_time