18#include <google/protobuf/util/time_util.h>
22#include "trackerdata.pb.h"
26using 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)));
127bool 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);
158bool 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();
Track an object selected by the user.
Header file for all Exception classes.
Header file for OpenCVUtilities (set some common macros)
void SetError(bool err, std::string message)
void trackClip(openshot::Clip &video, size_t _start=0, size_t _end=0, bool process_interval=false)
CVTracker(std::string processInfoJson, ProcessingController &processingController)
bool SaveTrackedData()
Save protobuf file.
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
void SetJson(const std::string value)
Load JSON string into this object.
cv::Rect2d filter_box_jitter(size_t frameId)
Filter current bounding box jitter.
void AddFrameDataToProto(pb_tracker::Frame *pbFrameData, FrameData &fData)
Add frame tracked data into protobuf message.
FrameData GetTrackedData(size_t frameId)
Get tracked data for a given frame.
cv::Ptr< OPENCV_TRACKER_TYPE > selectTracker(std::string trackerType)
float Start() const
Get start position (in seconds) of clip (trim start of video)
This class represents a clip (used to arrange readers on the timeline)
void Open() override
Open the internal reader.
float End() const override
Get end position (in seconds) of clip (trim end of video), which can be affected by the time curve.
std::shared_ptr< openshot::Frame > GetFrame(int64_t clip_frame_number) override
Get an openshot::Frame object for a specific frame number of this clip. The image size and number of ...
void Reader(openshot::ReaderBase *new_reader)
Set the current reader.
Exception for invalid JSON.
This namespace is the default namespace for all code in the openshot library.
const Json::Value stringToJson(const std::string value)