|
| 1 | +# Image Filtering Node |
| 2 | + |
| 3 | +The `image_filtering_node` is a ROS 2 node developed in the `vortex::image_filters` namespace. It is designed to subscribe to image topics, apply various image filters using OpenCV, and publish the filtered images back to ROS. |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +- **Multiple Filters**: Supports sharpening, unsharpening, eroding, dilating, white balancing, and a custom "ebus" filter. |
| 8 | +- **Dynamic Reconfiguration**: Allows for runtime changes to filter parameters and subscribed image topics via ROS 2 parameters. |
| 9 | +- **Parameter-Driven Configuration**: Configures filter types and specific attributes through ROS 2 parameters. |
| 10 | + |
| 11 | +## Configuration |
| 12 | + |
| 13 | +Configure the node using ROS 2 parameters: |
| 14 | + |
| 15 | +- **`image_topic`**: Topic from which the node will subscribe to image messages. |
| 16 | +- **`filter_params.filter_type`**: Specifies the filter to apply. Current options include: |
| 17 | + - `nofilter` |
| 18 | + - `sharpening` |
| 19 | + - `unsharpening` |
| 20 | + - `eroding` |
| 21 | + - `dilating` |
| 22 | + - `white_balancing` |
| 23 | + - `ebus` |
| 24 | +- **Other filter-specific parameters** such as `blur_size`, `size`, `contrast_percentage`, can be configured through parameter `filter_params`.{filter_name}.{param_name} |
| 25 | + |
| 26 | +Parameters can be set through a YAML file or dynamically adjusted at runtime. |
| 27 | + |
| 28 | +## Additional filters |
| 29 | + |
| 30 | +## Implementing New Filters |
| 31 | + |
| 32 | +To extend the functionality of the `image_filtering_node` by adding new filters, follow these steps to ensure compatibility and integration with the existing codebase: |
| 33 | + |
| 34 | +### Step 1: Define Filter Parameters |
| 35 | + |
| 36 | +Each filter should have its own set of parameters encapsulated in a structure. Define this structure within the `vortex::image_filters` namespace. |
| 37 | + |
| 38 | +```cpp |
| 39 | +struct YourFilterParams { |
| 40 | + // Add necessary parameters here |
| 41 | + int example_param; |
| 42 | +}; |
| 43 | +``` |
| 44 | +
|
| 45 | +### Step 2: Add to FilterParams Structure |
| 46 | +
|
| 47 | +Integrate your new filter parameters structure into the existing `FilterParams` structure. This allows the `apply_filter` function to access the parameters specific to your filter. |
| 48 | +
|
| 49 | +```cpp |
| 50 | +struct FilterParams { |
| 51 | + std::string filter_type; |
| 52 | + UnsharpeningFilterParams unsharpening; |
| 53 | + ErodingFilterParams eroding; |
| 54 | + DilatingFilterParams dilating; |
| 55 | + WhiteBalancingFilterParams white_balancing; |
| 56 | + EbusFilterParams ebus; |
| 57 | + YourFilterParams your_filter; // Add your filter params here |
| 58 | +}; |
| 59 | +``` |
| 60 | + |
| 61 | +### Step 3: Create the Filter Function |
| 62 | + |
| 63 | +Implement your filter function. This function should take the `cv::Mat` objects for the input and output images and a `const FilterParams&` which includes your specific filter parameters. Make sure to use your parameter structure within this function. |
| 64 | + |
| 65 | +```cpp |
| 66 | +void your_filter_function(const cv::Mat &original, cv::Mat &filtered, const FilterParams& filter_params) { |
| 67 | + // Access your filter-specific parameters like this: |
| 68 | + int example_param = filter_params.your_filter.example_param; |
| 69 | + |
| 70 | + // Implement your filtering logic here |
| 71 | +} |
| 72 | +``` |
| 73 | +
|
| 74 | +### Step 4: Register the Filter Function |
| 75 | +
|
| 76 | +Add an entry to the `filter_functions` map for your new filter. This step is crucial as it links the filter name (as a string) to the corresponding filter function pointer. |
| 77 | +
|
| 78 | +```cpp |
| 79 | +std::map<std::string, FilterFunction> filter_functions = { |
| 80 | + {"no_filter", no_filter}, |
| 81 | + {"sharpening", sharpening_filter}, |
| 82 | + {"unsharpening", unsharpening_filter}, |
| 83 | + {"eroding", eroding_filter}, |
| 84 | + {"dilating", dilating_filter}, |
| 85 | + {"white_balancing", white_balance_filter}, |
| 86 | + {"ebus", ebus_filter}, |
| 87 | + {"your_filter", your_filter_function} // Add your filter here |
| 88 | +}; |
| 89 | +``` |
| 90 | + |
| 91 | +### Step 5: Declare and Assign Parameters |
| 92 | + |
| 93 | +Declare the new filter parameters in the ROS 2 node constructor and assign these parameters to the `FilterParams` structure within the `set_filter_params` function. |
| 94 | + |
| 95 | +#### In the Node Constructor |
| 96 | + |
| 97 | +In the constructor of your ROS 2 node, declare each of the new filter parameters using the `declare_parameter` function. This sets the default values and prepares the node to accept these parameters at runtime through command line or a YAML configuration file. |
| 98 | + |
| 99 | +```cpp |
| 100 | +ImageFilteringNode::ImageFilteringNode() : Node("image_filtering_node") |
| 101 | +{ |
| 102 | + this->declare_parameter<std::string>("filter_params.your_filter.example_param", "default_value"); |
| 103 | + ... |
| 104 | + // Other parameters declarations |
| 105 | +} |
| 106 | +``` |
| 107 | +
|
| 108 | +
|
| 109 | +#### In the set_filter_params Function |
| 110 | +
|
| 111 | +In the set_filter_params function, retrieve and assign the parameters to the corresponding fields in the FilterParams structure. Ensure to handle cases where the parameter might not be set or provided. |
| 112 | +
|
| 113 | +```cpp |
| 114 | +
|
| 115 | +void ImageFilteringNode::set_filter_params(){ |
| 116 | + FilterParams params = filter_params_; // assuming filter_params_ is already defined in your class |
| 117 | +
|
| 118 | + params.your_filter.example_param = this->get_parameter("filter_params.your_filter.example_param").as_string(); |
| 119 | + ... |
| 120 | + // Retrieve other parameters and handle cases where parameters might not be provided |
| 121 | + filter_params_ = params; // Update the filter parameters structure |
| 122 | + RCLCPP_INFO(this->get_logger(), "Filter parameters updated for your_filter."); |
| 123 | +} |
| 124 | +``` |
0 commit comments