def test_pipeline_execution_order(order_asserter_operator): pipeline = CompVizPipeline() pipeline.add_operator('op1', order_asserter_operator(0)) pipeline.add_operator('op2', order_asserter_operator(1)) pipeline.add_operator('op3', order_asserter_operator(2)) pipeline.run(build_img((16, 16)))
def test_rename_keeps_operators_order(self, order_asserter_operator): pipeline = CompVizPipeline() pipeline.add_operator('op1', order_asserter_operator(0)) pipeline.add_operator('op2', order_asserter_operator(1)) pipeline.add_operator('op3', order_asserter_operator(2)) pipeline.rename_operator('op2', 'new_name') pipeline.run(build_img((16, 16)))
def test_set_ctx_original_img(self, img): class TestCtxOriginalImgOperator(Operator): def run(self, img_: Image, ctx: PipelineContext) -> Image: assert np.all(ctx.original_img == img_) return img_ pipeline = CompVizPipeline() pipeline.add_operator('test_op', TestCtxOriginalImgOperator()) pipeline.run(img)
def test_operator_fail(): class FailingOperator(Operator): def run(self, img: Image, ctx: PipelineContext) -> Image: raise ValueError('Failed') pipeline = CompVizPipeline() pipeline.add_operator('op', FailingOperator()) with pytest.raises(OperatorFailedError): pipeline.run(build_img((16, 16)))
def test_check_op_return(self, return_value): class TestWrongReturnOperator(Operator): def run(self, img: np.ndarray, ctx: PipelineContext) -> Any: return return_value pipeline = CompVizPipeline() pipeline.add_operator('test_op', TestWrongReturnOperator()) with pytest.raises(BadImageError) as e: pipeline.run(build_img((16, 16))) assert_terms_in_exception(e, ['return', 'invalid'])
def test_gray_only_flag(self): @settings.GRAY_ONLY(True) class TestOnlyGrayFlagOperator(Operator): def run(self, img: Image, ctx: PipelineContext) -> Image: return img pipeline = CompVizPipeline() pipeline.add_operator('test_op', TestOnlyGrayFlagOperator()) with pytest.raises(OperatorFailedError) as e: pipeline.run(build_img((16, 16), rgb=True)) assert_terms_in_exception(e, ["expect", "gray"])
def test_operator_cant_alter_original_img(self): class TestCtxOriginalImg(Operator): def run(self, img: Image, ctx: PipelineContext) -> Image: original_img = ctx.original_img original_img[10, ...] = 255 return img pipeline = CompVizPipeline() pipeline.add_operator('test_op', TestCtxOriginalImg()) test_img = build_img((128, 128), kind='black') with pytest.raises(OperatorFailedError) as e: pipeline.run(test_img) assert_terms_in_exception(e, ['read-only'])
def test_parameters(self): input_img = build_img((16, 16)) reference_img = build_img((36, 36)) class ReferenceImgOperator(Operator): def run(self, img: Image, ctx: PipelineContext) -> Image: return reference_img reference_operator = ReferenceImgOperator() class TestHook(PipelineHook): def before_operator(self, operator: Operator, img: Image, ctx: PipelineContext): assert img is input_img assert operator is reference_operator def after_operator(self, operator: Operator, img: Image, ctx: PipelineContext): assert img is reference_img assert operator is reference_operator def after_pipeline(self, img: Image, ctx: PipelineContext): assert img is reference_img hook = TestHook() pipeline = CompVizPipeline() pipeline.add_operator('test', reference_operator) _ = pipeline.run(input_img, hooks=[hook])
def test_add_info_works(self): info_name = 'info_name' info_value = object() class TestCtxAddInfo(Operator): def run(self, img: Image, ctx: PipelineContext) -> Image: ctx.add_info(info_name, info_value) return img pipeline = CompVizPipeline() op_name1 = 'test_op1' pipeline.add_operator(op_name1, TestCtxAddInfo()) op_name2 = 'test_op2' pipeline.add_operator(op_name2, TestCtxAddInfo()) _, returned_ctx = pipeline.run(build_img((16, 16))) expected_info = { op_name1: { info_name: info_value }, op_name2: { info_name: info_value } } actual_info = returned_ctx.info assert actual_info == expected_info
class EzCVController(QObject): show_media = pyqtSignal(Image) operators_changed = pyqtSignal() operators_updated = pyqtSignal() operator_failed = pyqtSignal(OperatorFailedError) loading_failed = pyqtSignal(ConfigParsingError) def __init__(self): super().__init__() self.cvpipeline = CompVizPipeline() self.curr_media: Optional[Image] = None self._names_generator = _OperatorNameGenerator() self.operators_changed.connect(self._on_operators_changed) self.operators_updated.connect(self._on_operators_updated) def add_operator(self, operator_cls: Type[Operator]): operator = operator_cls() operator_name = self._names_generator.generate_name(operator_cls) self.cvpipeline.add_operator(operator_name, operator) self.operators_changed.emit() def process_curr_media(self): if self.curr_media is not None: try: result_img, ctx = self.cvpipeline.run(self.curr_media) self.show_media.emit(result_img) except OperatorFailedError as e: self.operator_failed.emit(e) self.show_media.emit(self.curr_media) def update_operator(self, name: str, param_name: str, param_value: Any): setattr(self.operators[name], param_name, param_value) self.operators_updated.emit() def load_media(self, fname: str): img = cv2.imread(fname) if img is None: raise ValueError("Couldn't open image located at %s" % fname) self.curr_media = img self.process_curr_media() def load_config(self, fname: str): with open(fname, 'r') as fin: try: self.cvpipeline = CompVizPipeline.load(fin) self.operators_changed.emit() except ConfigParsingError as e: self.loading_failed.emit(e) @property def operators(self): return self.cvpipeline.operators def _on_operators_changed(self): self.process_curr_media() def _on_operators_updated(self): self.process_curr_media()
def test_invalid_img(self, img): pipeline = CompVizPipeline() with pytest.raises(BadImageError) as e: pipeline.run(img) assert_terms_in_exception(e, ['invalid', 'image'])