def draw(self, data_list: typing.List[ClassifierResult], report_path: str = None, cut_result: VideoCutResult = None): """ draw report file :param data_list: classifierResult list, output of classifier :param report_path: your report will be there :param cut_result: more charts would be built :return: """ # draw line = self._draw_line(data_list) bar = self._draw_bar(data_list) # merge charts page = Page() page.add(line) page.add(bar) if cut_result: sim_line = self._draw_sim(cut_result) page.add(sim_line) # insert thumbnail if not self.thumbnail_list: logger.debug('auto insert thumbnail ...') _, unstable = cut_result.get_range() for each in unstable: self.add_thumbnail( f'{each.start}({each.start_time}) - {each.end}({each.end_time})', cut_result.thumbnail(each), ) # insert extras template = Template(TEMPLATE) template_content = template.render( chart=Markup(page.render_embed()), dir_link_list=self.dir_link_list, thumbnail_list=self.thumbnail_list, extras=self.extra_dict, ) # save to file if not report_path: report_path = f'{toolbox.get_timestamp_str()}.html' with open(report_path, "w") as fh: fh.write(template_content) logger.info(f'save report to {report_path}')
def classify(self, video_path: str, data_home: str, output_path: str = None, compress_rate: float = 0.2, limit: int = None): # TODO model? cut_result_json = os.path.join(data_home, 'cut_result.json') res = None stable = None if os.path.isfile(cut_result_json): res = VideoCutResult.load(cut_result_json) stable, _ = res.get_range(limit=limit) cl = SVMClassifier(compress_rate=compress_rate) cl.load(data_home) cl.train() classify_result = cl.classify(video_path, stable) # --- draw --- r = Reporter() r.add_dir_link(data_home) r.draw( classify_result, report_path=os.path.join(output_path or data_home, 'report.html'), cut_result=res, )
def test_dump_and_load(): cutter = VideoCutter() res = cutter.cut(VIDEO_PATH) json_path = "cutter_result.json" res.dump(json_path) res_from_file = VideoCutResult.load(json_path) assert res.dumps() == res_from_file.dumps()
def draw( self, data_list: typing.List[ClassifierResult], report_path: str = None, cut_result: VideoCutResult = None, language: str = None, *args, **kwargs, ): """ draw report file :param data_list: classifierResult list, output of classifier :param report_path: your report will be there :param cut_result: more charts would be built :param language: 'en' or 'zh' :return: """ # draw line = self._draw_line(data_list) bar = self._draw_bar(data_list) # merge charts page = Page() page.add(line) page.add(bar) # calc time cost cost_dict = DataUtils.calc_changing_cost(data_list) # insert pictures if cut_result: # sim chart sim_line = self._draw_sim(cut_result) page.add(sim_line) _, unstable = cut_result.get_range(*args, **kwargs) # insert thumbnail if not self.thumbnail_list: logger.debug("auto insert thumbnail ...") for each in unstable: self.add_thumbnail( f"{each.start}({each.start_time}) - {each.end}({each.end_time}), " f"duration: {each.end_time - each.start_time}", cut_result.thumbnail(each, *args, **kwargs), ) # insert stable frames stable_stage_sample = self.get_stable_stage_sample(data_list, compress_rate=0.2) stable_stage_sample = toolbox.np2b64str(stable_stage_sample) # time stamp timestamp = toolbox.get_timestamp_str() # insert extras # default: zh_cn report if not language: language = "zh" template = Template(get_template(language)) template_content = template.render( chart=Markup(page.render_embed()), dir_link_list=self.dir_link_list, thumbnail_list=self.thumbnail_list, stable_sample=stable_stage_sample, extras=self.extra_dict, background_color=BACKGROUND_COLOR, cost_dict=cost_dict, timestamp=timestamp, version_code=__VERSION__, ) # save to file if not report_path: report_path = f"{timestamp}.html" with open(report_path, "w", encoding=constants.CHARSET) as fh: fh.write(template_content) logger.info(f"save report to {report_path}")
# 开始切割 res = cutter.cut( video_path, # block 能够对每帧进行切割并分别进行比较,计算出更加敏感的ssim值 # 默认为2,即切为4宫格;若为4,即切为16宫格,以此类推;为1即不做切割,全图比较 # 值得注意,如果无法整除,block是会报错的 block=2, ) # 你可以将你的cutter结果保存起来,供其他时刻使用(>=0.4.4) cut_result = res.dumps() # 或直接保存成json文件 # res.dump('./YOUR_RES.json') # 在你想要使用时,使用loads读取即可 res = VideoCutResult.loads(cut_result) # 或直接从文件读取 # res = VideoCutResult.load('./YOUR_RES.json') # 你可以通过res获取切割结果,获取稳定状态与活动状态分别对应的区间 stable, unstable = res.get_range( # 判定阶段是否稳定的阈值 # 越高则越严格(判定为稳定的区间更少) # 默认为 0.95 (0-1) threshold=0.95, # 利用 psnr 进行增强型的检测 # 0.5.3加入的特性,默认关闭(float,0-1) # 设定后,它将对被认为stable的区间进行二次检测 # 例如,设定为0.5时,稳定区间的条件将变为: # ssim > 0.95 and psnr > 0.5 # 详见 https://github.com/williamfzc/stagesepx/issues/38
def draw(self, data_list: typing.List[ClassifierResult], report_path: str = None, cut_result: VideoCutResult = None, *args, **kwargs): """ draw report file :param data_list: classifierResult list, output of classifier :param report_path: your report will be there :param cut_result: more charts would be built :return: """ # draw line = self._draw_line(data_list) bar = self._draw_bar(data_list) # merge charts page = Page() page.add(line) page.add(bar) # calc time cost cost_dict = DataUtils.calc_changing_cost(data_list) # insert pictures if cut_result: # sim chart sim_line = self._draw_sim(cut_result) page.add(sim_line) _, unstable = cut_result.get_range(*args, **kwargs) # insert thumbnail if not self.thumbnail_list: logger.debug('auto insert thumbnail ...') for each in unstable: self.add_thumbnail( f'{each.start}({each.start_time}) - {each.end}({each.end_time}), ' f'duration: {each.end_time - each.start_time}', cut_result.thumbnail(each, *args, **kwargs), ) # insert stable frames stable_stage_sample = self.get_stable_stage_sample(data_list, compress_rate=0.2) stable_stage_sample = toolbox.np2b64str(stable_stage_sample) # insert extras template = Template(TEMPLATE) template_content = template.render( chart=Markup(page.render_embed()), dir_link_list=self.dir_link_list, thumbnail_list=self.thumbnail_list, stable_sample=stable_stage_sample, extras=self.extra_dict, background_color=BACKGROUND_COLOR, cost_dict=cost_dict, ) # save to file if not report_path: report_path = f'{toolbox.get_timestamp_str()}.html' with open(report_path, "w") as fh: fh.write(template_content) logger.info(f'save report to {report_path}')