18 #include <google/protobuf/util/time_util.h>
22 #include "trackerdata.pb.h"
26 using google::protobuf::util::TimeUtil;
30 : processingController(&processingController), json_interval(false){
39 if (trackerType ==
"BOOSTING")
40 return OPENCV_TRACKER_NS::TrackerBoosting::create();
41 if (trackerType ==
"MIL")
42 return OPENCV_TRACKER_NS::TrackerMIL::create();
43 if (trackerType ==
"KCF")
44 return OPENCV_TRACKER_NS::TrackerKCF::create();
45 if (trackerType ==
"TLD")
46 return OPENCV_TRACKER_NS::TrackerTLD::create();
47 if (trackerType ==
"MEDIANFLOW")
48 return OPENCV_TRACKER_NS::TrackerMedianFlow::create();
49 if (trackerType ==
"MOSSE")
50 return OPENCV_TRACKER_NS::TrackerMOSSE::create();
51 if (trackerType ==
"CSRT")
52 return OPENCV_TRACKER_NS::TrackerCSRT::create();
62 start = _start; end = _end;
64 if(!process_interval || end <= 1 || end-start == 0){
66 start = (int)(video.
Start() * video.
Reader()->info.fps.ToFloat()) + 1;
67 end = (int)(video.
End() * video.
Reader()->info.fps.ToFloat()) + 1;
71 start = (int)(start + video.
Start() * video.
Reader()->info.fps.ToFloat()) + 1;
72 end = (int)(video.
End() * video.
Reader()->info.fps.ToFloat()) + 1;
79 processingController->
SetError(
false,
"");
80 bool trackerInit =
false;
84 for (frame = start; frame <= end; frame++)
92 size_t frame_number = frame;
94 std::shared_ptr<openshot::Frame> f = video.
GetFrame(frame_number);
97 cv::Mat cvimage = f->GetImageCV();
101 bbox = cv::Rect2d(
int(bbox.x*cvimage.cols),
int(bbox.y*cvimage.rows),
102 int(bbox.width*cvimage.cols),
int(bbox.height*cvimage.rows));
109 initTracker(cvimage, frame_number);
115 trackerInit = trackFrame(cvimage, frame_number);
122 processingController->
SetProgress(uint(100*(frame_number-start)/(end-start)));
127 bool CVTracker::initTracker(cv::Mat &frame,
size_t frameId){
134 bbox.x = bbox.x - abs(bbox.width);
135 bbox.width = abs(bbox.width);
138 bbox.y = bbox.y - abs(bbox.height);
139 bbox.height = abs(bbox.height);
143 tracker->init(frame, bbox);
145 float fw = frame.size().width;
146 float fh = frame.size().height;
149 trackedDataById[frameId] =
FrameData(frameId, 0, (bbox.x)/fw,
151 (bbox.x+bbox.width)/fw,
152 (bbox.y+bbox.height)/fh);
158 bool CVTracker::trackFrame(cv::Mat &frame,
size_t frameId){
160 bool ok = tracker->update(frame, bbox);
166 float fw = frame.size().width;
167 float fh = frame.size().height;
171 trackedDataById[frameId] =
FrameData(frameId, 0, (filtered_box.x)/fw,
173 (filtered_box.x+filtered_box.width)/fw,
174 (filtered_box.y+filtered_box.height)/fh);
179 trackedDataById[frameId] = trackedDataById[frameId-1];
187 float last_box_width = trackedDataById[frameId-1].x2 - trackedDataById[frameId-1].x1;
188 float last_box_height = trackedDataById[frameId-1].y2 - trackedDataById[frameId-1].y1;
190 float curr_box_width = bbox.width;
191 float curr_box_height = bbox.height;
193 float threshold = 0.01;
195 cv::Rect2d filtered_box = bbox;
196 if(std::abs(1-(curr_box_width/last_box_width)) <= threshold){
197 filtered_box.width = last_box_width;
199 if(std::abs(1-(curr_box_height/last_box_height)) <= threshold){
200 filtered_box.height = last_box_height;
209 pb_tracker::Tracker trackerMessage;
212 for(std::map<size_t,FrameData>::iterator it=trackedDataById.begin(); it!=trackedDataById.end(); ++it){
214 pb_tracker::Frame* pbFrameData;
219 *trackerMessage.mutable_last_updated() = TimeUtil::SecondsToTimestamp(time(NULL));
223 std::fstream output(protobuf_data_path, ios::out | ios::trunc | ios::binary);
224 if (!trackerMessage.SerializeToOstream(&output)) {
225 std::cerr <<
"Failed to write protobuf message." << std::endl;
231 google::protobuf::ShutdownProtobufLibrary();
241 pbFrameData->set_id(fData.
frame_id);
242 pbFrameData->set_rotation(0);
244 pb_tracker::Frame::Box* box = pbFrameData->mutable_bounding_box();
246 box->set_x1(fData.
x1);
247 box->set_y1(fData.
y1);
248 box->set_x2(fData.
x2);
249 box->set_y2(fData.
y2);
256 if ( trackedDataById.find(frameId) == trackedDataById.end() ) {
261 return trackedDataById[frameId];
276 catch (
const std::exception& e)
287 if (!root[
"protobuf_data_path"].isNull()){
288 protobuf_data_path = (root[
"protobuf_data_path"].asString());
290 if (!root[
"tracker-type"].isNull()){
291 trackerType = (root[
"tracker-type"].asString());
294 if (!root[
"region"].isNull()){
295 double x = root[
"region"][
"normalized_x"].asDouble();
296 double y = root[
"region"][
"normalized_y"].asDouble();
297 double w = root[
"region"][
"normalized_width"].asDouble();
298 double h = root[
"region"][
"normalized_height"].asDouble();
299 cv::Rect2d prev_bbox(x,y,w,h);
302 if (!root[
"region"][
"first-frame"].isNull()){
303 start = root[
"region"][
"first-frame"].asInt64();
304 json_interval =
true;
307 processingController->
SetError(
true,
"No first-frame");
313 processingController->
SetError(
true,
"No initial bounding box selected");
330 pb_tracker::Tracker trackerMessage;
334 std::fstream input(protobuf_data_path, ios::in | ios::binary);
335 if (!trackerMessage.ParseFromIstream(&input)) {
336 std::cerr <<
"Failed to parse protobuf message." << std::endl;
342 trackedDataById.clear();
345 for (
size_t i = 0; i < trackerMessage.frame_size(); i++) {
346 const pb_tracker::Frame& pbFrameData = trackerMessage.frame(i);
349 size_t id = pbFrameData.id();
350 float rotation = pbFrameData.rotation();
353 const pb_tracker::Frame::Box& box = pbFrameData.bounding_box();
360 trackedDataById[id] =
FrameData(
id, rotation, x1, y1, x2, y2);
364 google::protobuf::ShutdownProtobufLibrary();