1a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. 2a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 3a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew HarpLicensed under the Apache License, Version 2.0 (the "License"); 4a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harpyou may not use this file except in compliance with the License. 5a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew HarpYou may obtain a copy of the License at 6a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 7a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp http://www.apache.org/licenses/LICENSE-2.0 8a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 9a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew HarpUnless required by applicable law or agreed to in writing, software 10a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harpdistributed under the License is distributed on an "AS IS" BASIS, 11a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew HarpWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew HarpSee the License for the specific language governing permissions and 13a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harplimitations under the License. 14a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp==============================================================================*/ 15a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 16a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp// NOTE: no native object detectors are currently provided or used by the code 17a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp// in this directory. This class remains mainly for historical reasons. 18a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp// Detection in the TF demo is done through TensorFlowMultiBoxDetector.java. 19a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 20a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp// Defines the ObjectDetector class that is the main interface for detecting 21a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp// ObjectModelBases in frames. 22a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 23f8347ceebbad0e06552633fcdf8e63f52246ba62Sanjoy Das#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OBJECT_DETECTOR_H_ 24f8347ceebbad0e06552633fcdf8e63f52246ba62Sanjoy Das#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OBJECT_DETECTOR_H_ 25a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 26a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include <float.h> 27a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include <map> 28a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include <memory> 29a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include <sstream> 30a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include <string> 31a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include <vector> 32a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 33a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include "tensorflow/examples/android/jni/object_tracking/geom.h" 34a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" 35a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include "tensorflow/examples/android/jni/object_tracking/image.h" 36a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include "tensorflow/examples/android/jni/object_tracking/integral_image.h" 37a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#ifdef __RENDER_OPENGL__ 38a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include "tensorflow/examples/android/jni/object_tracking/sprite.h" 39a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#endif 40a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include "tensorflow/examples/android/jni/object_tracking/utils.h" 41a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 42a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include "tensorflow/examples/android/jni/object_tracking/config.h" 43a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include "tensorflow/examples/android/jni/object_tracking/image_data.h" 44a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp#include "tensorflow/examples/android/jni/object_tracking/object_model.h" 45a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 46a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harpnamespace tf_tracking { 47a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 48a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp// Adds BoundingSquares to a vector such that the first square added is centered 49a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp// in the position given and of square_size, and the remaining squares are added 50a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp// concentrentically, scaling down by scale_factor until the minimum threshold 51a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp// size is passed. 52a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp// Squares that do not fall completely within image_bounds will not be added. 53a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harpstatic inline void FillWithSquares( 54a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp const BoundingBox& image_bounds, 55a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp const BoundingBox& position, 56a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp const float starting_square_size, 57a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp const float smallest_square_size, 58a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp const float scale_factor, 59a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp std::vector<BoundingSquare>* const squares) { 60a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp BoundingSquare descriptor_area = 61a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp GetCenteredSquare(position, starting_square_size); 62a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 63a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp SCHECK(scale_factor < 1.0f, "Scale factor too large at %.2f!", scale_factor); 64a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 65a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // Use a do/while loop to ensure that at least one descriptor is created. 66a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp do { 67a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp if (image_bounds.Contains(descriptor_area.ToBoundingBox())) { 68a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp squares->push_back(descriptor_area); 69a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } 70a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp descriptor_area.Scale(scale_factor); 71a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } while (descriptor_area.size_ >= smallest_square_size - EPSILON); 72a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp LOGV("Created %zu squares starting from size %.2f to min size %.2f " 73a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp "using scale factor: %.2f", 74a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp squares->size(), starting_square_size, smallest_square_size, 75a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp scale_factor); 76a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp} 77a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 78a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 79a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp// Represents a potential detection of a specific ObjectExemplar and Descriptor 80a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp// at a specific position in the image. 81a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harpclass Detection { 82a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp public: 83a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp explicit Detection(const ObjectModelBase* const object_model, 84a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp const MatchScore match_score, 85a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp const BoundingBox& bounding_box) 86a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp : object_model_(object_model), 87a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp match_score_(match_score), 88a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp bounding_box_(bounding_box) {} 89a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 90a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp Detection(const Detection& other) 91a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp : object_model_(other.object_model_), 92a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp match_score_(other.match_score_), 93a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp bounding_box_(other.bounding_box_) {} 94a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 95a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp virtual ~Detection() {} 96a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 97a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp inline BoundingBox GetObjectBoundingBox() const { 98a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp return bounding_box_; 99a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } 100a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 101a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp inline MatchScore GetMatchScore() const { 102a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp return match_score_; 103a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } 104a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 105a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp inline const ObjectModelBase* GetObjectModel() const { 106a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp return object_model_; 107a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } 108a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 109a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp inline bool Intersects(const Detection& other) { 110a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // Check if any of the four axes separates us, there must be at least one. 111a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp return bounding_box_.Intersects(other.bounding_box_); 112a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } 113a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 114a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp struct Comp { 115a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp inline bool operator()(const Detection& a, const Detection& b) const { 116a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp return a.match_score_ > b.match_score_; 117a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } 118a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp }; 119a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 120a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // TODO(andrewharp): add accessors to update these instead. 121a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp const ObjectModelBase* object_model_; 122a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp MatchScore match_score_; 123a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp BoundingBox bounding_box_; 124a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp}; 125a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 126a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harpinline std::ostream& operator<<(std::ostream& stream, 127a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp const Detection& detection) { 128a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp const BoundingBox actual_area = detection.GetObjectBoundingBox(); 129a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp stream << actual_area; 130a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp return stream; 131a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp} 132a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 133a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harpclass ObjectDetectorBase { 134a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp public: 135a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp explicit ObjectDetectorBase(const ObjectDetectorConfig* const config) 136a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp : config_(config), 137a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp image_data_(NULL) {} 138a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 139a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp virtual ~ObjectDetectorBase(); 140a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 141a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // Sets the current image data. All calls to ObjectDetector other than 142a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // FillDescriptors use the image data last set. 143a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp inline void SetImageData(const ImageData* const image_data) { 144a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp image_data_ = image_data; 145a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } 146a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 147a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // Main entry point into the detection algorithm. 148a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // Scans the frame for candidates, tweaks them, and fills in the 149a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // given std::vector of Detection objects with acceptable matches. 150a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp virtual void Detect(const std::vector<BoundingSquare>& positions, 151a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp std::vector<Detection>* const detections) const = 0; 152a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 153a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp virtual ObjectModelBase* CreateObjectModel(const std::string& name) = 0; 154a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 155a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp virtual void DeleteObjectModel(const std::string& name) = 0; 156a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 157a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp virtual void GetObjectModels( 158a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp std::vector<const ObjectModelBase*>* models) const = 0; 159a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 160a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // Creates a new ObjectExemplar from the given position in the context of 161a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // the last frame passed to NextFrame. 162a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // Will return null in the case that there's no room for a descriptor to be 163a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // created in the example area, or the example area is not completely 164a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // contained within the frame. 165a99712b6229a39d6c6a6e0bb60b8ff6934216017A. Unique TensorFlower virtual void UpdateModel(const Image<uint8_t>& base_image, 166a99712b6229a39d6c6a6e0bb60b8ff6934216017A. Unique TensorFlower const IntegralImage& integral_image, 167a99712b6229a39d6c6a6e0bb60b8ff6934216017A. Unique TensorFlower const BoundingBox& bounding_box, const bool locked, 168a99712b6229a39d6c6a6e0bb60b8ff6934216017A. Unique TensorFlower ObjectModelBase* model) const = 0; 169a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 170a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp virtual void Draw() const = 0; 171a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 172a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp virtual bool AllowSpontaneousDetections() = 0; 173a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 174a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp protected: 175a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp const std::unique_ptr<const ObjectDetectorConfig> config_; 176a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 177a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // The latest frame data, upon which all detections will be performed. 178a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // Not owned by this object, just provided for reference by ObjectTracker 179a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp // via SetImageData(). 180a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp const ImageData* image_data_; 181a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 182a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp private: 183a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp TF_DISALLOW_COPY_AND_ASSIGN(ObjectDetectorBase); 184a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp}; 185a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 186a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harptemplate <typename ModelType> 187a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harpclass ObjectDetector : public ObjectDetectorBase { 188a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp public: 189a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp explicit ObjectDetector(const ObjectDetectorConfig* const config) 190a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp : ObjectDetectorBase(config) {} 191a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 192a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp virtual ~ObjectDetector() { 193a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp typename std::map<std::string, ModelType*>::const_iterator it = 194a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp object_models_.begin(); 195a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp for (; it != object_models_.end(); ++it) { 196a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp ModelType* model = it->second; 197a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp delete model; 198a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } 199a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } 200a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 201a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp virtual void DeleteObjectModel(const std::string& name) { 202a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp ModelType* model = object_models_[name]; 203a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp CHECK_ALWAYS(model != NULL, "Model was null!"); 204a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp object_models_.erase(name); 205a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp SAFE_DELETE(model); 206a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } 207a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 208a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp virtual void GetObjectModels( 209a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp std::vector<const ObjectModelBase*>* models) const { 210a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp typename std::map<std::string, ModelType*>::const_iterator it = 211a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp object_models_.begin(); 212a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp for (; it != object_models_.end(); ++it) { 213a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp models->push_back(it->second); 214a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } 215a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } 216a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 217a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp virtual bool AllowSpontaneousDetections() { 218a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp return false; 219a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp } 220a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 221a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp protected: 222a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp std::map<std::string, ModelType*> object_models_; 223a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 224a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp private: 225a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp TF_DISALLOW_COPY_AND_ASSIGN(ObjectDetector); 226a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp}; 227a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 228a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp} // namespace tf_tracking 229a30b9926bd7d5276d6ff35af9428dee3e77b7dcbAndrew Harp 230f8347ceebbad0e06552633fcdf8e63f52246ba62Sanjoy Das#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OBJECT_DETECTOR_H_ 231