4 #include <opencv2/opencv.hpp>
7 typedef std::list<Frame *> trail_t;
11 virtual void iterate(cv::Mat& frame, void (*action)(cv::Mat&, Frame *, int, int)) = 0;
13 cv::Mat *background = NULL;
14 bool redraw_current_frame;
17 void (*drawStrategy)(cv::Mat&, Frame *, int, int);
19 static void frameCopy(cv::Mat& destination, Frame *frame, int frame_index, int trail_size)
23 frame->copyTo(destination);
26 static void frameAccumulate(cv::Mat& destination, Frame *frame, int frame_index, int trail_size)
30 cv::accumulate(frame->getData(), destination, frame->getMask());
33 static void frameFadeCopy(cv::Mat& destination, Frame *frame, int frame_index, int trail_size)
35 double weight = ((double) frame_index) / trail_size;
36 cv::Mat weighted_frame;
38 frame->getData().convertTo(weighted_frame, destination.type(), weight);
39 weighted_frame.copyTo(destination, frame->getMask());
42 static void frameFadeAccumulate(cv::Mat& destination, Frame *frame, int frame_index, int trail_size)
44 double weight = ((double) frame_index) / trail_size;
45 cv::accumulateWeighted(frame->getData(), destination, weight, frame->getMask());
48 static void frameAverage(cv::Mat& destination, Frame *frame, int frame_index, int trail_size)
51 double weight = 1. / trail_size;
52 cv::accumulateWeighted(frame->getData(), destination, weight, frame->getMask());
59 Trail(int trail_length, cv::Size frame_size)
61 redraw_current_frame = false;
62 drawStrategy = frameCopy;
65 if (trail_length < 0) {
67 background = new cv::Mat(frame_size, CV_8UC3);
73 for (int i = 0; i < trail_length; i++)
74 trail.push_back(new Frame(frame_size));
79 trail_t::iterator trail_it;
80 for (trail_it = trail.begin(); trail_it != trail.end(); trail_it++) {
87 void setBackground(cv::Mat trail_background)
90 background = new cv::Mat(trail_background);
93 int setDrawingMethod(std::string drawing_method)
95 if (drawing_method == "copy") {
96 drawStrategy = frameCopy;
97 } else if (drawing_method == "accumulate") {
98 drawStrategy = frameAccumulate;
99 } else if (drawing_method == "fadecopy") {
100 drawStrategy = frameFadeCopy;
101 } else if (drawing_method == "fadeaccumulate") {
102 drawStrategy = frameFadeAccumulate;
103 } else if (drawing_method == "average") {
104 drawStrategy = frameAverage;
111 void setRedrawCurrentFrame(bool do_redraw_current_frame)
113 redraw_current_frame = do_redraw_current_frame;
116 void update(Frame *frame)
118 Frame *front = trail.front();
122 trail.push_back(frame);
125 void draw(cv::Mat& destination)
127 cv::Mat float_destination;
130 background->convertTo(float_destination, CV_32FC3);
132 destination.convertTo(float_destination, CV_32FC3);
134 iterate(float_destination, drawStrategy);
135 float_destination.convertTo(destination, destination.type());
137 if (redraw_current_frame) {
138 Frame *current_frame = trail.back();
139 current_frame->getData().copyTo(destination, current_frame->getMask());
142 /* remember the current trail in the background image */
144 float_destination.convertTo(*background, background->type());
148 class ForwardTrail: public Trail {
149 void iterate(cv::Mat& destination, void (*action)(cv::Mat&, Frame *, int, int))
152 trail_t::iterator trail_it;
153 for (trail_it = trail.begin(); trail_it != trail.end(); trail_it++) {
154 action(destination, *trail_it, ++index, trail.size());
159 ForwardTrail(int trail_lenght, cv::Size frame_size) : Trail(trail_lenght, frame_size)
164 class ReverseTrail: public Trail {
165 void iterate(cv::Mat& destination, void (*action)(cv::Mat&, Frame *, int, int))
168 trail_t::reverse_iterator trail_it;
169 for (trail_it = trail.rbegin(); trail_it != trail.rend(); trail_it++) {
170 action(destination, *trail_it, ++index, trail.size());
175 ReverseTrail(int trail_lenght, cv::Size frame_size) : Trail(trail_lenght, frame_size)