Package: limbus
Limbus: Computer Vision pipelining for PyTorchSimilar to the eyecorneal limbus-Limbusis a framework to create Computer Vision pipelines within the context of Deep Learning and writen in terms of differentiable tensors message passing on top of Kornia and PyTorch.OverviewYou can create pipelines usinglimbus.Components as follows:# define your componentsc1=Constant("c1",1.)c2=Constant("c2",torch.ones(1,3))add=Adder("add")show=Printer("print")# connect the componentsc1.outputs.out>>add.inputs.ac2.outputs.out>>add.inputs.badd.outputs.out>>show.inputs.inp# create the pipeline and add its nodespipeline=Pipeline()pipeline.add_nodes([c1,c2,add,show])# run your pipelinepipeline.run(1)torch.allclose(add.outputs.out.value,torch.ones(1,3)*2.)Example using thestacktorch method:# define your componentsc1=Constant("c1",0)t1=Constant("t1",torch.ones(1,3))t2=Constant("t2",torch.ones(1,3)*2)stack=Stack("stack")show=Printer("print")# connect the componentsc1.outputs.out>>stack.inputs.dimt1.outputs.out>>stack.inputs.tensors.select(0)t2.outputs.out>>stack.inputs.tensors.select(1)stack.outputs.out>>show.inputs.inp# create the pipeline and add its nodespipeline=Pipeline()pipeline.add_nodes([c1,t1,t2,stack,show])# run your pipelinepipeline.run(1)torch.allclose(stack.outputs.out.value,torch.tensor([[1.,1.,1.],[2.,2.,2.]]))Remember that the components can be run without thePipeline, e.g in the last example you can also run:asyncio.run(asyncio.gather(c1(),t1(),t2(),stack(),show()))Basically,Pipelineobjects allow you to control the execution flow, e.g. you can stop, pause, resume the execution, determine the number of executions to be run...A higher level API on top ofPipelineisAppallowing to encapsulate some code. E.g.:classMyApp(App):defcreate_components(self):self.c1=Constant("c1",0)self.t1=Constant("t1",torch.ones(1,3))self.t2=Constant("t2",torch.ones(1,3)*2)self.stack=stack("stack")self.show=Printer("print")defconnect_components(self):self.c1.outputs.out>>self.stack.inputs.dimself.t1.outputs.out>>self.stack.inputs.tensors.select(0)self.t2.outputs.out>>self.stack.inputs.tensors.select(1)self.stack.outputs.out>>self.show.inputs.inpMyApp().run(1)Component definitionCreating your own components is pretty easy, you just need to inherit fromlimbus.Componentand implement some methods (see some examples inexamples/defining_cmps.py).TheComponentclass has the next main methods:__init__: where you can add class parameters to your component.register_inputs: where you need to declare the input pins of your component.register_outputs: where you need to declare the output pins of your component.register_properties: where you can declare properties that can be changed during the execution.forward: where you must define the logic of your component (mandatory).For a detailed list ofComponentmethods and attributes, please checklimbus/core/component.py.Notethat if you want intellisense (at least inVSCodeyou will need to define theinputandoutputtypes).Let's see a very simple example that sums 2 integers:classAdd(Component):"""Add two numbers."""# NOTE: type definition is optional, but it helps with the intellisense. ;)classInputsTyping(InputParams):a:InputParamb:InputParamclassOutputsTyping(OutputParams):out:OutputParaminputs:InputsTypingoutputs:OutputsTyping@staticmethoddefregister_inputs(inputs:InputParams)->None:# Here you need to declare the input parameters and their default values (if they have).inputs.declare("a",int)inputs.declare("b",int)@staticmethoddefregister_outputs(outputs:OutputParams)->None:# Here you need to declare the output parameters.outputs.declare("out",int)asyncdefforward(self)->ComponentState:# Here you must to define the logic of your component.a,b=awaitasyncio.gather(self.inputs.a.receive(),self.inputs.b.receive())awaitself.outputs.out.send(a+b)returnComponentState.OKNotethatComponentcan inherint fromnn.Module. By default inherints fromobject.To change the inheritance, before importing any otherlimbusmodule, set theCOMPONENT_TYPEvariable as:fromlimbus_configimportconfigconfig.COMPONENT_TYPE="torch"EcosystemLimbus is a core technology to easily build different components and create generic pipelines. In the following list, you can find different examples
about how to use Limbus with some first/third party projects containing components:Official examples:Basic pipeline generation:https://github.com/kornia/limbus/blob/main/examples/default_cmps.pyDefine custom components:https://github.com/kornia/limbus/blob/main/examples/defining_cmps.pyCreate a web camera application:https://github.com/kornia/limbus/blob/main/examples/defining_cmps.pyOfficial repository with a set of basic components:https://github.com/kornia/limbus-componentsExample combining limbus and the farm-ng Amiga:https://github.com/edgarriba/amiga-limbus-examplesExample implementing a Kornia face detection pipeline:https://github.com/edgarriba/limbus-face-detectorInstallationfrom PyPI:pipinstalllimbus# limbus alone# orpipinstalllimbus[components]# limbus + some predefined componentsNote that to use widgets you need to install their dependencies:pipinstalllimbus[widgets]from the repository:pipinstalllimbus@git+https://git@github.com/kornia/limbus.git# limbus alone# orpipinstalllimbus[components]@git+https://git@github.com/kornia/limbus.git# limbus + some predefined componentsfor developmentyou can install the environment with the following commands:gitclonehttps://github.com/kornia/limbuscdlimbussourcepath.bash.incIn order to regenerate the development environment:cdlimbus
rm-rf.dev_envsourcepath.bash.incTestingRunpytestand automatically will test:cov,pydocstyle,mypyandflake8