1 /** 2 * @file 3 * @brief Header file for the TrackedObjectBBox class 4 * @author Jonathan Thomas <jonathan@openshot.org> 5 * @author Brenno Caldato <brenno.caldato@outlook.com> 6 * 7 * @ref License 8 */ 9 10 /* LICENSE 11 * 12 * Copyright (c) 2008-2019 OpenShot Studios, LLC 13 * <http://www.openshotstudios.com/>. This file is part of 14 * OpenShot Library (libopenshot), an open-source project dedicated to 15 * delivering high quality video editing and animation solutions to the 16 * world. For more information visit <http://www.openshot.org/>. 17 * 18 * OpenShot Library (libopenshot) is free software: you can redistribute it 19 * and/or modify it under the terms of the GNU Lesser General Public License 20 * as published by the Free Software Foundation, either version 3 of the 21 * License, or (at your option) any later version. 22 * 23 * OpenShot Library (libopenshot) is distributed in the hope that it will be 24 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 * GNU Lesser General Public License for more details. 27 * 28 * You should have received a copy of the GNU Lesser General Public License 29 * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>. 30 */ 31 32 #ifndef OPENSHOT_TRACKEDOBJECTBBOX_H 33 #define OPENSHOT_TRACKEDOBJECTBBOX_H 34 35 #include "TrackedObjectBase.h" 36 37 #include "Color.h" 38 #include "Exceptions.h" 39 #include "Fraction.h" 40 #include "Json.h" 41 #include "KeyFrame.h" 42 43 namespace openshot 44 { 45 /** 46 * @brief This struct holds the information of a bounding-box. 47 * 48 * A bounding-box is a rectangular shape that enclosures an 49 * object or a desired set of pixels in a digital image. 50 * 51 * The bounding-box structure holds five floating-point properties: 52 * the x and y coordinates of the rectangle's center point (cx, cy), 53 * the rectangle's width, height and rotation. 54 */ 55 struct BBox 56 { 57 float cx = -1; ///< x-coordinate of the bounding box center 58 float cy = -1; ///< y-coordinate of the bounding box center 59 float width = -1; ///< bounding box width 60 float height = -1; ///< bounding box height 61 float angle = -1; ///< bounding box rotation angle [degrees] 62 63 /// Blank constructor BBoxBBox64 BBox() {} 65 66 /// Default constructor, which takes the bounding box top-left corner coordinates, width and height. 67 /// @param _cx X-coordinate of the bounding box center 68 /// @param _cy Y-coordinate of the bounding box center 69 /// @param _width Bounding box width 70 /// @param _height Bounding box height 71 /// @param _angle Bounding box rotation angle [degrees] BBoxBBox72 BBox(float _cx, float _cy, float _width, float _height, float _angle) 73 { 74 cx = _cx; 75 cy = _cy; 76 width = _width; 77 height = _height; 78 angle = _angle; 79 } 80 81 82 /// Generate JSON string of this object JsonBBox83 std::string Json() const 84 { 85 return JsonValue().toStyledString(); 86 } 87 88 /// Generate Json::Value for this object JsonValueBBox89 Json::Value JsonValue() const 90 { 91 Json::Value root; 92 root["cx"] = cx; 93 root["cy"] = cy; 94 root["width"] = width; 95 root["height"] = height; 96 root["angle"] = angle; 97 98 return root; 99 } 100 101 /// Load JSON string into this object SetJsonBBox102 void SetJson(const std::string value) 103 { 104 // Parse JSON string into JSON objects 105 try 106 { 107 const Json::Value root = openshot::stringToJson(value); 108 // Set all values that match 109 SetJsonValue(root); 110 } 111 catch (const std::exception &e) 112 { 113 // Error parsing JSON (or missing keys) 114 throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); 115 } 116 } 117 118 /// Load Json::Value into this object SetJsonValueBBox119 void SetJsonValue(const Json::Value root) 120 { 121 122 // Set data from Json (if key is found) 123 if (!root["cx"].isNull()) 124 cx = root["cx"].asDouble(); 125 if (!root["cy"].isNull()) 126 cy = root["cy"].asDouble(); 127 if (!root["width"].isNull()) 128 width = root["width"].asDouble(); 129 if (!root["height"].isNull()) 130 height = root["height"].asDouble(); 131 if (!root["angle"].isNull()) 132 angle = root["angle"].asDouble(); 133 } 134 }; 135 136 /** 137 * @brief This class contains the properties of a tracked object 138 * and functions to manipulate it. 139 * 140 * The bounding-box displacement in X and Y directions, it's width, 141 * height and rotation variation over the frames are set as 142 * openshot::Keyframe objects. 143 * 144 * The bounding-box information over the clip's frames are 145 * saved into a protobuf file and loaded into an 146 * object of this class. 147 */ 148 class TrackedObjectBBox : public TrackedObjectBase 149 { 150 private: 151 Fraction BaseFps; 152 double TimeScale; 153 154 public: 155 std::map<double, BBox> BoxVec; ///< Index the bounding-box by time of each frame 156 Keyframe delta_x; ///< X-direction displacement Keyframe 157 Keyframe delta_y; ///< Y-direction displacement Keyframe 158 Keyframe scale_x; ///< X-direction scale Keyframe 159 Keyframe scale_y; ///< Y-direction scale Keyframe 160 Keyframe rotation; ///< Rotation Keyframe 161 Keyframe background_alpha; ///< Background box opacity 162 Keyframe background_corner; ///< Radius of rounded corners 163 Keyframe stroke_width; ///< Thickness of border line 164 Keyframe stroke_alpha; ///< Stroke box opacity 165 Color stroke; ///< Border line color 166 Color background; ///< Background fill color 167 168 std::string protobufDataPath; ///< Path to the protobuf file that holds the bounding box points across the frames 169 170 /// Default Constructor 171 TrackedObjectBBox(); 172 TrackedObjectBBox(int Red, int Green, int Blue, int Alfa); 173 174 /// Add a BBox to the BoxVec map 175 void AddBox(int64_t _frame_num, float _cx, float _cy, float _width, float _height, float _angle) override; 176 177 /// Update object's BaseFps 178 void SetBaseFPS(Fraction fps); 179 180 /// Return the object's BaseFps 181 Fraction GetBaseFPS(); 182 183 /// Update the TimeScale member variable 184 void ScalePoints(double scale) override; 185 186 /// Check if there is a bounding-box in the given frame 187 bool Contains(int64_t frame_number) const; 188 /// Check if there is a bounding-box in the exact frame number 189 bool ExactlyContains(int64_t frame_number) const override; 190 191 /// Get the size of BoxVec map 192 int64_t GetLength() const; 193 194 /// Remove a bounding-box from the BoxVec map 195 void RemoveBox(int64_t frame_number); 196 197 /// Return a bounding-box from BoxVec with it's properties adjusted by the Keyframes 198 BBox GetBox(int64_t frame_number); 199 /// Const-cast of the GetBox function, so that it can be called inside other cont function GetBox(int64_t frame_number)200 BBox GetBox(int64_t frame_number) const 201 { 202 return const_cast<TrackedObjectBBox *>(this)->GetBox(frame_number); 203 } 204 205 /// Load the bounding-boxes information from the protobuf file 206 bool LoadBoxData(std::string inputFilePath); 207 208 /// Get the time of the given frame 209 double FrameNToTime(int64_t frame_number, double time_scale) const; 210 211 /// Interpolate the bouding-boxes properties 212 BBox InterpolateBoxes(double t1, double t2, BBox left, BBox right, double target); 213 214 /// Clear the BoxVec map 215 void clear(); 216 217 /// Get and Set JSON methods 218 std::string Json() const override; ///< Generate JSON string of this object 219 Json::Value JsonValue() const override; ///< Generate Json::Value for this object 220 void SetJson(const std::string value) override; ///< Load JSON string into this object 221 void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 222 223 /// Get all properties for a specific frame (perfect for a UI to display the current state 224 /// of all properties at any time) 225 Json::Value PropertiesJSON(int64_t requested_frame) const override; 226 227 // Generate JSON for a property 228 Json::Value add_property_json(std::string name, float value, std::string type, std::string memo, const Keyframe* keyframe, float min_value, float max_value, bool readonly, int64_t requested_frame) const; 229 230 /// Return a map that contains the bounding box properties and it's keyframes indexed by their names 231 std::map<std::string, float> GetBoxValues(int64_t frame_number) const override; 232 /// Return a map that contains the properties of this object's parent clip 233 std::map<std::string, float> GetParentClipProperties(int64_t frame_number) const override; 234 235 }; 236 } // namespace openshot 237 238 #endif 239