From b5852c758207f74a322097a07541c4d79dafb917 Mon Sep 17 00:00:00 2001 From: Wessel Tip Date: Thu, 13 Nov 2025 18:58:30 +0100 Subject: [PATCH] feat: Final openCV assignment --- .fish/activate.fish | 75 +++++++++ .fish/readme.norg | 60 ++++++++ Assignement - image reader.pdf | Bin 0 -> 68380 bytes src/image_reader_wessel_pkg/CMakeLists.txt | 35 +++++ src/image_reader_wessel_pkg/package.xml | 23 +++ src/image_reader_wessel_pkg/src/Main.cpp | 15 ++ .../src/nodes/ImageReader.cpp | 145 ++++++++++++++++++ .../src/nodes/ImageReader.hpp | 40 +++++ src/launch_wessel_pkg/CMakeLists.txt | 11 ++ .../launch/image_reader.launch.xml | 19 +++ src/launch_wessel_pkg/package.xml | 15 ++ .../rviz/image_processor_config.rviz | 131 ++++++++++++++++ src/usb_cam_wessel_pkg/CMakeLists.txt | 11 ++ src/usb_cam_wessel_pkg/config/params.yaml | 23 +++ src/usb_cam_wessel_pkg/package.xml | 15 ++ 15 files changed, 618 insertions(+) create mode 100755 .fish/activate.fish create mode 100644 .fish/readme.norg create mode 100644 Assignement - image reader.pdf create mode 100644 src/image_reader_wessel_pkg/CMakeLists.txt create mode 100644 src/image_reader_wessel_pkg/package.xml create mode 100644 src/image_reader_wessel_pkg/src/Main.cpp create mode 100644 src/image_reader_wessel_pkg/src/nodes/ImageReader.cpp create mode 100644 src/image_reader_wessel_pkg/src/nodes/ImageReader.hpp create mode 100644 src/launch_wessel_pkg/CMakeLists.txt create mode 100644 src/launch_wessel_pkg/launch/image_reader.launch.xml create mode 100644 src/launch_wessel_pkg/package.xml create mode 100644 src/launch_wessel_pkg/rviz/image_processor_config.rviz create mode 100644 src/usb_cam_wessel_pkg/CMakeLists.txt create mode 100644 src/usb_cam_wessel_pkg/config/params.yaml create mode 100644 src/usb_cam_wessel_pkg/package.xml diff --git a/.fish/activate.fish b/.fish/activate.fish new file mode 100755 index 0000000..aadfcdf --- /dev/null +++ b/.fish/activate.fish @@ -0,0 +1,75 @@ +# Self-contained environment: ros2-pass-2 +# Exported on: Thu Nov 13 06:58:18 PM CET 2025 +# Original environment from: /home/wessel/.config/fish/environments/configs/ros2-pass-2 + +# ROS2 development environment (requires distrobox) +# Environment: ros2-pass-2 + +# First check if running inside distrobox +if not test -f /run/.containerenv; and test -z "$CONTAINER_ID" + echo (set_color red)"This ROS2 environment should only be run inside a distrobox container"(set_color normal) + return 1 +end + +# Check if a previous initialization has occurred +if test -n "$__ENV_INITIALIZED" + echo (set_color yellow)"Environment already initialized"(set_color normal) + return 0 +end + +# Mark as initialized (only after distrobox check passes) +set -gx __ENV_INITIALIZED "1" +set -gx CURRENT_ENV "ros2-pass-2" +# Source ROS2 setup files using bass +if type -q bass + bass source /opt/ros/jazzy/setup.bash + if test -f ./install/setup.bash + bass source ./install/setup.bash + end +else + echo (set_color red)"Error: bass is required for ROS2 environment. Install with: fisher install edc/bass"(set_color normal) + return 1 +end + +# Set environment variable for the prompt prefix +set -gx ROS2_ACTIVE 1 + +# Save the original prompt function if it exists +# Only save if we don't already have a backup or if current prompt is not from an environment +if not functions -q __env_orig_prompt + if functions -q fish_prompt + functions -c fish_prompt __env_orig_prompt + else + function __env_orig_prompt + echo -n (whoami)'@'(prompt_hostname)' '(set_color $fish_color_cwd)(prompt_pwd)(set_color normal)'> ' + end + end +else + # If we already have a backup, we're switching environments + # No need to create a new backup +end + +# Define new prompt with ROS2 prefix +function fish_prompt + echo -n (set_color magenta)'(ros2-pass-2)'(set_color normal)' ' + __env_orig_prompt +end + +# ROS2 aliases and functions +alias cb="colcon build" +alias cbe="colcon build && env deactivate && cd ." +alias cbs="colcon build --symlink-install" +alias cbt="colcon build --packages-select" +alias ct="colcon test" +alias ctr="colcon test-result" + +echo (set_color green)"Activated ROS2 environment: ros2-pass-2"(set_color normal) + +# Custom deactivation function +function __env_custom_deactivate + # Remove ROS2-specific variables and aliases + set -e ROS2_ACTIVE + functions -e cb cbs cbt ct ctr 2>/dev/null + + echo (set_color blue)"ROS2 environment cleanup completed"(set_color normal) +end diff --git a/.fish/readme.norg b/.fish/readme.norg new file mode 100644 index 0000000..059556d --- /dev/null +++ b/.fish/readme.norg @@ -0,0 +1,60 @@ +* Exported Fish Environment: ros2-pass-2 +This directory contains a self-contained fish environment. + +** Files Structure + @code + .fish/ + |-- activate.fish + |-- readme.norg + |-- bin/ + @end + +** Usage + +*** Automatic Activation (Recommended) + The environment will automatically activate when you `cd` into this directory + if your Fish shell is configured with the auto-activation script. + + @code fish + function check_and_source_activate + if test -f (pwd)/.fish/activate.fish + source (pwd)/.fish/activate.fish + elif test -f (pwd)/activate.fish + source (pwd)/activate.fish + end + end + + function cd + builtin cd $argv && check_and_source_activate + end + @end + +*** Manual Activation + To manually activate the environment, run from the project root: + @code bash + source ./.fish/activate.fish + @end + +*** Deactivation + To deactivate the environment, run: + @code bash + env deactivate + @end + + Or simply `cd` to a different directory if using auto-activation. + +** What This Environment Provides + - Prompt showing the environment name + - Environment-specific aliases and functions + - Custom environment variables + - Automatic cleanup when deactivated + +** Requirements + - Fish shell + - `bass` plugin (`fisher install edc/bass`) for compatibility with bash scripts + +** Sharing + This environment is completely self-contained. You can: + - Copy this directory to another machine + - Share it with others + - Version control it with your project (add .fish/ to your repo) \ No newline at end of file diff --git a/Assignement - image reader.pdf b/Assignement - image reader.pdf new file mode 100644 index 0000000000000000000000000000000000000000..24b9a62b0c66a00f3d5f0779472539febae5772c GIT binary patch literal 68380 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
fT(w2Ke)HHLIv8-C&1DxGepY4E9)n++Yg$@b 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 DseJ>@ literal 0 HcmV?d00001 diff --git a/src/image_reader_wessel_pkg/CMakeLists.txt b/src/image_reader_wessel_pkg/CMakeLists.txt new file mode 100644 index 0000000..45ac9ca --- /dev/null +++ b/src/image_reader_wessel_pkg/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.8) +project(image_reader_wessel_pkg) + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +find_package(sensor_msgs REQUIRED) +find_package(cv_bridge REQUIRED) +find_package(OpenCV REQUIRED) + +# Add executable +add_executable(image_reader_node + src/Main.cpp + src/nodes/ImageReader.cpp +) + +# Link dependencies +ament_target_dependencies(image_reader_node + rclcpp + sensor_msgs + cv_bridge + OpenCV +) + +# Install targets +install(TARGETS + image_reader_node + DESTINATION lib/${PROJECT_NAME} +) + +ament_package() diff --git a/src/image_reader_wessel_pkg/package.xml b/src/image_reader_wessel_pkg/package.xml new file mode 100644 index 0000000..bb3a4f9 --- /dev/null +++ b/src/image_reader_wessel_pkg/package.xml @@ -0,0 +1,23 @@ + + + + image_reader_wessel_pkg + 0.0.0 + Image reader package with OpenCV processing + wessel + TODO: License declaration + + ament_cmake + + rclcpp + sensor_msgs + cv_bridge + libopencv-dev + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/src/image_reader_wessel_pkg/src/Main.cpp b/src/image_reader_wessel_pkg/src/Main.cpp new file mode 100644 index 0000000..0a7394f --- /dev/null +++ b/src/image_reader_wessel_pkg/src/Main.cpp @@ -0,0 +1,15 @@ +#include + +#include "rclcpp/rclcpp.hpp" +#include "nodes/ImageReader.hpp" + +int main(int argc,char *argv[]) { + rclcpp::init(argc,argv); + + auto node = std::make_shared(); + + rclcpp::spin(node); + rclcpp::shutdown(); + + return 0; +} \ No newline at end of file diff --git a/src/image_reader_wessel_pkg/src/nodes/ImageReader.cpp b/src/image_reader_wessel_pkg/src/nodes/ImageReader.cpp new file mode 100644 index 0000000..494d4e9 --- /dev/null +++ b/src/image_reader_wessel_pkg/src/nodes/ImageReader.cpp @@ -0,0 +1,145 @@ +#include "ImageReader.hpp" + +#include +#include + +namespace assignments::two::image_reader { + +ImageReaderNode::ImageReaderNode() : Node("image_reader_node") { + circle_color_.r = this->declare_parameter("circle_color_r", 255); + circle_color_.g = this->declare_parameter("circle_color_g", 0); + circle_color_.b = this->declare_parameter("circle_color_b", 0); + + RCLCPP_INFO(this->get_logger(), "circle_color_=(r%d, g%d, b%d)", + circle_color_.r, circle_color_.g, circle_color_.b); + + // Subscribe to image topic + image_subscriber_ = this->create_subscription( + "/image_raw", + 10, + std::bind( + &ImageReaderNode::image_callback, + this, + std::placeholders::_1 + ) + ); + + // Publisher for processed image + image_publisher_ = this->create_publisher("/image_processed", 10); + + RCLCPP_INFO(this->get_logger(), "initialized"); +} + +void ImageReaderNode::image_callback(const sensor_msgs::msg::Image::SharedPtr msg) { + RCLCPP_INFO_ONCE(this->get_logger(), "'/image_raw': received image, processing"); + + try { + // handle both RGB and BGR + cv_bridge::CvImagePtr cv_ptr; + if (msg->encoding == sensor_msgs::image_encodings::RGB8) { + cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::RGB8); + cv::cvtColor(cv_ptr->image, cv_ptr->image, cv::COLOR_RGB2BGR); + } else { + cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8); + } + + ImageMetadata img; + img.canvas = cv_ptr->image; + img.width = img.canvas.cols; + img.height = img.canvas.rows; + + process_top_left_quadrant_white(img); + process_top_right_quadrant_circle(img); + process_bottom_left_quadrant_remove_blue(img); + process_bottom_right_quadrant_edge_detection(img); + + draw_division_lines(img); + + cv_ptr->image = img.canvas; + image_publisher_->publish(*cv_ptr->toImageMsg()); + } catch (cv_bridge::Exception& e) { + RCLCPP_ERROR(this->get_logger(), "cv_bridge exception: %s", e.what()); + } +} + +void ImageReaderNode::draw_division_lines(ImageMetadata& img) { + int half_width = img.width / 2; + int half_height = img.height / 2; + + cv::line( + img.canvas, + cv::Point(half_width, 0), + cv::Point(half_width, img.height), + cv::Scalar(255, 255, 255), + 2 + ); + + cv::line( + img.canvas, + cv::Point(0, half_height), + cv::Point(img.width, half_height), + cv::Scalar(255, 255, 255), + 2 + ); +} + +void ImageReaderNode::process_top_left_quadrant_white(ImageMetadata& img) { + int half_width = img.width / 2; + int half_height = img.height / 2; + + cv::Mat top_left = img.canvas(cv::Rect(0, 0, half_width, half_height)); + top_left.setTo(cv::Scalar(255, 255, 255)); +} + +void ImageReaderNode::process_top_right_quadrant_circle(ImageMetadata& img) { + int half_width = img.width / 2; + int half_height = img.height / 2; + + cv::Mat top_right = img.canvas(cv::Rect(half_width, 0, img.width - half_width, half_height)); + int radius = std::min(top_right.cols, top_right.rows) / 4; + cv::Point center(top_right.cols / 2, top_right.rows / 2); + + cv::circle( + top_right, + center, + radius, + cv::Scalar(circle_color_.b, circle_color_.g, circle_color_.r), + -1 + ); +} + +void ImageReaderNode::process_bottom_left_quadrant_remove_blue(ImageMetadata& img) { + int half_width = img.width / 2; + int half_height = img.height / 2; + cv::Mat bottom_left = + img.canvas(cv::Rect(0, half_height, half_width, img.height - half_height)); + + for (int y = 0; y < bottom_left.rows; y++) { + for (int x = 0; x < bottom_left.cols; x++) { + bottom_left.at(y, x)[0] = 0; // Blue channel + } + } +} + +void ImageReaderNode::process_bottom_right_quadrant_edge_detection(ImageMetadata& img) { + int half_width = img.width / 2; + int half_height = img.height / 2; + + cv::Mat bottom_right = + img.canvas( + cv::Rect( + half_width, + half_height, + img.width - half_width, + img.height - half_height + ) + ); + + cv::Mat gray, edges; + + cv::cvtColor(bottom_right, gray, cv::COLOR_BGR2GRAY); + cv::Canny(gray, edges, 50, 150); + cv::cvtColor(edges, bottom_right, cv::COLOR_GRAY2BGR); +} + +} // namespace assignments::two::image_reader diff --git a/src/image_reader_wessel_pkg/src/nodes/ImageReader.hpp b/src/image_reader_wessel_pkg/src/nodes/ImageReader.hpp new file mode 100644 index 0000000..edb1565 --- /dev/null +++ b/src/image_reader_wessel_pkg/src/nodes/ImageReader.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "rclcpp/rclcpp.hpp" +#include "sensor_msgs/msg/image.hpp" +#include + +namespace assignments::two::image_reader { + +struct RGBColors { + int r; + int g; + int b; +}; + +struct ImageMetadata { + cv::Mat canvas; + int width; + int height; +}; + +class ImageReaderNode : public rclcpp::Node { +public: + ImageReaderNode(); + +private: + rclcpp::Subscription::SharedPtr image_subscriber_; + rclcpp::Publisher::SharedPtr image_publisher_; + + RGBColors circle_color_; + + void image_callback(const sensor_msgs::msg::Image::SharedPtr msg); + + void draw_division_lines(ImageMetadata& img); + void process_top_left_quadrant_white(ImageMetadata& img); + void process_top_right_quadrant_circle(ImageMetadata& img); + void process_bottom_left_quadrant_remove_blue(ImageMetadata& img); + void process_bottom_right_quadrant_edge_detection(ImageMetadata& img); +}; + +} // namespace assignments::two::image_reader \ No newline at end of file diff --git a/src/launch_wessel_pkg/CMakeLists.txt b/src/launch_wessel_pkg/CMakeLists.txt new file mode 100644 index 0000000..91e76ed --- /dev/null +++ b/src/launch_wessel_pkg/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.8) +project(launch_wessel_pkg) + +find_package(ament_cmake REQUIRED) + +install( + DIRECTORY launch rviz + DESTINATION share/${PROJECT_NAME} +) + +ament_package() diff --git a/src/launch_wessel_pkg/launch/image_reader.launch.xml b/src/launch_wessel_pkg/launch/image_reader.launch.xml new file mode 100644 index 0000000..39daf5b --- /dev/null +++ b/src/launch_wessel_pkg/launch/image_reader.launch.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/src/launch_wessel_pkg/package.xml b/src/launch_wessel_pkg/package.xml new file mode 100644 index 0000000..61923fe --- /dev/null +++ b/src/launch_wessel_pkg/package.xml @@ -0,0 +1,15 @@ + + + + launch_wessel_pkg + 0.0.0 + TODO: Package description + Wessel T + TODO: License declaration + + ament_cmake + + + ament_cmake + + diff --git a/src/launch_wessel_pkg/rviz/image_processor_config.rviz b/src/launch_wessel_pkg/rviz/image_processor_config.rviz new file mode 100644 index 0000000..65a172d --- /dev/null +++ b/src/launch_wessel_pkg/rviz/image_processor_config.rviz @@ -0,0 +1,131 @@ +Panels: + - Class: rviz_common/Displays + Help Height: 78 + Name: Displays + Property Tree Widget: + Expanded: + - /Global Options1 + - /Status1 + Splitter Ratio: 0.5 + Tree Height: 1255 + - Class: rviz_common/Selection + Name: Selection + - Class: rviz_common/Tool Properties + Expanded: + - /2D Goal Pose1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz_common/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz_common/Time + Experimental: false + Name: Time + SyncMode: 0 + SyncSource: "" +Visualization Manager: + Class: "" + Displays: + - Class: rviz_default_plugins/Image + Enabled: true + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /image_processed + Value: true + Enabled: true + Global Options: + Background Color: 48; 48; 48 + Fixed Frame: map + Frame Rate: 30 + Name: root + Tools: + - Class: rviz_default_plugins/Interact + Hide Inactive Objects: true + - Class: rviz_default_plugins/MoveCamera + - Class: rviz_default_plugins/Select + - Class: rviz_default_plugins/FocusCamera + - Class: rviz_default_plugins/Measure + Line color: 128; 128; 0 + - Class: rviz_default_plugins/SetInitialPose + Covariance x: 0.25 + Covariance y: 0.25 + Covariance yaw: 0.06853891909122467 + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /initialpose + - Class: rviz_default_plugins/SetGoal + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /goal_pose + - Class: rviz_default_plugins/PublishPoint + Single click: true + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /clicked_point + Transformation: + Current: + Class: rviz_default_plugins/TF + Value: true + Views: + Current: + Class: rviz_default_plugins/Orbit + Distance: 10 + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Focal Point: + X: 0 + Y: 0 + Z: 0 + Focal Shape Fixed Size: true + Focal Shape Size: 0.05000000074505806 + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Pitch: 0.785398006439209 + Target Frame: + Value: Orbit (rviz) + Yaw: 0.785398006439209 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 1436 + Hide Left Dock: false + Hide Right Dock: false + Image: + collapsed: false + QMainWindow State: 000000ff00000000fd0000000400000000000001560000056ffc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c00610079007301000000130000056f000000c600fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000032c0000056ffc0200000004fb0000000a0049006d00610067006501000000130000056f0000001600fffffffb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003a000005040000009e00fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004ae0000003efc0100000002fb0000000800540069006d00650000000000000004ae000002e800fffffffb0000000800540069006d00650100000000000004500000000000000000000000200000056f00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730000000000ffffffff0000000000000000 + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: false + Width: 1198 + X: 30 + Y: 54 diff --git a/src/usb_cam_wessel_pkg/CMakeLists.txt b/src/usb_cam_wessel_pkg/CMakeLists.txt new file mode 100644 index 0000000..1e05b48 --- /dev/null +++ b/src/usb_cam_wessel_pkg/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.8) +project(usb_cam_wessel_pkg) + +find_package(ament_cmake REQUIRED) + +install( + DIRECTORY config/ + DESTINATION share/${PROJECT_NAME}/config +) + +ament_package() diff --git a/src/usb_cam_wessel_pkg/config/params.yaml b/src/usb_cam_wessel_pkg/config/params.yaml new file mode 100644 index 0000000..31331a8 --- /dev/null +++ b/src/usb_cam_wessel_pkg/config/params.yaml @@ -0,0 +1,23 @@ +/usb_cam: + ros__parameters: + video_device: "/dev/video0" + framerate: 30.0 + io_method: "mmap" + frame_id: "camera" + pixel_format: "mjpeg2rgb" + color_format: "yuv422p" + image_width: 640 + image_height: 480 + camera_name: "usb_cam" + camera_info_url: "" + brightness: -1 + contrast: -1 + saturation: -1 + sharpness: -1 + gain: -1 + auto_white_balance: true + white_balance: 4000 + autoexposure: true + exposure: 100 + autofocus: false + focus: -1 diff --git a/src/usb_cam_wessel_pkg/package.xml b/src/usb_cam_wessel_pkg/package.xml new file mode 100644 index 0000000..00e0de5 --- /dev/null +++ b/src/usb_cam_wessel_pkg/package.xml @@ -0,0 +1,15 @@ + + + + usb_cam_wessel_pkg + 0.0.0 + USB camera package for ROS2 + wessel + TODO: License declaration + + ament_cmake + + + ament_cmake + +