示例#1
0
    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_default():
    # --- classify ---
    cl = SVMClassifier()
    cl.load(CUTTER_RESULT_DIR)
    cl.train()
    cl.save_model(MODEL_PATH, overwrite=True)
    cl.classify(VIDEO_PATH, boost_mode=False)
示例#3
0
def _classify(
    video: typing.Union[str, VideoObject],
    data_home: str = None,
    model: str = None,
    # optional: these args below are sent for `cutter`
    compress_rate: float = 0.2,
    target_size: typing.Tuple[int, int] = None,
    limit_range: typing.List[VideoCutRange] = None,
) -> ClassifierResult:
    """
    classify a video with some tagged pictures
    optional: if you have changed the default value in `cut`, you'd better keep them(offset and limit) equal.

    :param video: video path or object
    :param data_home: output path (dir)
    :param model: LinearSVC model (path)
    :param compress_rate: before_pic * compress_rate = after_pic. default to 0.2
    :param target_size: (100, 200)
    :param limit_range:

    :return: typing.List[ClassifierResult]
    """
    if isinstance(video, str):
        video = VideoObject(video)

    assert data_home or model, "classification should based on dataset or trained model"
    cl = SVMClassifier(compress_rate=compress_rate, target_size=target_size)

    if model:
        cl.load_model(model)
    else:
        cl.load(data_home)
        cl.train()
    return cl.classify(video, limit_range=limit_range)
示例#4
0
def test_hook():
    # init hook
    hook = ExampleHook()
    hook1 = ExampleHook(overwrite=True)
    hook2 = IgnoreHook(size=(0.5, 0.5), overwrite=True)
    frame_home = os.path.join(PROJECT_PATH, 'frame_save_dir')
    hook3 = FrameSaveHook(frame_home)
    hook4 = CropHook(
        size=(0.5, 0.5),
        offset=(0., 0.5),
        overwrite=True,
    )
    hook5 = RefineHook()
    hook6 = InvalidFrameDetectHook()
    hook7 = TemplateCompareHook({
        'amazon': IMAGE_PATH,
    })

    # --- cutter ---
    cutter = VideoCutter(compress_rate=0.8)
    # add hook
    cutter.add_hook(hook)
    cutter.add_hook(hook1)
    cutter.add_hook(hook2)
    cutter.add_hook(hook3)
    cutter.add_hook(hook4)
    cutter.add_hook(hook5)
    cutter.add_hook(hook6)
    cutter.add_hook(hook7)

    res = cutter.cut(VIDEO_PATH)
    stable, unstable = res.get_range()
    assert len(stable) == 2, 'count of stable range is not correct'

    data_home = res.pick_and_save(
        stable,
        5,
    )
    assert os.path.isdir(data_home), 'result dir not existed'

    # --- classify ---
    cl = SVMClassifier()
    cl.load(data_home)
    cl.train()
    classify_result = cl.classify(VIDEO_PATH, stable)

    # --- draw ---
    r = Reporter()
    report_path = os.path.join(data_home, 'report.html')
    r.draw(
        classify_result,
        report_path=report_path,
        cut_result=res,
    )
    assert os.path.isfile(report_path)

    # hook check
    assert os.path.isdir(frame_home)
    assert hook6.result
    assert hook7.result
示例#5
0
def test_save_and_load():
    # test save and load
    cl = SVMClassifier()
    cl.load_model(MODEL_PATH)
    classify_result = cl.classify(VIDEO_PATH)

    # --- draw ---
    _draw_report(classify_result)
def test_work_with_cutter():
    cl = SVMClassifier()
    cl.load_model(MODEL_PATH)
    stable, _ = cutter_res.get_range()
    classify_result = cl.classify(VIDEO_PATH, stable)

    # --- draw ---
    _draw_report(classify_result)
def test_keep_data():
    cl = SVMClassifier()
    cl.load_model(MODEL_PATH)
    stable, _ = cutter_res.get_range()
    classify_result = cl.classify(VIDEO_PATH, stable, keep_data=True)

    # todo findit bug here
    image_object = toolbox.imread(IMAGE_PATH)[0:20, 0:20]
    assert classify_result.data[0].contain_image(image_object=image_object)
示例#8
0
文件: cli.py 项目: testerLr/stagesepx
    def one_step(self,
                 video_path: str,
                 output_path: str = None,
                 threshold: float = 0.95,
                 frame_count: int = 5,
                 compress_rate: float = 0.2,
                 offset: int = 3,
                 limit: int = None):
        """
        one step => cut, classifier, draw

        :param video_path: your video path
        :param output_path: output path (dir)
        :param threshold: float, 0-1, default to 0.95. decided whether a range is stable. larger => more unstable ranges
        :param frame_count: default to 5, and finally you will get 5 frames for each range
        :param compress_rate: before_pic * compress_rate = after_pic. default to 0.2
        :param offset:
            it will change the way to decided whether two ranges can be merged
            before: first_range.end == second_range.start
            after: first_range.end + offset >= secord_range.start
        :param limit: ignore some ranges which are too short, 5 means ignore stable ranges which length < 5
        :return:
        """

        # --- cutter ---
        cutter = VideoCutter()
        res = cutter.cut(video_path, compress_rate=compress_rate)
        stable, unstable = res.get_range(
            threshold=threshold,
            limit=limit,
            offset=offset,
        )

        data_home = res.pick_and_save(stable, frame_count, to_dir=output_path)
        res_json_path = os.path.join(data_home, 'cut_result.json')
        res.dump(res_json_path)

        # --- classify ---
        cl = SVMClassifier(compress_rate=compress_rate)
        cl.load(data_home)
        cl.train()
        classify_result = cl.classify(video_path, stable)

        # --- draw ---
        r = Reporter()
        r.draw(
            classify_result,
            report_path=os.path.join(data_home, 'report.html'),
            cut_result=res,

            # kwargs of get_range
            # otherwise these thumbnails may become different
            threshold=threshold,
            limit=limit,
            offset=offset,
        )
示例#9
0
def test_result():
    cl = SVMClassifier()
    cl.load_model(MODEL_PATH)
    stable, _ = cutter_res.get_range()
    classify_result = cl.classify(VIDEO_PATH, stable, keep_data=True)

    assert classify_result.to_dict()
    classify_result.mark_range(1, 3, "0")
    classify_result.mark_range_unstable(1, 3)
    classify_result.get_important_frame_list()
示例#10
0
def test_default():
    # --- classify ---
    cl = SVMClassifier()
    cl.load(CUTTER_RESULT_DIR)
    cl.train()
    cl.save_model(MODEL_PATH, overwrite=True)
    classify_result = cl.classify(VIDEO_PATH)

    # --- draw ---
    _draw_report(classify_result)
def test_dump_and_load():
    cl = SVMClassifier()
    cl.load_model(MODEL_PATH)
    classify_result = cl.classify(VIDEO_PATH, boost_mode=False)

    json_path = "classify_result.json"
    classify_result.dump(json_path)

    res_from_file = ClassifierResult.load(json_path)
    assert classify_result.dumps() == res_from_file.dumps()
示例#12
0
def test_save_and_load():
    cl = SVMClassifier()
    cl.load_model(MODEL_PATH)
    classify_result = cl.classify(VIDEO_PATH)

    result_file = "save.json"
    reporter = Reporter()
    reporter.save(result_file, classify_result)
    assert os.path.isfile(result_file)
    classify_result_after = Reporter.load(result_file)

    assert len(classify_result) == len(classify_result_after)
    for i, j in zip(classify_result, classify_result_after):
        assert i.to_dict() == j.to_dict()
示例#13
0
def test_result():
    cl = SVMClassifier()
    cl.load_model(MODEL_PATH)
    stable, _ = cutter_res.get_range()
    classify_result = cl.classify(VIDEO_PATH, stable, keep_data=True)

    assert classify_result.to_dict()
    classify_result.mark_range(1, 3, "0")
    classify_result.mark_range_unstable(1, 3)
    classify_result.get_important_frame_list()
    classify_result.get_stage_range()
    classify_result.get_specific_stage_range("0")
    classify_result.get_not_stable_stage_range()
    assert classify_result.first("1").frame_id == 20
    assert classify_result.last("1").frame_id == 21
def test_hook():
    # init hook
    hook = ExampleHook()
    hook1 = ExampleHook()
    hook2 = IgnoreHook(size=(0.5, 0.5))
    frame_home = os.path.join(PROJECT_PATH, "frame_save_dir")
    hook3 = FrameSaveHook(frame_home)
    hook4 = CropHook(size=(0.5, 0.5), offset=(0.0, 0.5))
    hook5 = RefineHook()
    hook6 = InterestPointHook()
    hook7 = TemplateCompareHook({"amazon": IMAGE_PATH})

    # --- cutter ---
    cutter = VideoCutter(compress_rate=0.9)
    # add hook
    cutter.add_hook(hook)
    cutter.add_hook(hook1)
    cutter.add_hook(hook2)
    cutter.add_hook(hook3)
    cutter.add_hook(hook4)
    cutter.add_hook(hook5)
    cutter.add_hook(hook6)
    cutter.add_hook(hook7)

    res = cutter.cut(VIDEO_PATH)
    stable, unstable = res.get_range()
    assert len(stable) == 2, "count of stable range is not correct"

    data_home = res.pick_and_save(stable, 5)
    assert os.path.isdir(data_home), "result dir not existed"

    # --- classify ---
    cl = SVMClassifier()
    cl.load(data_home)
    cl.train()
    classify_result = cl.classify(VIDEO_PATH, stable)

    # --- draw ---
    r = Reporter()
    report_path = os.path.join(data_home, "report.html")
    r.draw(classify_result, report_path=report_path, cut_result=res)
    assert os.path.isfile(report_path)

    # hook check
    assert os.path.isdir(frame_home)
    assert hook6.result
    assert hook7.result
示例#15
0
    def one_step(self,
                 video_path: str,
                 output_path: str = None,
                 threshold: float = 0.95,
                 frame_count: int = 5,
                 compress_rate: float = 0.2,
                 limit: int = None):
        """
        one step => cut, classifier, draw

        :param video_path: your video path
        :param output_path: output path (dir)
        :param threshold: float, 0-1, default to 0.95. decided whether a range is stable. larger => more unstable ranges
        :param frame_count: default to 5, and finally you will get 5 frames for each range
        :param compress_rate: before_pic * compress_rate = after_pic. default to 0.2
        :param limit: ignore some ranges which are too short, 5 means ignore stable ranges which length < 5
        :return:
        """

        # --- cutter ---
        cutter = VideoCutter()
        res = cutter.cut(video_path, compress_rate=compress_rate)
        stable, unstable = res.get_range(
            threshold=threshold,
            limit=limit,
        )

        data_home = res.pick_and_save(stable, frame_count, to_dir=output_path)
        res_json_path = os.path.join(data_home, 'cut_result.json')
        res.dump(res_json_path)

        # --- classify ---
        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(data_home, 'report.html'),
            cut_result=res,
        )
def test_save_and_load():
    cl = SVMClassifier()
    cl.load_model(MODEL_PATH)
    classify_result = cl.classify(VIDEO_PATH, boost_mode=False)

    result_file = "save.json"
    reporter = Reporter()
    reporter.add_extra("some_name", "some_value")
    reporter.save(result_file, classify_result)
    assert os.path.isfile(result_file)
    classify_result_after = Reporter.load(result_file)

    assert classify_result.get_length() == classify_result_after.get_length()
    for i, j in zip(classify_result.data, classify_result_after.data):
        assert i.to_dict() == j.to_dict()

    assert isinstance(reporter.get_stable_stage_sample(classify_result),
                      np.ndarray)
示例#17
0
def classify(
    video: typing.Union[str, VideoObject],
    data_home: str = None,
    model: str = None,
    # optional: these args below are sent for `cutter`
    compress_rate: float = 0.2,
    target_size: typing.Tuple[int, int] = None,
    offset: int = 3,
    limit: int = None,
    threshold: float = 0.95,
) -> ClassifierResult:
    """
    classify a video with some tagged pictures
    optional: if you have changed the default value in `cut`, you'd better keep them(offset and limit) equal.

    :param video: video path or object
    :param data_home: output path (dir)
    :param model: LinearSVC model (path)
    :param compress_rate: before_pic * compress_rate = after_pic. default to 0.2
    :param target_size: (100, 200)
    :param offset:
        it will change the way to decided whether two ranges can be merged
        before: first_range.end == second_range.start
        after: first_range.end + offset >= secord_range.start
    :param limit: ignore some ranges which are too short, 5 means ignore stable ranges which length < 5
    :param threshold: cutter threshold

    :return: typing.List[ClassifierResult]
    """
    if isinstance(video, str):
        video = VideoObject(video)

    assert data_home or model, "classification should based on dataset or trained model"
    cl = SVMClassifier(compress_rate=compress_rate, target_size=target_size)

    if model:
        cl.load_model(model)
    else:
        cl.load(data_home)
        cl.train()
    # re cut
    cut_result, _ = cut(video, compress_rate=compress_rate, threshold=threshold)
    stable, _ = cut_result.get_range(offset=offset, limit=limit)
    return cl.classify(video, stable)
示例#18
0
def calculate_result(_cl, _SVM_or_Keras, _param, _from_movie_2_picture,
                     _model_file, _video_path_for_forecast):

    if _SVM_or_Keras == '1\n':
        print('使用SVM进行预测')
        cl = SVMClassifier(
            # 默认情况下使用 HoG 进行特征提取。你可以将其关闭从而直接对原始图片进行训练与测试:feature_type='raw'
            feature_type="hog",
            # 默认为0.2,即将图片缩放为0.2倍。主要为了提高计算效率,如果你担心影响分析效果,可以将其提高
            compress_rate=_param[0],
        )
        # 加载待训练数据
        cl.load_model(_model_file)
    elif _SVM_or_Keras == '2\n':
        # 分析视频_聚类
        print('使用KerasClassifier进行预测')
        cl = KerasClassifier(
            compress_rate=_param[0],
            # 在使用时需要保证数据集格式统一(与训练集)。因为 train_model.py 用了 600x800,所以这里设定成一样的
            # target_size=(600, 800),
        )
        cl.load_model(_model_file)

    # 开始预测
    _forecast_result = []

    # 获取forecast文件夹的mp4文件列表
    forecast_video_list = public_fun.get_mp4file_name(_video_path_for_forecast)

    for i in forecast_video_list:
        # 分析视频_切割视频
        stable = get_data.get_range('forecast', i, _param,
                                    _from_movie_2_picture)
        classify_result = cl.classify(i, stable, keep_data=True)
        result_dict = classify_result.to_dict()

        _forecast_result.append(
            public_fun.write_result_to_local(i, _from_movie_2_picture,
                                             result_dict, classify_result))
        # _forecast_result = [['5.mp4', '3.161888888888889', '1',
        # '4.155888888888889', '1', '8.040888888888889', '1']]

    return _forecast_result
示例#19
0
def _train(
    data_home: str,
    save_to: str,
    compress_rate: float = 0.2,
    target_size: typing.Tuple[int, int] = None,
):
    """
    build a trained model with a dataset

    :param data_home: output path (dir)
    :param save_to: model will be saved to this path
    :param compress_rate: before_pic * compress_rate = after_pic. default to 0.2
    :param target_size: (100, 200)
    """
    assert os.path.isdir(data_home), f"dir {data_home} not existed"
    assert not os.path.isfile(save_to), f"file {save_to} already existed"
    cl = SVMClassifier(compress_rate=compress_rate, target_size=target_size)
    cl.load(data_home)
    cl.train()
    cl.save_model(save_to)
示例#20
0
def train_model_SVM(_train_picture_path, _model_file_name):
    cl = SVMClassifier(
        # 默认情况下使用 HoG 进行特征提取
        # 你可以将其关闭从而直接对原始图片进行训练与测试:feature_type='raw'
        feature_type="hog",
        # 默认为0.2,即将图片缩放为0.2倍
        # 主要为了提高计算效率
        # 如果你担心影响分析效果,可以将其提高
        compress_rate=0.2,
        # 或者直接指定尺寸
        # 当压缩率与指定尺寸同时传入时,优先以指定尺寸为准
        # target_size=(200, 400),
    )

    # 加载待训练数据
    cl.load(_train_picture_path)
    # 在加载数据完成之后需要先训练
    cl.train()
    cl.save_model(_model_file_name, overwrite=True)

    return cl
示例#21
0
def analyse(
    video: typing.Union[str, VideoObject],
    output_path: str,
    pre_load: bool = True,
    threshold: float = 0.98,
    offset: int = 3,
    boost_mode: bool = True,
):
    """ designed for https://github.com/williamfzc/stagesepx/issues/123 """

    if isinstance(video, str):
        video = VideoObject(video, pre_load=pre_load)

    cutter = VideoCutter()
    res = cutter.cut(video)

    stable, unstable = res.get_range(
        threshold=threshold,
        offset=offset,
    )

    with tempfile.TemporaryDirectory() as temp_dir:
        res.pick_and_save(
            stable,
            5,
            to_dir=temp_dir,
        )

        cl = SVMClassifier()
        cl.load(temp_dir)
        cl.train()
        classify_result = cl.classify(video, stable, boost_mode=boost_mode)

    r = Reporter()
    r.draw(
        classify_result,
        report_path=output_path,
        unstable_ranges=unstable,
        cut_result=res,
    )
示例#22
0
def test_result():
    cl = SVMClassifier()
    cl.load_model(MODEL_PATH)
    stable, _ = cutter_res.get_range()
    classify_result = cl.classify(VIDEO_PATH, stable, keep_data=True)

    assert classify_result.to_dict()
    classify_result.mark_range(1, 3, "0")
    classify_result.mark_range_unstable(1, 3)
    classify_result.get_important_frame_list()
    classify_result.get_stage_range()
    classify_result.get_specific_stage_range("0")
    classify_result.get_not_stable_stage_range()
    classify_result.mark_range_ignore(23, 24)
    classify_result.time_cost_between("0", "1")
    assert classify_result.contain("1")
    assert classify_result.first("1").frame_id == 20
    assert classify_result.last("1").frame_id == 21
    assert classify_result.is_order_correct(["0", "0", "1", "2"])
    assert classify_result.is_order_correct(["0", "0", "2"])
    assert classify_result.is_order_correct(["0", "1"])
    assert classify_result.is_order_correct(["0", "2"])
    assert classify_result.is_order_correct(["1", "2"])
示例#23
0
    def handle(self, video_path: str) -> bool:
        super(NormalHandler, self).handle(video_path)
        video = VideoObject(video_path)
        if self.preload:
            video.load_frames()

        # --- cutter ---
        cutter = VideoCutter()
        res = cutter.cut(video)
        stable, unstable = res.get_range(threshold=0.98, offset=3)
        data_home = res.pick_and_save(stable,
                                      self.frame_count,
                                      to_dir=self.result_path)

        # --- classify ---
        cl = SVMClassifier()
        cl.load(data_home)
        cl.train()
        self.classifier_result = cl.classify(video, stable)

        # --- draw ---
        r = Reporter()
        r.draw(self.classifier_result, report_path=self.result_report_path)
        return True
示例#24
0
def run(config: typing.Union[dict, str]):
    """
    run with config

    :param config: config file path, or a preload dict
    :return:
    """
    class _VideoUserConfig(BaseModel):
        path: str
        pre_load: bool = True
        fps: int = None

    class _CutterUserConfig(BaseModel):
        threshold: float = None
        frame_count: int = None
        offset: int = None
        limit: int = None
        block: int = None

        # common
        compress_rate: float = None
        target_size: typing.Tuple[int, int] = None

    class _ClassifierType(Enum):
        SVM = "svm"
        KERAS = "keras"

    class _ClassifierUserConfig(BaseModel):
        boost_mode: bool = None
        classifier_type: _ClassifierType = _ClassifierType.SVM
        model: str = None

        # common
        compress_rate: float = None
        target_size: typing.Tuple[int, int] = None

    class _CalcOperatorType(Enum):
        BETWEEN = "between"
        DISPLAY = "display"

    class _CalcOperator(BaseModel):
        name: str
        calc_type: _CalcOperatorType
        args: dict = dict()

    class _CalcUserConfig(BaseModel):
        output: str = None
        ignore_error: bool = None
        operators: typing.List[_CalcOperator] = None

    class _ExtraUserConfig(BaseModel):
        save_train_set: str = None

    class UserConfig(BaseModel):
        output: str
        video: _VideoUserConfig
        cutter: _CutterUserConfig = _CutterUserConfig()
        classifier: _ClassifierUserConfig = _ClassifierUserConfig()
        calc: _CalcUserConfig = _CalcUserConfig()
        extras: _ExtraUserConfig = _ExtraUserConfig()

    if isinstance(config, str):
        # path
        config_path = pathlib.Path(config)
        assert config_path.is_file(), f"no config file found in {config_path}"

        # todo: support different types in the future
        assert config_path.as_posix().endswith(
            ".json"), "config file should be json format"
        with open(config_path, encoding=constants.CHARSET) as f:
            config = json.load(f)

    config = UserConfig(**config)
    logger.info(f"config: {config}")

    # main flow
    video = VideoObject(
        # fmt: off
        path=config.video.path,
        fps=config.video.fps,
    )
    if config.video.pre_load:
        video.load_frames()

    # cut
    cutter = VideoCutter(
        # fmt: off
        compress_rate=config.cutter.compress_rate,
        target_size=config.cutter.target_size,
    )
    res = cutter.cut(
        # fmt: off
        video=video,
        block=config.cutter.block,
    )
    stable, unstable = res.get_range(
        # fmt: off
        threshold=config.cutter.threshold,
        offset=config.cutter.offset,
    )

    with tempfile.TemporaryDirectory() as temp_dir:
        # classify
        if config.classifier.classifier_type is _ClassifierType.SVM:
            cl = SVMClassifier(
                # fmt: off
                compress_rate=config.classifier.compress_rate,
                target_size=config.classifier.target_size,
            )
        elif config.classifier.classifier_type is _ClassifierType.KERAS:
            from stagesepx.classifier.keras import KerasClassifier

            cl = KerasClassifier(
                # fmt: off
                compress_rate=config.classifier.compress_rate,
                target_size=config.classifier.target_size,
            )
        # validation has been applied by pydantic
        # so no `else`

        if config.classifier.model:
            # no need to retrain
            model_path = pathlib.Path(config.classifier.model)
            assert model_path.is_file(), f"file {model_path} not existed"
            cl.load_model(model_path)
        else:
            # train a new model
            train_set_dir = config.extras.save_train_set or temp_dir
            os.makedirs(train_set_dir, exist_ok=True)

            res.pick_and_save(
                # fmt: off
                stable,
                frame_count=config.cutter.frame_count,
                to_dir=train_set_dir,
            )
            cl.train(data_path=train_set_dir)

    # start classifying
    classify_result = cl.classify(
        # fmt: off
        video,
        stable,
        boost_mode=config.classifier.boost_mode,
    )

    # calc
    def _calc_display() -> dict:
        # jsonify
        return json.loads(classify_result.dumps())

    def _calc_between(*, from_stage: str = None, to_stage: str = None) -> dict:
        assert classify_result.contain(
            from_stage), f"no stage {from_stage} found in result"
        assert classify_result.contain(
            to_stage), f"no stage {to_stage} found in result"
        from_frame = classify_result.last(from_stage)
        to_frame = classify_result.first(to_stage)
        cost = to_frame.timestamp - from_frame.timestamp
        return {
            "from": from_frame.frame_id,
            "to": to_frame.frame_id,
            "cost": cost,
        }

    _calc_func_dict = {
        _CalcOperatorType.BETWEEN: _calc_between,
        _CalcOperatorType.DISPLAY: _calc_display,
    }
    calc_output = config.calc.output
    if calc_output:
        output_path = pathlib.Path(calc_output)
        assert not output_path.is_file(), f"file {output_path} already existed"
        result = []
        for each_calc in config.calc.operators:
            func = _calc_func_dict[each_calc.calc_type]
            try:
                func_ret = func(**each_calc.args)
            except Exception as e:
                if not config.calc.ignore_error:
                    raise
                logger.warning(e)
                func_ret = traceback.format_exc()
            calc_ret = {
                "name": each_calc.name,
                "type": each_calc.calc_type.value,
                "result": func_ret,
            }
            result.append(calc_ret)
        with open(output_path, "w", encoding=constants.CHARSET) as f:
            json.dump(result, f)

    # draw
    r = Reporter()
    r.draw(
        # fmt: off
        classify_result,
        report_path=config.output,
    )
示例#25
0
def test_boost():
    cl = SVMClassifier()
    cl.load_model(MODEL_PATH)
    classify_result = cl.classify(VIDEO_PATH, boost_mode=True)
    assert classify_result
示例#26
0
    # 采样结果保存的位置
    # 不指定的话则会在当前位置生成文件夹并返回它的路径
    # './cut_result',
    # prune被用于去除重复阶段(>=0.4.4)
    # float(0-1.0),设置为0.9时,如果两个stage相似度超过0.9,他们会合并成一个类别
    prune=None,
)

# --- classify ---

cl = SVMClassifier(
    # 默认情况下使用 HoG 进行特征提取
    # 你可以将其关闭从而直接对原始图片进行训练与测试:feature_type='raw'
    feature_type="hog",
    # 默认为0.2,即将图片缩放为0.2倍
    # 主要为了提高计算效率
    # 如果你担心影响分析效果,可以将其提高
    compress_rate=0.2,
    # 或者直接指定尺寸
    # 当压缩率与指定尺寸同时传入时,优先以指定尺寸为准
    # target_size=(200, 400),
)

# 加载数据
cl.load(data_home)
# 在加载数据完成之后需要先训练
cl.train()
# 在训练后你可以把模型保存起来
# cl.save_model('model.pkl')
# 或者直接读取已经训练好的模型
# cl.load_model('model.pkl')
示例#27
0
stable, _ = res.get_range()

# 检查最后一个阶段中是否包含图片 person.png
# 这种做法会在阶段中间取一帧进行模板匹配
# 当然,这种做法并不常用,最常用还是用于检测最终结果而不是中间量
# 值得注意,这里的模板匹配会受到压缩率的影响
# 虽然已经做了分辨率拟合,但是如果压缩率过高,依旧会出现图像难以辨认而导致的误判
# 正常来说没什么问题
match_result = stable[-1].contain_image(amazon_image_path,
                                        engine_template_scale=(0.5, 2, 5))
print(match_result)
# 分别输出:最可能存在的坐标、相似度、计算是否正常完成
# {'target_point': [550, 915], 'target_sim': 0.9867244362831116, 'ok': True}

data_home = res.pick_and_save(stable, 5)
cl = SVMClassifier()
cl.load(data_home)
cl.train()
classify_result = cl.classify(video_path, stable, keep_data=True)
result_dict = classify_result.to_dict()

final_result: dict = {}

for each_stage, each_frame_list in result_dict.items():
    # 你可以通过对这些阶段进行目标检测,以确认他们符合你的预期
    # 注意,如阶段名称为负数,意味着这个阶段是处在变化中,非稳定
    # 例如,检测每一个阶段的中间帧是否包含特定图片
    middle_id: int = int((len(each_frame_list) - 1) / 2)

    # 分别检测 amazon.png 与 phone.png (这两张是手动选出来的标志物)
    amazon_image_res = each_frame_list[middle_id].contain_image(
示例#28
0
from stagesepx.cutter import VideoCutter
from stagesepx.classifier import SVMClassifier
from stagesepx.reporter import Reporter
from stagesepx.video import VideoObject


video_path = "../videos/long.mp4"
video = VideoObject(video_path)
video.load_frames()

# --- cutter ---
cutter = VideoCutter()
res = cutter.cut(video)
stable, unstable = res.get_range()
data_home = res.pick_and_save(stable, 5)

# --- classify ---
cl = SVMClassifier(compress_rate=0.4)
cl.load(data_home)
cl.train()
classify_result = cl.classify(video, stable, keep_data=True)
result_dict = classify_result.to_dict()

# --- draw ---
r = Reporter()
r.draw(classify_result)
示例#29
0
from stagesepx.classifier import SVMClassifier
from stagesepx.reporter import Reporter

# 默认情况下使用 HoG 进行特征提取
# 你可以将其关闭从而直接对原始图片进行训练与测试:feature_type='raw'
cl = SVMClassifier(feature_type='hog')

# 基本与SSIM分类器的流程一致
# 但它对数据的要求可能有所差别,具体参见 cut.py 中的描述
data_home = './cut_result'
cl.load(data_home)

# 在加载数据完成之后需要先训练
cl.train()

# # 在训练后你可以把模型保存起来
# cl.save_model('model.pkl')
# # 或者直接读取已经训练好的模型
# cl.load_model('model.pkl')

# 开始分类
res = cl.classify(
    '../test.mp4',
    # 步长,可以自行设置用于平衡效率与颗粒度
    # 默认为1,即每帧都检测
    step=1,
)

# 为了更方便的可读性,stagesepx已经内置了图表绘制功能
# 你可以直接把分析结果绘制成图表
report = Reporter()
示例#30
0
    # 采样结果保存的位置
    # 不指定的话则会在当前位置生成文件夹并返回它的路径
    # './cut_result',

    # prune被用于去除重复阶段(>=0.4.4)
    # float(0-1.0),设置为0.9时,如果两个stage相似度超过0.9,他们会合并成一个类别
    prune=None,
)

# --- classify ---

cl = SVMClassifier(
    # 默认情况下使用 HoG 进行特征提取
    # 你可以将其关闭从而直接对原始图片进行训练与测试:feature_type='raw'
    feature_type='hog',
    # 默认为0.2,即将图片缩放为0.2倍
    # 主要为了提高计算效率
    # 如果你担心影响分析效果,可以将其提高
    compress_rate=0.2,
)

# 加载数据
cl.load(data_home)
# 在加载数据完成之后需要先训练
cl.train()
# 在训练后你可以把模型保存起来
# cl.save_model('model.pkl')
# 或者直接读取已经训练好的模型
# cl.load_model('model.pkl')

# 注意,如果在classify方法指定了范围