|
28 | 28 | },
|
29 | 29 | {
|
30 | 30 | "cell_type": "code",
|
31 |
| - "execution_count": 1, |
| 31 | + "execution_count": null, |
32 | 32 | "metadata": {},
|
33 |
| - "outputs": [ |
34 |
| - { |
35 |
| - "name": "stdout", |
36 |
| - "output_type": "stream", |
37 |
| - "text": [ |
38 |
| - "Name: degirum_tools\n", |
39 |
| - "Version: 0.10.1\n", |
40 |
| - "Summary: Tools for PySDK\n", |
41 |
| - "Home-page: \n", |
42 |
| - "Author: DeGirum\n", |
43 |
| - "Author-email: \n", |
44 |
| - "License: \n", |
45 |
| - "Location: c:\\users\\shashichilappagari\\anaconda3\\envs\\supervision\\lib\\site-packages\n", |
46 |
| - "Requires: degirum, ipython, numpy, opencv-python, pafy, pillow, psutil, pycocotools, python-dotenv, pyyaml, requests, scipy, youtube-dl\n", |
47 |
| - "Required-by: \n" |
48 |
| - ] |
49 |
| - } |
50 |
| - ], |
| 33 | + "outputs": [], |
51 | 34 | "source": [
|
52 | 35 | "# make sure degirum-tools package is installed\n",
|
53 | 36 | "!pip show degirum-tools || pip install degirum-tools"
|
|
63 | 46 | },
|
64 | 47 | {
|
65 | 48 | "cell_type": "code",
|
66 |
| - "execution_count": 2, |
| 49 | + "execution_count": 1, |
67 | 50 | "metadata": {},
|
68 | 51 | "outputs": [],
|
69 | 52 | "source": [
|
|
81 | 64 | "# '': ai server serving models from local folder\n",
|
82 | 65 | "# path to json file: single model zoo in case of @local inference\n",
|
83 | 66 | "# model_names: list of AI models to use for inferences (NOTE: they should have the same input size)\n",
|
84 |
| - "# allow_frame_drop:\n", |
85 |
| - "# when True, we drop video frames in case when AI performance is not enough to work in real time\n", |
86 |
| - "# when False, we buffer video frames to keep up with AI performance\n", |
87 | 67 | "hw_location = \"@cloud\"\n",
|
88 | 68 | "video_sources = [\n",
|
| 69 | + " \"https://raw.githubusercontent.com/DeGirum/PySDKExamples/main/images/WalkingPeople.mp4\",\n", |
89 | 70 | " \"https://raw.githubusercontent.com/DeGirum/PySDKExamples/main/images/Traffic.mp4\",\n",
|
90 |
| - " \"https://raw.githubusercontent.com/DeGirum/PySDKExamples/main/images/TrafficHD.mp4\",\n", |
91 | 71 | "]\n",
|
92 | 72 | "model_zoo_url = \"degirum/public\"\n",
|
93 | 73 | "model_names = [\n",
|
94 | 74 | " \"yolo_v5s_hand_det--512x512_quant_n2x_orca1_1\",\n",
|
95 | 75 | " \"yolo_v5s_face_det--512x512_quant_n2x_orca1_1\",\n",
|
96 | 76 | " \"yolo_v5n_car_det--512x512_quant_n2x_orca1_1\",\n",
|
97 | 77 | " \"yolo_v5s_person_det--512x512_quant_n2x_orca1_1\",\n",
|
98 |
| - "]\n", |
99 |
| - "allow_frame_drop = False" |
| 78 | + "]" |
100 | 79 | ]
|
101 | 80 | },
|
102 | 81 | {
|
103 | 82 | "cell_type": "markdown",
|
104 | 83 | "metadata": {},
|
105 | 84 | "source": [
|
106 |
| - "#### Specify where do you want to run your inferences" |
| 85 | + "#### The rest of the cells below should run without any modifications" |
107 | 86 | ]
|
108 | 87 | },
|
109 | 88 | {
|
110 | 89 | "cell_type": "code",
|
111 |
| - "execution_count": 3, |
| 90 | + "execution_count": null, |
112 | 91 | "metadata": {},
|
113 |
| - "outputs": [ |
114 |
| - { |
115 |
| - "ename": "", |
116 |
| - "evalue": "", |
117 |
| - "output_type": "error", |
118 |
| - "traceback": [ |
119 |
| - "\u001b[1;31mThe Kernel crashed while executing code in the current cell or a previous cell. \n", |
120 |
| - "\u001b[1;31mPlease review the code in the cell(s) to identify a possible cause of the failure. \n", |
121 |
| - "\u001b[1;31mClick <a href='https://aka.ms/vscodeJupyterKernelCrash'>here</a> for more info. \n", |
122 |
| - "\u001b[1;31mView Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details." |
123 |
| - ] |
124 |
| - } |
125 |
| - ], |
126 |
| - "source": [ |
127 |
| - "import degirum as dg, degirum_tools" |
128 |
| - ] |
129 |
| - }, |
130 |
| - { |
131 |
| - "cell_type": "code", |
132 |
| - "execution_count": 4, |
133 |
| - "metadata": {}, |
134 |
| - "outputs": [ |
135 |
| - { |
136 |
| - "name": "stdout", |
137 |
| - "output_type": "stream", |
138 |
| - "text": [ |
139 |
| - "Successfully opened video stream 'https://raw.githubusercontent.com/DeGirum/PySDKExamples/main/images/Traffic.mp4'Successfully opened video stream 'https://raw.githubusercontent.com/DeGirum/PySDKExamples/main/images/TrafficHD.mp4'\n", |
140 |
| - "\n" |
141 |
| - ] |
142 |
| - }, |
143 |
| - { |
144 |
| - "name": "stderr", |
145 |
| - "output_type": "stream", |
146 |
| - "text": [ |
147 |
| - "packet queue is empty, aborting\n", |
148 |
| - "packet queue is empty, aborting\n", |
149 |
| - "packet queue is empty, aborting\n", |
150 |
| - "packet queue is empty, aborting\n" |
151 |
| - ] |
152 |
| - } |
153 |
| - ], |
| 92 | + "outputs": [], |
154 | 93 | "source": [
|
| 94 | + "import degirum as dg, degirum_tools\n", |
155 | 95 | "from degirum_tools import streams as dgstreams\n",
|
156 | 96 | "\n",
|
157 |
| - "c = dgstreams.Composition()\n", |
158 |
| - "\n", |
159 |
| - "batch_size = len(\n", |
160 |
| - " video_sources\n", |
161 |
| - ") # set AI server batch size equal to the # of video sources for lowest latency\n", |
162 |
| - "\n", |
163 | 97 | "# create PySDK AI model objects\n",
|
164 |
| - "models = []\n", |
165 |
| - "for mi, model_name in enumerate(model_names):\n", |
166 |
| - " model = dg.load_model(\n", |
| 98 | + "models = [\n", |
| 99 | + " dg.load_model(\n", |
167 | 100 | " model_name=model_name,\n",
|
168 | 101 | " inference_host_address=hw_location,\n",
|
169 | 102 | " zoo_url=model_zoo_url,\n",
|
170 | 103 | " token=degirum_tools.get_token(),\n",
|
| 104 | + " overlay_line_width=2,\n", |
171 | 105 | " )\n",
|
172 |
| - " model.measure_time = True\n", |
173 |
| - " model.eager_batch_size = batch_size\n", |
174 |
| - " model.frame_queue_depth = batch_size\n", |
175 |
| - " models.append(model)\n", |
| 106 | + " for model_name in model_names\n", |
| 107 | + "]\n", |
176 | 108 | "\n",
|
177 | 109 | "# check that all models have the same input configuration\n",
|
178 |
| - "models_have_same_input = True\n", |
179 |
| - "for model in models[1:]:\n", |
180 |
| - " if (\n", |
181 |
| - " type(model._preprocessor) != type(models[0]._preprocessor)\n", |
182 |
| - " or model.model_info.InputH != models[0].model_info.InputH\n", |
183 |
| - " or model.model_info.InputW != models[0].model_info.InputW\n", |
184 |
| - " ):\n", |
185 |
| - " models_have_same_input = False\n", |
186 |
| - "\n", |
187 |
| - "resizers = []\n", |
188 |
| - "\n", |
189 |
| - "# create video sources and image resizers\n", |
190 |
| - "# (we use separate resizers to do resize only once per source when possible, to improve performance),\n", |
191 |
| - "# connect each resizer to corresponding video source\n", |
192 |
| - "for src in video_sources:\n", |
193 |
| - " source = c.add(dgstreams.VideoSourceGizmo(src))\n", |
194 |
| - " if models_have_same_input:\n", |
195 |
| - " resizer = c.add(\n", |
196 |
| - " dgstreams.AiPreprocessGizmo(\n", |
197 |
| - " models[0], stream_depth=2, allow_drop=allow_frame_drop\n", |
198 |
| - " )\n", |
199 |
| - " )\n", |
200 |
| - " else:\n", |
201 |
| - " resizer = c.add(dgstreams.FanoutGizmo(allow_drop=allow_frame_drop))\n", |
| 110 | + "assert all(\n", |
| 111 | + " type(model._preprocessor) == type(models[0]._preprocessor)\n", |
| 112 | + " and model.model_info.InputH == models[0].model_info.InputH\n", |
| 113 | + " and model.model_info.InputW == models[0].model_info.InputW\n", |
| 114 | + " for model in models[1:]\n", |
| 115 | + ")\n", |
202 | 116 | "\n",
|
203 |
| - " resizer.connect_to(source) # connect resizer to video source\n", |
204 |
| - " resizers.append(resizer)\n", |
| 117 | + "# create video source gizmos;\n", |
| 118 | + "# stop_composition_on_end=True to stop whole composition when one (shorter) video source ends\n", |
| 119 | + "sources = [\n", |
| 120 | + " dgstreams.VideoSourceGizmo(src, stop_composition_on_end=True)\n", |
| 121 | + " for src in video_sources\n", |
| 122 | + "]\n", |
205 | 123 | "\n",
|
206 |
| - "# create result combiner\n", |
207 |
| - "combiner = c.add(dgstreams.AiResultCombiningGizmo(len(models)))\n", |
| 124 | + "# create image resizer gizmos, one per video source\n", |
| 125 | + "# (we use separate resizers to do resize only once per source to improve performance)\n", |
| 126 | + "resizers = [dgstreams.AiPreprocessGizmo(models[0]) for _ in video_sources]\n", |
208 | 127 | "\n",
|
209 |
| - "# create multi-input detector gizmos,\n", |
210 |
| - "# connect each detector gizmo to every resizer gizmo,\n", |
211 |
| - "# connect result combiner gizmo to each detector gizmo\n", |
212 |
| - "for mi, model in enumerate(models):\n", |
213 |
| - " # create AI gizmo (aka detector) from the model\n", |
214 |
| - " detector = c.add(\n", |
215 |
| - " dgstreams.AiSimpleGizmo(model, stream_depth=2, inp_cnt=len(video_sources))\n", |
216 |
| - " )\n", |
217 |
| - "\n", |
218 |
| - " # connect detector gizmo to each resizer gizmo\n", |
219 |
| - " for fi, resizer in enumerate(resizers):\n", |
220 |
| - " detector.connect_to(resizer, fi)\n", |
| 128 | + "# create multi-input detector gizmos, one per model\n", |
| 129 | + "detectors = [\n", |
| 130 | + " dgstreams.AiSimpleGizmo(model, inp_cnt=len(video_sources)) for model in models\n", |
| 131 | + "]\n", |
221 | 132 | "\n",
|
222 |
| - " # connect result combiner gizmo to detector gizmo\n", |
223 |
| - " combiner.connect_to(detector, mi)\n", |
| 133 | + "# create result combiner gizmo to combine results from all detectors into single result\n", |
| 134 | + "combiner = dgstreams.AiResultCombiningGizmo(len(models))\n", |
224 | 135 | "\n",
|
225 | 136 | "# create multi-window video multiplexing display gizmo\n",
|
226 |
| - "# and connect it to combiner gizmo\n", |
227 | 137 | "win_captions = [f\"Stream #{i}: {str(src)}\" for i, src in enumerate(video_sources)]\n",
|
228 |
| - "display = c.add(\n", |
229 |
| - " dgstreams.VideoDisplayGizmo(\n", |
230 |
| - " win_captions, show_ai_overlay=True, show_fps=True, multiplex=True\n", |
231 |
| - " )\n", |
| 138 | + "display = dgstreams.VideoDisplayGizmo(\n", |
| 139 | + " win_captions, show_ai_overlay=True, show_fps=True, multiplex=True\n", |
232 | 140 | ")\n",
|
233 |
| - "display.connect_to(combiner)\n", |
234 | 141 | "\n",
|
235 |
| - "# start composition\n", |
236 |
| - "c.start()" |
| 142 | + "# connect all gizmos in the pipeline\n", |
| 143 | + "# source[i] -> resizer[i] -> detector[j] -> combiner -> display\n", |
| 144 | + "pipeline = (\n", |
| 145 | + " # each source is connected to corresponding resizer\n", |
| 146 | + " (source >> resizer for source, resizer in zip(sources, resizers)),\n", |
| 147 | + " # each resizer is connected to every detector\n", |
| 148 | + " (\n", |
| 149 | + " resizer >> detector[ri]\n", |
| 150 | + " for detector in detectors\n", |
| 151 | + " for ri, resizer in enumerate(resizers)\n", |
| 152 | + " ),\n", |
| 153 | + " # each detector is connected to result combiner\n", |
| 154 | + " (detector >> combiner[di] for di, detector in enumerate(detectors)),\n", |
| 155 | + " # result combiner is connected to display\n", |
| 156 | + " combiner >> display,\n", |
| 157 | + ")\n", |
| 158 | + "\n", |
| 159 | + "# create and start composition with given pipeline\n", |
| 160 | + "dgstreams.Composition(*pipeline).start()" |
237 | 161 | ]
|
| 162 | + }, |
| 163 | + { |
| 164 | + "cell_type": "code", |
| 165 | + "execution_count": null, |
| 166 | + "metadata": {}, |
| 167 | + "outputs": [], |
| 168 | + "source": [] |
238 | 169 | }
|
239 | 170 | ],
|
240 | 171 | "metadata": {
|
241 | 172 | "kernelspec": {
|
242 |
| - "display_name": "Python (supervision)", |
| 173 | + "display_name": "base", |
243 | 174 | "language": "python",
|
244 |
| - "name": "supervision" |
| 175 | + "name": "python3" |
245 | 176 | },
|
246 | 177 | "language_info": {
|
247 | 178 | "codemirror_mode": {
|
|
253 | 184 | "name": "python",
|
254 | 185 | "nbconvert_exporter": "python",
|
255 | 186 | "pygments_lexer": "ipython3",
|
256 |
| - "version": "3.9.18" |
| 187 | + "version": "3.9.16" |
257 | 188 | },
|
258 | 189 | "orig_nbformat": 4
|
259 | 190 | },
|
|
0 commit comments