From d8a339d370b96936cc916e343b6f845b1fca5576 Mon Sep 17 00:00:00 2001 From: Mohammed Yasin <32206511+Y-T-G@users.noreply.github.com> Date: Wed, 27 Nov 2024 01:23:41 +0800 Subject: [PATCH 01/25] Fix missing labels when all segment points are out of bounds (#17810) Co-authored-by: Ultralytics Assistant <135830346+UltralyticsAssistant@users.noreply.github.com> --- ultralytics/utils/ops.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ultralytics/utils/ops.py b/ultralytics/utils/ops.py index 25e83c61c3..ac53546ed1 100644 --- a/ultralytics/utils/ops.py +++ b/ultralytics/utils/ops.py @@ -75,9 +75,8 @@ def segment2box(segment, width=640, height=640): (np.ndarray): the minimum and maximum x and y values of the segment. """ x, y = segment.T # segment xy - inside = (x >= 0) & (y >= 0) & (x <= width) & (y <= height) - x = x[inside] - y = y[inside] + x = x.clip(0, width) + y = y.clip(0, height) return ( np.array([x.min(), y.min(), x.max(), y.max()], dtype=segment.dtype) if any(x) From 5b124dc7ca6278e85c399e29e24f559fe8be07bc Mon Sep 17 00:00:00 2001 From: Muhammad Rizwan Munawar Date: Tue, 26 Nov 2024 22:26:23 +0500 Subject: [PATCH 02/25] New Solutions sweep counting annotator (#17742) Co-authored-by: UltralyticsAssistant Co-authored-by: Glenn Jocher Co-authored-by: Ultralytics Assistant <135830346+UltralyticsAssistant@users.noreply.github.com> --- docs/en/usage/simple-utilities.md | 85 +++++++++++++++++++++++++++++++ ultralytics/utils/plotting.py | 49 +++++++++++++++--- 2 files changed, 126 insertions(+), 8 deletions(-) diff --git a/docs/en/usage/simple-utilities.md b/docs/en/usage/simple-utilities.md index 2026e5a216..d4bc8b08a2 100644 --- a/docs/en/usage/simple-utilities.md +++ b/docs/en/usage/simple-utilities.md @@ -374,6 +374,91 @@ See docstring for each function or visit the `ultralytics.utils.ops` [reference Ultralytics includes an Annotator class that can be used to annotate any kind of data. It's easiest to use with [object detection bounding boxes](../modes/predict.md#boxes), [pose key points](../modes/predict.md#keypoints), and [oriented bounding boxes](../modes/predict.md#obb). +#### Ultralytics Sweep Annotation + +!!! example "Python Examples using YOLO11 🚀" + + === "Python" + + ```python + import cv2 + + from ultralytics import YOLO + from ultralytics.utils.plotting import Annotator, colors + + # User defined video path and model file + cap = cv2.VideoCapture("Path/to/video/file.mp4") + model = YOLO(model="yolo11s-seg.pt") # Model file i.e. yolo11s.pt or yolo11m-seg.pt + + if not cap.isOpened(): + print("Error: Could not open video.") + exit() + + # Initialize the video writer object. + w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) + video_writer = cv2.VideoWriter("ultralytics.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) + + masks = None # Initialize variable to store masks data + f = 0 # Initialize frame count variable for enabling mouse event. + line_x = w # Store width of line. + dragging = False # Initialize bool variable for line dragging. + classes = model.names # Store model classes names for plotting. + window_name = "Ultralytics Sweep Annotator" + + + def drag_line(event, x, y, flags, param): # Mouse callback for dragging line. + global line_x, dragging + if event == cv2.EVENT_LBUTTONDOWN or (flags & cv2.EVENT_FLAG_LBUTTON): + line_x = max(0, min(x, w)) + dragging = True + + + while cap.isOpened(): # Loop over the video capture object. + ret, im0 = cap.read() + if not ret: + break + f = f + 1 # Increment frame count. + count = 0 # Re-initialize count variable on every frame for precise counts. + annotator = Annotator(im0) + results = model.track(im0, persist=True) # Track objects using track method. + if f == 1: + cv2.namedWindow(window_name) + cv2.setMouseCallback(window_name, drag_line) + + if results[0].boxes.id is not None: + if results[0].masks is not None: + masks = results[0].masks.xy + track_ids = results[0].boxes.id.int().cpu().tolist() + clss = results[0].boxes.cls.cpu().tolist() + boxes = results[0].boxes.xyxy.cpu() + + for mask, box, cls, t_id in zip(masks or [None] * len(boxes), boxes, clss, track_ids): + color = colors(t_id, True) # Assign different color to each tracked object. + if mask is not None and mask.size > 0: + # If you want to overlay the masks + # mask[:, 0] = np.clip(mask[:, 0], line_x, w) + # mask_img = cv2.fillPoly(im0.copy(), [mask.astype(int)], color) + # cv2.addWeighted(mask_img, 0.5, im0, 0.5, 0, im0) + + if box[0] > line_x: + count += 1 + annotator.seg_bbox(mask=mask, mask_color=color, label=str(classes[cls])) + else: + if box[0] > line_x: + count += 1 + annotator.box_label(box=box, color=color, label=str(classes[cls])) + + annotator.sweep_annotator(line_x=line_x, line_y=h, label=f"COUNT:{count}") # Display the sweep + cv2.imshow(window_name, im0) + video_writer.write(im0) + if cv2.waitKey(1) & 0xFF == ord("q"): + break + + cap.release() # Release the video capture. + video_writer.release() # Release the video writer. + cv2.destroyAllWindows() # Destroy all opened windows. + ``` + #### Horizontal Bounding Boxes ```{ .py .annotate } diff --git a/ultralytics/utils/plotting.py b/ultralytics/utils/plotting.py index f4514247cf..b2bac871c0 100644 --- a/ultralytics/utils/plotting.py +++ b/ultralytics/utils/plotting.py @@ -791,19 +791,52 @@ class Annotator: cv2.polylines(self.im, [np.int32([mask])], isClosed=True, color=mask_color, thickness=2) text_size, _ = cv2.getTextSize(label, 0, self.sf, self.tf) - cv2.rectangle( - self.im, - (int(mask[0][0]) - text_size[0] // 2 - 10, int(mask[0][1]) - text_size[1] - 10), - (int(mask[0][0]) + text_size[0] // 2 + 10, int(mask[0][1] + 10)), - mask_color, - -1, - ) - if label: + cv2.rectangle( + self.im, + (int(mask[0][0]) - text_size[0] // 2 - 10, int(mask[0][1]) - text_size[1] - 10), + (int(mask[0][0]) + text_size[0] // 2 + 10, int(mask[0][1] + 10)), + mask_color, + -1, + ) cv2.putText( self.im, label, (int(mask[0][0]) - text_size[0] // 2, int(mask[0][1])), 0, self.sf, txt_color, self.tf ) + def sweep_annotator(self, line_x=0, line_y=0, label=None, color=(221, 0, 186), txt_color=(255, 255, 255)): + """ + Function for drawing a sweep annotation line and an optional label. + + Args: + line_x (int): The x-coordinate of the sweep line. + line_y (int): The y-coordinate limit of the sweep line. + label (str, optional): Text label to be drawn in center of sweep line. If None, no label is drawn. + color (tuple): RGB color for the line and label background. + txt_color (tuple): RGB color for the label text. + """ + # Draw the sweep line + cv2.line(self.im, (line_x, 0), (line_x, line_y), color, self.tf * 2) + + # Draw label, if provided + if label: + (text_width, text_height), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, self.sf, self.tf) + cv2.rectangle( + self.im, + (line_x - text_width // 2 - 10, line_y // 2 - text_height // 2 - 10), + (line_x + text_width // 2 + 10, line_y // 2 + text_height // 2 + 10), + color, + -1, + ) + cv2.putText( + self.im, + label, + (line_x - text_width // 2, line_y // 2 + text_height // 2), + cv2.FONT_HERSHEY_SIMPLEX, + self.sf, + txt_color, + self.tf, + ) + def plot_distance_and_line( self, pixels_distance, centroids, line_color=(104, 31, 17), centroid_color=(255, 0, 255) ): From 7c97ed19372655a8b3d9050fc0f2ffb2e6a31276 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Tue, 26 Nov 2024 21:10:03 +0100 Subject: [PATCH 03/25] Improved Docs minify (#17816) Signed-off-by: UltralyticsAssistant Co-authored-by: UltralyticsAssistant --- .github/workflows/docs.yml | 2 +- docs/build_docs.py | 59 ++++++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 5b0c7a96d3..67473f2fac 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -48,7 +48,7 @@ jobs: python-version: "3.x" - uses: astral-sh/setup-uv@v4 - name: Install Dependencies - run: uv pip install --system ruff black tqdm mkdocs-material "mkdocstrings[python]" mkdocs-jupyter mkdocs-redirects mkdocs-ultralytics-plugin mkdocs-macros-plugin + run: uv pip install --system ruff black tqdm mkdocs-material "mkdocstrings[python]" mkdocs-jupyter mkdocs-redirects mkdocs-ultralytics-plugin mkdocs-macros-plugin csscompressor jsmin - name: Ruff fixes continue-on-error: true run: ruff check --fix --unsafe-fixes --select D --ignore=D100,D104,D203,D205,D212,D213,D401,D406,D407,D413 . diff --git a/docs/build_docs.py b/docs/build_docs.py index 0cf46ed57b..4ae9b41610 100644 --- a/docs/build_docs.py +++ b/docs/build_docs.py @@ -238,32 +238,41 @@ def remove_macros(): print(f"Removed {len(macros_indices)} URLs containing '/macros/' from {sitemap}") -def minify_html_files(): - """Minifies all HTML files in the site directory and prints reduction stats.""" +def minify_files(html=True, css=True, js=True): + """Minifies HTML, CSS, and JS files and prints total reduction stats.""" + minify, compress, jsmin = None, None, None try: - from minify_html import minify # pip install minify-html - except ImportError: + if html: + from minify_html import minify + if css: + from csscompressor import compress + if js: + import jsmin + except ImportError as e: + print(f"Missing required package: {str(e)}") return - total_original_size = 0 - total_minified_size = 0 - for html_file in tqdm(SITE.rglob("*.html"), desc="Minifying HTML files"): - with open(html_file, encoding="utf-8") as f: - content = f.read() - - original_size = len(content) - minified_content = minify(content, keep_closing_tags=True, minify_css=True, minify_js=True) - minified_size = len(minified_content) - - total_original_size += original_size - total_minified_size += minified_size - - with open(html_file, "w", encoding="utf-8") as f: - f.write(minified_content) - - total_reduction = total_original_size - total_minified_size - total_percent_reduction = (total_reduction / total_original_size) * 100 - print(f"Minify HTML reduction: {total_percent_reduction:.2f}% " f"({total_reduction / 1024:.2f} KB saved)") + stats = {} + for ext, minifier in { + "html": (lambda x: minify(x, keep_closing_tags=True, minify_css=True, minify_js=True)) if html else None, + "css": compress if css else None, + "js": jsmin.jsmin if js else None, + }.items(): + if not minifier: + continue + + stats[ext] = {"original": 0, "minified": 0} + for f in tqdm(SITE.rglob(f"*.{ext}"), desc=f"Minifying {ext.upper()}"): + content = f.read_text(encoding="utf-8") + minified = minifier(content) + stats[ext]["original"] += len(content) + stats[ext]["minified"] += len(minified) + f.write_text(minified, encoding="utf-8") + + for ext, data in stats.items(): + if data["original"]: + r = data["original"] - data["minified"] # reduction + print(f"Total {ext.upper()} reduction: {(r / data['original']) * 100:.2f}% ({r / 1024:.2f} KB saved)") def main(): @@ -279,8 +288,8 @@ def main(): # Update docs HTML pages update_docs_html() - # Minify HTML files - minify_html_files() + # Minify files + minify_files(html=False) # Show command to serve built website print('Docs built correctly ✅\nServe site at http://localhost:8000 with "python -m http.server --directory site"') From efbcf444a1082e458b923e06acf306c380902eb6 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Wed, 27 Nov 2024 12:37:43 +0100 Subject: [PATCH 04/25] Revert Docs minify attempt (#17831) Signed-off-by: UltralyticsAssistant Co-authored-by: UltralyticsAssistant --- .github/workflows/docs.yml | 2 +- docs/build_docs.py | 5 +++-- docs/overrides/assets/favicon.ico | Bin 9662 -> 0 bytes mkdocs.yml | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) delete mode 100644 docs/overrides/assets/favicon.ico diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 67473f2fac..5b0c7a96d3 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -48,7 +48,7 @@ jobs: python-version: "3.x" - uses: astral-sh/setup-uv@v4 - name: Install Dependencies - run: uv pip install --system ruff black tqdm mkdocs-material "mkdocstrings[python]" mkdocs-jupyter mkdocs-redirects mkdocs-ultralytics-plugin mkdocs-macros-plugin csscompressor jsmin + run: uv pip install --system ruff black tqdm mkdocs-material "mkdocstrings[python]" mkdocs-jupyter mkdocs-redirects mkdocs-ultralytics-plugin mkdocs-macros-plugin - name: Ruff fixes continue-on-error: true run: ruff check --fix --unsafe-fixes --select D --ignore=D100,D104,D203,D205,D212,D213,D401,D406,D407,D413 . diff --git a/docs/build_docs.py b/docs/build_docs.py index 4ae9b41610..9556415c8d 100644 --- a/docs/build_docs.py +++ b/docs/build_docs.py @@ -262,7 +262,8 @@ def minify_files(html=True, css=True, js=True): continue stats[ext] = {"original": 0, "minified": 0} - for f in tqdm(SITE.rglob(f"*.{ext}"), desc=f"Minifying {ext.upper()}"): + directory = "" # "stylesheets" if ext == css else "javascript" if ext == "js" else "" + for f in tqdm((SITE / directory).rglob(f"*.{ext}"), desc=f"Minifying {ext.upper()}"): content = f.read_text(encoding="utf-8") minified = minifier(content) stats[ext]["original"] += len(content) @@ -289,7 +290,7 @@ def main(): update_docs_html() # Minify files - minify_files(html=False) + minify_files(html=False, css=False, js=False) # Show command to serve built website print('Docs built correctly ✅\nServe site at http://localhost:8000 with "python -m http.server --directory site"') diff --git a/docs/overrides/assets/favicon.ico b/docs/overrides/assets/favicon.ico deleted file mode 100644 index 7aa5066187ae0bb3179a5bc13c282e481871404d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9662 zcmds-3vd)w7KSg80{UJSQmQ_$D3L?75q9Q6FqRT4cW7P#@d5IAb5z%E`MTnS1 zS1~FoYIHH`t|TELJVFve5)uRwV;~6xh$tEmBJv0+i_+B8l*j*c_nn!{OwS~w2dfNq zxJqZxcVCfli4YeEA^IcmD=`(pzdsv4nF&fF?nkUZR3i=} z4k4-#X^49e-OdI}N7evSSHv8|Q3OQ^-cwR$qKfOt8nHSTEWHt1qA-WsQxV>Ceyq6K zGq26wa0cvpKf8XbJz!nd%=S*O>phfaCid*wo_x7^4!GyLz^?Z&$4$0qbAdY^(d;5W zU-vTFx^5lES~Fc_*Pp>8xA>yX1NQtF@MlC@*Nx-Z34ah^KNbW21~>Sk%>i!qSZ@sY zf6PvZkG6cLkAs`9U9DL+$JUko<74j0zi0m3s}ya#Ls9uu>D@M4dMlog-tCV|?`IE7 zPw52d$seseIRhQFch>Wtb*ZA_`y|!9Ea_mLK|fR&bab0RO5 zk{Z`b`gV<^Z?Yxrc?dP%$_+Zc)1YHtfW6Y7@3(>- zzdKS2_Dzz$D>Uff2C%OKd#=TPAXC!UpGx}b6G>mDOWKtxy`>YBXVqoubgcE?yw8v) zYK;`;#Yo3@fV~PiN8a1ABkzUyOdQzv+w2Yhm9#HS(%yHlkEPPH`*k^I*Q+unz0j$B z#>nQq#@8oz``Ld8VVB4|^y0w&74mMfe<-Qp1F*jb_T`f5-;@M)0y}GQXU&W9%1#$b zdxBF9MjT=x*u7!dKeIJc0=*PTI#dA72A$l6yw^Z4)zJFq(9CvdhS|%Y_Y&yEWasPH&wd~R z`<~FeYjy%VRWFqE#WOOs>ghAPPqW$cH2ZM}_QNJSG*e*JAf0z7_Py_-{=5y%EQ4lV zGj&gO|B+O)1bKf!(vD=Xqc(t@KL4kr%BN&n#oV49^0iY9G7i_OFYh7jTpyA5!^P0d zMra20@gVABBiF|qNe8l^nU&DY|Dc(VpqUlW`uos&81~vQ>{Whtf`<@l?b421577Do z&ijeFw)HWzwnt}gaA2=nDk+40fuyQ`A@B2%_a`M)%mw>nlD5r~wDn;*y*+yX_wbYT zh6n7;$a^~UJ{5Il@X-p{`}?gjzNt)Jc%(!Qh2E2p_blZ7wCPJ>@@}%HS@jW~MfGn$ zGpVRCuYmm}Xy)J0%wlL}5%dy)9sW&QX2{d!)6~F7djPjY6ysW*aiUiCh;*(#2KHXi z%slwg(Li4ctnHc|UezJ?t;oC0PUX`il}%Pvr4yB-KQ!+)`tlw$n;vuf#&gf#4fomH zJ9p*R!9QR>51yLNo*K-)8+i|A-+{bWbKakYW}b#-{sGO*gI*qoUS>ltkAOW1d4JIC zr)cxvC4rqv#;cjZYlnNCk)YzhdK)4gu^-Wj;9iACe$CI=#$+b=Ys3DJ3<36;@Fg#M zYLG9P^|2-edeQYUD!b%f(9ixi^jr6;rlPwe-z$S_G@>4%d#gwzKf@Urm;==I$zb;e zcxq^E4`8ndn|J7Cs?0;3X=`KY@r2r4Wa!0Y=lfCQ{cc+`w?i*up!Hjzmr;uHMj-DuC|Y-&qBYkj${nHxVV&U! zoi{hfq53m`FV%A|)7F=CZHHbaqCQ%+-C`dHy*se4)$D&#wE8M_7uaXVh(Ag5!&BEd zvqLjM?1f?2*CFq1*as=fxdPwgB&d`a@h{N)sO>BK{Q&z?h^PAUj@qv4Bi9(p8xFl( z5B8zZ%+=5go*k_IBiIKj${wKRf_-tU`Qb~;*_W*P$iC#SkJ?jhUuwg?-hn+E?08;5 zS^dnKA1nR%d;q=gLO;8sr$%PSvoX$l_T^yj5B5uN%_f@PXWkH_{QLY7z3;fPDeOxY zdog+$pQi@+Qa*espgt1nBdr+%&44}U${=>D<|JluU!0&$xV(oZ^rgN&9rdvnYWwNZ z@pgT5@YHbZs4-6L4H*eN%}WgIsV?*Tyj@?z=-bo7d1@G6vhr@#M~i(xfM)!)e!iX? z?ED=r`@S3XpFhix?{(3)C!&}6$?RoNAGwza=SyqZmzdqEk6dGDRX^z6|D2Q=`8#kc z`SvF8dOE@l{)sv-!6W+ic}~9M^VI0<+^dfbp4+}hT-wP!q=dV-)N2)vHR8|@qy^_a zj4zpaM}6cP6P#0@ZuGo*Ty?SJK6(Ly_Za-XNUuFOe?GrI+E2kPDh|EOOYkMHlP{UI z9na>2*!jM7cC`8VIL;e}s6s?y*2gMwp0C$w&-{E2`mj;()Y?E#_4!gLJOBTR!R?)! z&qH11`}dKEw-B`meSg5?P6YSd@QyZ@QAd^#x!0&TT&ttuOYefcmcIkw??mji^cur* z`t@?0m#DQ5kq|_U-K{aXi#77^5WfhqC~))&F@j&~u~mpZ{Q6AC7W@5;LUiYO%7i$F zM<&K!SRMdEU^y)8A6xlAA0d9`H=K)8snHs{0HiyghxQ9&i?|3A3ehN#19Qa5U4$s( zgBX*=ImwYmyvaPSN1R_~pC3A6e$3lwuhYUyG>UUun6FigXk}inSo90;gOKH965?0S C#gL)^ diff --git a/mkdocs.yml b/mkdocs.yml index 7046ba43fa..0d3320a230 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -22,7 +22,7 @@ theme: language: en custom_dir: docs/overrides/ logo: https://raw.githubusercontent.com/ultralytics/assets/main/logo/Ultralytics_Logotype_Reverse.svg - favicon: assets/favicon.ico + favicon: https://raw.githubusercontent.com/ultralytics/assets/refs/heads/main/logo/favicon-yolo.png icon: repo: fontawesome/brands/github # font: # disabled for faster page load times From df82ce458644fc5e6fd81d596971a4f3bee3cf1e Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Wed, 27 Nov 2024 14:11:24 +0100 Subject: [PATCH 05/25] Update format.yml Discord and Kaggle links (#17814) --- .github/workflows/format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 28720abfba..84f39b7ebd 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -35,7 +35,7 @@ jobs: If this is a custom training ❓ Question, please provide as much information as possible, including dataset image examples and training logs, and verify you are following our [Tips for Best Training Results](https://docs.ultralytics.com/guides/model-training-tips/). - Join the Ultralytics community where it suits you best. For real-time chat, head to [Discord](https://ultralytics.com/discord) 🎧. Prefer in-depth discussions? Check out [Discourse](https://community.ultralytics.com). Or dive into threads on our [Subreddit](https://reddit.com/r/ultralytics) to share knowledge with the community. + Join the Ultralytics community where it suits you best. For real-time chat, head to [Discord](https://discord.com/invite/ultralytics) 🎧. Prefer in-depth discussions? Check out [Discourse](https://community.ultralytics.com). Or dive into threads on our [Subreddit](https://reddit.com/r/Ultralytics) to share knowledge with the community. ## Upgrade From 4c59cf604b60dc4d49b2665a96c2f5c30112b891 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Wed, 27 Nov 2024 14:18:11 +0100 Subject: [PATCH 06/25] Update contributing.md with open-sourcing guide (#17832) Co-authored-by: UltralyticsAssistant --- docs/en/help/contributing.md | 124 +++++++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 12 deletions(-) diff --git a/docs/en/help/contributing.md b/docs/en/help/contributing.md index 1dad4f5314..c637c59366 100644 --- a/docs/en/help/contributing.md +++ b/docs/en/help/contributing.md @@ -11,18 +11,6 @@ Welcome! We're thrilled that you're considering contributing to our [Ultralytics Ultralytics open-source contributors -## Table of Contents - -1. [Code of Conduct](#code-of-conduct) -2. [Contributing via Pull Requests](#contributing-via-pull-requests) - - [CLA Signing](#cla-signing) - - [Google-Style Docstrings](#google-style-docstrings) - - [GitHub Actions CI Tests](#github-actions-ci-tests) -3. [Reporting Bugs](#reporting-bugs) -4. [License](#license) -5. [Conclusion](#conclusion) -6. [FAQ](#faq) - ## Code of Conduct To ensure a welcoming and inclusive environment for everyone, all contributors must adhere to our [Code of Conduct](https://docs.ultralytics.com/help/code_of_conduct/). Respect, kindness, and professionalism are at the heart of our community. @@ -131,6 +119,118 @@ Ultralytics uses the [GNU Affero General Public License v3.0 (AGPL-3.0)](https:/ We encourage all contributors to familiarize themselves with the terms of the AGPL-3.0 license to contribute effectively and ethically to the Ultralytics open-source community. +## Open-Sourcing Your Projects with YOLO and AGPL-3.0 Compliance + +If you're planning to develop and release your own project using YOLO models, the [GNU Affero General Public License v3.0 (AGPL-3.0)](https://www.gnu.org/licenses/agpl-3.0.html) ensures that all derivative works remain open and accessible. This section provides guidance, including steps, best practices, and requirements, to help you open-source your project while complying with AGPL-3.0. + +### Options for Starting Your Project + +You can kick-start your project using one of these approaches: + +1. **Fork the Ultralytics YOLO Repository** + Fork the official Ultralytics YOLO repository directly from [https://github.com/ultralytics/ultralytics](https://github.com/ultralytics/ultralytics). + + - Use this option if you plan to build directly on the latest YOLO implementation. + - Modify the forked code as needed while ensuring compliance with AGPL-3.0. + +2. **Start from the Ultralytics Template Repository** + Use the Ultralytics template repository available at [https://github.com/ultralytics/template](https://github.com/ultralytics/template). + - Ideal for starting a clean, modular project with pre-configured best practices. + - This option provides a lightweight starting point for projects that integrate or extend YOLO models. + +### What You Need to Open-Source + +To comply with AGPL-3.0, you must make the following components of your project openly available: + +1. **Your Entire Project Source Code**: + + - Include all code for the larger project containing your YOLO models, scripts, and utilities. + +2. **Model Weights** (if modified): + + - Share any fine-tuned or modified model weights as part of the open-source project. + +3. **Configuration Files**: + + - Provide configuration files such as `.yaml` or `.json` that define the training setup, hyperparameters, or deployment configurations. + +4. **Training Data (if redistributable)**: + + - If you include preprocessed or generated data that is redistributable, ensure it is part of the repository or clearly linked. + +5. **Web Application Components**: + + - Include all backend and frontend source code if your project is a web application, especially server-side components. + +6. **Documentation**: + + - Include clear documentation on how to use, build, and extend your project. + +7. **Build and Deployment Scripts**: + + - Share scripts for setting up the environment, building the application, and deploying it, such as `Dockerfiles`, `requirements.txt`, or `Makefiles`. + +8. **Testing Framework**: + + - Open-source your test cases, such as unit and integration tests, to ensure reproducibility and reliability. + +9. **Third-Party Modifications**: + - Provide source code for any third-party libraries you've modified. + +### Steps to Open-Source Your Project + +1. **Choose Your Starting Point**: + + - Fork the Ultralytics YOLO repository or start from the Ultralytics template repository. + +2. **Set Your License**: + + - Add a `LICENSE` file containing the AGPL-3.0 text. + +3. **Credit Upstream Contributions**: + + - Include attribution to Ultralytics YOLO in your README. For example: + ``` + This project builds on [Ultralytics YOLO](https://github.com/ultralytics/ultralytics), licensed under AGPL-3.0. + ``` + +4. **Make Your Code Public**: + + - Push your entire project (including the components listed above) to a public GitHub repository. + +5. **Document Your Project**: + + - Write a clear `README.md` with instructions for setup, usage, and contributions. + +6. **Enable Contributions**: + - Set up an issue tracker and contribution guidelines to foster collaboration. + +By following these steps and ensuring you include all necessary components, you'll comply with AGPL-3.0 and contribute meaningfully to the open-source community. Let's continue fostering collaboration and innovation in computer vision together! 🚀 + +### Example Repository Structure + +Below is an example structure for an AGPL-3.0 project. See [https://github.com/ultralytics/template](https://github.com/ultralytics/template) for details. + +``` +my-yolo-project/ +│ +├── LICENSE # AGPL-3.0 license text +├── README.md # Project overview and license information +├── src/ # Source code for the project +│ ├── model.py # YOLO-based model implementation +│ ├── utils.py # Utility scripts +│ └── ... +├── pyproject.toml # Python dependencies +├── tests/ # Unit and integration tests +├── .github/ # GitHub Actions for CI +│ └── workflows/ +│ └── ci.yml # Continuous integration configuration +└── docs/ # Project documentation + └── index.md +``` + +By following this guide, you can ensure your project remains compliant with AGPL-3.0 while contributing to the open-source community. Your adherence strengthens the ethos of collaboration, transparency, and accessibility that drives the success of projects like YOLO. + ## Conclusion Thank you for your interest in contributing to [Ultralytics](https://www.ultralytics.com/) [open-source](https://github.com/ultralytics) YOLO projects. Your participation is essential in shaping the future of our software and building a vibrant community of innovation and collaboration. Whether you're enhancing code, reporting bugs, or suggesting new features, your contributions are invaluable. From ff0b107bf5b19cbcef4ba2926e974e7470626064 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Wed, 27 Nov 2024 14:37:25 +0100 Subject: [PATCH 07/25] Fix YOLO11 usage (#17834) Signed-off-by: UltralyticsAssistant Co-authored-by: UltralyticsAssistant --- docs/en/integrations/albumentations.md | 4 ++-- examples/YOLO-Series-ONNXRuntime-Rust/README.md | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/en/integrations/albumentations.md b/docs/en/integrations/albumentations.md index fe7b081c2a..3fa4040bac 100644 --- a/docs/en/integrations/albumentations.md +++ b/docs/en/integrations/albumentations.md @@ -52,7 +52,7 @@ Now that we've covered what Albumentations is and what it can do, let's look at ### Installation -To use Albumentations with YOLOv11, start by making sure you have the necessary packages installed. If Albumentations isn't installed, the augmentations won't be applied during training. Once set up, you'll be ready to create an augmented dataset for training, with Albumentations integrated to enhance your model automatically. +To use Albumentations with YOLO11, start by making sure you have the necessary packages installed. If Albumentations isn't installed, the augmentations won't be applied during training. Once set up, you'll be ready to create an augmented dataset for training, with Albumentations integrated to enhance your model automatically. !!! tip "Installation" @@ -67,7 +67,7 @@ For detailed instructions and best practices related to the installation process ### Usage -After installing the necessary packages, you're ready to start using Albumentations with YOLO11. When you train YOLOv11, a set of augmentations is automatically applied through its integration with Albumentations, making it easy to enhance your model's performance. +After installing the necessary packages, you're ready to start using Albumentations with YOLO11. When you train YOLO11, a set of augmentations is automatically applied through its integration with Albumentations, making it easy to enhance your model's performance. !!! example "Usage" diff --git a/examples/YOLO-Series-ONNXRuntime-Rust/README.md b/examples/YOLO-Series-ONNXRuntime-Rust/README.md index ca05fbb180..0b6fabe20d 100644 --- a/examples/YOLO-Series-ONNXRuntime-Rust/README.md +++ b/examples/YOLO-Series-ONNXRuntime-Rust/README.md @@ -62,7 +62,7 @@ cargo run -r -- --task detect --ver v8 --nc 6 --model xxx.onnx # YOLOv8 # Classify cargo run -r -- --task classify --ver v5 --scale s --width 224 --height 224 --nc 1000 # YOLOv5 cargo run -r -- --task classify --ver v8 --scale n --width 224 --height 224 --nc 1000 # YOLOv8 -cargo run -r -- --task classify --ver v11 --scale n --width 224 --height 224 --nc 1000 # YOLOv11 +cargo run -r -- --task classify --ver v11 --scale n --width 224 --height 224 --nc 1000 # YOLO11 # Detect cargo run -r -- --task detect --ver v5 --scale n # YOLOv5 @@ -71,12 +71,12 @@ cargo run -r -- --task detect --ver v7 --scale t # YOLOv7 cargo run -r -- --task detect --ver v8 --scale n # YOLOv8 cargo run -r -- --task detect --ver v9 --scale t # YOLOv9 cargo run -r -- --task detect --ver v10 --scale n # YOLOv10 -cargo run -r -- --task detect --ver v11 --scale n # YOLOv11 +cargo run -r -- --task detect --ver v11 --scale n # YOLO11 cargo run -r -- --task detect --ver rtdetr --scale l # RTDETR # Pose cargo run -r -- --task pose --ver v8 --scale n # YOLOv8-Pose -cargo run -r -- --task pose --ver v11 --scale n # YOLOv11-Pose +cargo run -r -- --task pose --ver v11 --scale n # YOLO11-Pose # Segment cargo run -r -- --task segment --ver v5 --scale n # YOLOv5-Segment @@ -86,7 +86,7 @@ cargo run -r -- --task segment --ver v8 --model yolo/FastSAM-s-dyn-f16.onnx # F # OBB cargo run -r -- --ver v8 --task obb --scale n --width 1024 --height 1024 --source images/dota.png # YOLOv8-Obb -cargo run -r -- --ver v11 --task obb --scale n --width 1024 --height 1024 --source images/dota.png # YOLOv11-Obb +cargo run -r -- --ver v11 --task obb --scale n --width 1024 --height 1024 --source images/dota.png # YOLO11-Obb ``` **`cargo run -- --help` for more options** From 55b2137f187fc8faccaf0827462dcee288010de4 Mon Sep 17 00:00:00 2001 From: Paula Derrenger <107626595+pderrenger@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:02:45 +0100 Subject: [PATCH 08/25] Update Tasks Banner in README.md (#17833) Co-authored-by: Muhammad Rizwan Munawar Co-authored-by: Glenn Jocher --- README.md | 4 +++- README.zh-CN.md | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 61dd03d37c..04f9b36247 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,9 @@ See YOLO [Python Docs](https://docs.ultralytics.com/usage/python/) for more exam YOLO11 [Detect](https://docs.ultralytics.com/tasks/detect/), [Segment](https://docs.ultralytics.com/tasks/segment/) and [Pose](https://docs.ultralytics.com/tasks/pose/) models pretrained on the [COCO](https://docs.ultralytics.com/datasets/detect/coco/) dataset are available here, as well as YOLO11 [Classify](https://docs.ultralytics.com/tasks/classify/) models pretrained on the [ImageNet](https://docs.ultralytics.com/datasets/classify/imagenet/) dataset. [Track](https://docs.ultralytics.com/modes/track/) mode is available for all Detect, Segment and Pose models. -Ultralytics YOLO supported tasks + + Ultralytics YOLO supported tasks + All [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use. diff --git a/README.zh-CN.md b/README.zh-CN.md index 0ddb98ddb2..628f830c90 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -119,7 +119,9 @@ path = model.export(format="onnx") # 返回导出模型的路径 YOLO11 [检测](https://docs.ultralytics.com/tasks/detect/)、[分割](https://docs.ultralytics.com/tasks/segment/) 和 [姿态](https://docs.ultralytics.com/tasks/pose/) 模型在 [COCO](https://docs.ultralytics.com/datasets/detect/coco/) 数据集上进行预训练,这些模型可在此处获得,此外还有在 [ImageNet](https://docs.ultralytics.com/datasets/classify/imagenet/) 数据集上预训练的 YOLO11 [分类](https://docs.ultralytics.com/tasks/classify/) 模型。所有检测、分割和姿态模型均支持 [跟踪](https://docs.ultralytics.com/modes/track/) 模式。 -Ultralytics YOLO supported tasks + + Ultralytics YOLO supported tasks + 所有[模型](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models)在首次使用时自动从最新的 Ultralytics [发布](https://github.com/ultralytics/assets/releases)下载。 From 386a3b7625b3263989650d69eec6ed3b1ce067cd Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Wed, 27 Nov 2024 18:12:19 +0100 Subject: [PATCH 09/25] Fix region-counting indents (#17835) Signed-off-by: UltralyticsAssistant Co-authored-by: UltralyticsAssistant --- docs/en/guides/region-counting.md | 79 +++++++++++++------------ ultralytics/cfg/__init__.py | 1 - ultralytics/models/yolo/detect/train.py | 2 +- ultralytics/utils/torch_utils.py | 16 ++--- 4 files changed, 46 insertions(+), 52 deletions(-) diff --git a/docs/en/guides/region-counting.md b/docs/en/guides/region-counting.md index 94120bcab6..d1c439fa2f 100644 --- a/docs/en/guides/region-counting.md +++ b/docs/en/guides/region-counting.md @@ -4,7 +4,7 @@ description: Learn how to use Ultralytics YOLOv8 for precise object counting in keywords: object counting, regions, YOLOv8, computer vision, Ultralytics, efficiency, accuracy, automation, real-time, applications, surveillance, monitoring --- -# Object Counting in Different Regions using Ultralytics YOLOv8 🚀 +# Object Counting in Different Regions using Ultralytics YOLO 🚀 ## What is Object Counting in Regions? @@ -39,44 +39,45 @@ keywords: object counting, regions, YOLOv8, computer vision, Ultralytics, effici === "Python" ```python - import cv2 - from ultralytics import solutions - - cap = cv2.VideoCapture("Path/to/video/file.mp4") - assert cap.isOpened(), "Error reading video file" - w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) - - # Define region points - # region_points = [(20, 400), (1080, 400), (1080, 360), (20, 360)] # Pass region as list - - # pass region as dictionary - region_points = { - "region-01": [(50, 50), (250, 50), (250, 250), (50, 250)], - "region-02": [(640, 640), (780, 640), (780, 720), (640, 720)] - } - - # Video writer - video_writer = cv2.VideoWriter("region_counting.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) - - # Init Object Counter - region = solutions.RegionCounter( - show=True, - region=region_points, - model="yolo11n.pt", - ) - - # Process video - while cap.isOpened(): - success, im0 = cap.read() - if not success: - print("Video frame is empty or video processing has been successfully completed.") - break - im0 = region.count(im0) - video_writer.write(im0) - - cap.release() - video_writer.release() - cv2.destroyAllWindows() + import cv2 + + from ultralytics import solutions + + cap = cv2.VideoCapture("Path/to/video/file.mp4") + assert cap.isOpened(), "Error reading video file" + w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) + + # Define region points + # region_points = [(20, 400), (1080, 400), (1080, 360), (20, 360)] # Pass region as list + + # pass region as dictionary + region_points = { + "region-01": [(50, 50), (250, 50), (250, 250), (50, 250)], + "region-02": [(640, 640), (780, 640), (780, 720), (640, 720)], + } + + # Video writer + video_writer = cv2.VideoWriter("region_counting.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) + + # Init Object Counter + region = solutions.RegionCounter( + show=True, + region=region_points, + model="yolo11n.pt", + ) + + # Process video + while cap.isOpened(): + success, im0 = cap.read() + if not success: + print("Video frame is empty or video processing has been successfully completed.") + break + im0 = region.count(im0) + video_writer.write(im0) + + cap.release() + video_writer.release() + cv2.destroyAllWindows() ``` !!! tip "Ultralytics Example Code" diff --git a/ultralytics/cfg/__init__.py b/ultralytics/cfg/__init__.py index de9ef96a17..5f0222a71f 100644 --- a/ultralytics/cfg/__init__.py +++ b/ultralytics/cfg/__init__.py @@ -11,7 +11,6 @@ import cv2 from ultralytics.utils import ( ASSETS, - ASSETS_URL, DEFAULT_CFG, DEFAULT_CFG_DICT, DEFAULT_CFG_PATH, diff --git a/ultralytics/models/yolo/detect/train.py b/ultralytics/models/yolo/detect/train.py index 606b9fb92b..4a32acec1e 100644 --- a/ultralytics/models/yolo/detect/train.py +++ b/ultralytics/models/yolo/detect/train.py @@ -146,5 +146,5 @@ class DetectionTrainer(BaseTrainer): """Get batch size by calculating memory occupation of model.""" train_dataset = self.build_dataset(self.trainset, mode="train", batch=16) # 4 for mosaic augmentation - max_num_obj = max(len(l["cls"]) for l in train_dataset.labels) * 4 + max_num_obj = max(len(label["cls"]) for label in train_dataset.labels) * 4 return super().auto_batch(max_num_obj) diff --git a/ultralytics/utils/torch_utils.py b/ultralytics/utils/torch_utils.py index b413297be0..a6e7447629 100644 --- a/ultralytics/utils/torch_utils.py +++ b/ultralytics/utils/torch_utils.py @@ -301,28 +301,22 @@ def fuse_deconv_and_bn(deconv, bn): def model_info(model, detailed=False, verbose=True, imgsz=640): - """ - Model information. - - imgsz may be int or list, i.e. imgsz=640 or imgsz=[640, 320]. - """ + """Print and return detailed model information layer by layer.""" if not verbose: return n_p = get_num_params(model) # number of parameters n_g = get_num_gradients(model) # number of gradients n_l = len(list(model.modules())) # number of layers if detailed: - LOGGER.info( - f"{'layer':>5} {'name':>40} {'gradient':>9} {'parameters':>12} {'shape':>20} {'mu':>10} {'sigma':>10}" - ) + LOGGER.info(f"{'layer':>5}{'name':>40}{'gradient':>10}{'parameters':>12}{'shape':>20}{'mu':>10}{'sigma':>10}") for i, (name, p) in enumerate(model.named_parameters()): name = name.replace("module_list.", "") LOGGER.info( - "%5g %40s %9s %12g %20s %10.3g %10.3g %10s" - % (i, name, p.requires_grad, p.numel(), list(p.shape), p.mean(), p.std(), p.dtype) + f"{i:>5g}{name:>40s}{p.requires_grad!r:>10}{p.numel():>12g}{str(list(p.shape)):>20s}" + f"{p.mean():>10.3g}{p.std():>10.3g}{str(p.dtype):>15s}" ) - flops = get_flops(model, imgsz) + flops = get_flops(model, imgsz) # imgsz may be int or list, i.e. imgsz=640 or imgsz=[640, 320] fused = " (fused)" if getattr(model, "is_fused", lambda: False)() else "" fs = f", {flops:.1f} GFLOPs" if flops else "" yaml_file = getattr(model, "yaml_file", "") or getattr(model, "yaml", {}).get("yaml_file", "") From 7e2ce71c2943d9d7fda0ab91cf784111794d9a5e Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Thu, 28 Nov 2024 02:05:04 +0100 Subject: [PATCH 10/25] Update Tasks banner spacing (#17843) --- README.md | 10 +++++----- README.zh-CN.md | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 04f9b36247..d1e6bb5f20 100644 --- a/README.md +++ b/README.md @@ -117,13 +117,13 @@ See YOLO [Python Docs](https://docs.ultralytics.com/usage/python/) for more exam ##
Models
-YOLO11 [Detect](https://docs.ultralytics.com/tasks/detect/), [Segment](https://docs.ultralytics.com/tasks/segment/) and [Pose](https://docs.ultralytics.com/tasks/pose/) models pretrained on the [COCO](https://docs.ultralytics.com/datasets/detect/coco/) dataset are available here, as well as YOLO11 [Classify](https://docs.ultralytics.com/tasks/classify/) models pretrained on the [ImageNet](https://docs.ultralytics.com/datasets/classify/imagenet/) dataset. [Track](https://docs.ultralytics.com/modes/track/) mode is available for all Detect, Segment and Pose models. +YOLO11 [Detect](https://docs.ultralytics.com/tasks/detect/), [Segment](https://docs.ultralytics.com/tasks/segment/) and [Pose](https://docs.ultralytics.com/tasks/pose/) models pretrained on the [COCO](https://docs.ultralytics.com/datasets/detect/coco/) dataset are available here, as well as YOLO11 [Classify](https://docs.ultralytics.com/tasks/classify/) models pretrained on the [ImageNet](https://docs.ultralytics.com/datasets/classify/imagenet/) dataset. [Track](https://docs.ultralytics.com/modes/track/) mode is available for all Detect, Segment and Pose models. All [Models](https://docs.ultralytics.com/models/) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use. Ultralytics YOLO supported tasks - -All [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use. +
+
Detection (COCO) @@ -214,9 +214,9 @@ See [OBB Docs](https://docs.ultralytics.com/tasks/obb/) for usage examples with Our key integrations with leading AI platforms extend the functionality of Ultralytics' offerings, enhancing tasks like dataset labeling, training, visualization, and model management. Discover how Ultralytics, in collaboration with [W&B](https://docs.wandb.ai/guides/integrations/ultralytics/), [Comet](https://bit.ly/yolov8-readme-comet), [Roboflow](https://roboflow.com/?ref=ultralytics) and [OpenVINO](https://docs.ultralytics.com/integrations/openvino/), can optimize your AI workflow. -
-Ultralytics active learning integrations + Ultralytics active learning integrations +

diff --git a/README.zh-CN.md b/README.zh-CN.md index 628f830c90..3dca72735f 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -117,13 +117,13 @@ path = model.export(format="onnx") # 返回导出模型的路径 ##
模型
-YOLO11 [检测](https://docs.ultralytics.com/tasks/detect/)、[分割](https://docs.ultralytics.com/tasks/segment/) 和 [姿态](https://docs.ultralytics.com/tasks/pose/) 模型在 [COCO](https://docs.ultralytics.com/datasets/detect/coco/) 数据集上进行预训练,这些模型可在此处获得,此外还有在 [ImageNet](https://docs.ultralytics.com/datasets/classify/imagenet/) 数据集上预训练的 YOLO11 [分类](https://docs.ultralytics.com/tasks/classify/) 模型。所有检测、分割和姿态模型均支持 [跟踪](https://docs.ultralytics.com/modes/track/) 模式。 +YOLO11 [检测](https://docs.ultralytics.com/tasks/detect/)、[分割](https://docs.ultralytics.com/tasks/segment/) 和 [姿态](https://docs.ultralytics.com/tasks/pose/) 模型在 [COCO](https://docs.ultralytics.com/datasets/detect/coco/) 数据集上进行预训练,这些模型可在此处获得,此外还有在 [ImageNet](https://docs.ultralytics.com/datasets/classify/imagenet/) 数据集上预训练的 YOLO11 [分类](https://docs.ultralytics.com/tasks/classify/) 模型。所有检测、分割和姿态模型均支持 [跟踪](https://docs.ultralytics.com/modes/track/) 模式。所有[模型](https://docs.ultralytics.com/models/)在首次使用时自动从最新的 Ultralytics [发布](https://github.com/ultralytics/assets/releases)下载。 Ultralytics YOLO supported tasks - -所有[模型](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models)在首次使用时自动从最新的 Ultralytics [发布](https://github.com/ultralytics/assets/releases)下载。 +
+
检测 (COCO) @@ -214,9 +214,9 @@ YOLO11 [检测](https://docs.ultralytics.com/tasks/detect/)、[分割](https://d 我们与领先的 AI 平台的关键集成扩展了 Ultralytics 产品的功能,提升了数据集标注、训练、可视化和模型管理等任务。探索 Ultralytics 如何通过与 [W&B](https://docs.wandb.ai/guides/integrations/ultralytics/)、[Comet](https://bit.ly/yolov8-readme-comet)、[Roboflow](https://roboflow.com/?ref=ultralytics) 和 [OpenVINO](https://docs.ultralytics.com/integrations/openvino/) 的合作,优化您的 AI 工作流程。 -
-Ultralytics active learning integrations + Ultralytics active learning integrations +

From 408d4380a474d5cf120bea7f112a5db5cb79e485 Mon Sep 17 00:00:00 2001 From: Muhammad Rizwan Munawar Date: Thu, 28 Nov 2024 06:05:23 +0500 Subject: [PATCH 11/25] Add functions descriptions in `plotting.py` (#17813) Co-authored-by: UltralyticsAssistant Co-authored-by: Ultralytics Assistant <135830346+UltralyticsAssistant@users.noreply.github.com> Co-authored-by: Glenn Jocher --- ultralytics/utils/plotting.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/ultralytics/utils/plotting.py b/ultralytics/utils/plotting.py index b2bac871c0..3943a87e8c 100644 --- a/ultralytics/utils/plotting.py +++ b/ultralytics/utils/plotting.py @@ -238,7 +238,16 @@ class Annotator: } def get_txt_color(self, color=(128, 128, 128), txt_color=(255, 255, 255)): - """Assign text color based on background color.""" + """ + Assign text color based on background color. + + Args: + color (tuple, optional): The background color of the rectangle for text (B, G, R). + txt_color (tuple, optional): The color of the text (R, G, B). + + Returns: + txt_color (tuple): Text color for label + """ if color in self.dark_colors: return 104, 31, 17 elif color in self.light_colors: @@ -544,7 +553,9 @@ class Annotator: bbox (tuple): Bounding box coordinates in the format (x_min, y_min, x_max, y_max). Returns: - angle (degree): Degree value of angle between three points + width (float): Width of the bounding box. + height (float): Height of the bounding box. + area (float): Area enclosed by the bounding box. """ x_min, y_min, x_max, y_max = bbox width = x_max - x_min From 0183eaeeba746bb20a88a2b5e7af5e4078249bac Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Thu, 28 Nov 2024 02:08:49 +0100 Subject: [PATCH 12/25] Remove Docs Tasks banner linebreak (#17844) --- docs/en/tasks/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/en/tasks/index.md b/docs/en/tasks/index.md index b31b96c447..d71825fa8e 100644 --- a/docs/en/tasks/index.md +++ b/docs/en/tasks/index.md @@ -6,7 +6,6 @@ keywords: Ultralytics YOLO11, detection, segmentation, classification, oriented # Ultralytics YOLO11 Tasks -
Ultralytics YOLO supported tasks YOLO11 is an AI framework that supports multiple [computer vision](https://www.ultralytics.com/glossary/computer-vision-cv) **tasks**. The framework can be used to perform [detection](detect.md), [segmentation](segment.md), [obb](obb.md), [classification](classify.md), and [pose](pose.md) estimation. Each of these tasks has a different objective and use case. From c1554935e6568ec4b27fc0c25d7e36bb32aaa24c Mon Sep 17 00:00:00 2001 From: Muhammad Rizwan Munawar Date: Fri, 29 Nov 2024 00:02:34 +0500 Subject: [PATCH 13/25] Add https://youtu.be/-aYO-6VaDrw and https://youtu.be/M7xWw4Iodhg to docs (#17863) --- docs/en/datasets/segment/carparts-seg.md | 4 +-- docs/en/guides/model-evaluation-insights.md | 11 +++++++ docs/en/guides/region-counting.md | 4 +-- docs/en/models/sam-2.md | 11 +++++++ docs/en/modes/benchmark.md | 4 +-- docs/en/tasks/pose.md | 32 +++++++-------------- 6 files changed, 38 insertions(+), 28 deletions(-) diff --git a/docs/en/datasets/segment/carparts-seg.md b/docs/en/datasets/segment/carparts-seg.md index 96615752bf..dbc69ce4a7 100644 --- a/docs/en/datasets/segment/carparts-seg.md +++ b/docs/en/datasets/segment/carparts-seg.md @@ -12,13 +12,13 @@ Whether you're working on automotive research, developing AI solutions for vehic


-
- Watch: Carparts Instance Segmentation Using Ultralytics HUB + Watch: Carparts Instance Segmentation with Ultralytics YOLO11

## Dataset Structure diff --git a/docs/en/guides/model-evaluation-insights.md b/docs/en/guides/model-evaluation-insights.md index 24514f4a4f..5bd8bedead 100644 --- a/docs/en/guides/model-evaluation-insights.md +++ b/docs/en/guides/model-evaluation-insights.md @@ -10,6 +10,17 @@ keywords: Model Evaluation, Machine Learning Model Evaluation, Fine Tuning Machi Once you've [trained](./model-training-tips.md) your computer vision model, evaluating and refining it to perform optimally is essential. Just training your model isn't enough. You need to make sure that your model is accurate, efficient, and fulfills the [objective](./defining-project-goals.md) of your computer vision project. By evaluating and fine-tuning your model, you can identify weaknesses, improve its accuracy, and boost overall performance. +

+
+ +
+ Watch: Insights into Model Evaluation and Fine-Tuning | Tips for Improving Mean Average Precision +

+ In this guide, we'll share insights on model evaluation and fine-tuning that'll make this [step of a computer vision project](./steps-of-a-cv-project.md) more approachable. We'll discuss how to understand evaluation metrics and implement fine-tuning techniques, giving you the knowledge to elevate your model's capabilities. ## Evaluating Model Performance Using Metrics diff --git a/docs/en/guides/region-counting.md b/docs/en/guides/region-counting.md index d1c439fa2f..d2c9a55a11 100644 --- a/docs/en/guides/region-counting.md +++ b/docs/en/guides/region-counting.md @@ -12,13 +12,13 @@ keywords: object counting, regions, YOLOv8, computer vision, Ultralytics, effici


-
- Watch: Ultralytics YOLOv8 Object Counting in Multiple & Movable Regions + Watch: Object Counting in Different Regions using Ultralytics YOLO11 | Ultralytics Solutions 🚀

## Advantages of Object Counting in Regions? diff --git a/docs/en/models/sam-2.md b/docs/en/models/sam-2.md index 983d8cdcd9..8d39b5eaec 100644 --- a/docs/en/models/sam-2.md +++ b/docs/en/models/sam-2.md @@ -271,6 +271,17 @@ Auto-annotation is a powerful feature of SAM 2, enabling users to generate segme ### How to Auto-Annotate with SAM 2 +

+
+ +
+ Watch: Auto Annotation with Meta's Segment Anything 2 Model using Ultralytics | Data Labeling +

+ To auto-annotate your dataset using SAM 2, follow this example: !!! example "Auto-Annotation Example" diff --git a/docs/en/modes/benchmark.md b/docs/en/modes/benchmark.md index 587462dfee..149ad5a273 100644 --- a/docs/en/modes/benchmark.md +++ b/docs/en/modes/benchmark.md @@ -47,13 +47,13 @@ Once your model is trained and validated, the next logical step is to evaluate i


-
- Watch: Ultralytics Modes Tutorial: Benchmark + Watch: Benchmark Ultralytics YOLO11 Models | How to Compare Model Performance on Different Hardware?

## Why Is Benchmarking Crucial? diff --git a/docs/en/tasks/pose.md b/docs/en/tasks/pose.md index 0523239fc5..7efe7414fd 100644 --- a/docs/en/tasks/pose.md +++ b/docs/en/tasks/pose.md @@ -13,28 +13,16 @@ Pose estimation is a task that involves identifying the location of specific poi The output of a pose estimation model is a set of points that represent the keypoints on an object in the image, usually along with the confidence scores for each point. Pose estimation is a good choice when you need to identify specific parts of an object in a scene, and their location in relation to each other. - - - - - -
- -
- Watch: Pose Estimation with Ultralytics YOLO. -
- -
- Watch: Pose Estimation with Ultralytics HUB. -
+

+
+ +
+ Watch: Ultralytics YOLO11 Pose Estimation Tutorial | Real-Time Object Tracking and Human Pose Detection +

!!! tip From 4a5dbc0bfbd22d5542044e19f2df7550e61e5737 Mon Sep 17 00:00:00 2001 From: Mohammed Yasin <32206511+Y-T-G@users.noreply.github.com> Date: Fri, 29 Nov 2024 05:49:44 +0800 Subject: [PATCH 14/25] Add `classes` to train arguments (#17856) Co-authored-by: UltralyticsAssistant Co-authored-by: Glenn Jocher --- docs/en/macros/train-args.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/macros/train-args.md b/docs/en/macros/train-args.md index 924bd31345..e9e026e640 100644 --- a/docs/en/macros/train-args.md +++ b/docs/en/macros/train-args.md @@ -20,6 +20,7 @@ | `seed` | `0` | Sets the random seed for training, ensuring reproducibility of results across runs with the same configurations. | | `deterministic` | `True` | Forces deterministic algorithm use, ensuring reproducibility but may affect performance and speed due to the restriction on non-deterministic algorithms. | | `single_cls` | `False` | Treats all classes in multi-class datasets as a single class during training. Useful for binary classification tasks or when focusing on object presence rather than classification. | +| `classes` | `None` | Specifies a list of class IDs to train on. Useful for filtering out and focusing only on certain classes during training. | | `rect` | `False` | Enables rectangular training, optimizing batch composition for minimal padding. Can improve efficiency and speed but may affect model accuracy. | | `cos_lr` | `False` | Utilizes a cosine [learning rate](https://www.ultralytics.com/glossary/learning-rate) scheduler, adjusting the learning rate following a cosine curve over epochs. Helps in managing learning rate for better convergence. | | `close_mosaic` | `10` | Disables mosaic [data augmentation](https://www.ultralytics.com/glossary/data-augmentation) in the last N epochs to stabilize training before completion. Setting to 0 disables this feature. | From e668de6e02e722a3cc546ccffe36a8c57e25e89f Mon Sep 17 00:00:00 2001 From: Mohammed Yasin <32206511+Y-T-G@users.noreply.github.com> Date: Fri, 29 Nov 2024 05:50:04 +0800 Subject: [PATCH 15/25] Add BGR to RGB conversion in LibTorch example (#17864) --- examples/YOLOv8-LibTorch-CPP-Inference/main.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/YOLOv8-LibTorch-CPP-Inference/main.cc b/examples/YOLOv8-LibTorch-CPP-Inference/main.cc index b68b7f7e4b..0937b56828 100644 --- a/examples/YOLOv8-LibTorch-CPP-Inference/main.cc +++ b/examples/YOLOv8-LibTorch-CPP-Inference/main.cc @@ -226,6 +226,7 @@ int main() { cv::Mat image = cv::imread("/path/to/bus.jpg"); cv::Mat input_image; letterbox(image, input_image, {640, 640}); + cv::cvtColor(input_image, input_image, cv::COLOR_BGR2RGB); torch::Tensor image_tensor = torch::from_blob(input_image.data, {input_image.rows, input_image.cols, 3}, torch::kByte).to(device); image_tensor = image_tensor.toType(torch::kFloat32).div(255); From 29826241a00cff032e0739bad49c28bede59497f Mon Sep 17 00:00:00 2001 From: Void <94819873+WYYAHYT@users.noreply.github.com> Date: Fri, 29 Nov 2024 05:51:33 +0800 Subject: [PATCH 16/25] `__getattr__` support to access YOLO attributes via Model class (#17805) Co-authored-by: UltralyticsAssistant Co-authored-by: Ultralytics Assistant <135830346+UltralyticsAssistant@users.noreply.github.com> Co-authored-by: Glenn Jocher --- ultralytics/engine/model.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/ultralytics/engine/model.py b/ultralytics/engine/model.py index 667b54eba2..874613d2f1 100644 --- a/ultralytics/engine/model.py +++ b/ultralytics/engine/model.py @@ -144,6 +144,9 @@ class Model(nn.Module): else: self._load(model, task=task) + # Delete super().training for accessing self.model.training + del self.training + def __call__( self, source: Union[str, Path, int, Image.Image, list, tuple, np.ndarray, torch.Tensor] = None, @@ -1143,3 +1146,29 @@ class Model(nn.Module): """ self.model.eval() return self + + def __getattr__(self, name): + """ + Enables accessing model attributes directly through the Model class. + + This method provides a way to access attributes of the underlying model directly through the Model class + instance. It first checks if the requested attribute is 'model', in which case it returns the model from + the module dictionary. Otherwise, it delegates the attribute lookup to the underlying model. + + Args: + name (str): The name of the attribute to retrieve. + + Returns: + (Any): The requested attribute value. + + Raises: + AttributeError: If the requested attribute does not exist in the model. + + Examples: + >>> model = YOLO("yolo11n.pt") + >>> print(model.stride) + >>> print(model.task) + """ + if name == "model": + return self._modules["model"] + return getattr(self.model, name) From e60992214c91d3ba169965053af69d6eb233b45e Mon Sep 17 00:00:00 2001 From: Mohammed Yasin <32206511+Y-T-G@users.noreply.github.com> Date: Fri, 29 Nov 2024 06:08:28 +0800 Subject: [PATCH 17/25] `ultralytics 8.3.39` fix classification validation loss scaling (#17851) Co-authored-by: Glenn Jocher --- ultralytics/__init__.py | 2 +- ultralytics/models/yolo/classify/predict.py | 2 +- ultralytics/nn/modules/head.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ultralytics/__init__.py b/ultralytics/__init__.py index fe22ab07a7..7b73169deb 100644 --- a/ultralytics/__init__.py +++ b/ultralytics/__init__.py @@ -1,6 +1,6 @@ # Ultralytics YOLO 🚀, AGPL-3.0 license -__version__ = "8.3.38" +__version__ = "8.3.39" import os diff --git a/ultralytics/models/yolo/classify/predict.py b/ultralytics/models/yolo/classify/predict.py index 596931a176..b75a194984 100644 --- a/ultralytics/models/yolo/classify/predict.py +++ b/ultralytics/models/yolo/classify/predict.py @@ -54,6 +54,6 @@ class ClassificationPredictor(BasePredictor): orig_imgs = ops.convert_torch2numpy_batch(orig_imgs) return [ - Results(orig_img, path=img_path, names=self.model.names, probs=pred) + Results(orig_img, path=img_path, names=self.model.names, probs=pred.softmax(0)) for pred, orig_img, img_path in zip(preds, orig_imgs, self.batch[0]) ] diff --git a/ultralytics/nn/modules/head.py b/ultralytics/nn/modules/head.py index 29a1953e47..25964ac2e5 100644 --- a/ultralytics/nn/modules/head.py +++ b/ultralytics/nn/modules/head.py @@ -296,7 +296,7 @@ class Classify(nn.Module): if isinstance(x, list): x = torch.cat(x, 1) x = self.linear(self.drop(self.pool(self.conv(x)).flatten(1))) - return x if self.training else x.softmax(1) + return x class WorldDetect(Detect): From 6696e88a25d9a3df9e9f8c133715ba34222884e7 Mon Sep 17 00:00:00 2001 From: Skillnoob <78843978+Skillnoob@users.noreply.github.com> Date: Sun, 1 Dec 2024 10:07:24 -0800 Subject: [PATCH 18/25] GPU CI Fix wrong Ultralytics Installation (#17883) --- .github/workflows/ci.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3a65188e4c..7c504d949e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -214,7 +214,8 @@ jobs: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v4 - name: Install requirements - run: uv pip install --system . pytest-cov + shell: bash # for Windows compatibility + run: uv pip install --system -e . pytest-cov - name: Check environment run: | yolo checks From 00fc95fb9dc6ba339853c1f5f658714dbe24f7a2 Mon Sep 17 00:00:00 2001 From: Lakshantha Dissanayake Date: Sun, 1 Dec 2024 10:09:00 -0800 Subject: [PATCH 19/25] Fix typo in Sony IMX500 doc (#17871) Co-authored-by: Glenn Jocher --- docs/en/integrations/sony-imx500.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/integrations/sony-imx500.md b/docs/en/integrations/sony-imx500.md index 88338ebb67..5dccbc5585 100644 --- a/docs/en/integrations/sony-imx500.md +++ b/docs/en/integrations/sony-imx500.md @@ -162,7 +162,7 @@ cd examples/imx500 Step 3: Run YOLOv8 object detection, using the labels.txt file that has been generated during the IMX500 export. ```bash -python imx500_object_detection_demo.py --model --fps 25 --bbox-normalization --ignore-dash-labels --bbox-order xy –labels +python imx500_object_detection_demo.py --model --fps 25 --bbox-normalization --ignore-dash-labels --bbox-order xy --labels ``` Then you will be able to see live inference output as follows From 5c2cdb68411ccea2cd9130746e7f8ce70ec3e50d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dr=2E=20Artificial=E6=9B=BE=E5=B0=8F=E5=81=A5?= <875100501@qq.com> Date: Mon, 2 Dec 2024 02:18:55 +0800 Subject: [PATCH 20/25] wrong expression fix Update README.md (#17868) Co-authored-by: Glenn Jocher --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d1e6bb5f20..b03e95d034 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ YOLO may be used directly in the Command Line Interface (CLI) with a `yolo` comm yolo predict model=yolo11n.pt source='https://ultralytics.com/images/bus.jpg' ``` -`yolo` can be used for a variety of tasks and modes and accepts additional arguments, i.e. `imgsz=640`. See the YOLO [CLI Docs](https://docs.ultralytics.com/usage/cli/) for examples. +`yolo` can be used for a variety of tasks and modes and accepts additional arguments, e.g. `imgsz=640`. See the YOLO [CLI Docs](https://docs.ultralytics.com/usage/cli/) for examples. ### Python From 69c12a4ba36d3dd9c6f541085125de588df15be3 Mon Sep 17 00:00:00 2001 From: Muhammad Rizwan Munawar Date: Sun, 1 Dec 2024 23:19:36 +0500 Subject: [PATCH 21/25] Add more tracking args for solutions (#17878) Co-authored-by: UltralyticsAssistant Co-authored-by: Glenn Jocher --- ultralytics/solutions/ai_gym.py | 2 +- ultralytics/solutions/solutions.py | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ultralytics/solutions/ai_gym.py b/ultralytics/solutions/ai_gym.py index 68e3697627..359ed9dd49 100644 --- a/ultralytics/solutions/ai_gym.py +++ b/ultralytics/solutions/ai_gym.py @@ -71,7 +71,7 @@ class AIGym(BaseSolution): >>> processed_image = gym.monitor(image) """ # Extract tracks - tracks = self.model.track(source=im0, persist=True, classes=self.CFG["classes"])[0] + tracks = self.model.track(source=im0, persist=True, classes=self.CFG["classes"], **self.track_add_args)[0] if tracks.boxes.id is not None: # Extract and check keypoints diff --git a/ultralytics/solutions/solutions.py b/ultralytics/solutions/solutions.py index fc05d42d6e..f47223b570 100644 --- a/ultralytics/solutions/solutions.py +++ b/ultralytics/solutions/solutions.py @@ -74,6 +74,10 @@ class BaseSolution: self.model = YOLO(self.CFG["model"]) self.names = self.model.names + self.track_add_args = { # Tracker additional arguments for advance configuration + k: self.CFG[k] for k in ["verbose", "iou", "conf", "device", "max_det", "half", "tracker"] + } + if IS_CLI and self.CFG["source"] is None: d_s = "solutions_ci_demo.mp4" if "-pose" not in self.CFG["model"] else "solution_ci_pose_demo.mp4" LOGGER.warning(f"⚠️ WARNING: source not provided. using default source {ASSETS_URL}/{d_s}") @@ -98,7 +102,7 @@ class BaseSolution: >>> frame = cv2.imread("path/to/image.jpg") >>> solution.extract_tracks(frame) """ - self.tracks = self.model.track(source=im0, persist=True, classes=self.CFG["classes"]) + self.tracks = self.model.track(source=im0, persist=True, classes=self.CFG["classes"], **self.track_add_args) # Extract tracks for OBB or object detection self.track_data = self.tracks[0].obb or self.tracks[0].boxes From 5015d1e01b60894935327a4450d86d78ff0f2a99 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Mon, 2 Dec 2024 15:48:02 +0100 Subject: [PATCH 22/25] `uv pip install` for Benchmarks (#17749) Co-authored-by: Ultralytics Assistant <135830346+UltralyticsAssistant@users.noreply.github.com> Co-authored-by: Laughing <61612323+Laughing-q@users.noreply.github.com> Co-authored-by: Laughing-q <1185102784@qq.com> --- .github/workflows/ci.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7c504d949e..e0eff35cb8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -102,21 +102,19 @@ jobs: python-version: ["3.11"] model: [yolo11n] steps: + - uses: astral-sh/setup-uv@v3 - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - cache: "pip" # caching pip dependencies - name: Install requirements shell: bash # for Windows compatibility run: | - # Warnings: uv causes numpy errors during benchmarking - python -m pip install --upgrade pip wheel - pip install -e ".[export]" "coverage[toml]" --extra-index-url https://download.pytorch.org/whl/cpu + uv pip install --system -e ".[export]" "coverage[toml]" --extra-index-url https://download.pytorch.org/whl/cpu --index-strategy unsafe-first-match - name: Check environment run: | yolo checks - pip list + uv pip list - name: Benchmark DetectionModel shell: bash run: coverage run -a --source=ultralytics -m ultralytics.cfg.__init__ benchmark model='path with spaces/${{ matrix.model }}.pt' imgsz=160 verbose=0.309 From d59a66f7c2dc21f0f57f3116b0904fb222831a91 Mon Sep 17 00:00:00 2001 From: Lakshantha Dissanayake Date: Mon, 2 Dec 2024 06:49:32 -0800 Subject: [PATCH 23/25] Add `MNN` benchmarks to Raspberry Pi doc (#17910) Co-authored-by: Glenn Jocher --- docs/en/guides/raspberry-pi.md | 47 +++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/docs/en/guides/raspberry-pi.md b/docs/en/guides/raspberry-pi.md index a834d8f074..ef41d0f8cf 100644 --- a/docs/en/guides/raspberry-pi.md +++ b/docs/en/guides/raspberry-pi.md @@ -142,9 +142,10 @@ YOLO11 benchmarks were run by the Ultralytics team on nine different model forma We have only included benchmarks for YOLO11n and YOLO11s models because other models sizes are too big to run on the Raspberry Pis and does not offer decent performance. -
- YOLO11 benchmarks on RPi 5 -
+
+ YOLO11 benchmarks on RPi 5 +
Benchmarked with Ultralytics v8.3.39
+
### Detailed Comparison Table @@ -156,29 +157,33 @@ The below table represents the benchmark results for two different models (YOLO1 | Format | Status | Size on disk (MB) | mAP50-95(B) | Inference time (ms/im) | |---------------|--------|-------------------|-------------|------------------------| - | PyTorch | ✅ | 5.4 | 0.61 | 524.828 | - | TorchScript | ✅ | 10.5 | 0.6082 | 666.874 | - | ONNX | ✅ | 10.2 | 0.6082 | 181.818 | - | OpenVINO | ✅ | 10.4 | 0.6082 | 530.224 | - | TF SavedModel | ✅ | 25.8 | 0.6082 | 405.964 | - | TF GraphDef | ✅ | 10.3 | 0.6082 | 473.558 | - | TF Lite | ✅ | 10.3 | 0.6082 | 324.158 | - | PaddlePaddle | ✅ | 20.4 | 0.6082 | 644.312 | - | NCNN | ✅ | 10.2 | 0.6106 | 93.938 | + | PyTorch | ✅ | 5.4 | 0.6100 | 405.238 | + | TorchScript | ✅ | 10.5 | 0.6082 | 526.628 | + | ONNX | ✅ | 10.2 | 0.6082 | 168.082 | + | OpenVINO | ✅ | 10.4 | 0.6082 | 81.192 | + | TF SavedModel | ✅ | 25.8 | 0.6082 | 377.968 | + | TF GraphDef | ✅ | 10.3 | 0.6082 | 487.244 | + | TF Lite | ✅ | 10.3 | 0.6082 | 317.398 | + | PaddlePaddle | ✅ | 20.4 | 0.6082 | 561.892 | + | MNN | ✅ | 10.1 | 0.6106 | 112.554 | + | NCNN | ✅ | 10.2 | 0.6106 | 88.026 | === "YOLO11s" | Format | Status | Size on disk (MB) | mAP50-95(B) | Inference time (ms/im) | |---------------|--------|-------------------|-------------|------------------------| - | PyTorch | ✅ | 18.4 | 0.7526 | 1226.426 | - | TorchScript | ✅ | 36.5 | 0.7416 | 1507.95 | - | ONNX | ✅ | 36.3 | 0.7416 | 415.24 | - | OpenVINO | ✅ | 36.4 | 0.7416 | 1167.102 | - | TF SavedModel | ✅ | 91.1 | 0.7416 | 776.14 | - | TF GraphDef | ✅ | 36.4 | 0.7416 | 1014.396 | - | TF Lite | ✅ | 36.4 | 0.7416 | 845.934 | - | PaddlePaddle | ✅ | 72.5 | 0.7416 | 1567.824 | - | NCNN | ✅ | 36.2 | 0.7419 | 197.358 | + | PyTorch | ✅ | 18.4 | 0.7526 | 1011.60 | + | TorchScript | ✅ | 36.5 | 0.7416 | 1268.502 | + | ONNX | ✅ | 36.3 | 0.7416 | 324.17 | + | OpenVINO | ✅ | 36.4 | 0.7416 | 179.324 | + | TF SavedModel | ✅ | 91.1 | 0.7416 | 714.382 | + | TF GraphDef | ✅ | 36.4 | 0.7416 | 1019.83 | + | TF Lite | ✅ | 36.4 | 0.7416 | 849.86 | + | PaddlePaddle | ✅ | 72.5 | 0.7416 | 1276.34 | + | MNN | ✅ | 36.2 | 0.7409 | 273.032 | + | NCNN | ✅ | 36.2 | 0.7419 | 194.858 | + + Benchmarked with Ultralytics `v8.3.39` ## Reproduce Our Results From 9cf7b5039221b31027236aba1f2dd570a06ace89 Mon Sep 17 00:00:00 2001 From: Muhammad Rizwan Munawar Date: Mon, 2 Dec 2024 19:50:23 +0500 Subject: [PATCH 24/25] Add arguments for solutions in `usage/cfg` docs page (#17920) Co-authored-by: UltralyticsAssistant --- docs/en/guides/instance-segmentation-and-tracking.md | 8 -------- docs/en/macros/solutions-args.md | 11 +++++++++++ docs/en/usage/cfg.md | 8 ++++++++ 3 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 docs/en/macros/solutions-args.md diff --git a/docs/en/guides/instance-segmentation-and-tracking.md b/docs/en/guides/instance-segmentation-and-tracking.md index a910a21d8f..12cd7477a6 100644 --- a/docs/en/guides/instance-segmentation-and-tracking.md +++ b/docs/en/guides/instance-segmentation-and-tracking.md @@ -82,15 +82,11 @@ There are two types of instance segmentation tracking available in the Ultralyti === "Instance Segmentation with Object Tracking" ```python - from collections import defaultdict - import cv2 from ultralytics import YOLO from ultralytics.utils.plotting import Annotator, colors - track_history = defaultdict(lambda: []) - model = YOLO("yolo11n-seg.pt") # segmentation model cap = cv2.VideoCapture("path/to/video/file.mp4") w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) @@ -205,15 +201,11 @@ To implement object tracking, use the `model.track` method and ensure that each === "Python" ```python - from collections import defaultdict - import cv2 from ultralytics import YOLO from ultralytics.utils.plotting import Annotator, colors - track_history = defaultdict(lambda: []) - model = YOLO("yolo11n-seg.pt") # segmentation model cap = cv2.VideoCapture("path/to/video/file.mp4") w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) diff --git a/docs/en/macros/solutions-args.md b/docs/en/macros/solutions-args.md new file mode 100644 index 0000000000..0ce5d52a05 --- /dev/null +++ b/docs/en/macros/solutions-args.md @@ -0,0 +1,11 @@ +| Argument | Type | Default | Description | +| ---------------- | -------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `region` | `list` | `[(20, 400), (1080, 400), (1080, 360), (20, 360)]` | Defines the region points for object counting, queue monitoring, trackzone or speed estimation. The points are defined as coordinates forming a polygonal area for analysis. | +| `show_in` | `bool` | `True` | Indicates whether to display objects that are counted as entering the defined region. Essential for real-world analytics, such as monitoring ingress trends. | +| `show_out` | `bool` | `True` | Indicates whether to display objects that are counted as exiting the defined region. Useful for applications requiring egress tracking and analytics. | +| `colormap` | `int or tuple` | `COLORMAP_PARULA` | Specifies the OpenCV-supported colormap for heatmap visualization. Default is `COLORMAP_PARULA`, but other colormaps can be used for different visualization preferences. | +| `up_angle` | `float` | `145.0` | Angle threshold for detecting the "up" position in workouts monitoring. Can be adjusted based on the position of keypoints for different exercises. | +| `down_angle` | `float` | `90.0` | Angle threshold for detecting the "down" position in workouts monitoring. Adjust this based on keypoint positions for specific exercises. | +| `kpts` | `list` | `[6, 8, 10]` | List of keypoints used for monitoring workouts. These keypoints correspond to body joints or parts, such as shoulders, elbows, and wrists, for exercises like push-ups, pull-ups, squats, ab-workouts. | +| `analytics_type` | `str` | `line` | Specifies the type of analytics visualization to generate. Options include `"line"`, `"pie"`, `"bar"`, or `"area"`. The default is `"line"` for trend visualization. | +| `json_file` | `str` | `None` | Path to the JSON file defining regions for parking systems or similar applications. Enables flexible configuration of analysis areas. | diff --git a/docs/en/usage/cfg.md b/docs/en/usage/cfg.md index 95dc8b46f2..c51863c5e0 100644 --- a/docs/en/usage/cfg.md +++ b/docs/en/usage/cfg.md @@ -130,6 +130,14 @@ It is crucial to thoughtfully configure these settings to ensure the exported mo [Export Guide](../modes/export.md){ .md-button } +## Solutions Settings + +The configuration settings for Ultralytics Solutions offer a flexible way to customize the model for various tasks like object counting, heatmap creation, workout tracking, data analysis, zone tracking, queue management, and region-based counting. These options make it easy to adjust the setup for accurate and useful results tailored to specific needs. + +{% include "macros/solutions-args.md" %} + +[Solutions Guide](../solutions/index.md){ .md-button } + ## Augmentation Settings Augmentation techniques are essential for improving the robustness and performance of YOLO models by introducing variability into the [training data](https://www.ultralytics.com/glossary/training-data), helping the model generalize better to unseen data. The following table outlines the purpose and effect of each augmentation argument: From dbdb451512ad4b3c636e6d61ad7af31e07301ece Mon Sep 17 00:00:00 2001 From: Muhammad Rizwan Munawar Date: Mon, 2 Dec 2024 20:02:48 +0500 Subject: [PATCH 25/25] `ultralytics 8.3.40` new `TrackZone` Solution (#17918) Co-authored-by: UltralyticsAssistant Co-authored-by: Glenn Jocher --- docs/en/guides/trackzone.md | 160 +++++++++++++++++++++++ docs/en/reference/solutions/trackzone.md | 16 +++ docs/en/solutions/index.md | 4 +- mkdocs.yml | 4 +- ultralytics/__init__.py | 2 +- ultralytics/cfg/__init__.py | 15 ++- ultralytics/solutions/__init__.py | 2 + ultralytics/solutions/trackzone.py | 68 ++++++++++ 8 files changed, 262 insertions(+), 9 deletions(-) create mode 100644 docs/en/guides/trackzone.md create mode 100644 docs/en/reference/solutions/trackzone.md create mode 100644 ultralytics/solutions/trackzone.py diff --git a/docs/en/guides/trackzone.md b/docs/en/guides/trackzone.md new file mode 100644 index 0000000000..ec98221385 --- /dev/null +++ b/docs/en/guides/trackzone.md @@ -0,0 +1,160 @@ +--- +comments: true +description: Discover how TrackZone leverages Ultralytics YOLO11 to precisely track objects within specific zones, enabling real-time insights for crowd analysis, surveillance, and targeted monitoring. +keywords: TrackZone, object tracking, YOLO11, Ultralytics, real-time object detection, AI, deep learning, crowd analysis, surveillance, zone-based tracking, resource optimization +--- + +# TrackZone using Ultralytics YOLO11 + +## What is TrackZone? + +TrackZone specializes in monitoring objects within designated areas of a frame instead of the whole frame. Built on [Ultralytics YOLO11](https://github.com/ultralytics/ultralytics/), it integrates object detection and tracking specifically within zones for videos and live camera feeds. YOLO11's advanced algorithms and [deep learning](https://www.ultralytics.com/glossary/deep-learning-dl) technologies make it a perfect choice for real-time use cases, offering precise and efficient object tracking in applications like crowd monitoring and surveillance. + +## Advantages of Object Tracking in Zones (TrackZone) + +- **Targeted Analysis:** Tracking objects within specific zones allows for more focused insights, enabling precise monitoring and analysis of areas of interest, such as entry points or restricted zones. +- **Improved Efficiency:** By narrowing the tracking scope to defined zones, TrackZone reduces computational overhead, ensuring faster processing and optimal performance. +- **Enhanced Security:** Zonal tracking improves surveillance by monitoring critical areas, aiding in the early detection of unusual activity or security breaches. +- **Scalable Solutions:** The ability to focus on specific zones makes TrackZone adaptable to various scenarios, from retail spaces to industrial settings, ensuring seamless integration and scalability. + +## Real World Applications + +| Agriculture | Transportation | +| :-----------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| ![Plants Tracking in Field Using Ultralytics YOLO11](https://github.com/ultralytics/docs/releases/download/0/plants-tracking-in-zone-using-ultralytics-yolo11.avif) | ![Vehicles Tracking on Road using Ultralytics YOLO11](https://github.com/ultralytics/docs/releases/download/0/vehicle-tracking-in-zone-using-ultralytics-yolo11.avif) | +| Plants Tracking in Field Using Ultralytics YOLO11 | Vehicles Tracking on Road using Ultralytics YOLO11 | + +!!! example "TrackZone using YOLO11 Example" + + === "CLI" + + ```bash + # Run a trackzone example + yolo solutions trackzone show=True + + # Pass a source video + yolo solutions trackzone show=True source="path/to/video/file.mp4" + + # Pass region coordinates + yolo solutions trackzone show=True region=[(150, 150), (1130, 150), (1130, 570), (150, 570)] + ``` + + === "Python" + + ```python + import cv2 + + from ultralytics import solutions + + cap = cv2.VideoCapture("path/to/video/file.mp4") + assert cap.isOpened(), "Error reading video file" + w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) + + # Define region points + region_points = [(150, 150), (1130, 150), (1130, 570), (150, 570)] + + # Video writer + video_writer = cv2.VideoWriter("object_counting_output.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) + + # Init TrackZone (Object Tracking in Zones, not complete frame) + trackzone = solutions.TrackZone( + show=True, # Display the output + region=region_points, # Pass region points + model="yolo11n.pt", # You can use any model that Ultralytics support, i.e. YOLOv9, YOLOv10 + # line_width=2, # Adjust the line width for bounding boxes and text display + # classes=[0, 2], # If you want to count specific classes i.e. person and car with COCO pretrained model. + ) + + # Process video + while cap.isOpened(): + success, im0 = cap.read() + if not success: + print("Video frame is empty or video processing has been successfully completed.") + break + im0 = trackzone.trackzone(im0) + video_writer.write(im0) + + cap.release() + video_writer.release() + cv2.destroyAllWindows() + ``` + +### Argument `TrackZone` + +Here's a table with the `TrackZone` arguments: + +| Name | Type | Default | Description | +| ------------ | ------ | ---------------------------------------------------- | ---------------------------------------------------- | +| `model` | `str` | `None` | Path to Ultralytics YOLO Model File | +| `region` | `list` | `[(150, 150), (1130, 150), (1130, 570), (150, 570)]` | List of points defining the object tracking region. | +| `line_width` | `int` | `2` | Line thickness for bounding boxes. | +| `show` | `bool` | `False` | Flag to control whether to display the video stream. | + +### Arguments `model.track` + +{% include "macros/track-args.md" %} + +## FAQ + +### How do I track objects in a specific area or zone of a video frame using Ultralytics YOLO11? + +Tracking objects in a defined area or zone of a video frame is straightforward with Ultralytics YOLO11. Simply use the command provided below to initiate tracking. This approach ensures efficient analysis and accurate results, making it ideal for applications like surveillance, crowd management, or any scenario requiring zonal tracking. + +```bash +yolo solutions trackzone source="path/to/video/file.mp4" show=True +``` + +### How can I use TrackZone in Python with Ultralytics YOLO11? + +With just a few lines of code, you can set up object tracking in specific zones, making it easy to integrate into your projects. + +```python +import cv2 + +from ultralytics import solutions + +cap = cv2.VideoCapture("path/to/video/file.mp4") +assert cap.isOpened(), "Error reading video file" +w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) + +# Define region points +region_points = [(150, 150), (1130, 150), (1130, 570), (150, 570)] + +# Video writer +video_writer = cv2.VideoWriter("object_counting_output.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) + +# Init TrackZone (Object Tracking in Zones, not complete frame) +trackzone = solutions.TrackZone( + show=True, # Display the output + region=region_points, # Pass region points + model="yolo11n.pt", +) + +# Process video +while cap.isOpened(): + success, im0 = cap.read() + if not success: + print("Video frame is empty or video processing has been successfully completed.") + break + im0 = trackzone.trackzone(im0) + video_writer.write(im0) + +cap.release() +video_writer.release() +cv2.destroyAllWindows() +``` + +### How do I configure the zone points for video processing using Ultralytics TrackZone? + +Configuring zone points for video processing with Ultralytics TrackZone is simple and customizable. You can directly define and adjust the zones through a Python script, allowing precise control over the areas you want to monitor. + +```python +# Define region points +region_points = [(150, 150), (1130, 150), (1130, 570), (150, 570)] + +# Init TrackZone (Object Tracking in Zones, not complete frame) +trackzone = solutions.TrackZone( + show=True, # Display the output + region=region_points, # Pass region points +) +``` diff --git a/docs/en/reference/solutions/trackzone.md b/docs/en/reference/solutions/trackzone.md new file mode 100644 index 0000000000..546d61dcb0 --- /dev/null +++ b/docs/en/reference/solutions/trackzone.md @@ -0,0 +1,16 @@ +--- +description: Discover Ultralytics' TrackZone solution for real-time object tracking within defined zones. Gain insights into initializing regions, tracking objects exclusively within specific areas, and optimizing video stream processing for region-based object detection. +keywords: Ultralytics, TrackZone, Object Tracking, Zone Tracking, Region Tracking, Python, Real-time Object Tracking, Video Stream Processing, Region-based Detection +--- + +# Reference for `ultralytics/solutions/trackzone.py` + +!!! note + + This file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/solutions/trackzone.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/solutions/trackzone.py). If you spot a problem please help fix it by [contributing](https://docs.ultralytics.com/help/contributing/) a [Pull Request](https://github.com/ultralytics/ultralytics/edit/main/ultralytics/solutions/trackzone.py) 🛠️. Thank you 🙏! + +
+ +## ::: ultralytics.solutions.trackzone.TrackZone + +

diff --git a/docs/en/solutions/index.md b/docs/en/solutions/index.md index 4046975de7..243fbf2757 100644 --- a/docs/en/solutions/index.md +++ b/docs/en/solutions/index.md @@ -27,8 +27,10 @@ Here's our curated list of Ultralytics solutions that can be used to create awes - [Distance Calculation](../guides/distance-calculation.md) 🚀: Calculate distances between objects using [bounding box](https://www.ultralytics.com/glossary/bounding-box) centroids in YOLO11, essential for spatial analysis. - [Queue Management](../guides/queue-management.md) 🚀: Implement efficient queue management systems to minimize wait times and improve productivity using YOLO11. - [Parking Management](../guides/parking-management.md) 🚀: Organize and direct vehicle flow in parking areas with YOLO11, optimizing space utilization and user experience. -- [Analytics](../guides/analytics.md) 📊 NEW: Conduct comprehensive data analysis to discover patterns and make informed decisions, leveraging YOLO11 for descriptive, predictive, and prescriptive analytics. +- [Analytics](../guides/analytics.md) 📊: Conduct comprehensive data analysis to discover patterns and make informed decisions, leveraging YOLO11 for descriptive, predictive, and prescriptive analytics. - [Live Inference with Streamlit](../guides/streamlit-live-inference.md) 🚀: Leverage the power of YOLO11 for real-time [object detection](https://www.ultralytics.com/glossary/object-detection) directly through your web browser with a user-friendly Streamlit interface. +- [Live Inference with Streamlit](../guides/streamlit-live-inference.md) 🚀: Leverage the power of YOLO11 for real-time [object detection](https://www.ultralytics.com/glossary/object-detection) directly through your web browser with a user-friendly Streamlit interface. +- [Track Objects in Zone](../guides/trackzone.md) 🎯 NEW: Learn how to track objects within specific zones of video frames using YOLO11 for precise and efficient monitoring. ## Solutions Usage diff --git a/mkdocs.yml b/mkdocs.yml index 0d3320a230..283d52f3d9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -326,7 +326,8 @@ nav: - Distance Calculation: guides/distance-calculation.md - Queue Management: guides/queue-management.md - Parking Management: guides/parking-management.md - - Live Inference 🚀 NEW: guides/streamlit-live-inference.md + - Live Inference: guides/streamlit-live-inference.md + - Track Objects in Zone 🚀 NEW: guides/trackzone.md - Guides: - guides/index.md - YOLO Common Issues: guides/yolo-common-issues.md @@ -573,6 +574,7 @@ nav: - speed_estimation: reference/solutions/speed_estimation.md - streamlit_inference: reference/solutions/streamlit_inference.md - region_counter: reference/solutions/region_counter.md + - trackzone: reference/solutions/trackzone.md - trackers: - basetrack: reference/trackers/basetrack.md - bot_sort: reference/trackers/bot_sort.md diff --git a/ultralytics/__init__.py b/ultralytics/__init__.py index 7b73169deb..601d1bb363 100644 --- a/ultralytics/__init__.py +++ b/ultralytics/__init__.py @@ -1,6 +1,6 @@ # Ultralytics YOLO 🚀, AGPL-3.0 license -__version__ = "8.3.39" +__version__ = "8.3.40" import os diff --git a/ultralytics/cfg/__init__.py b/ultralytics/cfg/__init__.py index 5f0222a71f..e4c239f3d4 100644 --- a/ultralytics/cfg/__init__.py +++ b/ultralytics/cfg/__init__.py @@ -41,6 +41,7 @@ SOLUTION_MAP = { "speed": ("SpeedEstimator", "estimate_speed"), "workout": ("AIGym", "monitor"), "analytics": ("Analytics", "process_data"), + "trackzone": ("TrackZone", "trackzone"), "help": None, } @@ -74,13 +75,12 @@ ARGV = sys.argv or ["", ""] # sometimes sys.argv = [] SOLUTIONS_HELP_MSG = f""" Arguments received: {str(['yolo'] + ARGV[1:])}. Ultralytics 'yolo solutions' usage overview: - yolo SOLUTIONS SOLUTION ARGS - - Where SOLUTIONS (required) is a keyword - SOLUTION (optional) is one of {list(SOLUTION_MAP.keys())} - ARGS (optional) are any number of custom 'arg=value' pairs like 'show_in=True' that override defaults. - See all ARGS at https://docs.ultralytics.com/usage/cfg or with 'yolo cfg' + yolo solutions SOLUTION ARGS + Where SOLUTION (optional) is one of {list(SOLUTION_MAP.keys())} + ARGS (optional) are any number of custom 'arg=value' pairs like 'show_in=True' that override defaults + at https://docs.ultralytics.com/usage/cfg + 1. Call object counting solution yolo solutions count source="path/to/video/file.mp4" region=[(20, 400), (1080, 400), (1080, 360), (20, 360)] @@ -95,6 +95,9 @@ SOLUTIONS_HELP_MSG = f""" 5. Generate analytical graphs yolo solutions analytics analytics_type="pie" + + 6. Track Objects Within Specific Zones + yolo solutions trackzone source="path/to/video/file.mp4" region=[(150, 150), (1130, 150), (1130, 570), (150, 570)] """ CLI_HELP_MSG = f""" Arguments received: {str(['yolo'] + ARGV[1:])}. Ultralytics 'yolo' commands use the following syntax: diff --git a/ultralytics/solutions/__init__.py b/ultralytics/solutions/__init__.py index 9de61edce2..a2333129bb 100644 --- a/ultralytics/solutions/__init__.py +++ b/ultralytics/solutions/__init__.py @@ -10,6 +10,7 @@ from .queue_management import QueueManager from .region_counter import RegionCounter from .speed_estimation import SpeedEstimator from .streamlit_inference import inference +from .trackzone import TrackZone __all__ = ( "AIGym", @@ -23,4 +24,5 @@ __all__ = ( "Analytics", "inference", "RegionCounter", + "TrackZone", ) diff --git a/ultralytics/solutions/trackzone.py b/ultralytics/solutions/trackzone.py new file mode 100644 index 0000000000..0492c0a7e5 --- /dev/null +++ b/ultralytics/solutions/trackzone.py @@ -0,0 +1,68 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import cv2 +import numpy as np + +from ultralytics.solutions.solutions import BaseSolution +from ultralytics.utils.plotting import Annotator, colors + + +class TrackZone(BaseSolution): + """ + A class to manage region-based object tracking in a video stream. + + This class extends the BaseSolution class and provides functionality for tracking objects within a specific region + defined by a polygonal area. Objects outside the region are excluded from tracking. It supports dynamic initialization + of the region, allowing either a default region or a user-specified polygon. + + Attributes: + region (ndarray): The polygonal region for tracking, represented as a convex hull. + + Methods: + trackzone: Processes each frame of the video, applying region-based tracking. + + Examples: + >>> tracker = TrackZone() + >>> frame = cv2.imread("frame.jpg") + >>> processed_frame = tracker.trackzone(frame) + >>> cv2.imshow("Tracked Frame", processed_frame) + """ + + def __init__(self, **kwargs): + """Initializes the TrackZone class for tracking objects within a defined region in video streams.""" + super().__init__(**kwargs) + default_region = [(150, 150), (1130, 150), (1130, 570), (150, 570)] + self.region = cv2.convexHull(np.array(self.region or default_region, dtype=np.int32)) + + def trackzone(self, im0): + """ + Processes the input frame to track objects within a defined region. + + This method initializes the annotator, creates a mask for the specified region, extracts tracks + only from the masked area, and updates tracking information. Objects outside the region are ignored. + + Args: + im0 (numpy.ndarray): The input image or frame to be processed. + + Returns: + (numpy.ndarray): The processed image with tracking id and bounding boxes annotations. + + Examples: + >>> tracker = TrackZone() + >>> frame = cv2.imread("path/to/image.jpg") + >>> tracker.trackzone(frame) + """ + self.annotator = Annotator(im0, line_width=self.line_width) # Initialize annotator + # Create a mask for the region and extract tracks from the masked image + masked_frame = cv2.bitwise_and(im0, im0, mask=cv2.fillPoly(np.zeros_like(im0[:, :, 0]), [self.region], 255)) + self.extract_tracks(masked_frame) + + cv2.polylines(im0, [self.region], isClosed=True, color=(255, 255, 255), thickness=self.line_width * 2) + + # Iterate over boxes, track ids, classes indexes list and draw bounding boxes + for box, track_id, cls in zip(self.boxes, self.track_ids, self.clss): + self.annotator.box_label(box, label=f"{self.names[cls]}:{track_id}", color=colors(track_id, True)) + + self.display_output(im0) # display output with base class function + + return im0 # return output image for more usage