Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
e8785e9
Create ros2 package boilerplate for image segmentation nodes
MadsJJ Oct 22, 2025
8492b91
Add UNet and YOLO segmentation nodes with entry points in setup.py
MadsJJ Oct 22, 2025
74f1e85
create simple launch file
MadsJJ Oct 22, 2025
0884e29
add parameter files for unet, yolo and common
MadsJJ Oct 22, 2025
56a894e
remove duplicates from requirements.txt
MadsJJ Oct 22, 2025
dae704f
add blending of image and mask to the base node. Also update the imag…
MadsJJ Oct 22, 2025
8e12da2
create Dockerfile, and build and run script. Add install, build and l…
MadsJJ Oct 22, 2025
712692d
add training script for yolo model training with roboflow. add packag…
MadsJJ Oct 22, 2025
0575b16
make training script usable without cuda
MadsJJ Oct 22, 2025
8ad50bc
add separate requirements file for training script
MadsJJ Oct 22, 2025
c731202
remove requirements only needed for training
MadsJJ Oct 22, 2025
74fb5bf
upgrde packages in requirements in yolo training
MadsJJ Oct 22, 2025
3319e8c
looks like training on instance segmentation might be working
MadsJJ Oct 22, 2025
fee9c53
gitignore OS generated files
MadsJJ Oct 23, 2025
21e82d5
change model type to segmentation model
MadsJJ Oct 23, 2025
13ac688
add worker amount to be half of cpu count
MadsJJ Oct 23, 2025
13e5bd5
change project_name to project_id to clear up confusion for projects …
MadsJJ Oct 23, 2025
c49673c
change from os paths to Pathlib. Also create parent folder for datase…
MadsJJ Oct 23, 2025
be47cc6
format
MadsJJ Oct 23, 2025
14a3951
add patience parameter to model
MadsJJ Oct 23, 2025
b7fe81c
gitignore .vscode folder
MadsJJ Oct 26, 2025
8f178c9
add devcontainer file
MadsJJ Oct 26, 2025
7443658
remove annoying pylint
MadsJJ Oct 26, 2025
e4d9c5e
add dockerignore
MadsJJ Oct 26, 2025
7b248d8
gitignore bags
MadsJJ Oct 26, 2025
f0e2392
improve python dependency caching in dockerfile
MadsJJ Oct 26, 2025
8232a57
forgotten in previous commit
MadsJJ Oct 26, 2025
4e5e0fb
move bashrc sourcing to a script (wont need to rebuild image to modif…
MadsJJ Oct 26, 2025
633549d
add two launch files (yolo and unet)
MadsJJ Oct 26, 2025
0922ca2
change image_callback to abstract method in base node, because of dif…
MadsJJ Nov 2, 2025
ac2809e
update ultralytics version in requirements for segmentation model inf…
MadsJJ Nov 2, 2025
283007b
remove unet node
MadsJJ Nov 5, 2025
dc19869
simplify base node and use yolo.plot function for visualization
MadsJJ Nov 5, 2025
139f26a
add parameters confidence_threshold, imgsz, max_detections. Move yolo…
MadsJJ Nov 9, 2025
750c6fa
add: todo tree extension in devcontainer
MadsJJ Nov 14, 2025
d0c0c5f
Reword: package description and maintainer
MadsJJ Nov 14, 2025
c7e70f2
Start: remove base node inheritance and split yolo node and yolo impl…
MadsJJ Nov 14, 2025
2bd56f2
Remove: common params
MadsJJ Nov 14, 2025
e30f1a6
Rename "config" dir to "params" dir
MadsJJ Nov 14, 2025
2b15d52
add device, imgsz, compile and debug params
MadsJJ Nov 14, 2025
d4aa066
Delete: base and unet node
MadsJJ Nov 14, 2025
63a64ce
split yolo node into ros node and implementation
MadsJJ Nov 14, 2025
3235cbc
Reformat: yolo
MadsJJ Nov 14, 2025
0050f29
create Dockerfile, and build and run script. Add install, build and l…
MadsJJ Oct 22, 2025
c477d59
add devcontainer file
MadsJJ Oct 26, 2025
f793a52
remove annoying pylint
MadsJJ Oct 26, 2025
2e34410
add dockerignore
MadsJJ Oct 26, 2025
4af58ba
improve python dependency caching in dockerfile
MadsJJ Oct 26, 2025
a5e218d
forgotten in previous commit
MadsJJ Oct 26, 2025
83e4951
move bashrc sourcing to a script (wont need to rebuild image to modif…
MadsJJ Oct 26, 2025
474992e
add: todo tree extension in devcontainer
MadsJJ Nov 14, 2025
a8eef5d
fix: update devcontainer terminal profile setting and clean up runArgs
MadsJJ Nov 28, 2025
66f63a3
fix: copilot pr comment
MadsJJ Nov 28, 2025
e79a74a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 28, 2025
fcaf0fa
add: network=host to docker build script
MadsJJ Jan 5, 2026
33926e2
rename: docker image name to the same as repo name
MadsJJ Jan 5, 2026
118558b
Merge branch 'main' into feat/docker
kluge7 Jan 5, 2026
bcc7ec6
Merge remote-tracking branch 'origin/feat/docker' into 24-yolo-node-f…
MadsJJ Jan 6, 2026
ad75676
fix: image name used by devcontainer
MadsJJ Jan 6, 2026
7a6a964
add: package description and maintainer
MadsJJ Jan 6, 2026
b63d01d
fix: use get_package_share_directory for non docker users
MadsJJ Jan 6, 2026
6353e43
add: type hints
MadsJJ Jan 6, 2026
4fcede2
update: remove unnecessary requirements
MadsJJ Jan 6, 2026
ae382a3
fix: install params file to shared folder. this fixes the broken comm…
MadsJJ Jan 6, 2026
28d2591
update: move hardcoded params to params file.
MadsJJ Jan 6, 2026
7f4b544
Merge commit '8ca393d01e24fafc94309880380edf2940746565' into 24-yolo-…
MadsJJ Jan 6, 2026
878abfc
remove: tests
MadsJJ Jan 7, 2026
77e7523
update: confitionally initialize debug_pub based on debug flag
MadsJJ Jan 8, 2026
65935e1
add: parameterization for publishing mask and bbox. this way, the nod…
MadsJJ Jan 9, 2026
8618fa5
add: retina_masks parameter and only publish one merged mask image
MadsJJ Jan 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vortex-image-segmentation-devcontainer",
"image": "vortex-image-segmentation:latest",
"name": "vortex-deep-learning-pipelines-devcontainer",
"image": "vortex-deep-learning-pipelines:latest",
"customizations": {
"vscode": {
"settings": {
Expand Down
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ venv/
*.swp
*.swo
node_modules/
bags/
rosbags/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not ignore both?

14 changes: 13 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -173,7 +185,7 @@ build/
log/

# data
data/
rosbags/
Comment on lines -176 to +188
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not ignore both?


# Training outputs and Roboflow datasets
results/
Expand Down
Binary file modified requirements.txt
Binary file not shown.
17 changes: 17 additions & 0 deletions vortex_image_segmentation/LICENSE
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.
19 changes: 19 additions & 0 deletions vortex_image_segmentation/launch/yolo_segmentation.launch.py
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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ehh, actually. 🤓
We don't need the intermediate pkg_share variable here


return LaunchDescription([
Node(
package='vortex_image_segmentation',
executable='yolo_seg_node',
name='yolo_segmentation_node',
output='screen',
parameters=[yolo_params]
)
])
21 changes: 21 additions & 0 deletions vortex_image_segmentation/package.xml
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>
<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>
19 changes: 19 additions & 0 deletions vortex_image_segmentation/params/yolo_params.yaml
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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Me no understand...
Explain these parameters 🧙

Empty file.
4 changes: 4 additions & 0 deletions vortex_image_segmentation/setup.cfg
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
30 changes: 30 additions & 0 deletions vortex_image_segmentation/setup.py
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',
],
},
)
Empty file.
78 changes: 78 additions & 0 deletions vortex_image_segmentation/vortex_image_segmentation/yolo_seg.py
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
Copy link

Choose a reason for hiding this comment

The 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()
Loading