background_subtractor.cpp
Go to the documentation of this file.
1 #include <opencv2/highgui/highgui.hpp>
2 //#include <opencv2/cvv/cvv.hpp>
4 
5 BackgroundSubtractor::BackgroundSubtractor(const Params &parameters): params_(parameters)
6 {
7 }
8 
9 void BackgroundSubtractor::apply(const cv::Mat& image, cv::Mat& fg_mask, int shift_x, int shift_y)
10 {
11  current_frame_ = image;
12 
13  // occupancy grids are empty only once in the beginning -> initialize variables
14  if (occupancy_grid_fast_.empty() && occupancy_grid_slow_.empty())
15  {
18  previous_shift_x_ = shift_x;
19  previous_shift_y_ = shift_y;
20  return;
21  }
22 
23  // Shift previous occupancy grid to new location (match current_frame_)
24  int shift_relative_to_previous_pos_x_ = shift_x - previous_shift_x_;
25  int shift_relative_to_previous_pos_y_ = shift_y - previous_shift_y_;
26  previous_shift_x_ = shift_x;
27  previous_shift_y_ = shift_y;
28 
29  // if(shift_relative_to_previous_pos_x_ != 0 || shift_relative_to_previous_pos_y_ != 0)
30  transformToCurrentFrame(shift_relative_to_previous_pos_x_, shift_relative_to_previous_pos_y_);
31 
32  // cvv::debugFilter(occupancy_grid_fast_, currentFrame_, CVVISUAL_LOCATION);
33 
34  // Calculate normalized sum (mean) of nearest neighbors
35  int size = 3; // 3, 5, 7, ....
36  cv::Mat nearest_neighbor_mean_fast(occupancy_grid_fast_.size(), CV_8UC1);
37  cv::Mat nearest_neighbor_mean_slow(occupancy_grid_slow_.size(), CV_8UC1);
38  cv::boxFilter(occupancy_grid_fast_, nearest_neighbor_mean_fast, -1, cv::Size(size, size), cv::Point(-1, -1), true,
39  cv::BORDER_REPLICATE);
40  cv::boxFilter(occupancy_grid_slow_, nearest_neighbor_mean_slow, -1, cv::Size(size, size), cv::Point(-1, -1), true,
41  cv::BORDER_REPLICATE);
42  // cv::GaussianBlur(occupancy_grid_fast_, nearest_neighbor_mean_fast, cv::Size(size,size), 1, 1, cv::BORDER_REPLICATE);
43  // cv::GaussianBlur(occupancy_grid_fast_, nearest_neighbor_mean_fast, cv::Size(size,size), 1, 1, cv::BORDER_REPLICATE);
44 
45  // compute time mean value for each pixel according to learningrate alpha
46  // occupancy_grid_fast_ = beta*(alpha_fast*current_frame_ + (1.0-alpha_fast)*occupancy_grid_fast_) + (1-beta)*nearest_neighbor_mean_fast;
48  cv::addWeighted(occupancy_grid_fast_, params_.beta, nearest_neighbor_mean_fast, (1 - params_.beta), 0, occupancy_grid_fast_);
49  // occupancy_grid_slow_ = beta*(alpha_slow*current_frame_ + (1.0-alpha_slow)*occupancy_grid_slow) + (1-beta)*nearest_neighbor_mean_slow;
51  cv::addWeighted(occupancy_grid_slow_, params_.beta, nearest_neighbor_mean_slow, (1 - params_.beta), 0, occupancy_grid_slow_);
52 
53  // 1) Obstacles should be detected after a minimum response of the fast filter
54  // occupancy_grid_fast_ > min_occupancy_probability
55  cv::threshold(occupancy_grid_fast_, occupancy_grid_fast_, params_.min_occupancy_probability, 0 /*unused*/, cv::THRESH_TOZERO);
56  // 2) Moving obstacles have a minimum difference between the responses of the slow and fast filter
57  // occupancy_grid_fast_-occupancy_grid_slow_ > min_sep_between_fast_and_slow_filter
59  cv::THRESH_BINARY);
60  // 3) Dismiss static obstacles
61  // nearest_neighbor_mean_slow < max_occupancy_neighbors
62  cv::threshold(nearest_neighbor_mean_slow, nearest_neighbor_mean_slow, params_.max_occupancy_neighbors, 255, cv::THRESH_BINARY_INV);
63  cv::bitwise_and(nearest_neighbor_mean_slow, fg_mask, fg_mask);
64 
65  //visualize("Current frame", currentFrame_);
66  cv::Mat setBorderToZero = cv::Mat(current_frame_.size(), CV_8UC1, 0.0);
67  int border = 5;
68  setBorderToZero(cv::Rect(border, border, current_frame_.cols-2*border, current_frame_.rows-2*border)) = 255;
69 
70  cv::bitwise_and(setBorderToZero, fg_mask, fg_mask);
71 
72  // cv::imwrite("/home/albers/Desktop/currentFrame.png", currentFrame_);
73  // visualize("Foreground mask", fgMask);
74 
75  // Closing Operation
76  cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE,
77  cv::Size(2*params_.morph_size + 1, 2*params_.morph_size + 1),
78  cv::Point(params_.morph_size, params_.morph_size));
79  cv::dilate(fg_mask, fg_mask, element);
80  cv::dilate(fg_mask, fg_mask, element);
81  cv::erode(fg_mask, fg_mask, element);
82 }
83 
84 void BackgroundSubtractor::transformToCurrentFrame(int shift_x, int shift_y)
85 {
86  // TODO: initialize with current_frame (first observed image) rather than zeros
87 
88  // Translate (shift) image in costmap coordinates
89  // in cv::Mat: shift X -> to the left; shift y -> to the top
90  cv::Mat temp_fast, temp_slow;
91  cv::Mat translation_mat = (cv::Mat_<double>(2, 3, CV_64F) << 1, 0, -shift_x, 0, 1, -shift_y);
92  cv::warpAffine(occupancy_grid_fast_, temp_fast, translation_mat, occupancy_grid_fast_.size()); // can't operate in-place
93  cv::warpAffine(occupancy_grid_slow_, temp_slow, translation_mat, occupancy_grid_slow_.size()); // can't operate in-place
94 
95  // cvv::debugFilter(occupancy_grid_fast_, temp_fast);
96 
97  occupancy_grid_fast_ = temp_fast;
98  occupancy_grid_slow_ = temp_slow;
99 }
100 
101 void BackgroundSubtractor::visualize(const std::string& name, const cv::Mat& image)
102 {
103  if (!image.empty())
104  {
105  cv::Mat im = image.clone();
106  cv::flip(im, im, 0);
107  cv::imshow(name, im);
108  cv::waitKey(1);
109  }
110 }
111 
113 {
114  params_ = parameters;
115 }
void apply(const cv::Mat &image, cv::Mat &fg_mask, int shift_x=0, int shift_y=0)
Computes a foreground mask.
double alpha_fast
Filter constant (learning rate) of the fast filter part.
void visualize(const std::string &name, const cv::Mat &image)
OpenCV Visualization.
double alpha_slow
Filter constant (learning rate) of the slow filter part.
void transformToCurrentFrame(int shift_x, int shift_y)
Transform/shift all internal matrices/grids according to a given translation vector.
BackgroundSubtractor(const Params &parameters)
Constructor that accepts a specific parameter configuration.
void updateParameters(const Params &parameters)
Update internal parameters.


costmap_converter
Author(s): Christoph Rösmann , Franz Albers , Otniel Rinaldo
autogenerated on Sat May 16 2020 03:19:18