Skip to content

Commit d1b80c4

Browse files
authored
Merge pull request #19 from vortexntnu/thomas_sonar_filter
Thomas sonar filter
2 parents d3627a5 + e5c5021 commit d1b80c4

5 files changed

Lines changed: 118 additions & 1 deletion

File tree

image-filtering/config/image_filtering_params.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
output_encoding: "mono8"
77

88
filter_params:
9-
filter_type: "otsu"
9+
filter_type: "temporal_noise"
1010
flip:
1111
flip_code: 1
1212
unsharpening:
@@ -40,3 +40,11 @@
4040
threshold: 20. # in percent
4141
maxval: 255.
4242
invert: true
43+
temporal_noise:
44+
median_kernel_size: 3
45+
power_law_weight: 4.0 # Weight for the gamma function
46+
erotion_size: 2
47+
dilation_size: 4
48+
canny_high: 90 # upper weight for canny edge detection
49+
canny_low: 30 # lower weight ---------- || ----------
50+
edge_protection_radius: 2 # Radius for protecting edges

image-filtering/include/image_filtering/lib/filters/all_filters.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "image_filtering/lib/filters/otsu.hpp"
1212
#include "image_filtering/lib/filters/overlap.hpp"
1313
#include "image_filtering/lib/filters/sharpening.hpp"
14+
#include "image_filtering/lib/filters/temporal_noise.hpp"
1415
#include "image_filtering/lib/filters/unsharpening.hpp"
1516
#include "image_filtering/lib/filters/white_balancing.hpp"
1617

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#ifndef IMAGE_FILTERING__LIB__FILTERS__TEMPORAL_NOISE_HPP_
2+
#define IMAGE_FILTERING__LIB__FILTERS__TEMPORAL_NOISE_HPP_
3+
4+
#include "abstract_filter_class.hpp"
5+
#include "image_filtering/lib/utilities.hpp"
6+
7+
/////////////////////////////
8+
// Sonar noise
9+
/////////////////////////////
10+
namespace vortex::image_filtering {
11+
struct TemporalNoiseParams {
12+
int median_kernel_size;
13+
double power_law_weight;
14+
15+
int canny_low;
16+
int canny_high;
17+
int edge_protection_radius;
18+
19+
int erotion_size;
20+
int dilation_size;
21+
};
22+
23+
class TemporalNoise : public Filter {
24+
public:
25+
explicit TemporalNoise(TemporalNoiseParams params)
26+
: filter_params_(params) {}
27+
void apply_filter(const cv::Mat& original,
28+
cv::Mat& filtered) const override;
29+
30+
private:
31+
TemporalNoiseParams filter_params_;
32+
mutable cv::Mat previous_;
33+
mutable bool has_prev_{false};
34+
};
35+
36+
inline void TemporalNoise::apply_filter(const cv::Mat& original,
37+
cv::Mat& filtered) const {
38+
const double power_law_weight = filter_params_.power_law_weight;
39+
const int erosion_size = filter_params_.erotion_size;
40+
const int dilation_size = filter_params_.dilation_size;
41+
const int protect_radius = filter_params_.edge_protection_radius;
42+
const int canny_low = filter_params_.canny_low;
43+
const int canny_high = filter_params_.canny_high;
44+
const int median_kernel_size = filter_params_.median_kernel_size;
45+
46+
cv::Mat temp;
47+
original.copyTo(temp);
48+
49+
apply_median(temp, temp, median_kernel_size);
50+
51+
apply_auto_gamma(temp, power_law_weight);
52+
53+
if (!has_prev_) {
54+
temp.copyTo(previous_);
55+
temp.copyTo(filtered);
56+
has_prev_ = true;
57+
} else {
58+
cv::addWeighted(temp, 0.5, previous_, 0.5, 0.0, filtered);
59+
temp.copyTo(previous_);
60+
}
61+
62+
cv::Mat edges;
63+
cv::Canny(filtered, edges, canny_low, canny_high);
64+
65+
// Thicken mask a bit so we protect the whole line, not just 1px edge.
66+
if (protect_radius > 0) {
67+
cv::Mat k = cv::getStructuringElement(
68+
cv::MORPH_ELLIPSE,
69+
cv::Size(2 * protect_radius + 1, 2 * protect_radius + 1));
70+
cv::dilate(edges, edges, k);
71+
}
72+
73+
// Invert mask: where NOT edges => safe to morph aggressively.
74+
cv::Mat not_edges;
75+
cv::bitwise_not(edges, not_edges);
76+
77+
// Morphing only outside the protected areas
78+
cv::Mat morphed = filtered.clone();
79+
80+
apply_erosion(morphed, morphed, erosion_size);
81+
apply_dilation(morphed, morphed, dilation_size);
82+
83+
morphed.copyTo(filtered, not_edges);
84+
}
85+
} // namespace vortex::image_filtering
86+
#endif // IMAGE_FILTERING__LIB__FILTERS__TEMPORAL_NOISE_HPP_

image-filtering/include/image_filtering/lib/typedef.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enum class FilterType {
2222
Overlap,
2323
MedianBinary,
2424
Binary,
25+
TemporalNoise,
2526

2627
Unknown
2728
};
@@ -39,6 +40,7 @@ static constexpr std::pair<std::string_view, FilterType> kFilterMap[] = {
3940
{"overlap", FilterType::Overlap},
4041
{"median_binary", FilterType::MedianBinary},
4142
{"binary", FilterType::Binary},
43+
{"temporal_noise", FilterType::TemporalNoise},
4244

4345
{"unknown", FilterType::Unknown}};
4446

image-filtering/src/ros/image_filtering_ros.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,26 @@ void ImageFilteringNode::set_filter_params() {
144144
filter_ptr_ = std::make_unique<BinaryThreshold>(params);
145145
break;
146146
}
147+
case FilterType::TemporalNoise: {
148+
TemporalNoiseParams params;
149+
params.median_kernel_size = declare_and_get<int>(
150+
"filter_params.temporal_noise.median_kernel_size");
151+
params.power_law_weight = declare_and_get<double>(
152+
"filter_params.temporal_noise.power_law_weight");
153+
params.erotion_size = declare_and_get<int>(
154+
"filter_params.temporal_noise.erotion_size");
155+
params.dilation_size = declare_and_get<int>(
156+
"filter_params.temporal_noise.dilation_size");
157+
params.canny_high =
158+
declare_and_get<int>("filter_params.temporal_noise.canny_high");
159+
params.canny_low =
160+
declare_and_get<int>("filter_params.temporal_noise.canny_low");
161+
params.edge_protection_radius = declare_and_get<int>(
162+
"filter_params.temporal_noise.edge_protection_radius");
163+
164+
filter_ptr_ = std::make_unique<TemporalNoise>(params);
165+
break;
166+
}
147167

148168
default:;
149169
if (filter_type == FilterType::Unknown) {

0 commit comments

Comments
 (0)