1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[96],{2659:function(e,s,t){(window.__NEXT_P=window.__NEXT_P||[]).push(["/v1/getting-started",function(){return t(3325)}])},9369:function(e,s,t){"use strict";var n=t(5893);t(7294);var o=t(5675),i=t.n(o),a=t(3750),r=t(1163),l=t(2681);let c={logo:(0,n.jsxs)("span",{style:{display:"flex",alignItems:"center"},children:[(0,n.jsx)(i(),{alt:"logo",width:30,height:30,src:"/docs/logo-400x400-rounded.png"}),"\xa0",(0,n.jsx)("b",{children:"Pipeless"})]}),logoLink:"https://pipeless.ai",primaryHue:297,project:{link:"https://github.com/pipeless-ai/pipeless"},chat:{link:"https://discord.gg/K2qxQ8uedG",icon:(0,n.jsx)(a.KpZ,{size:25})},docsRepositoryBase:"https://github.com/pipeless-ai/docs/tree/main",footer:{text:(0,n.jsx)("p",{children:"Copyright \xa9 2023 Pipeless, Inc."})},search:{loading:"Loading..."},head:()=>{let{asPath:e,defaultLocale:s,locale:t}=(0,r.useRouter)(),{frontMatter:o}=(0,l.ZR)(),i="https://www.pipeless.ai"+(s===t?e:"/".concat(t).concat(e));return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("meta",{property:"og:url",content:i}),(0,n.jsx)("meta",{property:"og:title",content:o.title||"Pipeless Documentation"}),(0,n.jsx)("meta",{property:"og:description",content:o.description||"Documentation about Pipeless, the computer vision framework"}),(0,n.jsx)("meta",{property:"og:image",content:"https://www.pipeless.ai/docs/logo-400x400-rounded.png"})]})},useNextSeoProps:()=>({titleTemplate:"%s â Pipeless"}),banner:{dismissible:!1,key:"agents",text:(0,n.jsx)("a",{target:"blank",href:"https://agents.pipeless.ai",children:(0,n.jsxs)("p",{children:["\uD83D\uDE80 \xa0\xa0",(0,n.jsx)("b",{children:"Pipeless Agents is live!"}),"\xa0Create vision powered apps and automations effortlessly within seconds.\xa0",(0,n.jsx)("span",{style:{textDecoration:"underline"},children:"Click here to get started!"})]})})},sidebar:{defaultMenuCollapseLevel:1}};s.Z=c},3325:function(e,s,t){"use strict";t.r(s),t.d(s,{__toc:function(){return c}});var n=t(5893),o=t(2673),i=t(2681),a=t(9369);t(9966);var r=t(2643),l=t(9013);let c=[{depth:2,value:"Pipeless basic concepts",id:"pipeless-basic-concepts"},{depth:2,value:"Create a new project",id:"create-a-new-project"},{depth:2,value:"Creating a new stage",id:"creating-a-new-stage"},{depth:3,value:"Stage context",id:"stage-context"},{depth:2,value:"Writting hooks",id:"writting-hooks"},{depth:3,value:"Implementing a code hook",id:"implementing-a-code-hook"},{depth:3,value:"Inference Runtime - JSON hooks",id:"inference-runtime---json-hooks"},{depth:3,value:"Frame data fields",id:"frame-data-fields"},{depth:3,value:"Stateless vs Stateful hooks",id:"stateless-vs-stateful-hooks"}];function d(e){let s=Object.assign({h1:"h1",p:"p",a:"a",h2:"h2",strong:"strong",pre:"pre",code:"code",span:"span",h3:"h3",ul:"ul",li:"li"},(0,r.a)(),e.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{children:"Getting Started with Pipeless \uD83D\uDE80"}),"\n",(0,n.jsxs)(s.p,{children:["Make sure to have Pipeless and its dependencies installed before continuing. Check the ",(0,n.jsx)(s.a,{href:"/v1/getting-started/installation",children:"installation guide"}),"."]}),"\n","\n",(0,n.jsx)(s.h2,{id:"pipeless-basic-concepts",children:"Pipeless basic concepts"}),"\n",(0,n.jsxs)(s.p,{children:["A Pipeless project is structured in ",(0,n.jsx)(s.strong,{children:"stages"}),". Each stage is a like a box that performs a very specific\ntask. You can think about a stage like a micro pipeline. Within each stage you can implement pre-processing,\nprocessing and post-processing, as well as run models."]}),"\n",(0,n.jsxs)(s.p,{children:['When you provide a new stream to Pipeless, you have to specify a sorted list of stages. We call that list\nthe "',(0,n.jsx)(s.strong,{children:"frame execution path"}),'" or just the ',(0,n.jsx)(s.strong,{children:"frame path"}),", and it represents the whole pipeline that the\nframes of that stream will go through. Execution paths are run in parallel for all frames, no matter which\nstream the frame belongs to. A single stage can be used in as many streams as you need."]}),"\n",(0,n.jsxs)(s.p,{children:["A Pipeless project consists of ",(0,n.jsx)(s.strong,{children:"at least"})," one stage. So your project will be a directory where each\nsub-directory defines a stage."]}),"\n",(0,n.jsxs)(s.p,{children:["Within each stage folder you create the files that define your Pipeless ",(0,n.jsx)(s.strong,{children:"hooks"}),". Each hook represents a\nprocessing step in the stage micro pipeline (i.e. pre-processing, processing or post-processing). All of them\nare optional and you can implement them in ",(0,n.jsx)(s.strong,{children:"several programming languages"}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["Finally, each stage is isolated from the others. Every hook of a stage receives a structure that contains\n",(0,n.jsx)(s.a,{href:"#frame-data-fields",children:"several fields"}),', we usually call it the "frame data". You can perform changes on the\nframe data fields (some of them are read-only). Next hooks of the stage or the hooks of a following stage\nwill have access to the modified data. Ideally, you should design your stages so that they are self-contained\nand do not depend on other stages data.']}),"\n",(0,n.jsx)(s.h2,{id:"create-a-new-project",children:"Create a new project"}),"\n",(0,n.jsx)(s.p,{children:"Run the following command:"}),"\n",(0,n.jsx)(s.pre,{"data-language":"bash","data-theme":"default",hasCopyCode:!0,children:(0,n.jsxs)(s.code,{"data-language":"bash","data-theme":"default",children:[(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"pipeless"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"init"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"my_project"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"--template"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"scaffold"})]}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"cd"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"my_project"})]})]})}),"\n",(0,n.jsxs)(s.p,{children:["The above command creates a directory for the project root and, inside it, a directory called ",(0,n.jsx)(s.code,{children:"my-stage"}),",\nwhich contains a scaffold of a new stage. If you remove the ",(0,n.jsx)(s.code,{children:"--template"})," option and interactive shell will\nask you a few questions to generate the stages."]}),"\n",(0,n.jsxs)(s.p,{children:["The stage created can be executed correctly, but the code it c
1ontains does nothing. You can add some code later to the generated files\ngetting inspiration from the ",(0,n.jsx)(s.a,{href:"/v1/examples",children:"examples"}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["Let's start Pipeless and provide a stream. Run the following command from ",(0,n.jsx)(s.code,{children:"my_project"}),":"]}),"\n",(0,n.jsx)(s.pre,{"data-language":"bash","data-theme":"default",hasCopyCode:!0,children:(0,n.jsx)(s.code,{"data-language":"bash","data-theme":"default",children:(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"pipeless"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"start"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"--stages-dir"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"."})]})})}),"\n",(0,n.jsx)(s.p,{children:"Pipeless will load your stages and you will see something like:"}),"\n",(0,n.jsx)(s.pre,{"data-language":"text","data-theme":"default",children:(0,n.jsxs)(s.code,{"data-language":"text","data-theme":"default",children:[(0,n.jsx)(s.span,{className:"line",children:(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"âï¸ Loading stages from my_project"})}),"\n",(0,n.jsx)(s.span,{className:"line",children:(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"â³ Loading stage 'my_stage' from my_project/my-stage"})}),"\n",(0,n.jsx)(s.span,{className:"line",children:(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" Loading hook from my_project/my-stage/post-process.py"})}),"\n",(0,n.jsx)(s.span,{className:"line",children:(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" Loading hook from my_project/my-stage/process.py"})}),"\n",(0,n.jsx)(s.span,{className:"line",children:(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" Loading hook from my_project/my-stage/pre-process.py"})})]})}),"\n",(0,n.jsx)(s.p,{children:"You should now be able to submit streams:"}),"\n",(0,n.jsx)(s.pre,{"data-language":"bash","data-theme":"default",hasCopyCode:!0,children:(0,n.jsx)(s.code,{"data-language":"bash","data-theme":"default",children:(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"pipeless"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"add"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"stream"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"--input-uri"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"https://pipeless-public.s3.eu-west-3.amazonaws.com/cats.mp4"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"--output-uri"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"screen"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"--frame-path"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"my-stage"'})]})})}),"\n",(0,n.jsx)(s.p,{children:"We indicated to read the video from the provided URL and show the results in the screen. The output is optional\nsince in many computer vision use cases you don't actually want to see the output video but to execute some code on some events.\nThe frame path indicates the stages that should be executed for each frame of the provided stream."}),"\n",(0,n.jsx)(s.p,{children:"The CLI allows you to easily add, edit or remove streams. You can also configure backpressure mechanisms or export the events that happen on the streams to monitor them."}),"\n",(0,n.jsx)(s.p,{children:"To see all the available options and commands run:"}),"\n",(0,n.jsx)(s.pre,{"data-language":"bash","data-theme":"default",hasCopyCode:!0,children:(0,n.jsx)(s.code,{"data-language":"bash","data-theme":"default",children:(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"pipeless"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"--help"})]})})}),"\n",(0,n.jsx)(s.h2,{id:"creating-a-new-stage",children:"Creating a new stage"}),"\n",(0,n.jsx)(s.p,{children:"Creating a new stage is as simple as creating a new folder. The folder name will be adopted by Pipeless as the stage name, you\nwill use it when providing the frame path of a new stream."}),"\n",(0,n.jsx)(s.p,{children:"You can run the following command from inside your project directory to generate a stage and its files using the interactive shell:"}),"\n",(0,n.jsx)(s.pre,{"data-language":"bash","data-theme":"default",hasCopyCode:!0,children:(0,n.jsx)(s.code,{"data-language":"bash","data-theme":"default",children:(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"pipeless"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"generate"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"stage"})]})})}),"\n",(0,n.jsx)(s.h3,{id:"stage-context",children:"Stage context"}),"\n",(0,n.jsxs)(s.p,{children:["A stage can have its own global context. The ",(0,n.jsx)(s.strong,{children:"stage context"})," is provided to the hooks\nas read-only. This allows to perform slow tasks just once when Pipeless initializes\nthe stage instead of performing the same operation on every frame, avoiding extra processing\ntime. For example, you can open connections to external servers, load a model file from the filesystem, etc."]}),"\n",(0,n.jsxs)(s.p,{children:["To define context initialization logic for a stage create a ",(0,n.jsx)(s.code,{children:"init.{py,rs,...}"})," file containing a\nfunction called ",(0,n.jsx)(s.code,{children:"init"})," that should return any data you want to have available in the context. The\nfollowing is an example that initializes a stage context with a XML file that we can later use on the hooks:"]}),"\n",(0,n.jsx)(s.pre,{"data-language":"python","data-theme":"default",filename:"init.py",children:(0,n.jsxs)(s.code,{"data-language":"python","data-theme":"default",children:[(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" cv2"})]}),"\n",(0,n.jsx)(s.span,{className:"line",children:" "}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"def"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"init"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"}
1,children:"():"})]}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"return"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:"{"})]}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'model'"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:":"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" cv2"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:"."}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"CascadeClassifier"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:"("}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'/home/path/pipeless/examples/cats/cats.xml'"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:")"})]}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:"}"})]})]})}),"\n",(0,n.jsx)(l.UW,{children:(0,n.jsxs)(s.p,{children:["Pipeless loads stages when you run ",(0,n.jsx)(s.code,{children:"pipeless start"}),". In the short future we plan to support\nloading and unloading stages dynamically, but at this moment you need to restart Pipeless\nfor changes to take effect."]})}),"\n",(0,n.jsx)(s.h2,{id:"writting-hooks",children:"Writting hooks"}),"\n",(0,n.jsxs)(s.p,{children:["A stage is composed of zero or more hooks. There are 3 kind of hooks: ",(0,n.jsx)(s.code,{children:"pre-processing"}),", ",(0,n.jsx)(s.code,{children:"processing"})," and ",(0,n.jsx)(s.code,{children:"post-processing"})," hooks.\nOnly one hook of each kind can be added to a stage."]}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.code,{children:"process"})," hook is special and it can be either implemented via code or provided as a JSON file to perform inference using one of the\nsupported inference runtimes. See the ",(0,n.jsx)(s.a,{href:"#inference-runtime-json-hooks",children:"inference runtime"})," section below."]}),"\n",(0,n.jsx)(s.p,{children:"To interactively create a new hook move to your project directory and run the following command:"}),"\n",(0,n.jsx)(s.pre,{"data-language":"bash","data-theme":"default",hasCopyCode:!0,children:(0,n.jsx)(s.code,{"data-language":"bash","data-theme":"default",children:(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"pipeless"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"generate"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"hook"})]})})}),"\n",(0,n.jsx)(s.h3,{id:"implementing-a-code-hook",children:"Implementing a code hook"}),"\n",(0,n.jsxs)(s.p,{children:["Defining a code hook is as simple as creating a file containing a ",(0,n.jsx)(s.code,{children:"hook"})," function that receives the frame data and the stage context (read-only)."]}),"\n",(0,n.jsxs)(s.p,{children:["Depending on the hook type you will create a file named ",(0,n.jsx)(s.code,{children:"pre-process.xx"}),", ",(0,n.jsx)(s.code,{children:"process.xx"})," or ",(0,n.jsx)(s.code,{children:"post-process.xx"})," where ",(0,n.jsx)(s.code,{children:"xx"}),"\nis the extension of the programming language."]}),"\n",(0,n.jsx)(s.p,{children:"The following is an example of a Python hook for processing:"}),"\n",(0,n.jsx)(s.pre,{"data-language":"python","data-theme":"default",filename:"process.py",children:(0,n.jsxs)(s.code,{"data-language":"python","data-theme":"default",children:[(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" cv2"})]}),"\n",(0,n.jsx)(s.span,{className:"line",children:" "}),"\n",(0,n.jsxs)(s.span,{className:"line highlighted",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"def"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"hook"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"("}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-parameter)"},children:"frame_data"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-parameter)"},children:"context"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"):"})]}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" model "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" context"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:"["}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'model'"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:"]"})]}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" rgb_frame_arr "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" frame_data"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:"["}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'modified'"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:"]"})]}),"\n",(0,n.jsx)(s.span,{className:"line",children:" "}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" bounding_boxes "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" model"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:"."}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"detectMultiScale"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:"(reduced_frame, minSize "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:" ("}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"30"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:", "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"30"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:"))"})]}),"\n",(0,n.jsx)(s.span,{className:"line",children:" "}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" frame_data"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:"["}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'inference_output'"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:"]"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" bounding_boxes"})]})]})}),"\n",(0,n.jsxs)(s.p,{children:["In the hook above we have taken out our model from the stage context. The model was loaded from a XML file during the\nstage initialization (",(0,n.jsx)(s.code,{children:"init.py"}),", see ",(0,n.jsx)(s.a,{href:"#creating-a-new-stage",children:"section above"}),")."]}),"\n",(0,n.jsxs)(s.p,{children:["You can also see we take the RGB frame array from the frame data, run our model with it and update the ",(0,n.jsx)(s.code,{children:"inference_output"})," field of the frame data."]}),"\n",(0,n.jsx)(l.UW,{children:(0,n.jsxs)(s.p,{children:["Note in most cases you do not implement a ",(0,n.jsx)(s.code,{children:"process"})," hook via code but instead you use an ",(0,n.jsx)(s.a,{href:"#inference-runtime",children:"inference runtime"}),"\nand pass your model to it, implementing only the pre-process and post-process hooks."]})}),"\n",(0,n.jsx)(s.h3,{id:"inference-runtime---json-hooks",children:"Inference Runtime - JSON hooks"}),"\n",(0,n.jsxs)(s.p,{children:["When you have a model and want to perform inference using one of the supported inference runtimes you\nuse a ",(0,n.jsx)(s.code,{children:"process.json"})," file."]}),"\n",(0,n.jsx)(s.p,{children:"Within this JSON you define the model to use, the inference runtime and the runtime parameters."}),"\n",(0,n.jsxs)(s.p,{children:["To provide the inputs you set the ",(0,n.jsx)(s.code,{children:"inference_input"})," field of the frame data in your ",(0,n.jsx)(s.code,{children:"pre-process"}),"\nhook. And to parse the output you read the ",(0,n.jsx)(s.code,{children:"inference_output"})," field from the frame data in your ",(0,n.jsx)(s.code,{children:"post-process"})," hook."]}),"\n",(0,n.jsx)(s.p,{children:"The following is an example of using the ONNX Runtime with the CPU execution provider:"}),"\n",(0,n.jsx)(s.pre,{"data-language":"json","data-theme":"default",filename:"process.json",children:(0,n.jsxs)(s.code,{"data-language":"json","data-theme":"default",children:[(0,n.jsx)(s.span,{className:"line",children:(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"{"})}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:'"runtime"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:":"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"onnx"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:'"model_uri"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:":"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"https://pipeless-public.s3.eu-west-3.amazonaws.com/yolov8n.onnx"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:'"inference_params"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:":"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" {"})]}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:'"execution_provider"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:":"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"cpu"'})]}),"\n",(0,n.jsx)(s.span,{className:"line",children:(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" }"})}),"\n",(0,n.jsx)(s.span,{className:"line",children:(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})})]})}),"\n",(0,n.jsx)(s.h3,{id:"frame-data-fields",children:"Frame data fields"}),"\n",(0,n.jsx)(s.p,{children:"The frame data provided to the hook functions contains the following fields:"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"uuid"}),": The internal unique id of the frame."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"original"}),": An array containing the RGB pixels in format ",(0,n.jsx)(s.code,{children:"height,width,channels"}),". You can read the ",(0,n.jsx)(s.code,{children:"original"})," field but it is not editable."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"modified"}),": An array containing the modifiable RGB pixels in format ",(0,n.jsx)(s.code,{children:"height,width,channels"}),". You can read and edit the ",(0,n.jsx)(s.code,{children:"modified"})," field. When an output video is enabled it shows the content of the ",(0,n.jsx)(s.code,{children:"modified"})," field. When you provide a frame path with several stages to a stream, you probably want to work with ",(0,n.jsx)(s.code,{children:"modified"})," instead of ",(0,n.jsx)(s.code,{children:"original"})," in order to maintain the changes done to the frame in all stages."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"width"}),": Frame with."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"height"}),": Frame height."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"pts"}),": Presentation timestamp of the frame."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"duration"}),": Amount of time that this frame is shown when playing the video."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"fps"}),": Stream FPS."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"input_ts"}),": Timestamp of when this frame reached Pipeless. Mainly used in internaly."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"inference_input"}),": When using an inference runtime (",(0,n.jsx)(s.code,{children:"process.json"}),") you provide the inference inputs by setting the ",(0,n.jsx)(s.code,{children:"inference_input"})," field at the ",(0,n.jsx)(s.code,{children:"pre-process"})," hook."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"inference_output"}),": When using an inference runtime (",(0,n.jsx)(s.code,{children:"process.json"}),") you can obtain the inference outputs by reading the ",(0,n.jsx)(s.code,{children:"inference_output"})," field from the ",(0,n.jsx)(s.code,{children:"post-process"})," hook."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"user_data"}),": This field allows you to associate data to the frame that you can later retreive from subsequent hooks, even if those hooks belong to other stages. It c
1an contain any type of data, the only restriction is that dictionaries must use strings as keys. For more information check ",(0,n.jsx)(s.a,{href:"/v1/examples/custom-data",children:"this example"}),"."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"frame_number"}),": Number of the frame in the stream"]}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"stateless-vs-stateful-hooks",children:"Stateless vs Stateful hooks"}),"\n",(0,n.jsx)(s.p,{children:"Pipeless allows to create two kinds of hooks:"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.code,{children:"stateless"})," (default): A stateless hook can run multiple instances of the hook at the same time for different frames. They run with the ",(0,n.jsx)(s.strong,{children:"highest level of parallelization"}),".\nStateless hooks should be used when an internal state is not required. For example, if you implement some pre-processing as a simple resize your hook does not\nrequire an internal state."]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.code,{children:"stateful"}),": Stateful hooks are the kind of hook you want to use when some internal state is required. A good example of when to use a stateful hook is\nwhen you use an object tracking model, since these models maintain internal state. Stateful hooks introduce a bit of latency compared to stateless\nhooks, since the internal state is locked and released on each frame to avoid corrupting it, thus many frames cannot be processed at the same time. Stateful hooks also\nensure ",(0,n.jsx)(s.strong,{children:"sequential frame processing"}),", which means it will run for frames sorted by the frame number."]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["By default all hooks are ",(0,n.jsx)(s.code,{children:"stateless"})," unless you specify they aren't. As a general rule, use ",(0,n.jsx)(s.code,{children:"stateless"})," hooks unless you need a hook to preserve some internal state, then you need to use ",(0,n.jsx)(s.code,{children:"stateful"})," hooks."]}),"\n",(0,n.jsxs)(s.p,{children:["To indicate a hook must be ",(0,n.jsx)(s.code,{children:"stateful"})," add a comment to the top of the file as follows (the comment ",(0,n.jsx)(s.strong,{children:"must be the first line"}),")."]}),"\n",(0,n.jsx)(s.pre,{"data-language":"python","data-theme":"default",filename:"pre-process.py",children:(0,n.jsxs)(s.code,{"data-language":"python","data-theme":"default",children:[(0,n.jsx)(s.span,{className:"line",children:(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"# make stateful"})}),"\n",(0,n.jsx)(s.span,{className:"line",children:" "}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"def"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"hook"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"("}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-parameter)"},children:"frame_data"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-parameter)"},children:"context"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"):"})]}),"\n",(0,n.jsx)(s.span,{className:"line",children:(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" ..."})})]})}),"\n",(0,n.jsxs)(s.p,{children:["When using ",(0,n.jsx)(s.code,{children:"json"})," hooks, include a boolean ",(0,n.jsx)(s.code,{children:"make_stateful"})," field at the JSON root:"]}),"\n",(0,n.jsx)(s.pre,{"data-language":"json","data-theme":"default",filename:"process.json",children:(0,n.jsxs)(s.code,{"data-language":"json","data-theme":"default",children:[(0,n.jsx)(s.span,{className:"line",children:(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"{"})}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:'"make_stateful"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:":"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"true"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:'"runtime"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:":"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"onnx"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:'"model_uri"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:":"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"https://pipeless-public.s3.eu-west-3.amazonaws.com/yolov8n.onnx"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:'"inference_params"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:":"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" {"})]}),"\n",(0,n.jsxs)(s.span,{className:"line",children:[(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:'"execution_provider"'}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:":"}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,n.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"cpu"'})]}),"\n",(0,n.jsx)(s.span,{className:"line",children:(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" }"})}),"\n",(0,n.jsx)(s.span,{className:"line",children:(0,n.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})})]})})]})}let h={MDXContent:function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:s}=Object.assign({},(0,r.a)(),e.components);return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)},pageOpts:{filePath:"pages/v1/getting-started.mdx",route:"/v1/getting-started",frontMatter:{title:"Getting started",description:"Get started with the Pipeless computer vision framework and enjoy the development experience of serverless frameworks for embedded computer vision."},timestamp:1710855924e3,pageMap:[{kind:"Meta",data:{index:"Introduction",contributing:"Contributing","-- Versions":{type:"separator",title:"Versions"},v1:"v1.x.x",v0:"v0.x.x",about:{title:"Home",type:"page",href:"https://pipeless.ai"},contact:{title:"Contact â",type:"page",href:"https://lfkz9noht13.typeform.com/to/aeOqKGPt",newWindow:!0}}},{kind:"MdxPage",name:"contributing",route:"/contributing",frontMatter:{title:"Contributing Guidelines",description:"Contribute to the Pipeless open-source computer vision framework in GitHub"}},{kind:"MdxPage",name:"index",route:"/",frontMatter:{title:"Introduction",description:"Introduction to Pipeless, the open-source and production ready computer vision framework. Enjoy serverless development experience for embedded computer vision."}},{kind:"MdxPage",name:"v0",route:"/v0",frontMatter:{title:"Pipeless v0.x",description:"Documentation for Pipeless ver
1sions 0.x. The open-source computer vision framework"}},{kind:"Folder",name:"v1",route:"/v1",children:[{kind:"Meta",data:{"getting-started":"\uD83D\uDE80 Getting Started","rest-api":"Pipeless REST API",formats:"Stream Formats and Protocols",inference:"Inference Runtimes",kvstore:"Key Value Store",container:"\uD83D\uDC0B Container images",deployment:"Deploying your application",models:"Ready to Use CV Models",monitoring:"Export and monitor stream events",examples:"\uD83C\uDF1F Examples",benchmark:"Benchmark",changes:"Version Notable Changes",troubleshooting:"Troubleshooting","restart-policy":"Processing Restart Policy"}},{kind:"MdxPage",name:"benchmark",route:"/v1/benchmark",frontMatter:{title:"Benchmark",description:"A benchmark obtained by running the Pipeless computer vision framework on different devices to measure the overhead"}},{kind:"MdxPage",name:"changes",route:"/v1/changes",frontMatter:{title:"Notable version changes",description:"A list of important changes between Pipeless versions"}},{kind:"MdxPage",name:"container",route:"/v1/container",frontMatter:{title:"Container Images",description:"Learn to run and deploy Pipeless using container images. There are images available for CPU, and GPU (CUDA and TensorRT). The container images can also be used to easily deploy Pipeless to the cloud."}},{kind:"MdxPage",name:"deployment",route:"/v1/deployment",frontMatter:{title:"Deploying your pipeless application",description:"Learn how to deploy a Pipeless application to either an edge device or to the cloud. Pipeless ca run in distributed cloud servers as well as edge and IoT devices."}},{kind:"Folder",name:"examples",route:"/v1/examples",children:[{kind:"Meta",data:{w
1attermark:"Adding wattermarks","custom-data":"Passing data between hooks and stages",cats:"Detecting Cats on a Video","tf-pose":"Pose detection with TensorFlow",yolov8:"Object detection - YOLOv8 Python lib","onnx-candy":"ONXX Runtime - Candy filter","onnx-yolo":"ONNX Runtime - Object detection with YOLO","onnx-yolo-world":"ONNX Runtime - PPE detection with YOLO-World","gaze-piano":"Play a piano with your eyes by looking to the notes","object-tracking":"Object tracking - YOLO and Norfair"}},{kind:"MdxPage",name:"cats",route:"/v1/examples/cats",frontMatter:{title:"Cats recognition example",description:"A Pipeless example to recognize and detect cats in a video stream"}},{kind:"MdxPage",name:"custom-data",route:"/v1/examples/custom-data",frontMatter:{title:"Passing data between stages",description:"A Pipeless example to show how you can easily add custom data to a frame, making it available for subsequent hooks."}},{kind:"MdxPage",name:"gaze-piano",route:"/v1/examples/gaze-piano",frontMatter:{title:"Play a piano with your eyes - Gaze estimation",description:"A Pipeless example that allows you play a virtual piano with your eyes by looking to the note you want to play"}},{kind:"MdxPage",name:"object-tracking",route:"/v1/examples/object-tracking",frontMatter:{title:"Object tracking with YOLO, Norfair and Pipeless",description:"A Pipeless example that runs inference using a YOLO model and performs object tracking via Norfair trackers"}},{kind:"MdxPage",name:"onnx-candy",route:"/v1/examples/onnx-candy",frontMatter:{title:"Candy filter with ONNX runtime",description:"A Pipeless example using the ONNX Runtime to apply a candy filter to a video stream"}},{kind:"MdxPage",name:"onnx-yolo-world",route:"/v1/examples/onnx-yolo-world",frontMatter:{title:"PPE detection with ONNX Runtime and YOLO-World",description:"A Pipeless example that runs inference using the ONNX Runtime and YOLO World to detect Personal Protective Equipment (PPE) in a video stream"}},{kind:"MdxPage",name:"onnx-yolo",route:"/v1/examples/onnx-yolo",frontMatter:{title:"Object detection with ONNX Runtime",description:"A Pipeless example that runs inference using the ONNX Runtime and YOLO to detect objects in a video stream"}},{kind:"MdxPage",name:"tf-pose",route:"/v1/examples/tf-pose",frontMatter:{title:"Pose estimation/detection with TensorFlow",description:"A Pipeless example that detects the pose with 17 keypoints in a video stream"}},{kind:"MdxPage",name:"wattermark",route:"/v1/examples/wattermark",frontMatter:{title:"Adding wattermarks to a video",description:"The most basic Pipeless example adding a wattermark to a video"}},{kind:"MdxPage",name:"yolov8",route:"/v1/examples/yolov8",frontMatter:{title:"Object detection with YOLOv8 and Ultralytics SDK",description:"A Pipeless example to detect objects in a video stream using YOLOv8 via the Ultralytics Python SDK"}}]},{kind:"MdxPage",name:"examples",route:"/v1/examples",frontMatter:{title:"Examples",description:"A list of fully functional examples to play around with the Pipeless computer vision framework."}},{kind:"MdxPage",name:"formats",route:"/v1/formats",frontMatter:{title:"Supported stream formats and protocols",description:"Learn the supported formats and protocols that can be used to provide video to your Pipeless application"}},{kind:"Folder",name:"getting-started",route:"/v1/getting-started",children:[{kind:"Meta",data:{installation:"\uD83D\uDEE0ï¸ Installation","project-structure":"\uD83D\uDCC2 Project Structure"}},{kind:"MdxPage",name:"installation",route:"/v1/getting-started/installation",frontMatter:{title:"Installation guide",description:"Learn to install Pipeless, the computer vision framework"}},{kind:"MdxPage",name:"project-structure",route:"/v1/getting-started/project-structure",frontMatter:{title:"Project structure",description:"Learn how a Pipeless project is structured in the filesystem"}}]},{kind:"MdxPage",name:"getting-started",route:"/v1/getting-started",frontMatter:{title:"Getting started",description:"Get started with the Pipeless computer vision framework and enjoy the development experience of serverless frameworks for embedded computer vision."}},{kind:"MdxPage",name:"inference",route:"/v1/inference",frontMatter:{title:"Inference runtimes",description:"Learn to how to load a model into one of the embedded inference runtimes to perform your computer vision tasks in CPU, or GPUs. Use CUDA, TensorRT, OpenVINO, CoreML in any kind of GPU, including Nvidia GPUs."}},{kind:"MdxPage",name:"kvstore",route:"/v1/kvstore",frontMatter:{title:"Key-Value Store usage",description:"Learn to how use the included key value store to communicate data between the processing of different frames and the execution of different hooks"}},{kind:"Folder",name:"models",route:"/v1/models",children:[{kind:"Folder",name:"tensorflow",route:"/v1/models/tensorflow",children:[{kind:"MdxPage",name:"multi-pose-estimation",route:"/v1/models/tensorflow/multi-pose-estimation",frontMatter:{title:"Multi-pose estimation Tensorflow Model",description:"A ready to use TensorFlow model for multipose estimation in Python"}},{kind:"Meta",data:{"multi-pose-estimation":"Multi-pose estimation Tensorflow Model"}}]},{kind:"MdxPage",name:"tensorflow",route:"/v1/models/tensorflow"},{kind:"Meta",data:{tensorflow:"Tensorflow"}}]},{kind:"MdxPage",name:"models",route:"/v1/models",frontMatter:{title:"Ready to use computer vision models",description:"A list of ready to use computer vision models with Python APIs"}},{kind:"MdxPage",name:"monitoring",route:"/v1/monitoring",frontMatter:{title:"Exporting stream events",description:"Understand how to export and monitor stream events from Pipeless"}},{kind:"MdxPage",name:"rest-api",route:"/v1/rest-api",frontMatter:{title:"Pipeless REST API",description:"Documentation about the endpoints exposed by a running Pipeless instance"}},{kind:"MdxPage",name:"restart-policy",route:"/v1/restart-policy",frontMatter:{title:"Processing Restart Policy",description:"Documentation about the restart policy for stream processing"}},{kind:"MdxPage",name:"troubleshooting",route:"/v1/troubleshooting",frontMatter:{title:"Troubleshooting your Pipeless application",description:"General guidance and common issues when running your Pipeless application"}}]},{kind:"MdxPage",name:"v1",route:"/v1",frontMatter:{title:"Pipeless v1.x",description:"Documentation for Pipeless ver
1sions 1.x. The open-source computer vision framework"}}],flexsearch:{codeblocks:!0},title:"Getting started",headings:c},pageNextRoute:"/v1/getting-started",nextraLayout:i.ZP,themeConfig:a.Z};s.default=(0,o.j)(h)}},function(e){e.O(0,[13,996,774,888,179],function(){return e(e.s=2659)}),_N_E=e.O()}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.