21 #include "trackerdata.pb.h" 
   23 #include <google/protobuf/util/time_util.h> 
   33 using google::protobuf::util::TimeUtil;
 
   36 Tracker::Tracker(std::string clipTrackerDataPath)
 
   39     init_effect_details();
 
   42     trackedData = std::make_shared<TrackedObjectBBox>(trackedDataObject);
 
   44     trackedData->LoadBoxData(clipTrackerDataPath);
 
   45     ClipBase* parentClip = this->ParentClip();
 
   46     trackedData->ParentClip(parentClip);
 
   47     trackedData->Id(std::to_string(0));
 
   49     trackedObjects.insert({0, trackedData});
 
   56     init_effect_details();
 
   59     trackedData = std::make_shared<TrackedObjectBBox>(trackedDataObject);
 
   60     ClipBase* parentClip = this->ParentClip();
 
   61     trackedData->ParentClip(parentClip);
 
   62     trackedData->Id(std::to_string(0));
 
   64     trackedObjects.insert({0, trackedData});
 
   69 void Tracker::init_effect_details()
 
   75     info.class_name = 
"Tracker";
 
   76     info.name = 
"Tracker";
 
   77     info.description = 
"Track the selected bounding box through the video.";
 
   78     info.has_audio = 
false;
 
   79     info.has_video = 
true;
 
   80     info.has_tracked_object = 
true;
 
   82     this->TimeScale = 1.0;
 
   87 std::shared_ptr<Frame> Tracker::GetFrame(std::shared_ptr<Frame> frame, int64_t frame_number) {
 
   89     std::shared_ptr<QImage> frame_image = frame->GetImage();
 
   92     if(frame_image && !frame_image->isNull() &&
 
   93        trackedData->Contains(frame_number) &&
 
   94        trackedData->visible.GetValue(frame_number) == 1) {
 
   95         QPainter painter(frame_image.get());
 
   98         BBox fd = trackedData->GetBox(frame_number);
 
  101         QRectF boxRect((fd.
cx - fd.
width / 2) * frame_image->width(),
 
  102                        (fd.
cy - fd.
height / 2) * frame_image->height(),
 
  103                        fd.
width * frame_image->width(),
 
  104                        fd.
height * frame_image->height());
 
  107         if (trackedData->draw_box.GetValue(frame_number) == 1) {
 
  108             painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
 
  111             std::vector<int> stroke_rgba = trackedData->stroke.GetColorRGBA(frame_number);
 
  112             int stroke_width = trackedData->stroke_width.GetValue(frame_number);
 
  113             float stroke_alpha = trackedData->stroke_alpha.GetValue(frame_number);
 
  114             std::vector<int> bg_rgba = trackedData->background.GetColorRGBA(frame_number);
 
  115             float bg_alpha = trackedData->background_alpha.GetValue(frame_number);
 
  116             float bg_corner = trackedData->background_corner.GetValue(frame_number);
 
  119             QPen pen(QColor(stroke_rgba[0], stroke_rgba[1], stroke_rgba[2], 255 * stroke_alpha));
 
  120             pen.setWidth(stroke_width);
 
  124             QBrush brush(QColor(bg_rgba[0], bg_rgba[1], bg_rgba[2], 255 * bg_alpha));
 
  125             painter.setBrush(brush);
 
  128             painter.drawRoundedRect(boxRect, bg_corner, bg_corner);
 
  139 std::string Tracker::GetVisibleObjects(int64_t frame_number)
 const{
 
  143     root[
"visible_objects_index"] = Json::Value(Json::arrayValue);
 
  144     root[
"visible_objects_id"] = Json::Value(Json::arrayValue);
 
  147     for (
const auto& trackedObject : trackedObjects){
 
  149         Json::Value trackedObjectJSON = trackedObject.second->PropertiesJSON(frame_number);
 
  150         if (trackedObjectJSON[
"visible"][
"value"].asBool()){
 
  152             root[
"visible_objects_index"].append(trackedObject.first);
 
  153             root[
"visible_objects_id"].append(trackedObject.second->Id());
 
  157     return root.toStyledString();
 
  161 std::string Tracker::Json()
 const {
 
  164     return JsonValue().toStyledString();
 
  168 Json::Value Tracker::JsonValue()
 const {
 
  171     Json::Value root = EffectBase::JsonValue(); 
 
  174     root[
"type"] = info.class_name;
 
  175     root[
"protobuf_data_path"] = protobuf_data_path;
 
  176     root[
"BaseFPS"][
"num"] = BaseFPS.num;
 
  177     root[
"BaseFPS"][
"den"] = BaseFPS.den;
 
  178     root[
"TimeScale"] = this->TimeScale;
 
  182     for (
auto const& trackedObject : trackedObjects){
 
  183         Json::Value trackedObjectJSON = trackedObject.second->JsonValue();
 
  185         objects[trackedObject.second->Id()] = trackedObjectJSON;
 
  187     root[
"objects"] = objects;
 
  194 void Tracker::SetJson(
const std::string value) {
 
  203     catch (
const std::exception& e)
 
  206         throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
 
  212 void Tracker::SetJsonValue(
const Json::Value root) {
 
  215     EffectBase::SetJsonValue(root);
 
  217     if (!root[
"BaseFPS"].isNull() && root[
"BaseFPS"].isObject())
 
  219         if (!root[
"BaseFPS"][
"num"].isNull())
 
  221             BaseFPS.num = (int) root[
"BaseFPS"][
"num"].asInt();
 
  223         if (!root[
"BaseFPS"][
"den"].isNull())
 
  225             BaseFPS.den = (int) root[
"BaseFPS"][
"den"].asInt();
 
  229     if (!root[
"TimeScale"].isNull())
 
  230         TimeScale = (
double) root[
"TimeScale"].asDouble();
 
  233     if (!root[
"protobuf_data_path"].isNull() && protobuf_data_path.size() <= 1)
 
  235         protobuf_data_path = root[
"protobuf_data_path"].asString();
 
  236         if(!trackedData->LoadBoxData(protobuf_data_path))
 
  238             std::clog << 
"Invalid protobuf data path " << protobuf_data_path << 
'\n';
 
  239             protobuf_data_path = 
"";
 
  243     if (!root[
"objects"].isNull()){
 
  244         for (
auto const& trackedObject : trackedObjects){
 
  245             std::string obj_id = std::to_string(trackedObject.first);
 
  246             if(!root[
"objects"][obj_id].isNull()){
 
  247                 trackedObject.second->SetJsonValue(root[
"objects"][obj_id]);
 
  253     if (!root[
"objects_id"].isNull()){
 
  254         for (
auto const& trackedObject : trackedObjects){
 
  255             Json::Value trackedObjectJSON;
 
  256             trackedObjectJSON[
"box_id"] = root[
"objects_id"][trackedObject.first].asString();
 
  257             trackedObject.second->SetJsonValue(trackedObjectJSON);
 
  265 std::string Tracker::PropertiesJSON(int64_t requested_frame)
 const {
 
  268     Json::Value root = BasePropertiesJSON(requested_frame);
 
  272     for (
auto const& trackedObject : trackedObjects){
 
  273         Json::Value trackedObjectJSON = trackedObject.second->PropertiesJSON(requested_frame);
 
  275         objects[trackedObject.second->Id()] = trackedObjectJSON;
 
  277     root[
"objects"] = objects;
 
  280     return root.toStyledString();