-
Notifications
You must be signed in to change notification settings - Fork 0
24 yolo node for instance segmentation #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e8785e9
8492b91
74f1e85
0884e29
56a894e
dae704f
8e12da2
712692d
0575b16
8ad50bc
c731202
74fb5bf
3319e8c
fee9c53
21e82d5
13ac688
13e5bd5
c49673c
be47cc6
14a3951
b7fe81c
8f178c9
7443658
e4d9c5e
7b248d8
f0e2392
8232a57
4e5e0fb
633549d
0922ca2
ac2809e
283007b
dc19869
139f26a
750c6fa
d0c0c5f
c7e70f2
2bd56f2
e30f1a6
2b15d52
d4aa066
63a64ce
3235cbc
0050f29
c477d59
f793a52
2e34410
4af58ba
a5e218d
83e4951
474992e
a8eef5d
66f63a3
e79a74a
fcaf0fa
33926e2
118558b
bcc7ec6
ad75676
7a6a964
b63d01d
6353e43
4fcede2
ae382a3
28d2591
7f4b544
878abfc
77e7523
65935e1
8618fa5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,4 +27,4 @@ venv/ | |
| *.swp | ||
| *.swo | ||
| node_modules/ | ||
| bags/ | ||
| rosbags/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,18 @@ share/python-wheels/ | |
| *.egg | ||
| MANIFEST | ||
|
|
||
| #VSCode | ||
| .vscode/ | ||
|
|
||
| # OS Generated files | ||
| .DS_Store | ||
| .DS_Store? | ||
| ._* | ||
| .Spotlight-V100 | ||
| .Trashes | ||
| ehthumbs.db | ||
| Thumbs.db | ||
|
|
||
| # PyInstaller | ||
| # Usually these files are written by a python script from a template | ||
| # before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
|
|
@@ -173,7 +185,7 @@ build/ | |
| log/ | ||
|
|
||
| # data | ||
| data/ | ||
| rosbags/ | ||
|
Comment on lines
-176
to
+188
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not ignore both? |
||
|
|
||
| # Training outputs and Roboflow datasets | ||
| results/ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
|
|
||
| The above copyright notice and this permission notice shall be included in | ||
| all copies or substantial portions of the Software. | ||
|
|
||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| THE SOFTWARE. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| from launch import LaunchDescription | ||
| from launch_ros.actions import Node | ||
| from ament_index_python.packages import get_package_share_directory | ||
| import os | ||
|
|
||
|
|
||
| def generate_launch_description(): | ||
| pkg_share = get_package_share_directory('vortex_image_segmentation') | ||
| yolo_params = os.path.join(pkg_share, 'params', 'yolo_params.yaml') | ||
|
Comment on lines
+8
to
+9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ehh, actually. 🤓 |
||
|
|
||
| return LaunchDescription([ | ||
| Node( | ||
| package='vortex_image_segmentation', | ||
| executable='yolo_seg_node', | ||
| name='yolo_segmentation_node', | ||
| output='screen', | ||
| parameters=[yolo_params] | ||
| ) | ||
| ]) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| <?xml version="1.0"?> | ||
| <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> | ||
| <package format="3"> | ||
| <name>vortex_image_segmentation</name> | ||
MadsJJ marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <version>0.0.0</version> | ||
| <description>Package for image segmentation nodes</description> | ||
| <maintainer email="[email protected]">Mads Engesvoll</maintainer> | ||
| <license>MIT</license> | ||
|
|
||
| <depend>rclpy</depend> | ||
| <depend>std_msgs</depend> | ||
|
|
||
| <test_depend>ament_copyright</test_depend> | ||
| <test_depend>ament_flake8</test_depend> | ||
| <test_depend>ament_pep257</test_depend> | ||
| <test_depend>python3-pytest</test_depend> | ||
|
|
||
| <export> | ||
| <build_type>ament_python</build_type> | ||
| </export> | ||
| </package> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| yolo_segmentation_node: | ||
| ros__parameters: | ||
| # Node parameters | ||
| input_topic: "/gripper_camera/image_raw" | ||
| output_bbox_topic: "/segmentation/bboxes" | ||
| output_mask_topic: "/segmentation/mask" | ||
| debug_topic: "/image_debug" | ||
| pub_bbox: True | ||
| pub_mask: True | ||
| pub_debug: True | ||
|
|
||
| # Implementation parameters | ||
| model_path: "/ros2_ws/yolo_segmentation_training/results/custom_yolov89/weights/last.pt" | ||
| device: "cpu" | ||
| imgsz: 640 | ||
| confidence_threshold: 0.3 | ||
| max_detections: 1 | ||
| compile: True | ||
| retina_masks: False # We dont need high res masks | ||
|
Comment on lines
+18
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Me no understand... |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| [develop] | ||
| script_dir=$base/lib/vortex_image_segmentation | ||
| [install] | ||
| install_scripts=$base/lib/vortex_image_segmentation |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
|
|
||
| from setuptools import find_packages, setup | ||
| import glob | ||
|
|
||
| package_name = 'vortex_image_segmentation' | ||
|
|
||
| setup( | ||
| name=package_name, | ||
| version='0.0.0', | ||
| packages=find_packages(exclude=['test']), | ||
| data_files=[ | ||
| ('share/ament_index/resource_index/packages', | ||
| ['resource/' + package_name]), | ||
| ('share/' + package_name, ['package.xml']), | ||
| ('share/' + package_name + '/launch', glob.glob('launch/*.launch.py')), | ||
| ('share/' + package_name + '/params', glob.glob('params/*.yaml')), | ||
| ], | ||
| install_requires=['setuptools'], | ||
| zip_safe=True, | ||
| maintainer='mads', | ||
| maintainer_email='[email protected]', | ||
| description='ROS 2 package that provides a YOLO-based instance segmentation node (yolo_seg_node) for real-time segmentation.', | ||
| license='MIT', | ||
| tests_require=['pytest'], | ||
| entry_points={ | ||
| 'console_scripts': [ | ||
| 'yolo_seg_node = vortex_image_segmentation.yolo_seg_node:main', | ||
| ], | ||
| }, | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| """ | ||
| YOLO segmentation model wrapper for inference and visualization using Ultralytics. | ||
| Defines parameter dataclass and main segmentation class. | ||
| """ | ||
|
|
||
| from dataclasses import dataclass | ||
| from typing import List | ||
|
|
||
| import numpy as np | ||
| import torch | ||
| from ultralytics import YOLO | ||
| from ultralytics.engine.results import Results | ||
|
|
||
|
|
||
| @dataclass | ||
| class YoloSegmentationParams: | ||
| """ | ||
| Dataclass for storing YOLO segmentation parameters. | ||
| """ | ||
| model_path: str | ||
| device: str | ||
| confidence_threshold: float | ||
| max_detections: int | ||
| imgsz: int | ||
| compile: bool | ||
| retina_masks: bool | ||
|
|
||
|
|
||
| class YoloSegmentation: | ||
| """ | ||
| Wrapper class for YOLO segmentation model inference and visualization. | ||
| """ | ||
|
|
||
| def __init__(self, params: YoloSegmentationParams) -> None: | ||
| """ | ||
| Initialize the YOLO segmentation model with given parameters. | ||
| Args: | ||
| params (YoloSegmentationParams): Parameters for YOLO segmentation. | ||
| """ | ||
| self.params: YoloSegmentationParams = params | ||
| self.model: YOLO = self._load_model() | ||
|
|
||
| def _load_model(self) -> YOLO: | ||
| """ | ||
| Load the YOLO segmentation model. | ||
| Returns: | ||
| YOLO: Ultralytics YOLO model instance. | ||
| """ | ||
| return YOLO(self.params.model_path, task="segment") | ||
|
|
||
| def predict(self, cv_image: np.ndarray) -> List[Results]: | ||
| """ | ||
| Run prediction on an input image and return the Results object(s). | ||
| Args: | ||
| cv_image (np.ndarray): Input image in OpenCV format. | ||
| Returns: | ||
| List[Results]: Ultralytics Results object(s) for the prediction. | ||
| """ | ||
| results = self.model.predict( | ||
| source=cv_image, | ||
| imgsz=self.params.imgsz, | ||
| conf=self.params.confidence_threshold, | ||
| device=torch.device(self.params.device), | ||
| max_det=self.params.max_detections, | ||
| retina_masks=self.params.retina_masks, | ||
| # compile=self.params.compile, | ||
| ) | ||
|
Comment on lines
+66
to
+67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ahh yes.. Important param |
||
| return results | ||
|
|
||
| def visualize(self, result: Results) -> np.ndarray: | ||
| """ | ||
| Generate a visualization image from the Results object. | ||
| Args: | ||
| result (Results): Ultralytics Results object from prediction. | ||
| Returns: | ||
| np.ndarray: Visualization image with segmentation overlays. | ||
| """ | ||
| return result.plot() | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not ignore both?