|
19 | 19 | from datetime import datetime |
20 | 20 | from funscript_editor.data.ffmpegstream import FFmpegStream, VideoInfo |
21 | 21 | from funscript_editor.algorithms.kalmanfilter import KalmanFilter2D |
| 22 | +from scipy.interpolate import interp1d |
22 | 23 |
|
23 | 24 | import funscript_editor.algorithms.signalprocessing as sp |
24 | 25 | import numpy as np |
@@ -222,12 +223,47 @@ def append_interpolated_bbox(self, bbox :tuple, target: str) -> None: |
222 | 223 | target (str): the target where to save the interpolated tracking boxes |
223 | 224 | """ |
224 | 225 | if self.params.skip_frames > 0 and len(self.bboxes[target]) > 0: |
225 | | - for i in range(1, self.params.skip_frames+1): |
226 | | - x0 = np.interp(i, [0, self.params.skip_frames+1], [self.bboxes[target][-1][0], bbox[0]]) |
227 | | - y0 = np.interp(i, [0, self.params.skip_frames+1], [self.bboxes[target][-1][1], bbox[1]]) |
228 | | - w = np.interp(i, [0, self.params.skip_frames+1], [self.bboxes[target][-1][2], bbox[2]]) |
229 | | - h = np.interp(i, [0, self.params.skip_frames+1], [self.bboxes[target][-1][3], bbox[3]]) |
230 | | - self.bboxes[target].append((x0, y0, w, h)) |
| 226 | + back_in_time = 2 |
| 227 | + if len(self.bboxes[target]) < (self.params.skip_frames+1)*back_in_time: |
| 228 | + for i in range(1, self.params.skip_frames+1): |
| 229 | + # use linear interpolation for the first steps |
| 230 | + x0 = np.interp(i, [0, self.params.skip_frames+1], [self.bboxes[target][-1][0], bbox[0]]) |
| 231 | + y0 = np.interp(i, [0, self.params.skip_frames+1], [self.bboxes[target][-1][1], bbox[1]]) |
| 232 | + w = np.interp(i, [0, self.params.skip_frames+1], [self.bboxes[target][-1][2], bbox[2]]) |
| 233 | + h = np.interp(i, [0, self.params.skip_frames+1], [self.bboxes[target][-1][3], bbox[3]]) |
| 234 | + self.bboxes[target].append((x0, y0, w, h)) |
| 235 | + else: |
| 236 | + # switch to quadratic interpolation as soon as there is enough data for interpolation |
| 237 | + x = [-1*(self.params.skip_frames+1)*back_in_time + x + 1 for x in range((self.params.skip_frames+1)*back_in_time)] \ |
| 238 | + + [self.params.skip_frames+1] |
| 239 | + |
| 240 | + fx0 = interp1d( |
| 241 | + x, |
| 242 | + [item[0] for item in self.bboxes[target][-1*(self.params.skip_frames+1)*back_in_time:]] + [bbox[0]], |
| 243 | + kind = 'quadratic' |
| 244 | + ) |
| 245 | + |
| 246 | + fy0 = interp1d( |
| 247 | + x, |
| 248 | + [item[1] for item in self.bboxes[target][-1*(self.params.skip_frames+1)*back_in_time:]] + [bbox[1]], |
| 249 | + kind = 'quadratic' |
| 250 | + ) |
| 251 | + |
| 252 | + fw = interp1d( |
| 253 | + x, |
| 254 | + [item[2] for item in self.bboxes[target][-1*(self.params.skip_frames+1)*back_in_time:]] + [bbox[2]], |
| 255 | + kind = 'quadratic' |
| 256 | + ) |
| 257 | + |
| 258 | + fh = interp1d( |
| 259 | + x, |
| 260 | + [item[3] for item in self.bboxes[target][-1*(self.params.skip_frames+1)*back_in_time:]] + [bbox[3]], |
| 261 | + kind = 'quadratic' |
| 262 | + ) |
| 263 | + |
| 264 | + for i in range(1, self.params.skip_frames+1): |
| 265 | + self.bboxes[target].append((fx0(i), fy0(i), fw(i), fh(i))) |
| 266 | + |
231 | 267 | self.bboxes[target].append(bbox) |
232 | 268 |
|
233 | 269 |
|
@@ -929,5 +965,10 @@ def run(self) -> None: |
929 | 965 | return |
930 | 966 |
|
931 | 967 | idx_dict = self.determin_change_points() |
| 968 | + |
| 969 | + idx_list = [x for k in ['min', 'max'] for x in idx_dict[k]] |
| 970 | + idx_list.sort() |
| 971 | + self.plot_y_score('debug.png', idx_list) |
| 972 | + |
932 | 973 | self.create_funscript(idx_dict) |
933 | 974 | self.finished(status, True) |
0 commit comments