From b69591deed975583d5659c9e96bc16edc990a683 Mon Sep 17 00:00:00 2001 From: raccoonliukai <903896015@qq.com> Date: Fri, 27 Sep 2019 17:04:28 +0800 Subject: [PATCH 1/4] fix(shotdetect): fix shot boundary --- gnes/preprocessor/helper.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gnes/preprocessor/helper.py b/gnes/preprocessor/helper.py index 2badba2f..69a7a2b3 100644 --- a/gnes/preprocessor/helper.py +++ b/gnes/preprocessor/helper.py @@ -319,7 +319,7 @@ def kmeans_algo(distances: List[float], **kwargs) -> List[int]: shots.append(0) for i in range(0, len(clt.labels_)): if big_center == clt.labels_[i]: - shots.append((i + 2)) + shots.append((i + 1)) if shots[-1] < num_frames: shots.append(num_frames) else: @@ -356,18 +356,18 @@ def motion_algo(distances: List[float], **kwargs) -> List[int]: arg_dict.update(kwargs) shots = [] - num_frames = len(distances) + 1 + num_frames = len(distances) + 2 * 2 + 1 p = peakutils.indexes(np.array(distances).astype('float32'), thres=arg_dict['threshold'], min_dist=arg_dict['min_dist']) if len(distances) else [] if len(p) == 0: return [0, num_frames] shots.append(0) - shots.append(p[0] + 2) + shots.append(p[0] + 2 + 1) for i in range(1, len(p)): # We check that the peak is not due to a motion in the image valid_dist = arg_dict['motion_step'] or not check_motion(distances[p[i]-arg_dict['motion_step']:p[i]], distances[p[i]]) if valid_dist: - shots.append(p[i] + 2) + shots.append(p[i] + 2 + 1) if shots[-1] < num_frames - arg_dict['min_dist']: shots.append(num_frames) elif shots[-1] > num_frames: From a6d1484ed2778f058186a5b4c4c648674382890f Mon Sep 17 00:00:00 2001 From: raccoonliukai <903896015@qq.com> Date: Fri, 27 Sep 2019 17:06:03 +0800 Subject: [PATCH 2/4] fix(shotdetect): fix bug with thre_algo --- gnes/preprocessor/helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnes/preprocessor/helper.py b/gnes/preprocessor/helper.py index 69a7a2b3..373d3ac7 100644 --- a/gnes/preprocessor/helper.py +++ b/gnes/preprocessor/helper.py @@ -365,7 +365,7 @@ def motion_algo(distances: List[float], **kwargs) -> List[int]: shots.append(p[0] + 2 + 1) for i in range(1, len(p)): # We check that the peak is not due to a motion in the image - valid_dist = arg_dict['motion_step'] or not check_motion(distances[p[i]-arg_dict['motion_step']:p[i]], distances[p[i]]) + valid_dist = not arg_dict['motion_step'] or not check_motion(distances[p[i]-arg_dict['motion_step']:p[i]], distances[p[i]]) if valid_dist: shots.append(p[i] + 2 + 1) if shots[-1] < num_frames - arg_dict['min_dist']: From 17aa78da2a395ca17099c23b03b796a3be9928f2 Mon Sep 17 00:00:00 2001 From: raccoonliukai <903896015@qq.com> Date: Fri, 27 Sep 2019 17:18:00 +0800 Subject: [PATCH 3/4] fix(shotdetect): fix bug with thre_algo after histcmp --- gnes/preprocessor/helper.py | 7 ++++--- gnes/preprocessor/video/shotdetect.py | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/gnes/preprocessor/helper.py b/gnes/preprocessor/helper.py index 373d3ac7..71cbf1d8 100644 --- a/gnes/preprocessor/helper.py +++ b/gnes/preprocessor/helper.py @@ -354,20 +354,21 @@ def motion_algo(distances: List[float], **kwargs) -> List[int]: 'motion_step': 15 } arg_dict.update(kwargs) + neigh_avg = kwargs.get('neigh_avg', 2) shots = [] - num_frames = len(distances) + 2 * 2 + 1 + num_frames = len(distances) + 2 * neigh_avg + 1 p = peakutils.indexes(np.array(distances).astype('float32'), thres=arg_dict['threshold'], min_dist=arg_dict['min_dist']) if len(distances) else [] if len(p) == 0: return [0, num_frames] shots.append(0) - shots.append(p[0] + 2 + 1) + shots.append(p[0] + neigh_avg + 1) for i in range(1, len(p)): # We check that the peak is not due to a motion in the image valid_dist = not arg_dict['motion_step'] or not check_motion(distances[p[i]-arg_dict['motion_step']:p[i]], distances[p[i]]) if valid_dist: - shots.append(p[i] + 2 + 1) + shots.append(p[i] + neigh_avg + 1) if shots[-1] < num_frames - arg_dict['min_dist']: shots.append(num_frames) elif shots[-1] > num_frames: diff --git a/gnes/preprocessor/video/shotdetect.py b/gnes/preprocessor/video/shotdetect.py index 1fd6bec4..1da422f4 100644 --- a/gnes/preprocessor/video/shotdetect.py +++ b/gnes/preprocessor/video/shotdetect.py @@ -63,8 +63,9 @@ def detect_shots(self, frames: 'np.ndarray') -> List[List['np.ndarray']]: compare_descriptor(pair[0], pair[1], self.distance_metric) for pair in zip(descriptors[:-1], descriptors[1:]) ] + self._detector_kwargs['neigh_avg'] = 0 - shot_bounds = detect_peak_boundary(dists, self.detect_method) + shot_bounds = detect_peak_boundary(dists, self.detect_method, **self._detector_kwargs) shots = [] for ci in range(0, len(shot_bounds) - 1): From ca73b7020d0bbef1c109b1fe78c95759a3fa258c Mon Sep 17 00:00:00 2001 From: raccoonliukai <903896015@qq.com> Date: Fri, 27 Sep 2019 17:43:30 +0800 Subject: [PATCH 4/4] fix(shotdetect): support get arguments from yaml --- gnes/preprocessor/helper.py | 34 ++++++++++++--------------- gnes/preprocessor/video/shotdetect.py | 2 +- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/gnes/preprocessor/helper.py b/gnes/preprocessor/helper.py index 71cbf1d8..0cec1116 100644 --- a/gnes/preprocessor/helper.py +++ b/gnes/preprocessor/helper.py @@ -215,21 +215,17 @@ def hsv_histogram(image: 'np.ndarray') -> 'np.ndarray': def canny_edge(image: 'np.ndarray', **kwargs) -> 'np.ndarray': import cv2 - arg_dict = { - 'sigma': 0.5, - 'gauss_kernel': (9, 9), - 'l2_gradient': True - } - arg_dict.update(kwargs) + sigma = kwargs.get('sigma', 0.5) + gauss_kernel = kwargs.get('gauss_kernel', (9, 9)) + l2_gradient = kwargs.get('l2_gradient', True) image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # apply automatic Canny edge detection using the computed median v = np.median(image) - sigma = arg_dict['sigma'] low_threshold = ((1.0 - sigma) * v).astype("float32") high_threshold = ((1.0 + sigma) * v).astype("float32") - tmp_image = cv2.GaussianBlur(image, arg_dict['gauss_kernel'], 1.2) - edge_image = cv2.Canny(tmp_image, low_threshold, high_threshold, L2gradient=arg_dict['l2_gradient']) + tmp_image = cv2.GaussianBlur(image, gauss_kernel, 1.2) + edge_image = cv2.Canny(tmp_image, low_threshold, high_threshold, L2gradient=l2_gradient) return edge_image @@ -256,10 +252,12 @@ def compute_descriptor(image: 'np.ndarray', return funcs[method](image) -def compare_ecr(descriptors: List['np.ndarray'], dilate_rate: int = 5, neigh_avg: int = 2) -> List[float]: +def compare_ecr(descriptors: List['np.ndarray'], **kwargs) -> List[float]: import cv2 """ Apply the Edge Change Ratio Algorithm""" + dilate_rate = kwargs.get('dilate_rate', 5) + neigh_avg = kwargs.get('neigh_avg', 2) divd = lambda x, y: 0 if y == 0 else x / y dicts = [] @@ -348,17 +346,15 @@ def thre_algo(distances: List[float], **kwargs) -> List[int]: def motion_algo(distances: List[float], **kwargs) -> List[int]: import peakutils - arg_dict = { - 'threshold': 0.6, - 'min_dist': 10, - 'motion_step': 15 - } - arg_dict.update(kwargs) + + threshold = kwargs.get('threshold', 0.6) + min_dist = kwargs.get('min_dist', 10) + motion_step = kwargs.get('motion_step', 15) neigh_avg = kwargs.get('neigh_avg', 2) shots = [] num_frames = len(distances) + 2 * neigh_avg + 1 - p = peakutils.indexes(np.array(distances).astype('float32'), thres=arg_dict['threshold'], min_dist=arg_dict['min_dist']) if len(distances) else [] + p = peakutils.indexes(np.array(distances).astype('float32'), thres=threshold, min_dist=min_dist) if len(distances) else [] if len(p) == 0: return [0, num_frames] @@ -366,10 +362,10 @@ def motion_algo(distances: List[float], **kwargs) -> List[int]: shots.append(p[0] + neigh_avg + 1) for i in range(1, len(p)): # We check that the peak is not due to a motion in the image - valid_dist = not arg_dict['motion_step'] or not check_motion(distances[p[i]-arg_dict['motion_step']:p[i]], distances[p[i]]) + valid_dist = not motion_step or not check_motion(distances[p[i]-motion_step:p[i]], distances[p[i]]) if valid_dist: shots.append(p[i] + neigh_avg + 1) - if shots[-1] < num_frames - arg_dict['min_dist']: + if shots[-1] < num_frames - min_dist: shots.append(num_frames) elif shots[-1] > num_frames: shots[-1] = num_frames diff --git a/gnes/preprocessor/video/shotdetect.py b/gnes/preprocessor/video/shotdetect.py index 1da422f4..01b30e41 100644 --- a/gnes/preprocessor/video/shotdetect.py +++ b/gnes/preprocessor/video/shotdetect.py @@ -57,7 +57,7 @@ def detect_shots(self, frames: 'np.ndarray') -> List[List['np.ndarray']]: # compute distances between frames if self.distance_metric == 'edge_change_ration': - dists = compare_ecr(descriptors) + dists = compare_ecr(descriptors, **self._detector_kwargs) else: dists = [ compare_descriptor(pair[0], pair[1], self.distance_metric)