From 08f227902aed385582edd39d9104b3dc31e73bd7 Mon Sep 17 00:00:00 2001 From: MeZR <1562242162@qq.com> Date: Sat, 5 Jan 2019 10:21:05 +0800 Subject: [PATCH 01/31] 1 --- .../README.md" | 387 + .../UML\345\233\276/Andriond2.0.mdl" | 11461 ++++++++++++++++ .../\345\215\217\344\275\234\345\233\276.png" | Bin 0 -> 14792 bytes .../\345\272\217\345\210\227\345\233\276.png" | Bin 0 -> 18941 bytes .../\346\236\204\344\273\266\345\233\276.png" | Bin 0 -> 22224 bytes .../\346\264\273\345\212\250\345\233\276.png" | Bin 0 -> 39551 bytes .../\347\212\266\346\200\201\345\233\276.png" | Bin 0 -> 13472 bytes .../\347\224\250\344\276\213\345\233\276.png" | Bin 0 -> 13488 bytes .../\351\203\250\347\275\262\345\233\276.png" | Bin 0 -> 5407 bytes .../\344\273\243\347\240\201/android.zip" | Bin 0 -> 404588 bytes .../android/.gitignore" | 29 + .../android/AndroidManifest.xml" | 78 + .../\344\273\243\347\240\201/android/BUILD" | 123 + .../android/README.md" | 213 + .../android/__init__.py" | 0 .../android/assets/BUILD" | 15 + .../android/build.gradle" | 194 + .../android/download-models.gradle" | 70 + .../gradle/wrapper/gradle-wrapper.jar" | Bin 0 -> 53636 bytes .../gradle/wrapper/gradle-wrapper.properties" | 6 + .../\344\273\243\347\240\201/android/gradlew" | 160 + .../android/gradlew.bat" | 90 + .../android/jni/CMakeLists.txt" | 51 + .../android/jni/__init__.py" | 0 .../android/jni/imageutils_jni.cc" | 163 + .../android/jni/object_tracking/config.h" | 300 + .../android/jni/object_tracking/flow_cache.h" | 306 + .../jni/object_tracking/frame_pair.cc" | 308 + .../android/jni/object_tracking/frame_pair.h" | 103 + .../android/jni/object_tracking/geom.h" | 319 + .../android/jni/object_tracking/gl_utils.h" | 55 + .../android/jni/object_tracking/image-inl.h" | 644 + .../android/jni/object_tracking/image.h" | 341 + .../android/jni/object_tracking/image_data.h" | 264 + .../jni/object_tracking/image_neon.cc" | 269 + .../jni/object_tracking/image_utils.h" | 298 + .../jni/object_tracking/integral_image.h" | 187 + .../android/jni/object_tracking/jni_utils.h" | 63 + .../android/jni/object_tracking/keypoint.h" | 48 + .../jni/object_tracking/keypoint_detector.cc" | 548 + .../jni/object_tracking/keypoint_detector.h" | 128 + .../android/jni/object_tracking/logging.cc" | 140 + .../android/jni/object_tracking/logging.h" | 121 + .../jni/object_tracking/object_detector.cc" | 27 + .../jni/object_tracking/object_detector.h" | 230 + .../jni/object_tracking/object_model.h" | 102 + .../jni/object_tracking/object_tracker.cc" | 682 + .../jni/object_tracking/object_tracker.h" | 270 + .../object_tracking/object_tracker_jni.cc" | 459 + .../jni/object_tracking/optical_flow.cc" | 482 + .../jni/object_tracking/optical_flow.h" | 100 + .../android/jni/object_tracking/sprite.h" | 202 + .../android/jni/object_tracking/time_log.cc" | 25 + .../android/jni/object_tracking/time_log.h" | 137 + .../jni/object_tracking/tracked_object.cc" | 162 + .../jni/object_tracking/tracked_object.h" | 186 + .../android/jni/object_tracking/utils.h" | 381 + .../jni/object_tracking/utils_neon.cc" | 151 + .../android/jni/rgb2yuv.cc" | 99 + .../android/jni/rgb2yuv.h" | 35 + .../android/jni/yuv2rgb.cc" | 191 + .../android/jni/yuv2rgb.h" | 57 + .../android/res/animator/color_animation.xml" | 30 + .../res/drawable-hdpi/ic_action_info.png" | Bin 0 -> 1025 bytes .../res/drawable-hdpi/ic_launcher.png" | Bin 0 -> 4312 bytes .../android/res/drawable-hdpi/tile.9.png" | Bin 0 -> 196 bytes .../res/drawable-mdpi/ic_action_info.png" | Bin 0 -> 665 bytes .../res/drawable-mdpi/ic_launcher.png" | Bin 0 -> 2265 bytes .../res/drawable-xhdpi/ic_action_info.png" | Bin 0 -> 1355 bytes .../res/drawable-xhdpi/ic_launcher.png" | Bin 0 -> 6683 bytes .../res/drawable-xxhdpi/ic_action_info.png" | Bin 0 -> 2265 bytes .../res/drawable-xxhdpi/ic_launcher.png" | Bin 0 -> 12746 bytes .../android/res/drawable/border.xml" | 19 + .../android/res/layout/activity_camera.xml" | 22 + .../android/res/layout/activity_speech.xml" | 55 + .../layout/camera_connection_fragment.xml" | 38 + .../camera_connection_fragment_stylize.xml" | 51 + .../camera_connection_fragment_tracking.xml" | 34 + .../android/res/layout/list_text_item.xml" | 25 + .../res/values-sw600dp/template-dimens.xml" | 24 + .../res/values-sw600dp/template-styles.xml" | 25 + .../android/res/values-v11/styles.xml" | 24 + .../res/values-v11/template-styles.xml" | 22 + .../android/res/values-v14/styles.xml" | 12 + .../android/res/values-v21/base-colors.xml" | 21 + .../res/values-v21/base-template-styles.xml" | 24 + .../android/res/values/attrs.xml" | 14 + .../android/res/values/base-strings.xml" | 24 + .../android/res/values/colors.xml" | 19 + .../android/res/values/strings.xml" | 20 + .../android/res/values/styles.xml" | 18 + .../android/res/values/template-dimens.xml" | 32 + .../android/res/values/template-styles.xml" | 42 + .../android/sample_images/classify1.jpg" | Bin 0 -> 24476 bytes .../android/sample_images/detect1.jpg" | Bin 0 -> 45750 bytes .../android/sample_images/stylize1.jpg" | Bin 0 -> 52389 bytes .../tensorflow/demo/AutoFitTextureView.java" | 74 + .../org/tensorflow/demo/CameraActivity.java" | 457 + .../demo/CameraConnectionFragment.java" | 640 + .../src/org/tensorflow/demo/Classifier.java" | 107 + .../tensorflow/demo/ClassifierActivity.java" | 217 + .../tensorflow/demo/DetectorActivity.java" | 349 + .../demo/LegacyCameraConnectionFragment.java" | 216 + .../src/org/tensorflow/demo/OverlayView.java" | 52 + .../demo/RecognitionScoreView.java" | 69 + .../tensorflow/demo/RecognizeCommands.java" | 186 + .../src/org/tensorflow/demo/ResultsView.java" | 24 + .../org/tensorflow/demo/SpeechActivity.java" | 354 + .../org/tensorflow/demo/StylizeActivity.java" | 665 + .../demo/TensorFlowImageClassifier.java" | 199 + .../demo/TensorFlowMultiBoxDetector.java" | 285 + .../TensorFlowObjectDetectionAPIModel.java" | 219 + .../demo/TensorFlowYoloDetector.java" | 261 + .../tensorflow/demo/env/BorderedText.java" | 117 + .../org/tensorflow/demo/env/ImageUtils.java" | 344 + .../src/org/tensorflow/demo/env/Logger.java" | 191 + .../src/org/tensorflow/demo/env/Size.java" | 143 + .../org/tensorflow/demo/env/SplitTimer.java" | 50 + .../demo/tracking/MultiBoxTracker.java" | 421 + .../demo/tracking/ObjectTracker.java" | 661 + .../1.txt" | 0 121 files changed, 28356 insertions(+) create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/README.md" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/Andriond2.0.mdl" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\345\215\217\344\275\234\345\233\276.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\345\272\217\345\210\227\345\233\276.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\346\236\204\344\273\266\345\233\276.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\346\264\273\345\212\250\345\233\276.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\347\212\266\346\200\201\345\233\276.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\347\224\250\344\276\213\345\233\276.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\351\203\250\347\275\262\345\233\276.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android.zip" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/.gitignore" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/AndroidManifest.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/BUILD" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/README.md" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/__init__.py" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/assets/BUILD" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/build.gradle" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/download-models.gradle" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradle/wrapper/gradle-wrapper.jar" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradle/wrapper/gradle-wrapper.properties" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradlew" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradlew.bat" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/CMakeLists.txt" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/__init__.py" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/imageutils_jni.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/config.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/flow_cache.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/frame_pair.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/frame_pair.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/geom.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/gl_utils.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image-inl.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image_data.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image_neon.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image_utils.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/integral_image.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/jni_utils.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/keypoint.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/keypoint_detector.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/keypoint_detector.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/logging.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/logging.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_detector.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_detector.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_model.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_tracker.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_tracker.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_tracker_jni.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/optical_flow.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/optical_flow.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/sprite.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/time_log.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/time_log.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/tracked_object.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/tracked_object.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/utils.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/utils_neon.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/rgb2yuv.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/rgb2yuv.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/yuv2rgb.cc" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/yuv2rgb.h" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/animator/color_animation.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-hdpi/ic_action_info.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-hdpi/ic_launcher.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-hdpi/tile.9.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-mdpi/ic_action_info.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-mdpi/ic_launcher.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-xhdpi/ic_action_info.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-xhdpi/ic_launcher.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-xxhdpi/ic_action_info.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-xxhdpi/ic_launcher.png" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable/border.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/layout/activity_camera.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/layout/activity_speech.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/layout/camera_connection_fragment.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/layout/camera_connection_fragment_stylize.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/layout/camera_connection_fragment_tracking.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/layout/list_text_item.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values-sw600dp/template-dimens.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values-sw600dp/template-styles.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values-v11/styles.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values-v11/template-styles.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values-v14/styles.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values-v21/base-colors.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values-v21/base-template-styles.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values/attrs.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values/base-strings.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values/colors.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values/strings.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values/styles.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values/template-dimens.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/values/template-styles.xml" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/sample_images/classify1.jpg" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/sample_images/detect1.jpg" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/sample_images/stylize1.jpg" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/AutoFitTextureView.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/CameraActivity.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/CameraConnectionFragment.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/Classifier.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/ClassifierActivity.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/DetectorActivity.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/LegacyCameraConnectionFragment.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/OverlayView.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/RecognitionScoreView.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/RecognizeCommands.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/ResultsView.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/SpeechActivity.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/StylizeActivity.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/TensorFlowImageClassifier.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/TensorFlowMultiBoxDetector.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/TensorFlowObjectDetectionAPIModel.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/TensorFlowYoloDetector.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/env/BorderedText.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/env/ImageUtils.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/env/Logger.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/env/Size.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/env/SplitTimer.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/tracking/MultiBoxTracker.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/src/org/tensorflow/demo/tracking/ObjectTracker.java" create mode 100644 "Feat_16\347\247\221\344\272\2147\347\273\204/\345\256\236\351\252\214\346\212\245\345\221\212/1.txt" diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/README.md" "b/Feat_16\347\247\221\344\272\2147\347\273\204/README.md" new file mode 100644 index 0000000..0e73f1d --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/README.md" @@ -0,0 +1,387 @@ +<<<<<<< HEAD +# TensorFlow Android Camera Demo + +Tensorflow object detection API 物体检测手机APP +# 组成员 + 孟昭瑞 201601450201 + 伊桐杰 201601450205 + 韩韶波 201601450206 + 郭文康 201601450217 + 孙洪福 201601450222 + 吴延赛 201601450225 + 闫磊 201601450226 +# 组成员贡献 + 孟昭瑞: + 下载编译成功源程序 + UML协作图 + 伊桐杰: + 下载编译成功源程序 + UML部署图 + 韩韶波: + 下载编译成功源程序 + UML构件图 + 郭文康: + 下载编译成功源程序 + UML序列图 + 孙洪福: + 下载编译成功源程序 + UML用例图 + 吴延赛: + 下载编译成功源程序 + UML活动图 + 闫磊: + 下载编译成功源程序 + UML状态图 + + +# 组员共同任务 + 1. 在github下载源码,地址:https://github.com/tensorflow/tensorflow.git + 2. 将android项目解压出来并导入android studio 或 idea + 3. 安装并配置java 1.8 环境 + 4. 下载并配置android sdk + 5. 编译并修改错误 + 6. 编译成功后将debug文件夹下的apk安装到手机上 + 7. 在手机上测试程序 + + + + + + + + +此文件夹包含一个示例应用程序,该应用程序在Android设备上使用TensorFlow。 + +## 说明 + +此文件夹中的演示旨在提供在移动应用程序中使用TensorFlow的简单示例。 + + +推理是使用TensorFlowandroid推理接口完成的,如果您希望将一个独立的库放入现有的应用程序中,可以单独构建该接口。对象跟踪和有效的yuv->rgb转换由libtensorflow.so处理。 + + +由于使用了camera2 api,运行android 5.0(api 21)或更高版本的设备需要运行演示,尽管本机库本身可以在api>=14设备上运行。 + + +## 当前样本: + +1. [TF Classify](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/android/src/org/tensorflow/demo/ClassifierActivity.java): + tf classify:使用google inception模型实时对摄像机帧进行分类,在摄像机图像上显示叠加的顶部结果。 +2. [TF Detect](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/android/src/org/tensorflow/demo/DetectorActivity.java): + tf detect:演示一个SSD mobilenet模型,该模型使用 + [Tensorflow Object Detection API](https://github.com/tensorflow/models/tree/master/research/object_detection/) + TensorFlow对象检测API进行培训, 该API引入了[Speed/accuracy trade-offs for modern convolutional object detectors](https://arxiv.org/abs/1611.10012) 现代卷积对象检测器的速度/精度权衡,以实时定位和跟踪相机预览中的对象(80个类别)。 +3. [TF Stylize](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/android/src/org/tensorflow/demo/StylizeActivity.java): + tf-styleze:使用基于艺术风格的学习表示的模型,将相机预览图像重新设置为多个不同艺术家的图像。 +4. [TF Speech](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/android/src/org/tensorflow/demo/SpeechActivity.java): + 运行由 [audio trainingtutorial](https://www.tensorflow.org/versions/master/tutorials/audio_recognition)音频训练教程构建的简单语音识别模型。侦听一小组单词,并在识别时在UI中突出显示它们。 + + +## 预建组件: + +如果您只想要尝试演示的最快路径,可以在 +[here](https://ci.tensorflow.org/view/Nightly/job/nightly-android/). 此处下载每晚构建 。展开“View”,然后展开“Last Successful Artifacts”下的“out”文件夹,找到tensorflow_demo.apk。 + +另外还有预编译的本机库和一个jcenter包,您可以将其放入自己的应用程序中。有关 详细信息,请参阅 +[tensorflow/contrib/android/README.md](../../../tensorflow/contrib/android/README.md) + +## 运行演示 + +安装应用程序后,可以通过“TF Classify”,“TF Detect”,“TF Stylize”和“TF Speech”图标启动它们,这些图标的橙色TensorFlow标志作为其图标。 + +在运行活动时,按设备上的音量键将打开/关闭调试可视化,向屏幕呈现可能对开发有用的其他信息。 + +## 使用JCenter中的TensorFlow AAR在Android Studio中构建 + +自己编译演示应用程序并尝试更改项目代码的最简单方法是使用AndroidStudio。只需将此android目录设置为项目根目录即可。 + +然后编辑build.gradle文件并更改nativeBuildSystemto 的值,'none'以便以最简单的方式构建项目: + +def nativeBuildSystem ='none' +虽然此项目包括TensorFlow的完整构建集成,但此设置禁用它,并使用JCenter的TensorFlow推理接口包。 + +注意:目前,在此构建模式下,YUV - > RGB使用效率较低的Java实现完成,并且“TF Detect”活动中没有对象跟踪。将构建系统设置为'cmake'当前仅构建 libtensorflow_demo.so,提供快速YUV - > RGB转换和对象跟踪,同时仍通过下载的AAR获取TensorFlow支持,因此它可能是启用这些功能的轻量级方法。 + +对于任何不包含自定义低级TensorFlow代码的项目,这可能就足够了。 + +有关如何在您自己的项目中包含此JCenter包的详细信息,请参阅 +[tensorflow/contrib/android/README.md](../../../tensorflow/contrib/android/README.md) + +## 使用来自Source的TensorFlow构建演示 + +选择下面的首选方法。目前,我们完全支持Bazel,并且对gradle,cmake,make和Android Studio提供部分支持。 + +作为所有构建类型的第一步,克隆TensorFlow仓库: + +git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git +请注意,这--recurse-submodules是防止protobuf编译的一些问题所必需的。 +### Bazel + +注意:Bazel目前不支持在Windows上构建Android。对gradle / cmake构建的全面支持即将推出,但与此同时我们建议Windows用户下载预构建的二进制文件。 +[prebuilt binaries](https://ci.tensorflow.org/view/Nightly/job/nightly-android/) instead. + +##### 安装Bazel和Android先决条件 + +Bazel是TensorFlow的主要构建系统。要使用Bazel构建,必须在您的系统上安装它和Android NDK和SDK。 + + + +1. 按照Bazel网站上的说明安装最新版本的Bazel [on the Bazel website](https://bazel.build/versions/master/docs/install.html). +2. Android NDK是构建本机(C / C ++)TensorFlow代码所必需的。目前推荐的版本是14b,可在此处找到 。 + [here](https://developer.android.com/ndk/downloads/older_releases.html#ndk-14b-downloads). + + NDK 16,即2017年11月发布的修订版,与Bazel 不兼容。看到这里。[here](https://github.com/tensorflow/tensorflow/issues/14918). + +3. Android SDK和构建工具可以在此处获得, + [here](https://developer.android.com/tools/revisions/build-tools.html),也可以作为Android Studio的一部分获取 。 + [Android Studio](https://developer.android.com/studio/index.html). 构建工具API> = 23是构建TF Android演示所必需的(尽管它将在API> = 21设备上运行)。 + + Android Studio SDK Manager的NDK安装程序将安装最新版本的NDK,这与Bazel 不兼容。您需要手动下载旧版本,如(2)所示。 +##### 编辑WORKSPACE + +注意:只要安装了SDK和NDK,./configure脚本就会为您创建这些规则。当脚本要求自动配置时,回答“是” ./WORKSPACE。 + +/WORKSPACE必须取消注释Android条目, 并根据NDK和SDK的安装位置适当填充路径。否则会报告错误,例如:“外部标签'//外部:android / sdk'没有绑定任何东西”将被报告。 + +同时将WORKSPACE中SDK的API级别编辑为SDK中安装的最高级别。这必须> = 23(这完全独立于演示的API级别,该级别在AndroidManifest.xml中定义)。NDK API级别可能保持在14。 + +##### 安装模型文件(可选) + +GraphDef包含模型定义和权重的TensorFlow 由于其大小而未打包在repo中。它们会自动下载并通过Bazel通过WORKSPACE在构建过程中定义的new_http_archive 以及Gradle via download-models.gradle 与APK一起打包。 + +可选:如果您希望手动将模型放在资源中,请model_files从文件assets中tensorflow_demo 找到的列表中删除所有条目BUILD。然后自己下载并解压缩到assets源树中的目录: + +```bash +BASE_URL=https://storage.googleapis.com/download.tensorflow.org/models +for MODEL_ZIP in inception5h.zip ssd_mobilenet_v1_android_export.zip stylize_v1.zip +do + curl -L ${BASE_URL}/${MODEL_ZIP} -o /tmp/${MODEL_ZIP} + unzip /tmp/${MODEL_ZIP} -d tensorflow/examples/android/assets/ +done +``` + +这会将模型及其关联的元数据文件提取到本地assets /目录。 + +如果您使用的是Gradle,请确保在手动下载模型后从build.gradle中删除download-models.gradle引用; 否则gradle可能会再次下载模型并覆盖您的模型。 + +##### 建立 + +确保在Android 5.0(API 21)或更高版本的设备上启用了adb调试,然后在构建中使用工作区根目录中的以下命令来安装APK: + +```bash +bazel build -c opt //tensorflow/examples/android:tensorflow_demo +``` + +##### 安装 + +确保在Android 5.0(API 21)或更高版本的设备上启用了adb调试,然后在构建中使用工作区根目录中的以下命令来安装APK: + +```bash +adb install -r bazel-bin/tensorflow/examples/android/tensorflow_demo.apk +``` + +### 带有Bazel的Android Studio + +Android Studio可用于与Bazel一起构建演示。首先,确保您可以按照上述说明使用Bazel进行构建。然后,查看build.gradle并确保Bazel的路径与系统的路径匹配。 + +此时,您可以将tensorflow / examples / android目录添加为新的Android Studio项目。点击安装它请求的所有Gradle扩展,您应该能够让Android Studio像任何其他应用程序一样构建演示(它将调用Bazel以使用NDK构建本机代码)。 + +### CMake + +该演示的完整CMake支持即将推出,但目前可以使用 +======= +# TensorFlow Android Camera Demo + +Tensorflow object detection API 物体检测手机APP +# 组成员 + 孟昭瑞 201601450201 + 伊桐杰 201601450205 + 韩韶波 201601450206 + 郭文康 201601450217 + 孙洪福 201601450222 + 吴延赛 201601450225 + 闫磊 201601450226 +# 组成员贡献 + 孟昭瑞: + 下载编译成功源程序 + UML协作图 + 伊桐杰: + 下载编译成功源程序 + UML部署图 + 韩韶波: + 下载编译成功源程序 + UML构件图 + 韩韶波: + 下载编译成功源程序 + UML构件图 + 郭文康: + 下载编译成功源程序 + UML序列图 + 孙洪福: + 下载编译成功源程序 + UML用例图 + 吴延赛: + 下载编译成功源程序 + UML活动图 + 闫磊: + 下载编译成功源程序 + UML状态图 + + +# 组员共同任务 + 1. 在github下载源码,地址:https://github.com/tensorflow/tensorflow.git + 2. 将android项目解压出来并导入android studio 或 idea + 3. 安装并配置java 1.8 环境 + 4. 下载并配置android sdk + 5. 编译并修改错误 + 6. 编译成功后将debug文件夹下的apk安装到手机上 + 7. 在手机上测试程序 + + + + + + + + +此文件夹包含一个示例应用程序,该应用程序在Android设备上使用TensorFlow。 + +## 说明 + +此文件夹中的演示旨在提供在移动应用程序中使用TensorFlow的简单示例。 + + +推理是使用TensorFlowandroid推理接口完成的,如果您希望将一个独立的库放入现有的应用程序中,可以单独构建该接口。对象跟踪和有效的yuv->rgb转换由libtensorflow.so处理。 + + +由于使用了camera2 api,运行android 5.0(api 21)或更高版本的设备需要运行演示,尽管本机库本身可以在api>=14设备上运行。 + + +## 当前样本: + +1. [TF Classify](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/android/src/org/tensorflow/demo/ClassifierActivity.java): + tf classify:使用google inception模型实时对摄像机帧进行分类,在摄像机图像上显示叠加的顶部结果。 +2. [TF Detect](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/android/src/org/tensorflow/demo/DetectorActivity.java): + tf detect:演示一个SSD mobilenet模型,该模型使用 + [Tensorflow Object Detection API](https://github.com/tensorflow/models/tree/master/research/object_detection/) + TensorFlow对象检测API进行培训, 该API引入了[Speed/accuracy trade-offs for modern convolutional object detectors](https://arxiv.org/abs/1611.10012) 现代卷积对象检测器的速度/精度权衡,以实时定位和跟踪相机预览中的对象(80个类别)。 +3. [TF Stylize](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/android/src/org/tensorflow/demo/StylizeActivity.java): + tf-styleze:使用基于艺术风格的学习表示的模型,将相机预览图像重新设置为多个不同艺术家的图像。 +4. [TF Speech](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/android/src/org/tensorflow/demo/SpeechActivity.java): + 运行由 [audio trainingtutorial](https://www.tensorflow.org/versions/master/tutorials/audio_recognition)音频训练教程构建的简单语音识别模型。侦听一小组单词,并在识别时在UI中突出显示它们。 + + +## 预建组件: + +如果您只想要尝试演示的最快路径,可以在 +[here](https://ci.tensorflow.org/view/Nightly/job/nightly-android/). 此处下载每晚构建 。展开“View”,然后展开“Last Successful Artifacts”下的“out”文件夹,找到tensorflow_demo.apk。 + +另外还有预编译的本机库和一个jcenter包,您可以将其放入自己的应用程序中。有关 详细信息,请参阅 +[tensorflow/contrib/android/README.md](../../../tensorflow/contrib/android/README.md) + +## 运行演示 + +安装应用程序后,可以通过“TF Classify”,“TF Detect”,“TF Stylize”和“TF Speech”图标启动它们,这些图标的橙色TensorFlow标志作为其图标。 + +在运行活动时,按设备上的音量键将打开/关闭调试可视化,向屏幕呈现可能对开发有用的其他信息。 + +## 使用JCenter中的TensorFlow AAR在Android Studio中构建 + +自己编译演示应用程序并尝试更改项目代码的最简单方法是使用AndroidStudio。只需将此android目录设置为项目根目录即可。 + +然后编辑build.gradle文件并更改nativeBuildSystemto 的值,'none'以便以最简单的方式构建项目: + +def nativeBuildSystem ='none' +虽然此项目包括TensorFlow的完整构建集成,但此设置禁用它,并使用JCenter的TensorFlow推理接口包。 + +注意:目前,在此构建模式下,YUV - > RGB使用效率较低的Java实现完成,并且“TF Detect”活动中没有对象跟踪。将构建系统设置为'cmake'当前仅构建 libtensorflow_demo.so,提供快速YUV - > RGB转换和对象跟踪,同时仍通过下载的AAR获取TensorFlow支持,因此它可能是启用这些功能的轻量级方法。 + +对于任何不包含自定义低级TensorFlow代码的项目,这可能就足够了。 + +有关如何在您自己的项目中包含此JCenter包的详细信息,请参阅 +[tensorflow/contrib/android/README.md](../../../tensorflow/contrib/android/README.md) + +## 使用来自Source的TensorFlow构建演示 + +选择下面的首选方法。目前,我们完全支持Bazel,并且对gradle,cmake,make和Android Studio提供部分支持。 + +作为所有构建类型的第一步,克隆TensorFlow仓库: + +git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git +请注意,这--recurse-submodules是防止protobuf编译的一些问题所必需的。 +### Bazel + +注意:Bazel目前不支持在Windows上构建Android。对gradle / cmake构建的全面支持即将推出,但与此同时我们建议Windows用户下载预构建的二进制文件。 +[prebuilt binaries](https://ci.tensorflow.org/view/Nightly/job/nightly-android/) instead. + +##### 安装Bazel和Android先决条件 + +Bazel是TensorFlow的主要构建系统。要使用Bazel构建,必须在您的系统上安装它和Android NDK和SDK。 + + + +1. 按照Bazel网站上的说明安装最新版本的Bazel [on the Bazel website](https://bazel.build/versions/master/docs/install.html). +2. Android NDK是构建本机(C / C ++)TensorFlow代码所必需的。目前推荐的版本是14b,可在此处找到 。 + [here](https://developer.android.com/ndk/downloads/older_releases.html#ndk-14b-downloads). + + NDK 16,即2017年11月发布的修订版,与Bazel 不兼容。看到这里。[here](https://github.com/tensorflow/tensorflow/issues/14918). + +3. Android SDK和构建工具可以在此处获得, + [here](https://developer.android.com/tools/revisions/build-tools.html),也可以作为Android Studio的一部分获取 。 + [Android Studio](https://developer.android.com/studio/index.html). 构建工具API> = 23是构建TF Android演示所必需的(尽管它将在API> = 21设备上运行)。 + + Android Studio SDK Manager的NDK安装程序将安装最新版本的NDK,这与Bazel 不兼容。您需要手动下载旧版本,如(2)所示。 +##### 编辑WORKSPACE + +注意:只要安装了SDK和NDK,./configure脚本就会为您创建这些规则。当脚本要求自动配置时,回答“是” ./WORKSPACE。 + +/WORKSPACE必须取消注释Android条目, 并根据NDK和SDK的安装位置适当填充路径。否则会报告错误,例如:“外部标签'//外部:android / sdk'没有绑定任何东西”将被报告。 + +同时将WORKSPACE中SDK的API级别编辑为SDK中安装的最高级别。这必须> = 23(这完全独立于演示的API级别,该级别在AndroidManifest.xml中定义)。NDK API级别可能保持在14。 + +##### 安装模型文件(可选) + +GraphDef包含模型定义和权重的TensorFlow 由于其大小而未打包在repo中。它们会自动下载并通过Bazel通过WORKSPACE在构建过程中定义的new_http_archive 以及Gradle via download-models.gradle 与APK一起打包。 + +可选:如果您希望手动将模型放在资源中,请model_files从文件assets中tensorflow_demo 找到的列表中删除所有条目BUILD。然后自己下载并解压缩到assets源树中的目录: + +```bash +BASE_URL=https://storage.googleapis.com/download.tensorflow.org/models +for MODEL_ZIP in inception5h.zip ssd_mobilenet_v1_android_export.zip stylize_v1.zip +do + curl -L ${BASE_URL}/${MODEL_ZIP} -o /tmp/${MODEL_ZIP} + unzip /tmp/${MODEL_ZIP} -d tensorflow/examples/android/assets/ +done +``` + +这会将模型及其关联的元数据文件提取到本地assets /目录。 + +如果您使用的是Gradle,请确保在手动下载模型后从build.gradle中删除download-models.gradle引用; 否则gradle可能会再次下载模型并覆盖您的模型。 + +##### 建立 + +确保在Android 5.0(API 21)或更高版本的设备上启用了adb调试,然后在构建中使用工作区根目录中的以下命令来安装APK: + +```bash +bazel build -c opt //tensorflow/examples/android:tensorflow_demo +``` + +##### 安装 + +确保在Android 5.0(API 21)或更高版本的设备上启用了adb调试,然后在构建中使用工作区根目录中的以下命令来安装APK: + +```bash +adb install -r bazel-bin/tensorflow/examples/android/tensorflow_demo.apk +``` + +### 带有Bazel的Android Studio + +Android Studio可用于与Bazel一起构建演示。首先,确保您可以按照上述说明使用Bazel进行构建。然后,查看build.gradle并确保Bazel的路径与系统的路径匹配。 + +此时,您可以将tensorflow / examples / android目录添加为新的Android Studio项目。点击安装它请求的所有Gradle扩展,您应该能够让Android Studio像任何其他应用程序一样构建演示(它将调用Bazel以使用NDK构建本机代码)。 + +### CMake + +该演示的完整CMake支持即将推出,但目前可以使用 +>>>>>>> 2bdfc4c1855a2d9bbbba6bdca531bc8755b6697d +[tensorflow/contrib/android/cmake](../../../tensorflow/contrib/android/cmake).. \ No newline at end of file diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/Andriond2.0.mdl" "b/Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/Andriond2.0.mdl" new file mode 100644 index 0000000..0248633 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/Andriond2.0.mdl" @@ -0,0 +1,11461 @@ + +(object Petal + version 50 + _written "Rose 2006.0.0.060314" + charSet 134) + +(object Design "Logical View" + is_unit TRUE + is_loaded TRUE + attributes (list Attribute_Set + (object Attribute + tool "Java" + name "IDE" + value "Internal Editor") + (object Attribute + tool "Java" + name "UserDefineTagName1" + value "") + (object Attribute + tool "Java" + name "UserDefineTagText1" + value "") + (object Attribute + tool "Java" + name "UserDefineTagApply1" + value "") + (object Attribute + tool "Java" + name "UserDefineTagName2" + value "") + (object Attribute + tool "Java" + name "UserDefineTagText2" + value "") + (object Attribute + tool "Java" + name "UserDefineTagApply2" + value "") + (object Attribute + tool "Java" + name "UserDefineTagName3" + value "") + (object Attribute + tool "Java" + name "UserDefineTagText3" + value "") + (object Attribute + tool "Java" + name "UserDefineTagApply3" + value "") + (object Attribute + tool "Java" + name "AllExceptions" + value "")) + quid "39C9260C00D4" + enforceClosureAutoLoad FALSE + defaults (object defaults + rightMargin 0.250000 + leftMargin 0.250000 + topMargin 0.250000 + bottomMargin 0.500000 + pageOverlap 0.250000 + clipIconLabels TRUE + autoResize TRUE + snapToGrid TRUE + gridX 16 + gridY 16 + defaultFont (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + showMessageNum 1 + showClassOfObject TRUE + notation "Unified") + root_usecase_package (object Class_Category "Use Case View" + quid "39C9260C00D6" + exportControl "Public" + global TRUE + logical_models (list unit_reference_list + (object Class "û" + quid "5C2A2DE40377" + stereotype "Actor") + (object UseCase "ʵʱ" + quid "5C2A2DEE01C6") + (object UseCase "ƻʶ" + quid "5C2A2E0C0233") + (object UseCase "ʶ" + quid "5C2A2E1500E6") + (object UseCase "αʶ" + quid "5C2A2E1C00AF") + (object UseCase "ʵʱ˼" + quid "5C2A2E390266") + (object UseCase "ʵʱͼǨ" + quid "5C2A2E4C028F") + (object UseCase "񻯷" + quid "5C2A2E5D03D7") + (object UseCase "ɫ" + quid "5C2A2E8901D6") + (object UseCase "ŵ" + quid "5C2A2E9E01BF") + (object UseCase "" + quid "5C2AF8370057") + (object UseCase "" + quid "5C2AF85700AB") + (object UseCase "ʵʱʶ" + quid "5C2DE0920237") + (object UseCase "ת" + quid "5C2DE0AB0207") + (object Association "$UNNAMED$0" + quid "5C2A2EAC0175" + roles (list role_list + (object Role "$UNNAMED$1" + quid "5C2A2EAC03D0" + supplier "Use Case View::ʵʱ" + quidu "5C2A2DEE01C6" + is_navigable TRUE) + (object Role "$UNNAMED$2" + quid "5C2A2EAC03D3" + supplier "Use Case View::û" + quidu "5C2A2DE40377"))) + (object Association "$UNNAMED$3" + quid "5C2A2EAF02EA" + stereotype "include" + roles (list role_list + (object Role "$UNNAMED$4" + quid "5C2A2EB00318" + supplier "Use Case View::αʶ" + quidu "5C2A2E1C00AF" + is_navigable TRUE) + (object Role "$UNNAMED$5" + quid "5C2A2EB0031D" + supplier "Use Case View::ʵʱ" + quidu "5C2A2DEE01C6"))) + (object Association "$UNNAMED$6" + quid "5C2A2EB20283" + stereotype "include" + roles (list role_list + (object Role "$UNNAMED$7" + quid "5C2A2EB300D8" + supplier "Use Case View::ƻʶ" + quidu "5C2A2E0C0233" + is_navigable TRUE) + (object Role "$UNNAMED$8" + quid "5C2A2EB300DB" + supplier "Use Case View::ʵʱ" + quidu "5C2A2DEE01C6"))) + (object Association "$UNNAMED$9" + quid "5C2A2EB5007A" + stereotype "include" + roles (list role_list + (object Role "$UNNAMED$10" + quid "5C2A2EB50267" + supplier "Use Case View::ʶ" + quidu "5C2A2E1500E6" + is_navigable TRUE) + (object Role "$UNNAMED$11" + quid "5C2A2EB5026B" + supplier "Use Case View::ʵʱ" + quidu "5C2A2DEE01C6"))) + (object Association "$UNNAMED$12" + quid "5C2A2EB70295" + roles (list role_list + (object Role "$UNNAMED$13" + quid "5C2A2EB800B9" + supplier "Use Case View::ʵʱ˼" + quidu "5C2A2E390266" + is_navigable TRUE) + (object Role "$UNNAMED$14" + quid "5C2A2EB800BD" + supplier "Use Case View::û" + quidu "5C2A2DE40377"))) + (object Association "$UNNAMED$15" + quid "5C2A2EBA0260" + roles (list role_list + (object Role "$UNNAMED$16" + quid "5C2A2EBB00F1" + supplier "Use Case View::ʵʱͼǨ" + quidu "5C2A2E4C028F" + is_navigable TRUE) + (object Role "$UNNAMED$17" + quid "5C2A2EBB00F4" + supplier "Use Case View::û" + quidu "5C2A2DE40377"))) + (object Association "$UNNAMED$18" + quid "5C2A2EBD017E" + stereotype "include" + roles (list role_list + (object Role "$UNNAMED$19" + quid "5C2A2EBE0028" + supplier "Use Case View::񻯷" + quidu "5C2A2E5D03D7" + is_navigable TRUE) + (object Role "$UNNAMED$20" + quid "5C2A2EBE002C" + supplier "Use Case View::ʵʱͼǨ" + quidu "5C2A2E4C028F"))) + (object Association "$UNNAMED$21" + quid "5C2A2EC00011" + stereotype "include" + roles (list role_list + (object Role "$UNNAMED$22" + quid "5C2A2EC002D0" + supplier "Use Case View::ɫ" + quidu "5C2A2E8901D6" + is_navigable TRUE) + (object Role "$UNNAMED$23" + quid "5C2A2EC002D3" + supplier "Use Case View::ʵʱͼǨ" + quidu "5C2A2E4C028F"))) + (object Association "$UNNAMED$24" + quid "5C2A2EC202DB" + stereotype "include" + roles (list role_list + (object Role "$UNNAMED$25" + quid "5C2A2EC301A0" + supplier "Use Case View::ŵ" + quidu "5C2A2E9E01BF" + is_navigable TRUE) + (object Role "$UNNAMED$26" + quid "5C2A2EC301A3" + supplier "Use Case View::ʵʱͼǨ" + quidu "5C2A2E4C028F"))) + (object Association "$UNNAMED$27" + quid "5C2AF849019D" + roles (list role_list + (object Role "$UNNAMED$28" + quid "5C2AF84C01FF" + supplier "Use Case View::" + quidu "5C2AF8370057" + is_navigable TRUE) + (object Role "$UNNAMED$29" + quid "5C2AF84C0202" + supplier "Use Case View::û" + quidu "5C2A2DE40377"))) + (object Association "$UNNAMED$30" + quid "5C2AF864004D" + stereotype "include" + roles (list role_list + (object Role "$UNNAMED$31" + quid "5C2AF8640355" + supplier "Use Case View::" + quidu "5C2AF85700AB" + is_navigable TRUE) + (object Role "$UNNAMED$32" + quid "5C2AF8640359" + supplier "Use Case View::" + quidu "5C2AF8370057"))) + (object Association "$UNNAMED$33" + quid "5C2DE0A402A7" + roles (list role_list + (object Role "$UNNAMED$34" + quid "5C2DE0A60237" + supplier "Use Case View::ʵʱʶ" + quidu "5C2DE0920237" + is_navigable TRUE) + (object Role "$UNNAMED$35" + quid "5C2DE0A60239" + supplier "Use Case View::û" + quidu "5C2A2DE40377"))) + (object Association "$UNNAMED$36" + quid "5C2DE0BC0149" + stereotype "include" + roles (list role_list + (object Role "$UNNAMED$37" + quid "5C2DE0BC03CC" + supplier "Use Case View::ת" + quidu "5C2DE0AB0207" + is_navigable TRUE) + (object Role "$UNNAMED$38" + quid "5C2DE0BC03CE" + supplier "Use Case View::ʵʱʶ" + quidu "5C2DE0920237"))) + (object Mechanism @1 + logical_models (list unit_reference_list + (object Object "$UNNAMED$39" + quid "5C2B06C901A4" + collaborators (list link_list + (object Link + quid "5C2B0724004F" + supplier "TF Classify" + quidu "5C2B06CE00D3" + messages (list Messages + (object Message "ʶ" + quid "5C2B07240050" + frequency "Aperiodic" + synchronization "Simple" + dir "FromClientToSupplier" + sequence "1" + ordinal 0 + quidu "000000000000" + creation FALSE) + (object Message "ʶ" + quid "5C2B07380168" + frequency "Aperiodic" + synchronization "Return" + dir "ToClientFromSupplier" + sequence "1.2" + ordinal 3 + quidu "000000000000" + creation FALSE))) + (object Link + quid "5C2B073E025F" + supplier "TF Detect" + quidu "5C2B06F4020C" + messages (list Messages + (object Message "ʶ" + quid "5C2B073E0260" + frequency "Aperiodic" + synchronization "Simple" + dir "FromClientToSupplier" + sequence "3" + ordinal 8 + quidu "000000000000" + creation FALSE) + (object Message "ʶ" + quid "5C2B074C023F" + frequency "Aperiodic" + synchronization "Return" + dir "ToClientFromSupplier" + sequence "3.2" + ordinal 11 + quidu "000000000000" + creation FALSE))) + (object Link + quid "5C2B0756032F" + supplier "TF Stylize" + quidu "5C2B071000FE" + messages (list Messages + (object Message "ͼ" + quid "5C2B07560330" + frequency "Aperiodic" + synchronization "Simple" + dir "FromClientToSupplier" + sequence "4" + ordinal 12 + quidu "000000000000" + creation FALSE) + (object Message "شͼƬ" + quid "5C2B076600AF" + frequency "Aperiodic" + synchronization "Return" + dir "ToClientFromSupplier" + sequence "4.2" + ordinal 15 + quidu "000000000000" + creation FALSE))) + (object Link + quid "5C2DE1B4008A" + supplier "TF Speech" + quidu "5C2DE0F6010B" + messages (list Messages + (object Message "ʶ" + quid "5C2DE1B4008B" + frequency "Aperiodic" + synchronization "Simple" + dir "FromClientToSupplier" + sequence "2" + ordinal 4 + quidu "000000000000" + creation FALSE) + (object Message "ƥ" + quid "5C2DE1C9027C" + frequency "Aperiodic" + synchronization "Return" + dir "ToClientFromSupplier" + sequence "2.2" + ordinal 7 + quidu "000000000000" + creation FALSE)))) + class "Use Case View::û" + quidu "5C2A2DE40377" + persistence "Transient" + creationObj TRUE + multi FALSE) + (object Object "TF Classify" + quid "5C2B06CE00D3" + collaborators (list link_list + (object Link + quid "5C2B0730037F" + supplier "Google Inception" + quidu "5C2B06E300CF" + messages (list Messages + (object Message " goole Inception" + quid "5C2B07300380" + frequency "Aperiodic" + synchronization "Simple" + dir "FromClientToSupplier" + sequence "1.1" + ordinal 1 + quidu "000000000000" + creation FALSE) + (object Message "ʶ" + quid "5C2B073403E0" + frequency "Aperiodic" + synchronization "Return" + dir "ToClientFromSupplier" + sequence "1.1.1" + ordinal 2 + quidu "000000000000" + creation FALSE)))) + persistence "Transient" + creationObj TRUE + multi FALSE) + (object Object "Google Inception" + quid "5C2B06E300CF" + persistence "Transient" + creationObj TRUE + multi FALSE) + (object Object "TF Detect" + quid "5C2B06F4020C" + collaborators (list link_list + (object Link + quid "5C2B07420347" + supplier "Tensorflow Object Detection" + quidu "5C2B070403DE" + messages (list Messages + (object Message "ʶ" + quid "5C2B07420348" + frequency "Aperiodic" + synchronization "Simple" + dir "FromClientToSupplier" + sequence "3.1" + ordinal 9 + quidu "000000000000" + creation FALSE) + (object Message "ʶ" + quid "5C2B07460088" + frequency "Aperiodic" + synchronization "Return" + dir "ToClientFromSupplier" + sequence "3.1.1" + ordinal 10 + quidu "000000000000" + creation FALSE)))) + persistence "Transient" + creationObj TRUE + multi FALSE) + (object Object "Tensorflow Object Detection" + quid "5C2B070403DE" + persistence "Transient" + creationObj TRUE + multi FALSE) + (object Object "TF Stylize" + quid "5C2B071000FE" + collaborators (list link_list + (object Link + quid "5C2B075C0047" + supplier +| Artistic +| Style + + quidu "5C2B071C035E" + messages (list Messages + (object Message "artisc style" + quid "5C2B075C0048" + frequency "Aperiodic" + synchronization "Simple" + dir "FromClientToSupplier" + sequence "4.1" + ordinal 13 + quidu "000000000000" + creation FALSE) + (object Message "شͼƬ" + quid "5C2B076000D7" + frequency "Aperiodic" + synchronization "Return" + dir "ToClientFromSupplier" + sequence "4.1.1" + ordinal 14 + quidu "000000000000" + creation FALSE)))) + persistence "Transient" + creationObj TRUE + multi FALSE) + (object Object " Artistic + Style" + quid "5C2B071C035E" + persistence "Transient" + creationObj TRUE + multi FALSE) + (object Object "TF Speech" + quid "5C2DE0F6010B" + collaborators (list link_list + (object Link + quid "5C2DE26503C7" + supplier " audio training" + quidu "5C2DE25C00E8" + messages (list Messages + (object Message "ѵ㷨" + quid "5C2DE26503C8" + frequency "Aperiodic" + synchronization "Simple" + dir "FromClientToSupplier" + sequence "2.1" + ordinal 5 + quidu "000000000000" + creation FALSE) + (object Message "ƥ" + quid "5C2DE26B0184" + frequency "Aperiodic" + synchronization "Return" + dir "ToClientFromSupplier" + sequence "2.1.1" + ordinal 6 + quidu "000000000000" + creation FALSE)))) + persistence "Transient" + creationObj TRUE + multi FALSE) + (object Object " audio training" + quid "5C2DE25C00E8" + persistence "Transient" + creationObj TRUE + multi FALSE)))) + statemachine (object State_Machine "State/Activity Model" + quid "5C2A25930375" + states (list States + (object State "ʼ" + quid "5C2A25A500EF" + type "StartState") + (object State "" + quid "5C2A260A0185" + type "EndState") + (object ActivityState "Ӧ˳" + quid "5C2A262200D1") + (object ActivityState "ʼ" + quid "5C2A26970093") + (object ActivityState "ʶ" + quid "5C2A2716009A") + (object ActivityState "ͼǨ" + quid "5C2A275C0393") + (object ActivityState "ʾʶ" + quid "5C2A28230280") + (object ActivityState "ʵʱ⵽Ա" + quid "5C2A288B0211") + (object State "ʼ" + quid "5C2A3069007F" + type "Normal") + (object State "չʾ״̬" + quid "5C2A31370226" + type "Normal") + (object State "״̬" + quid "5C2A31BE02C0" + type "Normal") + (object ActivityState "¼һ" + quid "5C2AF51D0171") + (object State "ģ" + quid "5C2AF57A0198" + type "Normal") + (object ActivityState "audio_recognition" + quid "5C2AF58F0249") + (object ActivityState "ʶ" + quid "5C2AF64B0383") + (object ActivityState "ʾʶ" + quid "5C2AF66901EA") + (object State "δʼ" + quid "5C2AF89503B3" + type "Normal") + (object SynchronizationState "$UNNAMED$40" + quid "5C2B028E0338") + (object ActivityState "TF Classify" + quid "5C2B02A601DA") + (object ActivityState "TF Detect" + quid "5C2B02AF02EC") + (object ActivityState "TF Stylize" + quid "5C2B02CB008A") + (object ActivityState "Google Inception" + quid "5C2B02F8029E") + (object ActivityState "ƶͷ׼ƻ" + quid "5C2B038C03A3") + (object ActivityState "Ƶ" + quid "5C2B03CE01EC") + (object Decision "ʶǷɹ" + quid "5C2B03E801B0") + (object ActivityState "չʾʶĽʾ" + quid "5C2B04200293") + (object ActivityState "ʶʧ" + quid "5C2B04800283") + (object ActivityState "Artistic + Styleģ" + quid "5C2B04FC027A") + (object ActivityState "ͼƬ" + quid "5C2B05DE00BC") + (object State "ȡͼƬ" + quid "5C2B05F10065" + type "Normal") + (object ActivityState "ѡӦķͼƬ" + quid "5C2B05FE0021") + (object ActivityState "ݷͼƬ޸" + quid "5C2B06130123") + (object ActivityState "չʾ޸Ľ" + quid "5C2B062703AD") + (object State "ϵͳʼ" + quid "5C2DE6E00232" + type "Normal") + (object State " ʶ" + quid "5C2DE6E300BF" + type "Normal") + (object State "" + quid "5C2DE6E403CA" + type "Normal") + (object State "ͼƬ" + quid "5C2DE6E7038D" + type "Normal") + (object State "ת" + quid "5C2DE74C0382" + type "Normal") + (object State "չʾʶ" + quid "5C2DE801017C" + type "Normal") + (object State "ʾͼƬ" + quid "5C2DE86501BD" + type "Normal") + (object State "ʶ" + quid "5C2DE87A0051" + type "Normal") + (object State "ʶ" + quid "5C2DE8A60128" + type "Normal")) + partitions (list Partitions + (object Partition "û" + quid "5C2A25AA025B" + persistence "Transient" + creationObj FALSE + multi FALSE) + (object Partition "andriond ͼ" + quid "5C2A25BB014B" + persistence "Transient" + creationObj FALSE + multi FALSE)) + objects (list Objects) + transitions (list transition_list + (object State_Transition + quid "5C2A2672020D" + supplier "Use Case View::State/Activity Model::Ӧ˳" + supplier_quidu "5C2A262200D1" + client "Use Case View::State/Activity Model::ʼ" + client_quidu "5C2A25A500EF" + sendEvent (object sendEvent + quid "5C2A26720210")) + (object State_Transition + quid "5C2A26C20196" + supplier "Use Case View::State/Activity Model::ʼ" + supplier_quidu "5C2A26970093" + client "Use Case View::State/Activity Model::Ӧ˳" + client_quidu "5C2A262200D1" + sendEvent (object sendEvent + quid "5C2A26C20199")) + (object State_Transition + quid "5C2A287D03D6" + supplier "Use Case View::State/Activity Model::" + supplier_quidu "5C2A260A0185" + client "Use Case View::State/Activity Model::ʾʶ" + client_quidu "5C2A28230280" + sendEvent (object sendEvent + quid "5C2A287D03D9")) + (object State_Transition + quid "5C2A28A90046" + supplier "Use Case View::State/Activity Model::" + supplier_quidu "5C2A260A0185" + client "Use Case View::State/Activity Model::ʵʱ⵽Ա" + client_quidu "5C2A288B0211" + sendEvent (object sendEvent + quid "5C2A28A90049")) + (object State_Transition + quid "5C2A31330080" + label "" + supplier "Use Case View::State/Activity Model::δʼ" + supplier_quidu "5C2AF89503B3" + client "Use Case View::State/Activity Model::ʼ" + client_quidu "5C2A25A500EF" + Event (object Event "ƶƵ" + quid "5C2A31330081") + sendEvent (object sendEvent + quid "5C2A31330083")) + (object State_Transition + quid "5C2A31DB0167" + label "" + supplier "Use Case View::State/Activity Model::״̬" + supplier_quidu "5C2A31BE02C0" + client "Use Case View::State/Activity Model::ʼ" + client_quidu "5C2A3069007F" + Event (object Event "ȡϢ" + quid "5C2A31DB0168") + sendEvent (object sendEvent + quid "5C2A31DB016A")) + (object State_Transition + quid "5C2A32590098" + label "" + supplier "Use Case View::State/Activity Model::չʾ״̬" + supplier_quidu "5C2A31370226" + client "Use Case View::State/Activity Model::״̬" + client_quidu "5C2A31BE02C0" + Event (object Event "ʵʱչַ" + quid "5C2A32590099") + sendEvent (object sendEvent + quid "5C2A3259009B")) + (object State_Transition + quid "5C2A326F0370" + supplier "Use Case View::State/Activity Model::" + supplier_quidu "5C2A260A0185" + client "Use Case View::State/Activity Model::չʾ״̬" + client_quidu "5C2A31370226" + sendEvent (object sendEvent + quid "5C2A326F0373")) + (object State_Transition + quid "5C2AF52C014C" + supplier "$UNNAMED$40" + supplier_quidu "5C2B028E0338" + client "Use Case View::State/Activity Model::ʼ" + client_quidu "5C2A26970093" + sendEvent (object sendEvent + quid "5C2AF52C014F")) + (object State_Transition + quid "5C2AF610005C" + supplier "Use Case View::State/Activity Model::audio_recognition" + supplier_quidu "5C2AF58F0249" + client "Use Case View::State/Activity Model::ģ" + client_quidu "5C2AF57A0198" + sendEvent (object sendEvent + quid "5C2AF610005F")) + (object State_Transition + quid "5C2AF61203BD" + supplier "Use Case View::State/Activity Model::¼һ" + supplier_quidu "5C2AF51D0171" + client "Use Case View::State/Activity Model::audio_recognition" + client_quidu "5C2AF58F0249" + sendEvent (object sendEvent + quid "5C2AF61203C0")) + (object State_Transition + quid "5C2AF67B00A4" + supplier "Use Case View::State/Activity Model::ʶ" + supplier_quidu "5C2AF64B0383" + client "Use Case View::State/Activity Model::¼һ" + client_quidu "5C2AF51D0171" + sendEvent (object sendEvent + quid "5C2AF67B00A7")) + (object State_Transition + quid "5C2AF67E00F4" + supplier "Use Case View::State/Activity Model::ʾʶ" + supplier_quidu "5C2AF66901EA" + client "Use Case View::State/Activity Model::ʶ" + client_quidu "5C2AF64B0383" + sendEvent (object sendEvent + quid "5C2AF67E00F7")) + (object State_Transition + quid "5C2AF681024E" + supplier "Use Case View::State/Activity Model::" + supplier_quidu "5C2A260A0185" + client "Use Case View::State/Activity Model::ʾʶ" + client_quidu "5C2AF66901EA" + sendEvent (object sendEvent + quid "5C2AF6810251")) + (object State_Transition + quid "5C2AF8DF01FD" + supplier "Use Case View::State/Activity Model::ʼ" + supplier_quidu "5C2A3069007F" + client "Use Case View::State/Activity Model::δʼ" + client_quidu "5C2AF89503B3" + sendEvent (object sendEvent + quid "5C2AF8DF0200")) + (object State_Transition + quid "5C2B027B02B3" + supplier "Use Case View::State/Activity Model::ʶ" + supplier_quidu "5C2AF64B0383" + client "Use Case View::State/Activity Model::ʶ" + client_quidu "5C2AF64B0383" + sendEvent (object sendEvent + quid "5C2B027B02B6")) + (object State_Transition + quid "5C2B029B0056" + supplier "Use Case View::State/Activity Model::ģ" + supplier_quidu "5C2AF57A0198" + client "$UNNAMED$40" + client_quidu "5C2B028E0338" + sendEvent (object sendEvent + quid "5C2B029B0059")) + (object State_Transition + quid "5C2B02D300DF" + supplier "Use Case View::State/Activity Model::TF Classify" + supplier_quidu "5C2B02A601DA" + client "$UNNAMED$40" + client_quidu "5C2B028E0338" + sendEvent (object sendEvent + quid "5C2B02D300E2")) + (object State_Transition + quid "5C2B02D503AF" + supplier "Use Case View::State/Activity Model::TF Detect" + supplier_quidu "5C2B02AF02EC" + client "$UNNAMED$40" + client_quidu "5C2B028E0338" + sendEvent (object sendEvent + quid "5C2B02D503B2")) + (object State_Transition + quid "5C2B02D9009F" + supplier "Use Case View::State/Activity Model::TF Stylize" + supplier_quidu "5C2B02CB008A" + client "$UNNAMED$40" + client_quidu "5C2B028E0338" + sendEvent (object sendEvent + quid "5C2B02D900A2")) + (object State_Transition + quid "5C2B031F0127" + supplier "Use Case View::State/Activity Model::Google Inception" + supplier_quidu "5C2B02F8029E" + client "Use Case View::State/Activity Model::TF Classify" + client_quidu "5C2B02A601DA" + sendEvent (object sendEvent + quid "5C2B031F012A")) + (object State_Transition + quid "5C2B03A5004F" + supplier "Use Case View::State/Activity Model::ƶͷ׼ƻ" + supplier_quidu "5C2B038C03A3" + client "Use Case View::State/Activity Model::Google Inception" + client_quidu "5C2B02F8029E" + sendEvent (object sendEvent + quid "5C2B03A50052")) + (object State_Transition + quid "5C2B03E2037F" + supplier "Use Case View::State/Activity Model::Ƶ" + supplier_quidu "5C2B03CE01EC" + client "Use Case View::State/Activity Model::ƶͷ׼ƻ" + client_quidu "5C2B038C03A3" + sendEvent (object sendEvent + quid "5C2B03E20382")) + (object State_Transition + quid "5C2B041600FF" + supplier "Use Case View::State/Activity Model::ʶǷɹ" + supplier_quidu "5C2B03E801B0" + client "Use Case View::State/Activity Model::Ƶ" + client_quidu "5C2B03CE01EC" + sendEvent (object sendEvent + quid "5C2B04160102")) + (object State_Transition + quid "5C2B045F0137" + label "" + supplier "Use Case View::State/Activity Model::չʾʶĽʾ" + supplier_quidu "5C2B04200293" + client "Use Case View::State/Activity Model::ʶǷɹ" + client_quidu "5C2B03E801B0" + Event (object Event "" + quid "5C2B045F0138") + sendEvent (object sendEvent + quid "5C2B045F013A")) + (object State_Transition + quid "5C2B04950307" + label "" + supplier "Use Case View::State/Activity Model::ʶʧ" + supplier_quidu "5C2B04800283" + client "Use Case View::State/Activity Model::ʶǷɹ" + client_quidu "5C2B03E801B0" + Event (object Event "" + quid "5C2B04950308") + sendEvent (object sendEvent + quid "5C2B0495030A")) + (object State_Transition + quid "5C2B04AF0377" + supplier "Use Case View::State/Activity Model::" + supplier_quidu "5C2A260A0185" + client "Use Case View::State/Activity Model::չʾʶĽʾ" + client_quidu "5C2B04200293" + sendEvent (object sendEvent + quid "5C2B04AF037A")) + (object State_Transition + quid "5C2B04B301EF" + supplier "Use Case View::State/Activity Model::" + supplier_quidu "5C2A260A0185" + client "Use Case View::State/Activity Model::ʶʧ" + client_quidu "5C2B04800283" + sendEvent (object sendEvent + quid "5C2B04B301F2")) + (object State_Transition + quid "5C2B051F005F" + supplier +|Use Case View::State/Activity Model::Artistic +| Styleģ + + supplier_quidu "5C2B04FC027A" + client "Use Case View::State/Activity Model::TF Stylize" + client_quidu "5C2B02CB008A" + sendEvent (object sendEvent + quid "5C2B051F0062")) + (object State_Transition + quid "5C2B05EA021F" + supplier "Use Case View::State/Activity Model::ͼƬ" + supplier_quidu "5C2B05DE00BC" + client +|Use Case View::State/Activity Model::Artistic +| Styleģ + + client_quidu "5C2B04FC027A" + sendEvent (object sendEvent + quid "5C2B05EA0222")) + (object State_Transition + quid "5C2B05F900FF" + supplier "Use Case View::State/Activity Model::ȡͼƬ" + supplier_quidu "5C2B05F10065" + client "Use Case View::State/Activity Model::ͼƬ" + client_quidu "5C2B05DE00BC" + sendEvent (object sendEvent + quid "5C2B05F90102")) + (object State_Transition + quid "5C2B063902F7" + supplier "Use Case View::State/Activity Model::ѡӦķͼƬ" + supplier_quidu "5C2B05FE0021" + client "Use Case View::State/Activity Model::ȡͼƬ" + client_quidu "5C2B05F10065" + sendEvent (object sendEvent + quid "5C2B063902FA")) + (object State_Transition + quid "5C2B063C0150" + supplier "Use Case View::State/Activity Model::ݷͼƬ޸" + supplier_quidu "5C2B06130123" + client "Use Case View::State/Activity Model::ѡӦķͼƬ" + client_quidu "5C2B05FE0021" + sendEvent (object sendEvent + quid "5C2B063C0153")) + (object State_Transition + quid "5C2B063F0140" + supplier "Use Case View::State/Activity Model::չʾ޸Ľ" + supplier_quidu "5C2B062703AD" + client "Use Case View::State/Activity Model::ݷͼƬ޸" + client_quidu "5C2B06130123" + sendEvent (object sendEvent + quid "5C2B063F0143")) + (object State_Transition + quid "5C2B064502B7" + supplier "Use Case View::State/Activity Model::" + supplier_quidu "5C2A260A0185" + client "Use Case View::State/Activity Model::չʾ޸Ľ" + client_quidu "5C2B062703AD" + sendEvent (object sendEvent + quid "5C2B064502BA")) + (object State_Transition + quid "5C2DE6F900C7" + supplier "Use Case View::State/Activity Model::ϵͳʼ" + supplier_quidu "5C2DE6E00232" + client "Use Case View::State/Activity Model::ʼ" + client_quidu "5C2A25A500EF" + sendEvent (object sendEvent + quid "5C2DE6F900CA")) + (object State_Transition + quid "5C2DE7060399" + supplier "Use Case View::State/Activity Model:: ʶ" + supplier_quidu "5C2DE6E300BF" + client "Use Case View::State/Activity Model::ϵͳʼ" + client_quidu "5C2DE6E00232" + sendEvent (object sendEvent + quid "5C2DE706039C")) + (object State_Transition + quid "5C2DE7580026" + supplier "Use Case View::State/Activity Model::ʶ" + supplier_quidu "5C2DE87A0051" + client "Use Case View::State/Activity Model::ϵͳʼ" + client_quidu "5C2DE6E00232" + sendEvent (object sendEvent + quid "5C2DE7580029")) + (object State_Transition + quid "5C2DE75A023B" + supplier "Use Case View::State/Activity Model::ͼƬ" + supplier_quidu "5C2DE6E7038D" + client "Use Case View::State/Activity Model::ϵͳʼ" + client_quidu "5C2DE6E00232" + sendEvent (object sendEvent + quid "5C2DE75A023E")) + (object State_Transition + quid "5C2DE75D00E1" + supplier "Use Case View::State/Activity Model::" + supplier_quidu "5C2DE6E403CA" + client "Use Case View::State/Activity Model::ϵͳʼ" + client_quidu "5C2DE6E00232" + sendEvent (object sendEvent + quid "5C2DE75D00E4")) + (object State_Transition + quid "5C2DE8040239" + supplier "Use Case View::State/Activity Model::չʾʶ" + supplier_quidu "5C2DE801017C" + client "Use Case View::State/Activity Model:: ʶ" + client_quidu "5C2DE6E300BF" + sendEvent (object sendEvent + quid "5C2DE804023C")) + (object State_Transition + quid "5C2DE88700F7" + supplier "Use Case View::State/Activity Model::ת" + supplier_quidu "5C2DE74C0382" + client "Use Case View::State/Activity Model::ʶ" + client_quidu "5C2DE87A0051" + sendEvent (object sendEvent + quid "5C2DE88700FA")) + (object State_Transition + quid "5C2DE88B01FA" + supplier "Use Case View::State/Activity Model::ʾͼƬ" + supplier_quidu "5C2DE86501BD" + client "Use Case View::State/Activity Model::ͼƬ" + client_quidu "5C2DE6E7038D" + sendEvent (object sendEvent + quid "5C2DE88B01FD")) + (object State_Transition + quid "5C2DE8AF0315" + supplier "Use Case View::State/Activity Model::ʶ" + supplier_quidu "5C2DE8A60128" + client "Use Case View::State/Activity Model::" + client_quidu "5C2DE6E403CA" + sendEvent (object sendEvent + quid "5C2DE8AF0318")) + (object State_Transition + quid "5C2DE8B2030A" + supplier "Use Case View::State/Activity Model::" + supplier_quidu "5C2A260A0185" + client "Use Case View::State/Activity Model::ʶ" + client_quidu "5C2DE8A60128" + sendEvent (object sendEvent + quid "5C2DE8B2030D")) + (object State_Transition + quid "5C2DE8B500DC" + supplier "Use Case View::State/Activity Model::" + supplier_quidu "5C2A260A0185" + client "Use Case View::State/Activity Model::ʾͼƬ" + client_quidu "5C2DE86501BD" + sendEvent (object sendEvent + quid "5C2DE8B500DF")) + (object State_Transition + quid "5C2DE8B80196" + supplier "Use Case View::State/Activity Model::" + supplier_quidu "5C2A260A0185" + client "Use Case View::State/Activity Model::ת" + client_quidu "5C2DE74C0382" + sendEvent (object sendEvent + quid "5C2DE8B80199")) + (object State_Transition + quid "5C2DE8BB00A9" + supplier "Use Case View::State/Activity Model::" + supplier_quidu "5C2A260A0185" + client "Use Case View::State/Activity Model::չʾʶ" + client_quidu "5C2DE801017C" + sendEvent (object sendEvent + quid "5C2DE8BB00AC"))) + objectflows (list objectflow_list) + statediagrams (list StateDiagrams + (object ActivityDiagram "ͼ" + quid "5C2A25930389" + title "ͼ" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 1978 + items (list diagram_item_list + (object Swimlane "û" @2 + line_color 3342489 + quidu "5C2A25AA025B" + width 1544) + (object StateView "StartState" "ʼ" @3 + Parent_View @2 + location (400, 208) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @4 + Parent_View @3 + location (442, 178) + font (object Font + size 10 + face "Arial" + bold FALSE + italics TRUE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + nlines 2 + max_width 600 + justify 1 + label "ʼ" + pctDist 1.000000 + height 0 + orientation 0) + icon_style "Icon" + line_color 3342489 + quidu "5C2A25A500EF" + autoResize TRUE) + (object ActivityStateView "Ӧ˳" @5 + Parent_View @2 + location (400, 416) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @5 + location (400, 419) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "Ӧ˳") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A262200D1" + height 106 + annotation 1 + autoResize TRUE) + (object TransView "" @6 + stereotype TRUE + line_color 3342489 + quidu "5C2A2672020D" + client @3 + supplier @5 + vertices (list Points + (400, 238) + (400, 363)) + line_style 0 + x_offset FALSE) + (object ActivityStateView "¼һ" @7 + Parent_View @2 + location (1168, 1408) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @7 + location (1168, 1411) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "¼һ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2AF51D0171" + height 106 + annotation 1 + autoResize TRUE) + (object StateView "Normal" "ģ" @8 + Parent_View @2 + location (976, 1056) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @8 + location (976, 1045) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 204 + justify 0 + label "ģ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2AF57A0198" + height 134 + autoResize TRUE) + (object ActivityStateView "TF Classify" @9 + Parent_View @2 + location (1056, 1680) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @9 + location (1056, 1683) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "TF Classify") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B02A601DA" + height 106 + annotation 1 + autoResize TRUE) + (object ActivityStateView "TF Stylize" @10 + Parent_View @2 + location (672, 3168) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @10 + location (672, 3171) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "TF Stylize") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B02CB008A" + height 106 + annotation 1 + autoResize TRUE) + (object ActivityStateView "ƶͷ׼ƻ" @11 + Parent_View @2 + location (1184, 2080) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @11 + location (1184, 2083) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "ƶͷ׼ƻ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B038C03A3" + height 106 + annotation 1 + autoResize TRUE) + (object ActivityStateView "ͼƬ" @12 + Parent_View @2 + location (848, 3424) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @12 + location (848, 3427) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "ͼƬ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B05DE00BC" + height 106 + annotation 1 + autoResize TRUE) + (object ActivityStateView "ѡӦķͼƬ" @13 + Parent_View @2 + location (896, 3776) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @13 + location (896, 3779) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "ѡӦķͼƬ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B05FE0021" + height 106 + annotation 1 + autoResize TRUE) + (object Swimlane "andriond ͼ" @14 + location (1544, 0) + line_color 3342489 + quidu "5C2A25BB014B" + width 1282) + (object ActivityStateView "ʼ" @15 + Parent_View @14 + location (2102, 624) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @15 + location (2102, 627) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "ʼ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A26970093" + height 106 + annotation 1 + autoResize TRUE) + (object TransView "" @16 + stereotype TRUE + line_color 3342489 + quidu "5C2A26C20196" + client @5 + supplier @15 + vertices (list Points + (566, 436) + (1935, 603)) + line_style 0 + x_offset FALSE) + (object ActivityStateView "audio_recognition" @17 + Parent_View @14 + location (1840, 960) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @17 + location (1840, 963) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 314 + justify 0 + label "audio_recognition") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2AF58F0249" + width 420 + height 106 + annotation 1 + autoResize TRUE) + (object TransView "" @18 + stereotype TRUE + line_color 3342489 + quidu "5C2AF610005C" + client @8 + supplier @17 + vertices (list Points + (1126, 1039) + (1656, 980)) + line_style 0 + x_offset FALSE) + (object TransView "" @19 + stereotype TRUE + line_color 3342489 + quidu "5C2AF61203BD" + client @17 + supplier @7 + vertices (list Points + (1760, 1012) + (1247, 1354)) + line_style 0 + x_offset FALSE) + (object StateView "EndState" "" @20 + Parent_View @14 + location (2336, 4544) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @21 + Parent_View @20 + location (2390, 4502) + font (object Font + size 10 + face "Arial" + bold FALSE + italics TRUE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + nlines 2 + max_width 600 + justify 1 + label "" + pctDist 1.000000 + height 0 + orientation 0) + icon_style "Icon" + line_color 3342489 + quidu "5C2A260A0185" + autoResize TRUE) + (object ActivityStateView "ʶ" @22 + Parent_View @14 + location (2480, 1440) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @22 + location (2480, 1443) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "ʶ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2AF64B0383" + height 106 + annotation 1 + autoResize TRUE) + (object TransView "" @23 + stereotype TRUE + line_color 3342489 + quidu "5C2AF67B00A4" + client @7 + supplier @22 + vertices (list Points + (1339, 1412) + (2308, 1435)) + line_style 0 + x_offset FALSE) + (object SelfTransView "" @24 + location (2480, 1237) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @25 + Parent_View @24 + location (2480, 1178) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + hidden TRUE + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "" + pctDist 0.500000 + height 210 + orientation 0) + stereotype TRUE + line_color 3342489 + quidu "5C2B027B02B3" + client @22 + supplier @22 + vertices (list Points + (2423, 1387) + (2537, 1387)) + line_style 4) + (object ActivityStateView "ʾʶ" @26 + Parent_View @14 + location (2576, 2112) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @26 + location (2576, 2115) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "ʾʶ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2AF66901EA" + height 106 + annotation 1 + autoResize TRUE) + (object TransView "" @27 + stereotype TRUE + line_color 3342489 + quidu "5C2AF67E00F4" + client @22 + supplier @26 + vertices (list Points + (2487, 1493) + (2568, 2058)) + line_style 0 + x_offset FALSE) + (object TransView "" @28 + stereotype TRUE + line_color 3342489 + quidu "5C2AF681024E" + client @26 + supplier @20 + vertices (list Points + (2570, 2165) + (2340, 4502)) + line_style 0 + x_offset FALSE) + (object ActivityStateView "Google Inception" @29 + Parent_View @14 + location (1888, 1712) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @29 + location (1888, 1715) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "Google Inception") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B02F8029E" + height 106 + annotation 1 + autoResize TRUE) + (object TransView "" @30 + stereotype TRUE + line_color 3342489 + quidu "5C2B031F0127" + client @9 + supplier @29 + vertices (list Points + (1226, 1686) + (1717, 1705)) + line_style 0 + x_offset FALSE) + (object TransView "" @31 + stereotype TRUE + line_color 3342489 + quidu "5C2B03A5004F" + client @29 + supplier @11 + vertices (list Points + (1786, 1765) + (1285, 2026)) + line_style 0 + x_offset FALSE) + (object ActivityStateView "Ƶ" @32 + Parent_View @14 + location (1840, 2208) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @32 + location (1840, 2211) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "Ƶ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B03CE01EC" + height 106 + annotation 1 + autoResize TRUE) + (object TransView "" @33 + stereotype TRUE + line_color 3342489 + quidu "5C2B03E2037F" + client @11 + supplier @32 + vertices (list Points + (1342, 2110) + (1681, 2177)) + line_style 0 + x_offset FALSE) + (object DecisionView "ʶǷɹ" @34 + Parent_View @14 + location (1824, 2368) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @35 + Parent_View @34 + location (1880, 2319) + font (object Font + size 10 + face "Arial" + bold FALSE + italics TRUE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + anchor 1 + nlines 2 + max_width 300 + justify 1 + label "ʶǷɹ" + pctDist 1.000000 + height 0 + orientation 0) + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B03E801B0" + autoResize TRUE) + (object TransView "" @36 + stereotype TRUE + line_color 3342489 + quidu "5C2B041600FF" + client @32 + supplier @34 + vertices (list Points + (1834, 2261) + (1824, 2331)) + line_style 0 + x_offset FALSE) + (object ActivityStateView "չʾʶĽʾ" @37 + Parent_View @14 + location (1824, 2672) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @37 + location (1824, 2675) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 320 + justify 0 + label "չʾʶĽʾ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B04200293" + width 426 + height 106 + annotation 1 + autoResize TRUE) + (object TransView "" @38 + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @39 + Parent_View @38 + location (1869, 2512) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "" + pctDist 0.500000 + height 45 + orientation 0) + stereotype TRUE + line_color 3342489 + quidu "5C2B045F0137" + client @34 + supplier @37 + vertices (list Points + (1824, 2405) + (1824, 2619)) + line_style 0 + x_offset FALSE) + (object TransView "" @40 + stereotype TRUE + line_color 3342489 + quidu "5C2B04AF0377" + client @37 + supplier @20 + vertices (list Points + (1838, 2725) + (2324, 4502)) + line_style 0 + x_offset FALSE) + (object ActivityStateView "ʶʧ" @41 + Parent_View @14 + location (2208, 2512) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @41 + location (2208, 2515) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "ʶʧ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B04800283" + height 106 + annotation 1 + autoResize TRUE) + (object TransView "" @42 + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @43 + Parent_View @42 + location (2016, 2374) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "" + pctDist 0.500000 + height 45 + orientation 0) + stereotype TRUE + line_color 3342489 + quidu "5C2B04950307" + client @34 + supplier @41 + vertices (list Points + (1899, 2368) + (2094, 2459)) + line_style 0 + x_offset FALSE) + (object TransView "" @44 + stereotype TRUE + line_color 3342489 + quidu "5C2B04B301EF" + client @41 + supplier @20 + vertices (list Points + (2211, 2565) + (2333, 4501)) + line_style 0 + x_offset FALSE) + (object ActivityStateView "Artistic + Styleģ" @45 + Parent_View @14 + location (1792, 3296) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @45 + location (1792, 3299) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label +|Artistic +| Styleģ + ) + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B04FC027A" + height 106 + annotation 1 + autoResize TRUE) + (object TransView "" @46 + stereotype TRUE + line_color 3342489 + quidu "5C2B051F005F" + client @10 + supplier @45 + vertices (list Points + (838, 3187) + (1625, 3276)) + line_style 0 + x_offset FALSE) + (object TransView "" @47 + stereotype TRUE + line_color 3342489 + quidu "5C2B05EA021F" + client @45 + supplier @12 + vertices (list Points + (1626, 3318) + (1013, 3401)) + line_style 0 + x_offset FALSE) + (object StateView "Normal" "ȡͼƬ" @48 + Parent_View @14 + location (1792, 3520) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @48 + location (1792, 3509) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 204 + justify 0 + label "ȡͼƬ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B05F10065" + height 134 + autoResize TRUE) + (object TransView "" @49 + stereotype TRUE + line_color 3342489 + quidu "5C2B05F900FF" + client @12 + supplier @48 + vertices (list Points + (1017, 3441) + (1642, 3504)) + line_style 0 + x_offset FALSE) + (object ActivityStateView "ݷͼƬ޸" @50 + Parent_View @14 + location (1818, 3904) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @50 + location (1818, 3907) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 320 + justify 0 + label "ݷͼƬ޸") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B06130123" + width 426 + height 106 + annotation 1 + autoResize TRUE) + (object ActivityStateView "չʾ޸Ľ" @51 + Parent_View @14 + location (1824, 4208) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @51 + location (1824, 4211) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 269 + justify 0 + label "չʾ޸Ľ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B062703AD" + height 106 + annotation 1 + autoResize TRUE) + (object Swimlane "" @52 + location (2826, 0) + line_color 3342489 + width 450) + (object SynchronizationView "$UNNAMED$40" @53 + location (448, 784) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @54 + Parent_View @53 + location (610, 713) + font (object Font + size 10 + face "Arial" + bold FALSE + italics TRUE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + hidden TRUE + nlines 2 + max_width 300 + justify 1 + label "" + pctDist 1.000000 + height 0 + orientation 0) + icon_style "Icon" + line_color 3342489 + quidu "5C2B028E0338" + autoResize TRUE + sync_flow_direction 1 + sync_is_horizontal TRUE) + (object TransView "" @55 + stereotype TRUE + line_color 3342489 + quidu "5C2AF52C014C" + client @15 + supplier @53 + vertices (list Points + (1932, 640) + (530, 774)) + line_style 0 + x_offset FALSE) + (object TransView "" @56 + stereotype TRUE + line_color 3342489 + quidu "5C2B029B0056" + client @53 + supplier @8 + vertices (list Points + (466, 793) + (847, 988)) + line_style 0 + x_offset FALSE) + (object TransView "" @57 + stereotype TRUE + line_color 3342489 + quidu "5C2B02D300DF" + client @53 + supplier @9 + vertices (list Points + (453, 793) + (1019, 1626)) + line_style 0 + x_offset FALSE) + (object TransView "" @58 + stereotype TRUE + line_color 3342489 + quidu "5C2B02D9009F" + client @53 + supplier @10 + vertices (list Points + (448, 793) + (667, 3115)) + line_style 0 + x_offset FALSE) + (object TransView "" @59 + stereotype TRUE + line_color 3342489 + quidu "5C2B063902F7" + client @48 + supplier @13 + vertices (list Points + (1642, 3562) + (1044, 3733)) + line_style 0 + x_offset FALSE) + (object TransView "" @60 + stereotype TRUE + line_color 3342489 + quidu "5C2B063C0150" + client @13 + supplier @50 + vertices (list Points + (1061, 3798) + (1635, 3878)) + line_style 0 + x_offset FALSE) + (object TransView "" @61 + stereotype TRUE + line_color 3342489 + quidu "5C2B063F0140" + client @50 + supplier @51 + vertices (list Points + (1819, 3957) + (1822, 4154)) + line_style 0 + x_offset FALSE) + (object TransView "" @62 + stereotype TRUE + line_color 3342489 + quidu "5C2B064502B7" + client @51 + supplier @20 + vertices (list Points + (1904, 4261) + (2294, 4516)) + line_style 0 + x_offset FALSE))) + (object State_Diagram "״̬ͼ" + quid "5C2A2F080122" + title "״̬ͼ" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 0 + items (list diagram_item_list + (object StateView "StartState" "ʼ" @63 + location (1520, 240) + icon_style "Icon" + line_color 3342489 + quidu "5C2A25A500EF" + autoResize TRUE) + (object StateView "EndState" "" @64 + location (1648, 1904) + icon_style "Icon" + line_color 3342489 + quidu "5C2A260A0185" + autoResize TRUE) + (object StateView "Normal" "ϵͳʼ" @65 + location (1520, 720) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @65 + location (1520, 709) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 204 + justify 0 + label "ϵͳʼ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE6E00232" + height 134 + autoResize TRUE) + (object StateView "Normal" " ʶ" @66 + location (432, 1072) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @66 + location (432, 1061) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 204 + justify 0 + label " ʶ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE6E300BF" + height 134 + autoResize TRUE) + (object StateView "Normal" "" @67 + location (2384, 1168) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @67 + location (2384, 1157) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 204 + justify 0 + label "") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE6E403CA" + height 134 + autoResize TRUE) + (object StateView "Normal" "ͼƬ" @68 + location (1648, 1200) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @68 + location (1648, 1189) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 204 + justify 0 + label "ͼƬ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE6E7038D" + height 134 + autoResize TRUE) + (object TransView "" @69 + stereotype TRUE + line_color 3342489 + quidu "5C2DE6F900C7" + client @63 + supplier @65 + vertices (list Points + (1520, 270) + (1520, 653)) + line_style 0 + x_offset FALSE) + (object StateView "Normal" "ת" @70 + location (992, 1504) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @70 + location (992, 1493) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 204 + justify 0 + label "ת") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE74C0382" + height 134 + autoResize TRUE) + (object StateView "Normal" "չʾʶ" @71 + location (464, 1536) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @71 + location (464, 1525) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 204 + justify 0 + label "չʾʶ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE801017C" + height 134 + autoResize TRUE) + (object TransView "" @72 + stereotype TRUE + line_color 3342489 + quidu "5C2DE8040239" + client @66 + supplier @71 + vertices (list Points + (436, 1139) + (459, 1468)) + line_style 0 + x_offset FALSE) + (object StateView "Normal" "ʾͼƬ" @73 + location (1648, 1472) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @73 + location (1648, 1461) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 204 + justify 0 + label "ʾͼƬ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE86501BD" + height 134 + autoResize TRUE) + (object StateView "Normal" "ʶ" @74 + location (992, 1104) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @74 + location (992, 1093) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 204 + justify 0 + label "ʶ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE87A0051" + height 134 + autoResize TRUE) + (object TransView "" @75 + stereotype TRUE + line_color 3342489 + quidu "5C2DE7060399" + client @65 + supplier @66 + vertices (list Points + (1370, 768) + (582, 1023)) + line_style 0 + x_offset FALSE) + (object TransView "" @76 + stereotype TRUE + line_color 3342489 + quidu "5C2DE7580026" + client @65 + supplier @74 + vertices (list Points + (1427, 787) + (1084, 1037)) + line_style 0 + x_offset FALSE) + (object TransView "" @77 + stereotype TRUE + line_color 3342489 + quidu "5C2DE75A023B" + client @65 + supplier @68 + vertices (list Points + (1537, 787) + (1630, 1132)) + line_style 0 + x_offset FALSE) + (object TransView "" @78 + stereotype TRUE + line_color 3342489 + quidu "5C2DE75D00E1" + client @65 + supplier @67 + vertices (list Points + (1649, 786) + (2254, 1100)) + line_style 0 + x_offset FALSE) + (object TransView "" @79 + stereotype TRUE + line_color 3342489 + quidu "5C2DE88700F7" + client @74 + supplier @70 + vertices (list Points + (992, 1171) + (992, 1437)) + line_style 0 + x_offset FALSE) + (object TransView "" @80 + stereotype TRUE + line_color 3342489 + quidu "5C2DE88B01FA" + client @68 + supplier @73 + vertices (list Points + (1648, 1267) + (1648, 1405)) + line_style 0 + x_offset FALSE) + (object StateView "Normal" "ʶ" @81 + location (2384, 1472) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @81 + location (2384, 1461) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 204 + justify 0 + label "ʶ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE8A60128" + height 134 + autoResize TRUE) + (object TransView "" @82 + stereotype TRUE + line_color 3342489 + quidu "5C2DE8AF0315" + client @67 + supplier @81 + vertices (list Points + (2384, 1235) + (2384, 1405)) + line_style 0 + x_offset FALSE) + (object TransView "" @83 + stereotype TRUE + line_color 3342489 + quidu "5C2DE8B2030A" + client @81 + supplier @64 + vertices (list Points + (2269, 1539) + (1690, 1879)) + line_style 0 + x_offset FALSE) + (object TransView "" @84 + stereotype TRUE + line_color 3342489 + quidu "5C2DE8B500DC" + client @73 + supplier @64 + vertices (list Points + (1648, 1539) + (1648, 1862)) + line_style 0 + x_offset FALSE) + (object TransView "" @85 + stereotype TRUE + line_color 3342489 + quidu "5C2DE8B80196" + client @70 + supplier @64 + vertices (list Points + (1101, 1571) + (1606, 1878)) + line_style 0 + x_offset FALSE) + (object TransView "" @86 + stereotype TRUE + line_color 3342489 + quidu "5C2DE8BB00A9" + client @71 + supplier @64 + vertices (list Points + (614, 1582) + (1606, 1890)) + line_style 0 + x_offset FALSE))))) + logical_presentations (list unit_reference_list + (object UseCaseDiagram "Main" + quid "39C9261001B7" + title "Main" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 0 + items (list diagram_item_list)) + (object UseCaseDiagram "ͼ" + quid "5C2A2DD3030F" + title "ͼ" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 0 + items (list diagram_item_list + (object UseCaseView "Use Case View::αʶ" @87 + location (1616, 80) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @87 + location (1616, 218) + anchor_loc 1 + nlines 2 + max_width 630 + justify 0 + label "αʶ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A2E1C00AF" + height 118) + (object UseCaseView "Use Case View::ƻʶ" @88 + location (2000, 336) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @88 + location (2000, 474) + anchor_loc 1 + nlines 2 + max_width 630 + justify 0 + label "ƻʶ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A2E0C0233" + height 118) + (object UseCaseView "Use Case View::ʶ" @89 + location (1856, 640) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @89 + location (1856, 778) + anchor_loc 1 + nlines 2 + max_width 630 + justify 0 + label "ʶ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A2E1500E6" + height 118) + (object UseCaseView "Use Case View::񻯷" @90 + location (2128, 1120) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @90 + location (2128, 1258) + anchor_loc 1 + nlines 2 + max_width 630 + justify 0 + label "񻯷") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A2E5D03D7" + height 118) + (object UseCaseView "Use Case View::ɫ" @91 + location (1904, 1648) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @91 + location (1904, 1786) + anchor_loc 1 + nlines 2 + max_width 630 + justify 0 + label "ɫ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A2E8901D6" + height 118) + (object UseCaseView "Use Case View::ŵ" @92 + location (1648, 2032) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @92 + location (1648, 2170) + anchor_loc 1 + nlines 2 + max_width 630 + justify 0 + label "ŵ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A2E9E01BF" + height 118) + (object UseCaseView "Use Case View::ʵʱ" @93 + location (352, 240) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @93 + location (352, 378) + anchor_loc 1 + nlines 2 + max_width 630 + justify 0 + label "ʵʱ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A2DEE01C6" + height 118) + (object AssociationViewNew "$UNNAMED$3" @94 + location (982, 156) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + stereotype (object SegLabel @95 + Parent_View @94 + location (982, 37) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + anchor 10 + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "<>" + pctDist 0.500000 + height 120 + orientation 0) + line_color 3342489 + quidu "5C2A2EAF02EA" + roleview_list (list RoleViews + (object RoleView "$UNNAMED$4" @96 + Parent_View @94 + location (-42, -276) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EB00318" + client @94 + supplier @87 + vertices (list Points + (982, 156) + (1505, 90)) + line_style 0) + (object RoleView "$UNNAMED$5" @97 + Parent_View @94 + location (-42, -276) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EB0031D" + client @94 + supplier @93 + vertices (list Points + (982, 156) + (460, 223)) + line_style 0))) + (object AssociationViewNew "$UNNAMED$6" @98 + location (1175, 284) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + stereotype (object SegLabel @99 + Parent_View @98 + location (1175, 165) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + anchor 10 + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "<>" + pctDist 0.500000 + height 120 + orientation 0) + line_color 3342489 + quidu "5C2A2EB20283" + roleview_list (list RoleViews + (object RoleView "$UNNAMED$7" @100 + Parent_View @98 + location (151, -148) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EB300D8" + client @98 + supplier @88 + vertices (list Points + (1175, 284) + (1890, 326)) + line_style 0) + (object RoleView "$UNNAMED$8" @101 + Parent_View @98 + location (151, -148) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EB300DB" + client @98 + supplier @93 + vertices (list Points + (1175, 284) + (460, 243)) + line_style 0))) + (object AssociationViewNew "$UNNAMED$9" @102 + location (1103, 437) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + stereotype (object SegLabel @103 + Parent_View @102 + location (1103, 318) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + anchor 10 + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "<>" + pctDist 0.500000 + height 120 + orientation 0) + line_color 3342489 + quidu "5C2A2EB5007A" + roleview_list (list RoleViews + (object RoleView "$UNNAMED$10" @104 + Parent_View @102 + location (79, 5) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EB50267" + client @102 + supplier @89 + vertices (list Points + (1103, 437) + (1746, 609)) + line_style 0) + (object RoleView "$UNNAMED$11" @105 + Parent_View @102 + location (79, 5) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EB5026B" + client @102 + supplier @93 + vertices (list Points + (1103, 437) + (460, 266)) + line_style 0))) + (object UseCaseView "Use Case View::ʵʱ˼" @106 + location (960, 688) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @106 + location (960, 826) + anchor_loc 1 + nlines 2 + max_width 630 + justify 0 + label "ʵʱ˼") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A2E390266" + height 118) + (object UseCaseView "Use Case View::ʵʱͼǨ" @107 + location (528, 1856) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @107 + location (528, 1994) + anchor_loc 1 + nlines 2 + max_width 630 + justify 0 + label "ʵʱͼǨ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A2E4C028F" + height 118) + (object AssociationViewNew "$UNNAMED$18" @108 + location (1327, 1485) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + stereotype (object SegLabel @109 + Parent_View @108 + location (1327, 1366) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + anchor 10 + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "<>" + pctDist 0.500000 + height 120 + orientation 0) + line_color 3342489 + quidu "5C2A2EBD017E" + roleview_list (list RoleViews + (object RoleView "$UNNAMED$19" @110 + Parent_View @108 + location (543, -35) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EBE0028" + client @108 + supplier @90 + vertices (list Points + (1327, 1485) + (2018, 1167)) + line_style 0) + (object RoleView "$UNNAMED$20" @111 + Parent_View @108 + location (543, -35) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EBE002C" + client @108 + supplier @107 + vertices (list Points + (1327, 1485) + (636, 1803)) + line_style 0))) + (object AssociationViewNew "$UNNAMED$21" @112 + location (1214, 1748) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + stereotype (object SegLabel @113 + Parent_View @112 + location (1214, 1629) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + anchor 10 + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "<>" + pctDist 0.500000 + height 120 + orientation 0) + line_color 3342489 + quidu "5C2A2EC00011" + roleview_list (list RoleViews + (object RoleView "$UNNAMED$22" @114 + Parent_View @112 + location (430, 228) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EC002D0" + client @112 + supplier @91 + vertices (list Points + (1214, 1748) + (1793, 1661)) + line_style 0) + (object RoleView "$UNNAMED$23" @115 + Parent_View @112 + location (430, 228) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EC002D3" + client @112 + supplier @107 + vertices (list Points + (1214, 1748) + (636, 1836)) + line_style 0))) + (object AssociationViewNew "$UNNAMED$24" @116 + location (1087, 1941) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + stereotype (object SegLabel @117 + Parent_View @116 + location (1087, 1822) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + anchor 10 + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "<>" + pctDist 0.500000 + height 120 + orientation 0) + line_color 3342489 + quidu "5C2A2EC202DB" + roleview_list (list RoleViews + (object RoleView "$UNNAMED$25" @118 + Parent_View @116 + location (303, 421) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EC301A0" + client @116 + supplier @92 + vertices (list Points + (1087, 1941) + (1538, 2012)) + line_style 0) + (object RoleView "$UNNAMED$26" @119 + Parent_View @116 + location (303, 421) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EC301A3" + client @116 + supplier @107 + vertices (list Points + (1087, 1941) + (636, 1870)) + line_style 0))) + (object UseCaseView "Use Case View::" @120 + location (2560, 736) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @120 + location (2560, 874) + anchor_loc 1 + nlines 2 + max_width 630 + justify 0 + label "") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2AF85700AB" + height 118) + (object UseCaseView "Use Case View::" @121 + location (1920, 880) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @121 + location (1920, 1018) + anchor_loc 1 + nlines 2 + max_width 630 + justify 0 + label "") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2AF8370057" + height 118) + (object AssociationViewNew "$UNNAMED$30" @122 + location (2239, 805) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + stereotype (object SegLabel @123 + Parent_View @122 + location (2239, 686) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + anchor 10 + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "<>" + pctDist 0.500000 + height 120 + orientation 0) + line_color 3342489 + quidu "5C2AF864004D" + roleview_list (list RoleViews + (object RoleView "$UNNAMED$31" @124 + Parent_View @122 + location (319, -75) + stereotype TRUE + line_color 3342489 + quidu "5C2AF8640355" + client @122 + supplier @120 + vertices (list Points + (2239, 805) + (2450, 758)) + line_style 0) + (object RoleView "$UNNAMED$32" @125 + Parent_View @122 + location (319, -75) + stereotype TRUE + line_color 3342489 + quidu "5C2AF8640359" + client @122 + supplier @121 + vertices (list Points + (2239, 805) + (2028, 853)) + line_style 0))) + (object ClassView "Class" "Use Case View::û" @126 + ShowCompartmentStereotypes TRUE + IncludeAttribute TRUE + IncludeOperation TRUE + location (128, 1120) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @126 + location (128, 1280) + anchor_loc 1 + nlines 2 + max_width 325 + justify 0 + label "û") + icon "Actor" + icon_style "Icon" + line_color 3342489 + quidu "5C2A2DE40377" + annotation 8 + autoResize TRUE) + (object AssociationViewNew "$UNNAMED$0" @127 + location (227, 720) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EAC0175" + roleview_list (list RoleViews + (object RoleView "$UNNAMED$1" @128 + Parent_View @127 + location (-125, 288) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EAC03D0" + client @127 + supplier @93 + vertices (list Points + (227, 720) + (308, 403)) + line_style 0) + (object RoleView "$UNNAMED$2" @129 + Parent_View @127 + location (-125, 288) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EAC03D3" + client @127 + supplier @126 + vertices (list Points + (227, 720) + (146, 1038)) + line_style 0))) + (object AssociationViewNew "$UNNAMED$12" @130 + location (504, 922) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EB70295" + roleview_list (list RoleViews + (object RoleView "$UNNAMED$13" @131 + Parent_View @130 + location (152, 490) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EB800B9" + client @130 + supplier @106 + vertices (list Points + (504, 922) + (823, 757)) + line_style 0) + (object RoleView "$UNNAMED$14" @132 + Parent_View @130 + location (152, 490) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EB800BD" + client @130 + supplier @126 + vertices (list Points + (504, 922) + (185, 1087)) + line_style 0))) + (object AssociationViewNew "$UNNAMED$15" @133 + location (335, 1505) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EBA0260" + roleview_list (list RoleViews + (object RoleView "$UNNAMED$16" @134 + Parent_View @133 + location (-17, 1073) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EBB00F1" + client @133 + supplier @107 + vertices (list Points + (335, 1505) + (493, 1797)) + line_style 0) + (object RoleView "$UNNAMED$17" @135 + Parent_View @133 + location (-17, 1073) + stereotype TRUE + line_color 3342489 + quidu "5C2A2EBB00F4" + client @133 + supplier @126 + vertices (list Points + (335, 1505) + (177, 1213)) + line_style 0))) + (object AssociationViewNew "$UNNAMED$27" @136 + location (997, 999) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + stereotype TRUE + line_color 3342489 + quidu "5C2AF849019D" + roleview_list (list RoleViews + (object RoleView "$UNNAMED$28" @137 + Parent_View @136 + location (645, 567) + stereotype TRUE + line_color 3342489 + quidu "5C2AF84C01FF" + client @136 + supplier @121 + vertices (list Points + (997, 999) + (1809, 891)) + line_style 0) + (object RoleView "$UNNAMED$29" @138 + Parent_View @136 + location (645, 567) + stereotype TRUE + line_color 3342489 + quidu "5C2AF84C0202" + client @136 + supplier @126 + vertices (list Points + (997, 999) + (185, 1108)) + line_style 0))) + (object UseCaseView "Use Case View::ʵʱʶ" @139 + location (368, 2320) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @139 + location (368, 2458) + anchor_loc 1 + nlines 2 + max_width 630 + justify 0 + label "ʵʱʶ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE0920237" + height 118) + (object AssociationViewNew "$UNNAMED$33" @140 + location (258, 1783) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + stereotype TRUE + line_color 3342489 + quidu "5C2DE0A402A7" + roleview_list (list RoleViews + (object RoleView "$UNNAMED$34" @141 + Parent_View @140 + location (130, 663) + stereotype TRUE + line_color 3342489 + quidu "5C2DE0A60237" + client @140 + supplier @139 + vertices (list Points + (258, 1783) + (353, 2262)) + line_style 0) + (object RoleView "$UNNAMED$35" @142 + Parent_View @140 + location (130, 663) + stereotype TRUE + line_color 3342489 + quidu "5C2DE0A60239" + client @140 + supplier @126 + vertices (list Points + (258, 1783) + (163, 1305)) + line_style 0))) + (object UseCaseView "Use Case View::ת" @143 + location (1536, 2448) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @143 + location (1536, 2586) + anchor_loc 1 + nlines 2 + max_width 630 + justify 0 + label "ת") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE0AB0207" + height 118) + (object AssociationViewNew "$UNNAMED$36" @144 + location (950, 2381) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + stereotype (object SegLabel @145 + Parent_View @144 + location (950, 2262) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + anchor 10 + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "<>" + pctDist 0.500000 + height 120 + orientation 0) + line_color 3342489 + quidu "5C2DE0BC0149" + roleview_list (list RoleViews + (object RoleView "$UNNAMED$37" @146 + Parent_View @144 + location (582, 61) + stereotype TRUE + line_color 3342489 + quidu "5C2DE0BC03CC" + client @144 + supplier @143 + vertices (list Points + (950, 2381) + (1424, 2433)) + line_style 0) + (object RoleView "$UNNAMED$38" @147 + Parent_View @144 + location (582, 61) + stereotype TRUE + line_color 3342489 + quidu "5C2DE0BC03CE" + client @144 + supplier @139 + vertices (list Points + (950, 2381) + (476, 2330)) + line_style 0))))) + (object InteractionDiagram "˳ͼ" + mechanism_ref @1 + quid "5C2B06B2026A" + title "˳ͼ" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 375 + items (list diagram_item_list + (object InterObjView "$UNNAMED$39" @148 + location (352, 464) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline TRUE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @148 + location (352, 489) + anchor_loc 1 + nlines 2 + max_width 360 + justify 0 + label "") + icon "Actor" + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B06C901A4" + width 120 + height 2142 + icon_height 162 + icon_width 120 + icon_y_offset 0 + annotation 1 + Focus_Of_Control (object Focus_Of_Control "" @149 + location (352, 544) + line_color 3342489 + InterObjView @148 + height 90 + y_coord 0 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @150 + location (352, 752) + line_color 3342489 + InterObjView @148 + height 836 + y_coord 746 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @151 + location (352, 1072) + line_color 3342489 + InterObjView @148 + height 1 + y_coord -89 + Nested TRUE) + Focus_Of_Control (object Focus_Of_Control "" @152 + location (352, 1488) + line_color 3342489 + InterObjView @148 + height 1 + y_coord -89 + Nested TRUE) + Focus_Of_Control (object Focus_Of_Control "" @153 + location (352, 1600) + line_color 3342489 + InterObjView @148 + height 404 + y_coord 314 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @154 + location (352, 1904) + line_color 3342489 + InterObjView @148 + height 1 + y_coord -89 + Nested TRUE) + Focus_Of_Control (object Focus_Of_Control "" @155 + location (352, 2112) + line_color 3342489 + InterObjView @148 + height 404 + y_coord 314 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @156 + location (352, 2416) + line_color 3342489 + InterObjView @148 + height 1 + y_coord -89 + Nested TRUE)) + (object InterObjView "TF Classify" @157 + location (1024, 480) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline TRUE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @157 + location (1024, 480) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 282 + justify 0 + label "TF Classify") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B06CE00D3" + width 300 + height 2126 + icon_height 0 + icon_width 0 + icon_y_offset 0 + annotation 1 + Focus_Of_Control (object Focus_Of_Control "" @158 + location (1024, 560) + line_color 3342489 + InterObjView @157 + height 90 + y_coord 0 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @159 + location (1024, 752) + line_color 3342489 + InterObjView @157 + height 315 + y_coord 225 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @160 + location (1024, 960) + line_color 3342489 + InterObjView @157 + height 1 + y_coord -89 + Nested TRUE)) + (object InterObjView "Google Inception" @161 + location (1712, 512) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline TRUE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @161 + location (1712, 512) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 282 + justify 0 + label "Google Inception") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B06E300CF" + width 300 + height 2094 + icon_height 0 + icon_width 0 + icon_y_offset 0 + annotation 1 + Focus_Of_Control (object Focus_Of_Control "" @162 + location (1712, 592) + line_color 3342489 + InterObjView @161 + height 90 + y_coord 0 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @163 + location (1712, 864) + line_color 3342489 + InterObjView @161 + height 98 + y_coord 8 + Nested FALSE)) + (object InterObjView "TF Detect" @164 + location (2192, 480) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline TRUE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @164 + location (2192, 480) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 282 + justify 0 + label "TF Detect") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B06F4020C" + width 300 + height 2126 + icon_height 0 + icon_width 0 + icon_y_offset 0 + annotation 1 + Focus_Of_Control (object Focus_Of_Control "" @165 + location (2192, 560) + line_color 3342489 + InterObjView @164 + height 90 + y_coord 0 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @166 + location (2192, 1600) + line_color 3342489 + InterObjView @164 + height 307 + y_coord 217 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @167 + location (2192, 1808) + line_color 3342489 + InterObjView @164 + height 1 + y_coord -89 + Nested TRUE)) + (object InterObjView "Tensorflow Object Detection" @168 + location (2592, 496) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline TRUE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @168 + location (2592, 496) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 358 + justify 0 + label "Tensorflow Object Detection") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B070403DE" + width 376 + height 2110 + icon_height 0 + icon_width 0 + icon_y_offset 0 + annotation 1 + Focus_Of_Control (object Focus_Of_Control "" @169 + location (2592, 576) + line_color 3342489 + InterObjView @168 + height 90 + y_coord 0 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @170 + location (2592, 1696) + line_color 3342489 + InterObjView @168 + height 201 + y_coord 111 + Nested FALSE)) + (object InterObjView "TF Stylize" @171 + location (2992, 480) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline TRUE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @171 + location (2992, 480) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 282 + justify 0 + label "TF Stylize") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B071000FE" + width 300 + height 2126 + icon_height 0 + icon_width 0 + icon_y_offset 0 + annotation 1 + Focus_Of_Control (object Focus_Of_Control "" @172 + location (2992, 560) + line_color 3342489 + InterObjView @171 + height 90 + y_coord 0 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @173 + location (2992, 2112) + line_color 3342489 + InterObjView @171 + height 307 + y_coord 217 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @174 + location (2992, 2320) + line_color 3342489 + InterObjView @171 + height 1 + y_coord -89 + Nested TRUE)) + (object InterObjView " Artistic + Style" @175 + location (3440, 480) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline TRUE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @175 + location (3440, 480) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 282 + justify 0 + label +| Artistic +| Style + ) + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B071C035E" + width 300 + height 2126 + icon_height 0 + icon_width 0 + icon_y_offset 0 + annotation 1 + Focus_Of_Control (object Focus_Of_Control "" @176 + location (3440, 560) + line_color 3342489 + InterObjView @175 + height 90 + y_coord 0 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @177 + location (3440, 2208) + line_color 3342489 + InterObjView @175 + height 201 + y_coord 111 + Nested FALSE)) + (object InterObjView "TF Speech" @178 + location (3808, 480) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline TRUE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @178 + location (3808, 480) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 282 + justify 0 + label "TF Speech") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE0F6010B" + width 300 + height 2126 + icon_height 0 + icon_width 0 + icon_y_offset 0 + annotation 1 + Focus_Of_Control (object Focus_Of_Control "" @179 + location (3808, 560) + line_color 3342489 + InterObjView @178 + height 90 + y_coord 0 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @180 + location (3808, 1168) + line_color 3342489 + InterObjView @178 + height 319 + y_coord 229 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @181 + location (3808, 1376) + line_color 3342489 + InterObjView @178 + height 1 + y_coord -89 + Nested TRUE)) + (object InterObjView " audio training" @182 + location (4176, 464) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline TRUE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @182 + location (4176, 464) + fill_color 13434879 + anchor_loc 1 + nlines 2 + max_width 282 + justify 0 + label " audio training") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE25C00E8" + width 300 + height 2142 + icon_height 0 + icon_width 0 + icon_y_offset 0 + annotation 1 + Focus_Of_Control (object Focus_Of_Control "" @183 + location (4176, 544) + line_color 3342489 + InterObjView @182 + height 90 + y_coord 0 + Nested FALSE) + Focus_Of_Control (object Focus_Of_Control "" @184 + location (4176, 1280) + line_color 3342489 + InterObjView @182 + height 102 + y_coord 12 + Nested FALSE)) + (object InterMessView "ʶ" @185 + location (16, 752) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @186 + Parent_View @185 + location (687, 708) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B07240050" + anchor_loc 1 + nlines 1 + max_width 274 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 0) + line_color 3342489 + client @148 + supplier @157 + Focus_Src @150 + Focus_Entry @159 + origin (367, 752) + terminus (1008, 752) + ordinal 0) + (object InterMessView " goole Inception" @187 + location (16, 857) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @188 + Parent_View @187 + location (1367, 813) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B07300380" + anchor_loc 1 + nlines 1 + max_width 381 + justify 0 + label " goole Inception" + pctDist 0.500000 + height 45 + orientation 0) + line_color 3342489 + client @157 + supplier @161 + Focus_Src @159 + Focus_Entry @163 + origin (1039, 857) + terminus (1696, 857) + ordinal 1) + (object InterMessView "ʶ" @189 + location (16, 962) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @190 + Parent_View @189 + location (1368, 918) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B073403E0" + anchor_loc 1 + nlines 1 + max_width 272 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 1) + line_color 3342489 + client @161 + supplier @157 + Focus_Src @163 + Focus_Entry @160 + origin (1696, 962) + terminus (1040, 962) + ordinal 2) + (object InterMessView "ʶ" @191 + location (16, 1067) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @192 + Parent_View @191 + location (688, 1023) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B07380168" + anchor_loc 1 + nlines 1 + max_width 316 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 1) + line_color 3342489 + client @157 + supplier @148 + Focus_Src @159 + Focus_Entry @151 + origin (1008, 1067) + terminus (368, 1067) + ordinal 3) + (object InterMessView "ʶ" @193 + location (16, 1592) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @194 + Parent_View @193 + location (1271, 1548) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B073E0260" + anchor_loc 1 + nlines 1 + max_width 210 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 0) + line_color 3342489 + client @148 + supplier @164 + Focus_Src @153 + Focus_Entry @166 + origin (367, 1592) + terminus (2176, 1592) + ordinal 8) + (object InterMessView "ʶ" @195 + location (16, 1697) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @196 + Parent_View @195 + location (2391, 1653) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B07420348" + anchor_loc 1 + nlines 1 + max_width 273 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 0) + line_color 3342489 + client @164 + supplier @168 + Focus_Src @166 + Focus_Entry @170 + origin (2207, 1697) + terminus (2576, 1697) + ordinal 9) + (object InterMessView "ʶ" @197 + location (16, 1802) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @198 + Parent_View @197 + location (2392, 1758) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B07460088" + anchor_loc 1 + nlines 1 + max_width 404 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 1) + line_color 3342489 + client @168 + supplier @164 + Focus_Src @170 + Focus_Entry @167 + origin (2576, 1802) + terminus (2208, 1802) + ordinal 10) + (object InterMessView "ʶ" @199 + location (16, 1907) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @200 + Parent_View @199 + location (1272, 1863) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B074C023F" + anchor_loc 1 + nlines 1 + max_width 404 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 1) + line_color 3342489 + client @164 + supplier @148 + Focus_Src @166 + Focus_Entry @154 + origin (2176, 1907) + terminus (368, 1907) + ordinal 11) + (object InterMessView "ͼ" @201 + location (16, 2104) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @202 + Parent_View @201 + location (1671, 2060) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B07560330" + anchor_loc 1 + nlines 1 + max_width 210 + justify 0 + label "ͼ" + pctDist 0.500000 + height 45 + orientation 0) + line_color 3342489 + client @148 + supplier @171 + Focus_Src @155 + Focus_Entry @173 + origin (367, 2104) + terminus (2976, 2104) + ordinal 12) + (object InterMessView "artisc style" @203 + location (16, 2209) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @204 + Parent_View @203 + location (3215, 2165) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B075C0048" + anchor_loc 1 + nlines 1 + max_width 289 + justify 0 + label "artisc style" + pctDist 0.500000 + height 45 + orientation 0) + line_color 3342489 + client @171 + supplier @175 + Focus_Src @173 + Focus_Entry @177 + origin (3007, 2209) + terminus (3424, 2209) + ordinal 13) + (object InterMessView "شͼƬ" @205 + location (16, 2314) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @206 + Parent_View @205 + location (3216, 2270) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B076000D7" + anchor_loc 1 + nlines 1 + max_width 448 + justify 0 + label "شͼƬ" + pctDist 0.500000 + height 45 + orientation 1) + line_color 3342489 + client @175 + supplier @171 + Focus_Src @177 + Focus_Entry @174 + origin (3424, 2314) + terminus (3008, 2314) + ordinal 14) + (object InterMessView "شͼƬ" @207 + location (16, 2419) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @208 + Parent_View @207 + location (1672, 2375) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B076600AF" + anchor_loc 1 + nlines 1 + max_width 360 + justify 0 + label "شͼƬ" + pctDist 0.500000 + height 45 + orientation 1) + line_color 3342489 + client @171 + supplier @148 + Focus_Src @173 + Focus_Entry @156 + origin (2976, 2419) + terminus (368, 2419) + ordinal 15) + (object InterMessView "ʶ" @209 + location (16, 1172) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @210 + Parent_View @209 + location (2079, 1128) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2DE1B4008B" + anchor_loc 1 + nlines 1 + max_width 185 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 0) + line_color 3342489 + client @148 + supplier @178 + Focus_Src @150 + Focus_Entry @180 + origin (367, 1172) + terminus (3792, 1172) + ordinal 4) + (object InterMessView "ƥ" @211 + location (16, 1487) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @212 + Parent_View @211 + location (2080, 1443) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2DE1C9027C" + anchor_loc 1 + nlines 1 + max_width 273 + justify 0 + label "ƥ" + pctDist 0.500000 + height 45 + orientation 1) + line_color 3342489 + client @178 + supplier @148 + Focus_Src @180 + Focus_Entry @152 + origin (3792, 1487) + terminus (368, 1487) + ordinal 7) + (object InterMessView "ѵ㷨" @213 + location (16, 1277) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @214 + Parent_View @213 + location (3991, 1233) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2DE26503C8" + anchor_loc 1 + nlines 1 + max_width 185 + justify 0 + label "ѵ㷨" + pctDist 0.500000 + height 45 + orientation 0) + line_color 3342489 + client @178 + supplier @182 + Focus_Src @180 + Focus_Entry @184 + origin (3823, 1277) + terminus (4160, 1277) + ordinal 5) + (object InterMessView "ƥ" @215 + location (16, 1382) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object SegLabel @216 + Parent_View @215 + location (3992, 1338) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2DE26B0184" + anchor_loc 1 + nlines 1 + max_width 273 + justify 0 + label "ƥ" + pctDist 0.500000 + height 45 + orientation 1) + line_color 3342489 + client @182 + supplier @178 + Focus_Src @184 + Focus_Entry @181 + origin (4160, 1382) + terminus (3824, 1382) + ordinal 6))) + (object ObjectDiagram "Эͼ" + mechanism_ref @1 + quid "5C2DE4020245" + title "Эͼ" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 0 + items (list diagram_item_list + (object ObjectView "$UNNAMED$39" @217 + location (112, 1072) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @217 + location (112, 1232) + anchor_loc 1 + nlines 2 + max_width 351 + justify 0 + label "") + icon "Actor" + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B06C901A4" + annotation 4 + autoResize TRUE + subobjects 0 + x_offset 0.000000 + y_offset 0.000000) + (object ObjectView "TF Classify" @218 + location (1440, 448) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @218 + location (1347, 397) + fill_color 13434879 + nlines 2 + max_width 186 + justify 0 + label "TF Classify") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B06CE00D3" + width 204 + height 126 + annotation 4 + autoResize TRUE + subobjects 0 + x_offset 0.000000 + y_offset 0.000000) + (object ObjectView "Google Inception" @219 + location (2672, 448) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @219 + location (2569, 397) + fill_color 13434879 + nlines 2 + max_width 206 + justify 0 + label "Google Inception") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B06E300CF" + width 224 + height 126 + annotation 4 + autoResize TRUE + subobjects 0 + x_offset 0.000000 + y_offset 0.000000) + (object ObjectView "TF Detect" @220 + location (1392, 1472) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @220 + location (1311, 1421) + fill_color 13434879 + nlines 2 + max_width 162 + justify 0 + label "TF Detect") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B06F4020C" + height 126 + annotation 4 + autoResize TRUE + subobjects 0 + x_offset 0.000000 + y_offset 0.000000) + (object ObjectView "Tensorflow Object Detection" @221 + location (2736, 1472) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @221 + location (2558, 1421) + fill_color 13434879 + nlines 2 + max_width 356 + justify 0 + label "Tensorflow Object Detection") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B070403DE" + width 374 + height 126 + annotation 4 + autoResize TRUE + subobjects 0 + x_offset 0.000000 + y_offset 0.000000) + (object ObjectView "TF Stylize" @222 + location (1392, 960) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @222 + location (1311, 909) + fill_color 13434879 + nlines 2 + max_width 162 + justify 0 + label "TF Stylize") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B071000FE" + height 126 + annotation 4 + autoResize TRUE + subobjects 0 + x_offset 0.000000 + y_offset 0.000000) + (object ObjectView " Artistic + Style" @223 + location (2752, 960) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @223 + location (2635, 909) + fill_color 13434879 + nlines 2 + max_width 234 + justify 0 + label +| Artistic +| Style + ) + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B071C035E" + width 252 + height 126 + annotation 4 + autoResize TRUE + subobjects 0 + x_offset 0.000000 + y_offset 0.000000) + (object ObjectView "TF Speech" @224 + location (1344, 1888) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @224 + location (1261, 1837) + fill_color 13434879 + nlines 2 + max_width 166 + justify 0 + label "TF Speech") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE0F6010B" + width 184 + height 126 + annotation 4 + autoResize TRUE + subobjects 0 + x_offset 0.000000 + y_offset 0.000000) + (object ObjectView " audio training" @225 + location (2752, 1888) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @225 + location (2668, 1837) + fill_color 13434879 + nlines 2 + max_width 168 + justify 0 + label " audio training") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2DE25C00E8" + width 186 + height 126 + annotation 4 + autoResize TRUE + subobjects 0 + x_offset 0.000000 + y_offset 0.000000) + (object LinkView "" @226 + stereotype TRUE + line_color 3342489 + quidu "5C2B0724004F" + client @217 + supplier @218 + vertices (list Points + (169, 1041) + (1337, 495)) + line_style 0) + (object MessView "" @227 + location (735, 728) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @228 + Parent_View @227 + location (718, 688) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B07240050" + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @226 + pctDist 0.500000 + height 45 + orientation 0 + dir 1 + origin (681, 752) + terminus (789, 704)) + (object MessView "" @229 + location (772, 809) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @230 + Parent_View @229 + location (792, 850) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B07380168" + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @226 + pctDist 0.500000 + height 45 + orientation 1 + dir -1 + origin (825, 784) + terminus (719, 834)) + (object LinkView "" @231 + stereotype TRUE + line_color 3342489 + quidu "5C2B073E025F" + client @217 + supplier @220 + vertices (list Points + (169, 1087) + (1301, 1442)) + line_style 0) + (object MessView "" @232 + location (748, 1222) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @233 + Parent_View @232 + location (762, 1180) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B073E0260" + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @231 + pctDist 0.500000 + height 45 + orientation 0 + dir 1 + origin (691, 1204) + terminus (805, 1240)) + (object MessView "" @234 + location (723, 1307) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @235 + Parent_View @234 + location (712, 1350) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B074C023F" + anchor_loc 1 + nlines 1 + max_width 463 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @231 + pctDist 0.500000 + height 45 + orientation 1 + dir -1 + origin (779, 1324) + terminus (667, 1290)) + (object LinkView "" @236 + stereotype TRUE + line_color 3342489 + quidu "5C2B0756032F" + client @217 + supplier @222 + vertices (list Points + (169, 1064) + (1301, 967)) + line_style 0) + (object MessView "" @237 + location (732, 972) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @238 + Parent_View @237 + location (730, 928) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B07560330" + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "ͼ" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @236 + pctDist 0.500000 + height 45 + orientation 0 + dir 1 + origin (672, 976) + terminus (792, 968)) + (object MessView "" @239 + location (739, 1061) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @240 + Parent_View @239 + location (743, 1106) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B076600AF" + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "شͼƬ" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @236 + pctDist 0.500000 + height 45 + orientation 1 + dir -1 + origin (798, 1056) + terminus (680, 1066)) + (object LinkView "" @241 + stereotype TRUE + line_color 3342489 + quidu "5C2DE1B4008A" + client @217 + supplier @224 + vertices (list Points + (169, 1108) + (1251, 1826)) + line_style 0) + (object MessView "" @242 + location (736, 1431) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @243 + Parent_View @242 + location (761, 1394) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2DE1B4008B" + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @241 + pctDist 0.500000 + height 45 + orientation 0 + dir 1 + origin (686, 1398) + terminus (786, 1464)) + (object MessView "" @244 + location (687, 1504) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @245 + Parent_View @244 + location (663, 1542) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2DE1C9027C" + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "ƥ" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @241 + pctDist 0.500000 + height 45 + orientation 1 + dir -1 + origin (736, 1536) + terminus (638, 1472)) + (object LinkView "" @246 + stereotype TRUE + line_color 3342489 + quidu "5C2B0730037F" + client @218 + supplier @219 + vertices (list Points + (1542, 448) + (2559, 448)) + line_style 0) + (object MessView "" @247 + location (2050, 404) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @248 + Parent_View @247 + location (2050, 360) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B07300380" + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label " goole Inception" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @246 + pctDist 0.500000 + height 45 + orientation 0 + dir 1 + origin (1990, 404) + terminus (2110, 404)) + (object MessView "" @249 + location (2050, 493) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @250 + Parent_View @249 + location (2050, 538) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B073403E0" + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @246 + pctDist 0.500000 + height 45 + orientation 1 + dir -1 + origin (2109, 493) + terminus (1991, 493)) + (object LinkView "" @251 + stereotype TRUE + line_color 3342489 + quidu "5C2B07420347" + client @220 + supplier @221 + vertices (list Points + (1482, 1472) + (2548, 1472)) + line_style 0) + (object MessView "" @252 + location (2015, 1428) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @253 + Parent_View @252 + location (2015, 1384) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B07420348" + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @251 + pctDist 0.500000 + height 45 + orientation 0 + dir 1 + origin (1955, 1428) + terminus (2075, 1428)) + (object MessView "" @254 + location (2015, 1517) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @255 + Parent_View @254 + location (2015, 1562) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B07460088" + anchor_loc 1 + nlines 1 + max_width 463 + justify 0 + label "ʶ" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @251 + pctDist 0.500000 + height 45 + orientation 1 + dir -1 + origin (2074, 1517) + terminus (1956, 1517)) + (object LinkView "" @256 + stereotype TRUE + line_color 3342489 + quidu "5C2B075C0047" + client @222 + supplier @223 + vertices (list Points + (1482, 960) + (2625, 960)) + line_style 0) + (object MessView "" @257 + location (2053, 916) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @258 + Parent_View @257 + location (2053, 872) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B075C0048" + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "artisc style" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @256 + pctDist 0.500000 + height 45 + orientation 0 + dir 1 + origin (1993, 916) + terminus (2113, 916)) + (object MessView "" @259 + location (2053, 1005) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @260 + Parent_View @259 + location (2053, 1050) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2B076000D7" + anchor_loc 1 + nlines 1 + max_width 507 + justify 0 + label "شͼƬ" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @256 + pctDist 0.500000 + height 45 + orientation 1 + dir -1 + origin (2112, 1005) + terminus (1994, 1005)) + (object LinkView "" @261 + stereotype TRUE + line_color 3342489 + quidu "5C2DE26503C7" + client @224 + supplier @225 + vertices (list Points + (1436, 1888) + (2658, 1888)) + line_style 0) + (object MessView "" @262 + location (2047, 1844) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @263 + Parent_View @262 + location (2047, 1800) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2DE26503C8" + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "ѵ㷨" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @261 + pctDist 0.500000 + height 45 + orientation 0 + dir 1 + origin (1987, 1844) + terminus (2107, 1844)) + (object MessView "" @264 + location (2047, 1933) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + label (object SegLabel @265 + Parent_View @264 + location (2047, 1978) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + quidu "5C2DE26B0184" + anchor_loc 1 + nlines 1 + max_width 450 + justify 0 + label "ƥ" + pctDist 0.500000 + height 45 + orientation 0) + object_arc @261 + pctDist 0.500000 + height 45 + orientation 1 + dir -1 + origin (2106, 1933) + terminus (1988, 1933)))))) + root_category (object Class_Category "Logical View" + quid "39C9260C00D5" + exportControl "Public" + global TRUE + subsystem "Component View" + quidu "39C9260C00D7" + logical_models (list unit_reference_list + (object Class_Category "User Services" + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "User Services")) + quid "5C2AF3C60209" + documentation "User services provide the visual interface for presenting information and gathering data in an application. The user services connect the user with the application and request the business and/or data services needed by the user to execute business tasks." + visible_categories (list visibility_relationship_list + (object Visibility_Relationship + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "Business Services")) + quid "5C2AF3C6020C" + supplier "Logical View::Business Services" + quidu "5C2AF3C6020A") + (object Visibility_Relationship + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "Data Services")) + quid "5C2AF3C6020D" + supplier "Logical View::Data Services" + quidu "5C2AF3C6020B") + (object Visibility_Relationship + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "Business Services")) + quid "5C2DE04E02D5" + supplier "Logical View::Business Services" + quidu "5C2AF3C6020A") + (object Visibility_Relationship + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "Data Services")) + quid "5C2DE04E02D6" + supplier "Logical View::Data Services" + quidu "5C2AF3C6020B")) + exportControl "Public" + logical_models (list unit_reference_list) + logical_presentations (list unit_reference_list)) + (object Class_Category "Business Services" + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "Business Services")) + quid "5C2AF3C6020A" + documentation "Business services respond to requests from the user (or other business services) in order to execute a business task. They accomplish this by requesting the data services needed and applying formal procedures and business rules to the relevant data. This protocol insulates the user from direct interaction with the database. Because business rules tend to change more frequently than the specific business tasks they support, they are ideal candidates for encapsulating in components that are physically separate from the application logic itself." + visible_categories (list visibility_relationship_list + (object Visibility_Relationship + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "User Services")) + quid "5C2AF3C6020E" + supplier "Logical View::User Services" + quidu "5C2AF3C60209") + (object Visibility_Relationship + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "Data Services")) + quid "5C2AF3C6020F" + supplier "Logical View::Data Services" + quidu "5C2AF3C6020B") + (object Visibility_Relationship + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "User Services")) + quid "5C2DE04E02D7" + supplier "Logical View::User Services" + quidu "5C2AF3C60209") + (object Visibility_Relationship + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "Data Services")) + quid "5C2DE04E02D8" + supplier "Logical View::Data Services" + quidu "5C2AF3C6020B")) + exportControl "Public" + logical_models (list unit_reference_list) + logical_presentations (list unit_reference_list)) + (object Class_Category "Data Services" + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "Data Services")) + quid "5C2AF3C6020B" + documentation "Data services maintain, access, and update data. They also manage and satisfy requests to manipulate data that are initiated by business services. Separating data services allows the data structure and access mechanisms to be maintained, modified, or, if necessary, even re-architected without affecting business or user services." + visible_categories (list visibility_relationship_list + (object Visibility_Relationship + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "User Services")) + quid "5C2AF3C60210" + supplier "Logical View::User Services" + quidu "5C2AF3C60209") + (object Visibility_Relationship + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "Data Services")) + quid "5C2AF3C60211" + supplier "Logical View::Business Services" + quidu "5C2AF3C6020A") + (object Visibility_Relationship + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "User Services")) + quid "5C2DE04E02D9" + supplier "Logical View::User Services" + quidu "5C2AF3C60209") + (object Visibility_Relationship + attributes (list Attribute_Set + (object Attribute + tool "VisualBasic" + name "TierPackage" + value "Data Services")) + quid "5C2DE04E02DA" + supplier "Logical View::Business Services" + quidu "5C2AF3C6020A")) + exportControl "Public" + logical_models (list unit_reference_list) + logical_presentations (list unit_reference_list)) + (object Class_Category "javax" + is_unit TRUE + is_loaded FALSE + file_name "$FRAMEWORK_PATH\\Shared Components\\j2ee_javax.cat" + quid "39C926610018") + (object Class_Category "java" + is_unit TRUE + is_loaded FALSE + file_name "$FRAMEWORK_PATH\\Shared Components\\j2se_1_3_java.cat" + quid "39C92661003B") + (object Class_Category "org" + is_unit TRUE + is_loaded FALSE + file_name "$FRAMEWORK_PATH\\Shared Components\\j2se_1_3_org.cat" + quid "39C92693036F")) + logical_presentations (list unit_reference_list + (object ClassDiagram "Main" + quid "5C2DE04E0081" + title "Main" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 0 + items (list diagram_item_list)) + (object Tier_Diagram "Three-Tiered Service Model" + quid "5C2AF3C60212" + title "Three-Tiered Service Model" + documentation "A three-tiered architectural approach separates the various components of a client/server system into three tiers of services. The user services, business and other middle tier services, and data services are the logical tiers that collaborate in an application" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 0 + items (list diagram_item_list + (object TierView "User Services" @266 + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @266 + location (6, 6) + hidden TRUE + nlines 2 + max_width 288 + justify 0 + label "User Services") + icon_style "Icon" + hidden TRUE + quidu "5C2AF3C60209" + width 300 + height 180) + (object TierView "Business Services" @267 + location (600, 0) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @267 + location (606, 6) + hidden TRUE + nlines 2 + max_width 288 + justify 0 + label "Business Services") + icon_style "Icon" + hidden TRUE + quidu "5C2AF3C6020A" + width 300 + height 180) + (object TierView "Data Services" @268 + location (1200, 0) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @268 + location (1206, 6) + hidden TRUE + nlines 2 + max_width 288 + justify 0 + label "Data Services") + icon_style "Icon" + hidden TRUE + quidu "5C2AF3C6020B" + width 300 + height 180))) + (object ClassDiagram "Package Hierarchy" + quid "39C9261001B8" + title "Package Hierarchy" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 0 + items (list diagram_item_list + (object CategoryView "Logical View::java" @269 + location (208, 272) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @269 + location (64, 188) + nlines 2 + max_width 288 + justify 0 + label "java") + icon_style "Icon" + line_color 3342489 + fill_color 16777215 + quidu "39C92661003B" + width 300 + height 180) + (object CategoryView "Logical View::javax" @270 + location (656, 272) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @270 + location (512, 188) + nlines 2 + max_width 288 + justify 0 + label "javax") + icon_style "Icon" + line_color 3342489 + fill_color 16777215 + quidu "39C926610018" + width 300 + height 180) + (object CategoryView "Logical View::org" @271 + location (1104, 272) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @271 + location (960, 188) + nlines 2 + max_width 288 + justify 0 + label "org") + icon_style "Icon" + line_color 3342489 + fill_color 16777215 + quidu "39C92693036F" + width 300 + height 180))) + (object ClassDiagram "Legend" + quid "39CD51840059" + title "Legend" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 0 + items (list diagram_item_list + (object NoteView @272 + location (224, 624) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + fill_color 12632256 + width 300 + height 132) + (object NoteView @273 + location (704, 624) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + fill_color 8421631 + width 300 + height 132) + (object NoteView @274 + location (1200, 624) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + fill_color 12615680 + width 300 + height 132) + (object NoteView @275 + location (1664, 624) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + line_color 3342489 + fill_color 16777215 + width 300 + height 132) + (object Label @276 + location (81, 369) + font (object Font + size 12 + face "Arial" + bold TRUE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + nlines 1 + max_width 1163 + justify 1 + label "J2EE: Java 2 Platform, Enterprise Edition - v 1.2.1") + (object Label @277 + location (96, 608) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + nlines 1 + max_width 268 + justify 1 + label "Abstract Class") + (object Label @278 + location (592, 608) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + nlines 1 + max_width 225 + justify 1 + label "Final Class") + (object Label @279 + location (1104, 608) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + nlines 1 + max_width 206 + justify 1 + label "Interface") + (object Label @280 + location (1552, 608) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + nlines 1 + max_width 144 + justify 1 + label "Class"))))) + root_subsystem (object SubSystem "Component View" + quid "39C9260C00D7" + physical_models (list unit_reference_list + (object module "NewPackageSpec2" "PackageType" "Specification" + quid "5C2A38470190" + stereotype "Package Specification" + language "") + (object module "ʵʱ" "NotAModuleType" "NotAModulePart" + quid "5C2A384E03D7" + stereotype "" + visible_modules (list dependency_list + (object Module_Visibility_Relationship + quid "5C2A393002A3" + supplier "Component View::Bitmap" + quidu "5C2A391D01A1" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2A396D0229" + supplier "Component View::Canvas" + quidu "5C2A39690130" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2B10CC00F1" + supplier "Component View::Google Inception" + quidu "5C2B10C80338" + supplier_is_spec TRUE)) + language "") + (object module "ʵʱ" "NotAModuleType" "NotAModulePart" + quid "5C2A38860257" + stereotype "" + visible_modules (list dependency_list + (object Module_Visibility_Relationship + quid "5C2A399F033A" + supplier "Component View::Bitmap" + quidu "5C2A391D01A1" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2A39A900B2" + supplier "Component View::Canvas" + quidu "5C2A39690130" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2B10E30331" + supplier "Component View::Tensorflow Object Detection" + quidu "5C2B10DD03A5" + supplier_is_spec TRUE)) + language "") + (object module "ʵʱͼ" "NotAModuleType" "NotAModulePart" + quid "5C2A388800E0" + stereotype "" + visible_modules (list dependency_list + (object Module_Visibility_Relationship + quid "5C2A39A20203" + supplier "Component View::Canvas" + quidu "5C2A39690130" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2A39AE008B" + supplier "Component View::Bitmap" + quidu "5C2A391D01A1" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2B10F40249" + supplier +|Component View::Artistic +| Style + + quidu "5C2B10F0028E" + supplier_is_spec TRUE)) + language "") + (object module "ʵʱʶ" "NotAModuleType" "NotAModulePart" + quid "5C2A388A004C" + stereotype "" + visible_modules (list dependency_list + (object Module_Visibility_Relationship + quid "5C2A39F7006A" + supplier "Component View::" + quidu "5C2A39D10267" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2B110D03B2" + supplier "Component View::audio_recognition" + quidu "5C2B11090107" + supplier_is_spec TRUE)) + language "") + (object module "Bitmap" "NotAModuleType" "NotAModulePart" + quid "5C2A391D01A1" + stereotype "" + language "") + (object module "NewComponent" "NotAModuleType" "NotAModulePart" + quid "5C2A395900E2" + stereotype "" + language "") + (object module "Canvas" "NotAModuleType" "NotAModulePart" + quid "5C2A39690130" + stereotype "" + language "") + (object module "" "NotAModuleType" "NotAModulePart" + quid "5C2A39D10267" + stereotype "" + language "") + (object module "" "NotAModuleType" "NotAModulePart" + quid "5C2B109101B1" + stereotype "" + visible_modules (list dependency_list + (object Module_Visibility_Relationship + quid "5C2B109D02BB" + supplier "Component View::ʵʱ" + quidu "5C2A384E03D7" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2B10A000A2" + supplier "Component View::ʵʱ" + quidu "5C2A38860257" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2B10A202A2" + supplier "Component View::ʵʱͼ" + quidu "5C2A388800E0" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2B10A501A2" + supplier "Component View::ʵʱʶ" + quidu "5C2A388A004C" + supplier_is_spec TRUE)) + language "") + (object module "Google Inception" "NotAModuleType" "NotAModulePart" + quid "5C2B10C80338" + stereotype "" + language "") + (object module "Tensorflow Object Detection" "NotAModuleType" "NotAModulePart" + quid "5C2B10DD03A5" + stereotype "" + language "") + (object module "Artistic + Style" "NotAModuleType" "NotAModulePart" + quid "5C2B10F0028E" + stereotype "" + language "") + (object module "audio_recognition" "NotAModuleType" "NotAModulePart" + quid "5C2B11090107" + stereotype "" + language "") + (object SubSystem "javax" + is_unit TRUE + is_loaded FALSE + file_name "$FRAMEWORK_PATH\\Shared Components\\j2ee_javax.sub" + quid "39C9266003D8") + (object SubSystem "java" + is_unit TRUE + is_loaded FALSE + file_name "$FRAMEWORK_PATH\\Shared Components\\j2se_1_3_java.sub" + quid "39C92661002C") + (object SubSystem "org" + is_unit TRUE + is_loaded FALSE + file_name "$FRAMEWORK_PATH\\Shared Components\\j2se_1_3_org.sub" + quid "39C9268C01C9") + (object SubSystem "android" + quid "5C2A2AF60162" + physical_models (list unit_reference_list + (object SubSystem "util" + quid "5C2A2AF60164" + physical_models (list unit_reference_list + (object module "Log" "NotAModuleType" "NotAModulePart" + quid "5C2A2AF60167" + stereotype "" + language "Java")) + physical_presentations (list unit_reference_list)) + (object SubSystem "os" + quid "5C2A2AF601BF" + physical_models (list unit_reference_list + (object module "SystemClock" "NotAModuleType" "NotAModulePart" + quid "5C2A2AF601C1" + stereotype "" + language "Java")) + physical_presentations (list unit_reference_list))) + physical_presentations (list unit_reference_list))) + physical_presentations (list unit_reference_list + (object Module_Diagram "Main" + quid "39C9261001B6" + title "Main" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 0 + items (list diagram_item_list)) + (object Module_Diagram " ͼ" + quid "5C2A378C00BE" + title " ͼ" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 128 + items (list diagram_item_list + (object ModView "Component View::ʵʱ" "NotAModuleType" "NotAModulePart" @281 + location (464, 176) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @281 + location (408, 151) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 208 + justify 1 + label "ʵʱ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A384E03D7" + width 374 + autoResize TRUE + width 374 + height 162) + (object ModView "Component View::ʵʱ" "NotAModuleType" "NotAModulePart" @282 + location (864, 1200) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @282 + location (805, 1175) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 221 + justify 1 + label "ʵʱ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A38860257" + width 398 + autoResize TRUE + width 398 + height 162) + (object ModView "Component View::ʵʱͼ" "NotAModuleType" "NotAModulePart" @283 + location (1120, 1840) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @283 + location (1050, 1815) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 262 + justify 1 + label "ʵʱͼ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A388800E0" + width 472 + autoResize TRUE + width 472 + height 162) + (object ModView "Component View::ʵʱʶ" "NotAModuleType" "NotAModulePart" @284 + location (1104, 2560) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @284 + location (1046, 2535) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 217 + justify 1 + label "ʵʱʶ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A388A004C" + width 390 + autoResize TRUE + width 390 + height 162) + (object ModView "Component View::Bitmap" "NotAModuleType" "NotAModulePart" @285 + location (2384, 944) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @285 + location (2339, 919) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 166 + justify 1 + label "Bitmap") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A391D01A1" + width 298 + autoResize TRUE + width 298 + height 162) + (object ModVisView "" @286 + stereotype TRUE + line_color 3342489 + quidu "5C2A393002A3" + client @281 + supplier @285 + vertices (list Points + (644, 246) + (2236, 884)) + line_style 0) + (object ModView "Component View::Canvas" "NotAModuleType" "NotAModulePart" @287 + location (2544, 1696) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @287 + location (2498, 1671) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 171 + justify 1 + label "Canvas") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A39690130" + width 308 + autoResize TRUE + width 308 + height 162) + (object ModVisView "" @288 + stereotype TRUE + line_color 3342489 + quidu "5C2A396D0229" + client @281 + supplier @287 + vertices (list Points + (568, 254) + (2435, 1616)) + line_style 0) + (object ModVisView "" @289 + stereotype TRUE + line_color 3342489 + quidu "5C2A399F033A" + client @282 + supplier @285 + vertices (list Points + (1056, 1165) + (2236, 966)) + line_style 0) + (object ModVisView "" @290 + stereotype TRUE + line_color 3342489 + quidu "5C2A39A20203" + client @283 + supplier @287 + vertices (list Points + (1347, 1814) + (2391, 1708)) + line_style 0) + (object ModVisView "" @291 + stereotype TRUE + line_color 3342489 + quidu "5C2A39A900B2" + client @282 + supplier @287 + vertices (list Points + (1056, 1256) + (2390, 1648)) + line_style 0) + (object ModVisView "" @292 + stereotype TRUE + line_color 3342489 + quidu "5C2A39AE008B" + client @283 + supplier @285 + vertices (list Points + (1228, 1758) + (2266, 1022)) + line_style 0) + (object ModView "Component View::" "NotAModuleType" "NotAModulePart" @293 + location (2592, 2192) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @293 + location (2543, 2167) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 181 + justify 1 + label "") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A39D10267" + width 326 + autoResize TRUE + width 326 + height 162) + (object ModVisView "" @294 + stereotype TRUE + line_color 3342489 + quidu "5C2A39F7006A" + client @284 + supplier @293 + vertices (list Points + (1292, 2510) + (2431, 2227)) + line_style 0) + (object ModView "Component View::" "NotAModuleType" "NotAModulePart" @295 + location (224, 1616) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @295 + location (177, 1591) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 174 + justify 1 + label "") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B109101B1" + width 314 + autoResize TRUE + width 314 + height 162) + (object ModVisView "" @296 + stereotype TRUE + line_color 3342489 + quidu "5C2B109D02BB" + client @295 + supplier @281 + vertices (list Points + (234, 1536) + (448, 254)) + line_style 0) + (object ModVisView "" @297 + stereotype TRUE + line_color 3342489 + quidu "5C2B10A000A2" + client @295 + supplier @282 + vertices (list Points + (341, 1536) + (735, 1278)) + line_style 0) + (object ModVisView "" @298 + stereotype TRUE + line_color 3342489 + quidu "5C2B10A202A2" + client @295 + supplier @283 + vertices (list Points + (376, 1651) + (890, 1781)) + line_style 0) + (object ModVisView "" @299 + stereotype TRUE + line_color 3342489 + quidu "5C2B10A501A2" + client @295 + supplier @284 + vertices (list Points + (297, 1694) + (1025, 2480)) + line_style 0) + (object ModView "Component View::Google Inception" "NotAModuleType" "NotAModulePart" @300 + location (2048, 448) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @300 + location (2001, 423) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 174 + justify 1 + label "Google Inception") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B10C80338" + width 314 + autoResize TRUE + width 314 + height 162) + (object ModVisView "" @301 + stereotype TRUE + line_color 3342489 + quidu "5C2B10CC00F1" + client @281 + supplier @300 + vertices (list Points + (644, 204) + (1894, 419)) + line_style 0) + (object ModView "Component View::Tensorflow Object Detection" "NotAModuleType" "NotAModulePart" @302 + location (2400, 1344) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @302 + location (2317, 1319) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 313 + justify 1 + label "Tensorflow Object Detection") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B10DD03A5" + width 564 + autoResize TRUE + width 564 + height 162) + (object ModVisView "" @303 + stereotype TRUE + line_color 3342489 + quidu "5C2B10E30331" + client @282 + supplier @302 + vertices (list Points + (1056, 1215) + (2126, 1317)) + line_style 0) + (object ModView "Component View::Artistic + Style" "NotAModuleType" "NotAModulePart" @304 + location (2576, 1920) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @304 + location (2529, 1895) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 174 + justify 1 + label +|Artistic +| Style + ) + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B10F0028E" + width 314 + autoResize TRUE + width 314 + height 162) + (object ModVisView "" @305 + stereotype TRUE + line_color 3342489 + quidu "5C2B10F40249" + client @283 + supplier @304 + vertices (list Points + (1347, 1850) + (2420, 1907)) + line_style 0) + (object ModView "Component View::audio_recognition" "NotAModuleType" "NotAModulePart" @306 + location (2192, 2816) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @306 + location (2145, 2791) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 174 + justify 1 + label "audio_recognition") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B11090107" + width 314 + autoResize TRUE + width 314 + height 162) + (object ModVisView "" @307 + stereotype TRUE + line_color 3342489 + quidu "5C2B110D03B2" + client @284 + supplier @306 + vertices (list Points + (1292, 2603) + (2036, 2777)) + line_style 0) + (object ModView "Component View::ʵʱ" "NotAModuleType" "NotAModulePart" @308 + location (848, 800) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @308 + location (792, 775) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 208 + justify 1 + label "ʵʱ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A384E03D7" + width 374 + autoResize TRUE + width 374 + height 162) + (object ModView "Component View::ʵʱ" "NotAModuleType" "NotAModulePart" @309 + location (864, 1200) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @309 + location (805, 1175) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 221 + justify 1 + label "ʵʱ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A38860257" + width 398 + autoResize TRUE + width 398 + height 162) + (object ModView "Component View::ʵʱͼ" "NotAModuleType" "NotAModulePart" @310 + location (992, 1488) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @310 + location (922, 1463) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 262 + justify 1 + label "ʵʱͼ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A388800E0" + width 472 + autoResize TRUE + width 472 + height 162) + (object ModView "Component View::ʵʱʶ" "NotAModuleType" "NotAModulePart" @311 + location (1216, 2176) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @311 + location (1158, 2151) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 217 + justify 1 + label "ʵʱʶ") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A388A004C" + width 390 + autoResize TRUE + width 390 + height 162) + (object ModView "Component View::Bitmap" "NotAModuleType" "NotAModulePart" @312 + location (2384, 944) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @312 + location (2339, 919) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 166 + justify 1 + label "Bitmap") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A391D01A1" + width 298 + autoResize TRUE + width 298 + height 162) + (object ModView "Component View::Canvas" "NotAModuleType" "NotAModulePart" @313 + location (2544, 1696) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @313 + location (2498, 1671) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 171 + justify 1 + label "Canvas") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A39690130" + width 308 + autoResize TRUE + width 308 + height 162) + (object ModView "Component View::" "NotAModuleType" "NotAModulePart" @314 + location (2592, 2192) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @314 + location (2543, 2167) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 181 + justify 1 + label "") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2A39D10267" + width 326 + autoResize TRUE + width 326 + height 162) + (object ModView "Component View::" "NotAModuleType" "NotAModulePart" @315 + location (224, 1616) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @315 + location (177, 1591) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 174 + justify 1 + label "") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B109101B1" + width 314 + autoResize TRUE + width 314 + height 162) + (object ModView "Component View::Google Inception" "NotAModuleType" "NotAModulePart" @316 + location (2048, 448) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @316 + location (2001, 423) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 174 + justify 1 + label "Google Inception") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B10C80338" + width 314 + autoResize TRUE + width 314 + height 162) + (object ModView "Component View::Tensorflow Object Detection" "NotAModuleType" "NotAModulePart" @317 + location (2400, 1344) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @317 + location (2317, 1319) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 313 + justify 1 + label "Tensorflow Object Detection") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B10DD03A5" + width 564 + autoResize TRUE + width 564 + height 162) + (object ModView "Component View::Artistic + Style" "NotAModuleType" "NotAModulePart" @318 + location (2576, 1920) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @318 + location (2529, 1895) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 174 + justify 1 + label +|Artistic +| Style + ) + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B10F0028E" + width 314 + autoResize TRUE + width 314 + height 162) + (object ModView "Component View::audio_recognition" "NotAModuleType" "NotAModulePart" @319 + location (2656, 2560) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @319 + location (2609, 2535) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 174 + justify 1 + label "audio_recognition") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2B11090107" + width 314 + autoResize TRUE + width 314 + height 162) + (object ModVisView "" @320 + stereotype TRUE + line_color 3342489 + quidu "5C2A393002A3" + client @308 + supplier @312 + vertices (list Points + (1028, 814) + (2235, 928)) + line_style 0) + (object ModVisView "" @321 + stereotype TRUE + line_color 3342489 + quidu "5C2A399F033A" + client @309 + supplier @312 + vertices (list Points + (1056, 1165) + (2236, 966)) + line_style 0) + (object ModVisView "" @322 + stereotype TRUE + line_color 3342489 + quidu "5C2A39AE008B" + client @310 + supplier @312 + vertices (list Points + (1188, 1408) + (2237, 999)) + line_style 0) + (object ModVisView "" @323 + stereotype TRUE + line_color 3342489 + quidu "5C2A396D0229" + client @308 + supplier @313 + vertices (list Points + (995, 878) + (2390, 1614)) + line_style 0) + (object ModVisView "" @324 + stereotype TRUE + line_color 3342489 + quidu "5C2A39A20203" + client @310 + supplier @313 + vertices (list Points + (1219, 1516) + (2393, 1673)) + line_style 0) + (object ModVisView "" @325 + stereotype TRUE + line_color 3342489 + quidu "5C2A39A900B2" + client @309 + supplier @313 + vertices (list Points + (1056, 1256) + (2390, 1648)) + line_style 0) + (object ModVisView "" @326 + stereotype TRUE + line_color 3342489 + quidu "5C2A39F7006A" + client @311 + supplier @314 + vertices (list Points + (1404, 2177) + (2431, 2188)) + line_style 0) + (object ModVisView "" @327 + stereotype TRUE + line_color 3342489 + quidu "5C2B109D02BB" + client @315 + supplier @308 + vertices (list Points + (280, 1536) + (784, 878)) + line_style 0) + (object ModVisView "" @328 + stereotype TRUE + line_color 3342489 + quidu "5C2B10A000A2" + client @315 + supplier @309 + vertices (list Points + (341, 1536) + (735, 1278)) + line_style 0) + (object ModVisView "" @329 + stereotype TRUE + line_color 3342489 + quidu "5C2B10A202A2" + client @315 + supplier @310 + vertices (list Points + (376, 1587) + (758, 1523)) + line_style 0) + (object ModVisView "" @330 + stereotype TRUE + line_color 3342489 + quidu "5C2B10A501A2" + client @315 + supplier @311 + vertices (list Points + (366, 1694) + (1072, 2096)) + line_style 0) + (object ModVisView "" @331 + stereotype TRUE + line_color 3342489 + quidu "5C2B10CC00F1" + client @308 + supplier @316 + vertices (list Points + (1028, 743) + (1892, 489)) + line_style 0) + (object ModVisView "" @332 + stereotype TRUE + line_color 3342489 + quidu "5C2B10E30331" + client @309 + supplier @317 + vertices (list Points + (1056, 1215) + (2126, 1317)) + line_style 0) + (object ModVisView "" @333 + stereotype TRUE + line_color 3342489 + quidu "5C2B10F40249" + client @310 + supplier @318 + vertices (list Points + (1219, 1548) + (2422, 1876)) + line_style 0) + (object ModVisView "" @334 + stereotype TRUE + line_color 3342489 + quidu "5C2B110D03B2" + client @311 + supplier @319 + vertices (list Points + (1404, 2225) + (2500, 2518)) + line_style 0)))) + category "Logical View" + quidu "5C2A257B02A0") + process_structure (object Processes + quid "39C9260C00D8" + ProcsNDevs (list + (object Processor "andriod tensorflow" + quid "5C2A3A3401CE" + connections (list connection_list + (object Connection_Relationship + quid "5C2A3A750272" + supplier "media ¼" + quidu "5C2A3A5902C0" + supplier_is_device FALSE) + (object Connection_Relationship + quid "5C2A3A87001B" + supplier "ʾ" + quidu "5C2A3A7D0169" + supplier_is_device FALSE)) + characteristics "" + scheduling "Preemptive" + processes (list processes)) + (object Processor "ͷ" + quid "5C2A3A500129" + connections (list connection_list + (object Connection_Relationship + quid "5C2CE89300B9" + supplier "andriodֻ" + quidu "5C2A3A1702DE" + supplier_is_device TRUE) + (object Connection_Relationship + quid "5C2CE89601AB" + supplier "andriodֻ" + quidu "5C2A3A1702DE" + supplier_is_device TRUE)) + characteristics "" + scheduling "Preemptive" + processes (list processes)) + (object Processor "media ¼" + quid "5C2A3A5902C0" + characteristics "" + scheduling "Preemptive" + processes (list processes)) + (object Processor "ʾ" + quid "5C2A3A7D0169" + characteristics "" + scheduling "Preemptive" + processes (list processes)) + (object Processor "Ƶ" + quid "5C2CE85903A5" + characteristics "" + scheduling "Preemptive" + processes (list processes)) + (object Device "andriodֻ" + quid "5C2A3A1702DE" + connections (list connection_list + (object Connection_Relationship + quid "5C2A3A7202C9" + supplier "ͷ" + quidu "5C2A3A500129" + supplier_is_device FALSE) + (object Connection_Relationship + quid "5C2CE89D02F2" + supplier "ͷ" + quidu "5C2A3A500129" + supplier_is_device FALSE)) + characteristics "") + (object Process_Diagram "Deployment View" + quid "39C9260C00DA" + title "Deployment View" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 0 + items (list diagram_item_list + (object ProcessorView "andriod tensorflow" @335 + location (1104, 1264) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @335 + location (899, 1133) + nlines 2 + max_width 338 + justify 0 + label "andriod tensorflow") + icon_style "Icon" + line_color 3342489 + quidu "5C2A3A3401CE" + width 413 + height 331 + annotation 0) + (object ProcessorView "media ¼" @336 + location (1760, 1600) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @336 + location (1555, 1469) + nlines 2 + max_width 338 + justify 0 + label "media ¼") + icon_style "Icon" + line_color 3342489 + quidu "5C2A3A5902C0" + width 413 + height 332 + annotation 0) + (object ConnectionView "" @337 + stereotype TRUE + line_color 3342489 + quidu "5C2A3A750272" + client @335 + supplier @336 + vertices (list Points + (1279, 1264) + (1554, 1600)) + line_style 0) + (object ProcessorView "ʾ" @338 + location (624, 1744) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @338 + location (513, 1689) + nlines 2 + max_width 150 + justify 0 + label "ʾ") + icon_style "Icon" + line_color 3342489 + quidu "5C2A3A7D0169" + width 225 + height 180 + annotation 0) + (object ConnectionView "" @339 + stereotype TRUE + line_color 3342489 + quidu "5C2A3A87001B" + client @335 + supplier @338 + vertices (list Points + (1104, 1429) + (624, 1669)) + line_style 0) + (object ProcessorView "Ƶ" @340 + location (1376, 880) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @340 + location (1265, 825) + nlines 2 + max_width 150 + justify 0 + label "Ƶ") + icon_style "Icon" + line_color 3342489 + quidu "5C2CE85903A5" + width 225 + height 180 + annotation 0) + (object DeviceView "andriodֻ" @341 + location (1312, 1232) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @341 + location (261, 423) + nlines 2 + max_width 2031 + justify 0 + label "andriodֻ") + icon_style "Icon" + line_color 3342489 + quidu "5C2A3A1702DE" + width 2106 + height 1687 + annotation 0) + (object ProcessorView "ͷ" @342 + location (608, 752) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @342 + location (497, 697) + nlines 2 + max_width 150 + justify 0 + label "ͷ") + icon_style "Icon" + line_color 3342489 + quidu "5C2A3A500129" + width 225 + height 180 + annotation 0) + (object ConnectionView "" @343 + stereotype TRUE + line_color 3342489 + quidu "5C2A3A7202C9" + client @341 + supplier @342 + vertices (list Points + (255, 752) + (490, 752)) + line_style 0) + (object ConnectionView "" @344 + stereotype TRUE + line_color 3342489 + quidu "5C2CE89300B9" + client @342 + supplier @341 + vertices (list Points + (490, 752) + (255, 752)) + line_style 0) + (object ConnectionView "" @345 + stereotype TRUE + line_color 3342489 + quidu "5C2CE89601AB" + client @342 + supplier @341 + vertices (list Points + (490, 752) + (255, 752)) + line_style 0) + (object ConnectionView "" @346 + stereotype TRUE + line_color 3342489 + quidu "5C2CE89D02F2" + client @341 + supplier @342 + vertices (list Points + (255, 752) + (490, 752)) + line_style 0))))) + properties (object Properties + attributes (list Attribute_Set + (object Attribute + tool "CORBA" + name "propertyId" + value "809135966") + (object Attribute + tool "CORBA" + name "default__Project" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "CreateMissingDirectories" + value TRUE) + (object Attribute + tool "CORBA" + name "Editor" + value ("EditorType" 100)) + (object Attribute + tool "CORBA" + name "IncludePath" + value "") + (object Attribute + tool "CORBA" + name "StopOnError" + value TRUE) + (object Attribute + tool "CORBA" + name "EditorType" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "BuiltIn" + value 100) + (object Attribute + tool "CORBA" + name "WindowsShell" + value 101))) + (object Attribute + tool "CORBA" + name "FundamentalTypes" + value "short; long; long long; unsigned short; unsigned long; unsigned long long; float; double; long double; char; boolean; wchar; octet; any;string; wstring; sequence; fixed; Object") + (object Attribute + tool "CORBA" + name "PathSeparator" + value "") + (object Attribute + tool "CORBA" + name "GenerateRoseID" + value TRUE) + (object Attribute + tool "CORBA" + name "NotShowRoseIDDlg" + value FALSE) + (object Attribute + tool "CORBA" + name "GenerateComments" + value TRUE) + (object Attribute + tool "CORBA" + name "UseTabs" + value FALSE) + (object Attribute + tool "CORBA" + name "UseSpaces" + value TRUE) + (object Attribute + tool "CORBA" + name "SpacingItems" + value 4) + (object Attribute + tool "CORBA" + name "BraceOnNewLine" + value FALSE))) + (object Attribute + tool "CORBA" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "ArrayDimensions" + value "") + (object Attribute + tool "CORBA" + name "ConstValue" + value "") + (object Attribute + tool "CORBA" + name "ImplementationType" + value "") + (object Attribute + tool "CORBA" + name "IsLocal" + value FALSE))) + (object Attribute + tool "CORBA" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "AdditionalIncludes" + value (value Text "")) + (object Attribute + tool "CORBA" + name "CmIdentification" + value (value Text " %X% %Q% %Z% %W%")) + (object Attribute + tool "CORBA" + name "CopyrightNotice" + value (value Text "")) + (object Attribute + tool "CORBA" + name "InclusionProtectionSymbol" + value "AUTO GENERATE"))) + (object Attribute + tool "CORBA" + name "default__Module-Body" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "AdditionalIncludes" + value (value Text "")) + (object Attribute + tool "CORBA" + name "CmIdentification" + value (value Text " %X% %Q% %Z% %W%")) + (object Attribute + tool "CORBA" + name "CopyrightNotice" + value (value Text "")) + (object Attribute + tool "CORBA" + name "InclusionProtectionSymbol" + value "AUTO GENERATE"))) + (object Attribute + tool "CORBA" + name "default__Operation" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "Context" + value "") + (object Attribute + tool "CORBA" + name "OperationIsOneWay" + value FALSE))) + (object Attribute + tool "CORBA" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "ArrayDimensions" + value "") + (object Attribute + tool "CORBA" + name "CaseSpecifier" + value "") + (object Attribute + tool "CORBA" + name "IsReadOnly" + value FALSE) + (object Attribute + tool "CORBA" + name "Order" + value ""))) + (object Attribute + tool "CORBA" + name "default__Role" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "ArrayDimensions" + value "") + (object Attribute + tool "CORBA" + name "CaseSpecifier" + value "") + (object Attribute + tool "CORBA" + name "GenerateForwardReference" + value FALSE) + (object Attribute + tool "CORBA" + name "IsReadOnly" + value FALSE) + (object Attribute + tool "CORBA" + name "Order" + value "") + (object Attribute + tool "CORBA" + name "BoundedRoleType" + value ("AssocTypeSet" 47)) + (object Attribute + tool "CORBA" + name "AssocTypeSet" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "Array" + value 24) + (object Attribute + tool "CORBA" + name "Sequence" + value 47))))) + (object Attribute + tool "CORBA" + name "default__Uses" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "GenerateForwardReference" + value FALSE))) + (object Attribute + tool "CORBA" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Data Modeler" + name "propertyId" + value "809135966") + (object Attribute + tool "Data Modeler" + name "default__Project" + value (list Attribute_Set + (object Attribute + tool "Data Modeler" + name "project" + value "") + (object Attribute + tool "Data Modeler" + name "TableCounter" + value 0) + (object Attribute + tool "Data Modeler" + name "DomainCounter" + value 0) + (object Attribute + tool "Data Modeler" + name "SPPackageCounter" + value 0) + (object Attribute + tool "Data Modeler" + name "TriggerCounter" + value 0) + (object Attribute + tool "Data Modeler" + name "IndexCounter" + value 0) + (object Attribute + tool "Data Modeler" + name "ConstraintCounter" + value 0) + (object Attribute + tool "Data Modeler" + name "StoreProcedureCounter" + value 0) + (object Attribute + tool "Data Modeler" + name "PrimaryKeyCounter" + value 0) + (object Attribute + tool "Data Modeler" + name "ForeignKeyCounter" + value 0) + (object Attribute + tool "Data Modeler" + name "TablePrefix" + value "") + (object Attribute + tool "Data Modeler" + name "DomainPrefix" + value "") + (object Attribute + tool "Data Modeler" + name "TriggerPrefix" + value "") + (object Attribute + tool "Data Modeler" + name "IndexPrefix" + value "") + (object Attribute + tool "Data Modeler" + name "ConstraintPrefix" + value "") + (object Attribute + tool "Data Modeler" + name "StoreProcedurePrefix" + value "") + (object Attribute + tool "Data Modeler" + name "PrimaryKeyPrefix" + value "") + (object Attribute + tool "Data Modeler" + name "ForeignKeyPrefix" + value "") + (object Attribute + tool "Data Modeler" + name "ViewCounter" + value 0) + (object Attribute + tool "Data Modeler" + name "JoinCounter" + value 0) + (object Attribute + tool "Data Modeler" + name "TableSpaceCounter" + value 0) + (object Attribute + tool "Data Modeler" + name "cONTAINERCounter" + value 0) + (object Attribute + tool "Data Modeler" + name "ViewPrefix" + value "") + (object Attribute + tool "Data Modeler" + name "TableSpacePrefix" + value ""))) + (object Attribute + tool "Data Modeler" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "Data Modeler" + name "dmItem" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DMName" + value "") + (object Attribute + tool "Data Modeler" + name "IsDatabase" + value FALSE) + (object Attribute + tool "Data Modeler" + name "TargetDatabase" + value "") + (object Attribute + tool "Data Modeler" + name "Location" + value "") + (object Attribute + tool "Data Modeler" + name "IsTableSpace" + value FALSE) + (object Attribute + tool "Data Modeler" + name "TableSpaceType" + value "") + (object Attribute + tool "Data Modeler" + name "IsDeault" + value FALSE) + (object Attribute + tool "Data Modeler" + name "BufferPool" + value "") + (object Attribute + tool "Data Modeler" + name "ExtentSize" + value 1) + (object Attribute + tool "Data Modeler" + name "PrefetchSize" + value 1) + (object Attribute + tool "Data Modeler" + name "PageSize" + value 4) + (object Attribute + tool "Data Modeler" + name "ManagedBy" + value "") + (object Attribute + tool "Data Modeler" + name "ContainerList" + value ""))) + (object Attribute + tool "Data Modeler" + name "default__Category" + value (list Attribute_Set + (object Attribute + tool "Data Modeler" + name "dmItem" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DMName" + value "") + (object Attribute + tool "Data Modeler" + name "dmSchema" + value "") + (object Attribute + tool "Data Modeler" + name "dmDomainPackage" + value "") + (object Attribute + tool "Data Modeler" + name "IsSchema" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsDomainPackage" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsRootSchema" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsRootDomainPackage" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsSchemaPackage" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DatabaseID" + value "") + (object Attribute + tool "Data Modeler" + name "DBMS" + value ""))) + (object Attribute + tool "Data Modeler" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "Data Modeler" + name "dmItem" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DMName" + value "") + (object Attribute + tool "Data Modeler" + name "IsTable" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsView" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsDomain" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsSPPackage" + value FALSE) + (object Attribute + tool "Data Modeler" + name "Synonymns" + value "") + (object Attribute + tool "Data Modeler" + name "TableSpace" + value "") + (object Attribute + tool "Data Modeler" + name "SourceId" + value "") + (object Attribute + tool "Data Modeler" + name "SourceType" + value "") + (object Attribute + tool "Data Modeler" + name "SelectClause" + value "") + (object Attribute + tool "Data Modeler" + name "IsUpdatable" + value FALSE) + (object Attribute + tool "Data Modeler" + name "CheckOption" + value 0) + (object Attribute + tool "Data Modeler" + name "PersistToServer" + value "") + (object Attribute + tool "Data Modeler" + name "TableSpaceID" + value "") + (object Attribute + tool "Data Modeler" + name "CorrelationName" + value "") + (object Attribute + tool "Data Modeler" + name "IsUpdateable" + value TRUE) + (object Attribute + tool "Data Modeler" + name "IsSnapShot" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsDistinct" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsPackage" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsPackageWrapped" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsPackageBodyWrapped" + value FALSE))) + (object Attribute + tool "Data Modeler" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "Data Modeler" + name "dmItem" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DMName" + value "") + (object Attribute + tool "Data Modeler" + name "Ordinal" + value 0) + (object Attribute + tool "Data Modeler" + name "IsIdentity" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsUnique" + value FALSE) + (object Attribute + tool "Data Modeler" + name "NullsAllowed" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DataTypeName" + value "") + (object Attribute + tool "Data Modeler" + name "Length" + value 0) + (object Attribute + tool "Data Modeler" + name "Scale" + value 0) + (object Attribute + tool "Data Modeler" + name "ColumnType" + value "Native") + (object Attribute + tool "Data Modeler" + name "ForBitData" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DefaultValueType" + value "") + (object Attribute + tool "Data Modeler" + name "DefaultValue" + value "") + (object Attribute + tool "Data Modeler" + name "SourceId" + value "") + (object Attribute + tool "Data Modeler" + name "SourceType" + value "") + (object Attribute + tool "Data Modeler" + name "OID" + value FALSE))) + (object Attribute + tool "Data Modeler" + name "default__Association" + value (list Attribute_Set + (object Attribute + tool "Data Modeler" + name "dmItem" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DMName" + value "") + (object Attribute + tool "Data Modeler" + name "IsRelationship" + value FALSE) + (object Attribute + tool "Data Modeler" + name "SourceId" + value "") + (object Attribute + tool "Data Modeler" + name "SourceType" + value "") + (object Attribute + tool "Data Modeler" + name "RIMethod" + value "") + (object Attribute + tool "Data Modeler" + name "ParentUpdateRule" + value "") + (object Attribute + tool "Data Modeler" + name "ParentUpdateRuleName" + value "") + (object Attribute + tool "Data Modeler" + name "ParentDeleteRule" + value "") + (object Attribute + tool "Data Modeler" + name "ParentDeleteRuleName" + value "") + (object Attribute + tool "Data Modeler" + name "ChildInsertRestrict" + value FALSE) + (object Attribute + tool "Data Modeler" + name "ChildInsertRestrictName" + value "") + (object Attribute + tool "Data Modeler" + name "ChildMultiplicity" + value FALSE) + (object Attribute + tool "Data Modeler" + name "ChildMultiplicityName" + value ""))) + (object Attribute + tool "Data Modeler" + name "default__Role" + value (list Attribute_Set + (object Attribute + tool "Data Modeler" + name "dmItem" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DMName" + value "") + (object Attribute + tool "Data Modeler" + name "ConstraintName" + value ""))) + (object Attribute + tool "Data Modeler" + name "default__Operation" + value (list Attribute_Set + (object Attribute + tool "Data Modeler" + name "dmItem" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DMName" + value "") + (object Attribute + tool "Data Modeler" + name "IsConstraint" + value FALSE) + (object Attribute + tool "Data Modeler" + name "ConstraintType" + value "") + (object Attribute + tool "Data Modeler" + name "IsIndex" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsTrigger" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsStoredProcedure" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsCluster" + value FALSE) + (object Attribute + tool "Data Modeler" + name "TableSpace" + value "") + (object Attribute + tool "Data Modeler" + name "FillFactor" + value 0) + (object Attribute + tool "Data Modeler" + name "KeyList" + value "") + (object Attribute + tool "Data Modeler" + name "CheckPredicate" + value "") + (object Attribute + tool "Data Modeler" + name "IsUnique" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DeferalMode" + value "") + (object Attribute + tool "Data Modeler" + name "InitialCheckTime" + value "") + (object Attribute + tool "Data Modeler" + name "TriggerType" + value "") + (object Attribute + tool "Data Modeler" + name "IsInsertEvent" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsUpdateEvent" + value FALSE) + (object Attribute + tool "Data Modeler" + name "IsDeleteEvent" + value FALSE) + (object Attribute + tool "Data Modeler" + name "RefOldTable" + value "") + (object Attribute + tool "Data Modeler" + name "RefNewTable" + value "") + (object Attribute + tool "Data Modeler" + name "RefOldRow" + value "") + (object Attribute + tool "Data Modeler" + name "RefNewRow" + value "") + (object Attribute + tool "Data Modeler" + name "IsRow" + value FALSE) + (object Attribute + tool "Data Modeler" + name "WhenClause" + value "") + (object Attribute + tool "Data Modeler" + name "Language" + value "SQL") + (object Attribute + tool "Data Modeler" + name "ProcType" + value "Procedure") + (object Attribute + tool "Data Modeler" + name "IsDeterministic" + value FALSE) + (object Attribute + tool "Data Modeler" + name "ParameterStyle" + value "") + (object Attribute + tool "Data Modeler" + name "ReturnedNull" + value FALSE) + (object Attribute + tool "Data Modeler" + name "ExternalName" + value "") + (object Attribute + tool "Data Modeler" + name "ReturnTypeName" + value "") + (object Attribute + tool "Data Modeler" + name "Length" + value "") + (object Attribute + tool "Data Modeler" + name "Scale" + value "") + (object Attribute + tool "Data Modeler" + name "ForBitData" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DefaultValue" + value "") + (object Attribute + tool "Data Modeler" + name "DefaultValueType" + value "") + (object Attribute + tool "Data Modeler" + name "IsWrapped" + value FALSE))) + (object Attribute + tool "Data Modeler" + name "default__Parameter" + value (list Attribute_Set + (object Attribute + tool "Data Modeler" + name "dmItem" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DMName" + value "") + (object Attribute + tool "Data Modeler" + name "IsInParameter" + value TRUE) + (object Attribute + tool "Data Modeler" + name "IsOutParameter" + value FALSE) + (object Attribute + tool "Data Modeler" + name "Ordinal" + value "") + (object Attribute + tool "Data Modeler" + name "DataTypeName" + value "") + (object Attribute + tool "Data Modeler" + name "Length" + value "") + (object Attribute + tool "Data Modeler" + name "Scale" + value "") + (object Attribute + tool "Data Modeler" + name "ForBitData" + value FALSE) + (object Attribute + tool "Data Modeler" + name "DefaultValueType" + value "") + (object Attribute + tool "Data Modeler" + name "DefaultValue" + value "") + (object Attribute + tool "Data Modeler" + name "OperationID" + value ""))) + (object Attribute + tool "Data Modeler" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Data Modeler Communicator" + name "HiddenTool" + value FALSE) + (object Attribute + tool "framework" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Java" + name "propertyId" + value "809135966") + (object Attribute + tool "Java" + name "default__Project" + value (list Attribute_Set + (object Attribute + tool "Java" + name "RootDir" + value "") + (object Attribute + tool "Java" + name "CreateMissingDirectories" + value TRUE) + (object Attribute + tool "Java" + name "StopOnError" + value FALSE) + (object Attribute + tool "Java" + name "UsePrefixes" + value FALSE) + (object Attribute + tool "Java" + name "AutoSync" + value FALSE) + (object Attribute + tool "Java" + name "ShowCodegenDlg" + value FALSE) + (object Attribute + tool "Java" + name "JavadocDefaultAuthor" + value "") + (object Attribute + tool "Java" + name "JavadocDefaultVersion" + value "") + (object Attribute + tool "Java" + name "JavadocDefaultSince" + value "") + (object Attribute + tool "Java" + name "JavadocNumAsterisks" + value 0) + (object Attribute + tool "Java" + name "MaxNumChars" + value 80) + (object Attribute + tool "Java" + name "Editor" + value ("EditorType" 100)) + (object Attribute + tool "Java" + name "VM" + value ("VMType" 200)) + (object Attribute + tool "Java" + name "ClassPath" + value "C:\\Program Files\\Java\\jdk1.8.0_91\\lib\\dt.jar;C:\\Program Files\\Java\\jdk1.8.0_91\\lib\\tools.jar;C:\\a1\\src\\test\\java\\com;C:\\a1\\src\\test\\java") + (object Attribute + tool "Java" + name "EditorType" + value (list Attribute_Set + (object Attribute + tool "Java" + name "BuiltIn" + value 100) + (object Attribute + tool "Java" + name "WindowsShell" + value 101))) + (object Attribute + tool "Java" + name "VMType" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Sun" + value 200) + (object Attribute + tool "Java" + name "Microsoft" + value 201) + (object Attribute + tool "Java" + name "IBM" + value 202))) + (object Attribute + tool "Java" + name "InstanceVariablePrefix" + value "m_") + (object Attribute + tool "Java" + name "ClassVariablePrefix" + value "s_") + (object Attribute + tool "Java" + name "DefaultAttributeDataType" + value "int") + (object Attribute + tool "Java" + name "DefaultOperationReturnType" + value "void") + (object Attribute + tool "Java" + name "NoClassCustomDlg" + value FALSE) + (object Attribute + tool "Java" + name "GlobalImports" + value (value Text "")) + (object Attribute + tool "Java" + name "OpenBraceClassStyle" + value TRUE) + (object Attribute + tool "Java" + name "OpenBraceMethodStyle" + value TRUE) + (object Attribute + tool "Java" + name "UseTabs" + value FALSE) + (object Attribute + tool "Java" + name "UseSpaces" + value TRUE) + (object Attribute + tool "Java" + name "SpacingItems" + value 3) + (object Attribute + tool "Java" + name "RoseDefaultCommentStyle" + value TRUE) + (object Attribute + tool "Java" + name "AsteriskCommentStyle" + value FALSE) + (object Attribute + tool "Java" + name "JavaCommentStyle" + value FALSE) + (object Attribute + tool "Java" + name "JavadocAuthor" + value FALSE) + (object Attribute + tool "Java" + name "JavadocSince" + value FALSE) + (object Attribute + tool "Java" + name "JavadocVersion" + value FALSE) + (object Attribute + tool "Java" + name "FundamentalType" + value "boolean; char; byte; short; int; long; float; double; Boolean; Byte; Character; Double; Float; Integer; Long; Object; Short; String; StringBuffer; Void; java.math.BigDecimal; java.math.BigInteger; java.sql.Date; java.sql.Time; java.sql.Timestamp; java.util.AbstractCollection; java.util.AbstractList;java.util.AbstractMap; java.util.AbstractSequentialList; java.util.AbstractSet; java.util.ArrayList; java.util.Arrays; java.util.BitSet; java.util.Calendar; java.util.Collections; java.util.Date; java.util.Date; java.util.Dictionary; java.util.EventObject; java.util.GregorianCalendar; java.util.HashMap; java.util.HashSet; java.util.Hashtable; java.util.LinkedList; java.util.ListResourceBundle; java.util.Locale; java.util.Observable; java.util.Properties; java.util.PropertyPermission; java.util.PropertyResourceBundle; java.util.Random; java.util.ResourceBundle; java.util.SimpleTimeZone; java.util.Stack; java.util.StringTokenizer; java.util.Timer; java.util.TimerTask; java.util.TimeZone; java.util.TreeMap; java.util.TreeSet; java.util.Vector; java.util.WeakHashMap") + (object Attribute + tool "Java" + name "NotShowRoseIDDlg" + value FALSE) + (object Attribute + tool "Java" + name "GenerateRoseID" + value TRUE) + (object Attribute + tool "Java" + name "GenerateDefaultJ2EEJavadoc" + value TRUE) + (object Attribute + tool "Java" + name "GenerateDefaultReturnLine" + value TRUE) + (object Attribute + tool "Java" + name "UserDefineJavaDocTags" + value "") + (object Attribute + tool "Java" + name "ReferenceClasspath" + value "") + (object Attribute + tool "Java" + name "VAJavaWorkingFolder" + value "") + (object Attribute + tool "Java" + name "JavadocExceptionTag" + value "@throws") + (object Attribute + tool "Java" + name "BeanPrefix" + value "") + (object Attribute + tool "Java" + name "BeanSuffix" + value "") + (object Attribute + tool "Java" + name "RemotePrefix" + value "") + (object Attribute + tool "Java" + name "RemoteSuffix" + value "") + (object Attribute + tool "Java" + name "HomePrefix" + value "") + (object Attribute + tool "Java" + name "HomeSuffix" + value "") + (object Attribute + tool "Java" + name "LocalPrefix" + value "") + (object Attribute + tool "Java" + name "LocalSuffix" + value "") + (object Attribute + tool "Java" + name "LocalHomePrefix" + value "") + (object Attribute + tool "Java" + name "LocalHomeSuffix" + value "") + (object Attribute + tool "Java" + name "PrimaryKeyPrefix" + value "") + (object Attribute + tool "Java" + name "PrimaryKeySuffix" + value "") + (object Attribute + tool "Java" + name "EJBDTDLocation" + value "") + (object Attribute + tool "Java" + name "ServletDTDLocation" + value "") + (object Attribute + tool "Java" + name "DefaultEJBVersion" + value "") + (object Attribute + tool "Java" + name "DefaultServletVersion" + value "") + (object Attribute + tool "Java" + name "SourceControl" + value FALSE) + (object Attribute + tool "Java" + name "SCCSelected" + value FALSE) + (object Attribute + tool "Java" + name "SCCProjectSourceRoot" + value "") + (object Attribute + tool "Java" + name "SCCProjectName" + value "") + (object Attribute + tool "Java" + name "SCCComment" + value FALSE))) + (object Attribute + tool "Java" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Final" + value FALSE) + (object Attribute + tool "Java" + name "Static" + value FALSE) + (object Attribute + tool "Java" + name "GenerateDefaultConstructor" + value TRUE) + (object Attribute + tool "Java" + name "ConstructorIs" + value ("Ctor_Set" 62)) + (object Attribute + tool "Java" + name "Ctor_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "public" + value 62) + (object Attribute + tool "Java" + name "protected" + value 63) + (object Attribute + tool "Java" + name "private" + value 64) + (object Attribute + tool "Java" + name "package" + value 65))) + (object Attribute + tool "Java" + name "GenerateFinalizer" + value FALSE) + (object Attribute + tool "Java" + name "GenerateStaticInitializer" + value FALSE) + (object Attribute + tool "Java" + name "GenerateInstanceInitializer" + value FALSE) + (object Attribute + tool "Java" + name "GenerateCode" + value TRUE) + (object Attribute + tool "Java" + name "DisableAutoSync" + value FALSE) + (object Attribute + tool "Java" + name "ReadOnly" + value FALSE) + (object Attribute + tool "Java" + name "Strictfp" + value FALSE) + (object Attribute + tool "Java" + name "ServletXMLFilePath" + value "") + (object Attribute + tool "Java" + name "EJBSessionSync" + value FALSE) + (object Attribute + tool "Java" + name "EJBVersion" + value ("EJBVersion_Set" 230)) + (object Attribute + tool "Java" + name "EJBVersion_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "2.0" + value 230) + (object Attribute + tool "Java" + name "1.x" + value 231))) + (object Attribute + tool "Java" + name "EJBXMLFilePath" + value ""))) + (object Attribute + tool "Java" + name "Default_Servlet__Class" + value (list Attribute_Set + (object Attribute + tool "Java" + name "ServletName" + value "") + (object Attribute + tool "Java" + name "ServletContextRef" + value FALSE) + (object Attribute + tool "Java" + name "IsSingleThread" + value FALSE) + (object Attribute + tool "Java" + name "ServletInitParameter" + value "") + (object Attribute + tool "Java" + name "ServletInitParameterNames" + value FALSE) + (object Attribute + tool "Java" + name "ServletIsSecure" + value FALSE) + (object Attribute + tool "Java" + name "ServletRequestDispatcher" + value FALSE) + (object Attribute + tool "Java" + name "ServletRequestDispatcherPath" + value "") + (object Attribute + tool "Java" + name "DispatcherInclude" + value FALSE) + (object Attribute + tool "Java" + name "DispatcherForward" + value FALSE) + (object Attribute + tool "Java" + name "ServletSecurityRoles" + value "") + (object Attribute + tool "Java" + name "ServletgetInfo" + value "") + (object Attribute + tool "Java" + name "ReadOnly" + value FALSE) + (object Attribute + tool "Java" + name "Strictfp" + value FALSE) + (object Attribute + tool "Java" + name "ServletXMLFilePath" + value "") + (object Attribute + tool "Java" + name "EJBSessionSync" + value FALSE) + (object Attribute + tool "Java" + name "EJBVersion" + value ("EJBVersion_Set" 230)) + (object Attribute + tool "Java" + name "EJBVersion_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "2.0" + value 230) + (object Attribute + tool "Java" + name "1.x" + value 231))) + (object Attribute + tool "Java" + name "EJBXMLFilePath" + value ""))) + (object Attribute + tool "Java" + name "Http_Servlet__Class" + value (list Attribute_Set + (object Attribute + tool "Java" + name "ServletRequestAttribute" + value "") + (object Attribute + tool "Java" + name "ServletRequestAttributesNames" + value FALSE) + (object Attribute + tool "Java" + name "MethodForRequestAttributes" + value "") + (object Attribute + tool "Java" + name "ServletRequestParameter" + value "") + (object Attribute + tool "Java" + name "ServletRequestParameterNames" + value FALSE) + (object Attribute + tool "Java" + name "MethodForRequestParameters" + value "") + (object Attribute + tool "Java" + name "ServletHeader" + value "") + (object Attribute + tool "Java" + name "ServletHeaderNames" + value FALSE) + (object Attribute + tool "Java" + name "MethodForHeaders" + value "") + (object Attribute + tool "Java" + name "ServletIntHeader" + value FALSE) + (object Attribute + tool "Java" + name "ServletDateHeader" + value FALSE) + (object Attribute + tool "Java" + name "ServletCookie" + value FALSE) + (object Attribute + tool "Java" + name "MethodForCookie" + value "") + (object Attribute + tool "Java" + name "ServletContentType" + value "") + (object Attribute + tool "Java" + name "GenerateHTML" + value FALSE) + (object Attribute + tool "Java" + name "ReadOnly" + value FALSE) + (object Attribute + tool "Java" + name "Strictfp" + value FALSE) + (object Attribute + tool "Java" + name "ServletXMLFilePath" + value "") + (object Attribute + tool "Java" + name "EJBSessionSync" + value FALSE) + (object Attribute + tool "Java" + name "EJBVersion" + value ("EJBVersion_Set" 230)) + (object Attribute + tool "Java" + name "EJBVersion_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "2.0" + value 230) + (object Attribute + tool "Java" + name "1.x" + value 231))) + (object Attribute + tool "Java" + name "EJBXMLFilePath" + value ""))) + (object Attribute + tool "Java" + name "Default_EJB__Class" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Generate_XML_DD" + value TRUE) + (object Attribute + tool "Java" + name "EJBCmpField" + value "") + (object Attribute + tool "Java" + name "EJBEnvironmentProperties" + value "") + (object Attribute + tool "Java" + name "EJBCnxFactory" + value "") + (object Attribute + tool "Java" + name "EJBReferences" + value "") + (object Attribute + tool "Java" + name "EJBSecurityRoles" + value "") + (object Attribute + tool "Java" + name "EJBNameInJAR" + value "") + (object Attribute + tool "Java" + name "EJBSessionType" + value ("EJBSessionType_Set" 200)) + (object Attribute + tool "Java" + name "EJBSessionType_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "" + value 200) + (object Attribute + tool "Java" + name "Stateless" + value 201) + (object Attribute + tool "Java" + name "Stateful" + value 202))) + (object Attribute + tool "Java" + name "EJBTransactionType" + value ("EJBTransactionType_Set" 211)) + (object Attribute + tool "Java" + name "EJBTransactionType_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Container" + value 211) + (object Attribute + tool "Java" + name "Bean" + value 212))) + (object Attribute + tool "Java" + name "EJBPersistenceType" + value ("EJBPersistenceType_Set" 220)) + (object Attribute + tool "Java" + name "EJBPersistenceType_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "" + value 220) + (object Attribute + tool "Java" + name "Bean" + value 221) + (object Attribute + tool "Java" + name "Container" + value 222))) + (object Attribute + tool "Java" + name "EJBReentrant" + value FALSE) + (object Attribute + tool "Java" + name "BMP_Extend_CMP" + value FALSE) + (object Attribute + tool "Java" + name "ReadOnly" + value FALSE) + (object Attribute + tool "Java" + name "Strictfp" + value FALSE) + (object Attribute + tool "Java" + name "ServletXMLFilePath" + value "") + (object Attribute + tool "Java" + name "EJBSessionSync" + value FALSE) + (object Attribute + tool "Java" + name "EJBVersion" + value ("EJBVersion_Set" 230)) + (object Attribute + tool "Java" + name "EJBVersion_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "2.0" + value 230) + (object Attribute + tool "Java" + name "1.x" + value 231))) + (object Attribute + tool "Java" + name "EJBXMLFilePath" + value ""))) + (object Attribute + tool "Java" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "Java" + name "CmIdentification" + value (value Text "")) + (object Attribute + tool "Java" + name "CopyrightNotice" + value (value Text "")))) + (object Attribute + tool "Java" + name "default__Module-Body" + value (list Attribute_Set + (object Attribute + tool "Java" + name "CmIdentification" + value (value Text "")) + (object Attribute + tool "Java" + name "CopyrightNotice" + value (value Text "")))) + (object Attribute + tool "Java" + name "default__Operation" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Abstract" + value FALSE) + (object Attribute + tool "Java" + name "Static" + value FALSE) + (object Attribute + tool "Java" + name "Final" + value FALSE) + (object Attribute + tool "Java" + name "Native" + value FALSE) + (object Attribute + tool "Java" + name "Synchronized" + value FALSE) + (object Attribute + tool "Java" + name "GenerateFullyQualifiedReturn" + value FALSE) + (object Attribute + tool "Java" + name "ReplaceExistingCode" + value TRUE) + (object Attribute + tool "Java" + name "Strictfp" + value FALSE))) + (object Attribute + tool "Java" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Final" + value FALSE) + (object Attribute + tool "Java" + name "Transient" + value FALSE) + (object Attribute + tool "Java" + name "Volatile" + value FALSE) + (object Attribute + tool "Java" + name "PropertyType" + value ("BeanProperty_Set" 71)) + (object Attribute + tool "Java" + name "BeanProperty_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Not A Property" + value 71) + (object Attribute + tool "Java" + name "Simple" + value 72) + (object Attribute + tool "Java" + name "Bound" + value 73) + (object Attribute + tool "Java" + name "Constrained" + value 74))) + (object Attribute + tool "Java" + name "IndividualChangeMgt" + value FALSE) + (object Attribute + tool "Java" + name "Read/Write" + value ("Read/Write_Set" 81)) + (object Attribute + tool "Java" + name "Read/Write_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Read & Write" + value 81) + (object Attribute + tool "Java" + name "Read Only" + value 82) + (object Attribute + tool "Java" + name "Write Only" + value 83))) + (object Attribute + tool "Java" + name "GenerateFullyQualifiedTypes" + value FALSE))) + (object Attribute + tool "Java" + name "default__Role" + value (list Attribute_Set + (object Attribute + tool "Java" + name "ContainerClass" + value "") + (object Attribute + tool "Java" + name "InitialValue" + value "") + (object Attribute + tool "Java" + name "Final" + value FALSE) + (object Attribute + tool "Java" + name "Transient" + value FALSE) + (object Attribute + tool "Java" + name "Volatile" + value FALSE) + (object Attribute + tool "Java" + name "PropertyType" + value ("BeanProperty_Set" 71)) + (object Attribute + tool "Java" + name "BeanProperty_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Not A Property" + value 71) + (object Attribute + tool "Java" + name "Simple" + value 72) + (object Attribute + tool "Java" + name "Bound" + value 73) + (object Attribute + tool "Java" + name "Constrained" + value 74))) + (object Attribute + tool "Java" + name "IndividualChangeMgt" + value FALSE) + (object Attribute + tool "Java" + name "Read/Write" + value ("Read/Write_Set" 81)) + (object Attribute + tool "Java" + name "Read/Write_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Read & Write" + value 81) + (object Attribute + tool "Java" + name "Read Only" + value 82) + (object Attribute + tool "Java" + name "Write Only" + value 83))) + (object Attribute + tool "Java" + name "GenerateFullyQualifiedTypes" + value FALSE) + (object Attribute + tool "Java" + name "IsNavigable" + value TRUE))) + (object Attribute + tool "Java" + name "HiddenTool" + value FALSE) + (object Attribute + tool "R2Editor" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Rose Web Publisher" + name "HiddenTool" + value FALSE) + (object Attribute + tool "COM" + name "propertyId" + value "783606378") + (object Attribute + tool "COM" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "COM" + name "TypeKinds" + value (list Attribute_Set + (object Attribute + tool "COM" + name "enum" + value 100) + (object Attribute + tool "COM" + name "record" + value 101) + (object Attribute + tool "COM" + name "module" + value 102) + (object Attribute + tool "COM" + name "interface" + value 103) + (object Attribute + tool "COM" + name "dispinterface" + value 104) + (object Attribute + tool "COM" + name "coclass" + value 105) + (object Attribute + tool "COM" + name "alias" + value 106) + (object Attribute + tool "COM" + name "union" + value 107) + (object Attribute + tool "COM" + name "max" + value 108) + (object Attribute + tool "COM" + name "(none)" + value 109))) + (object Attribute + tool "COM" + name "Generate" + value TRUE) + (object Attribute + tool "COM" + name "kind" + value ("TypeKinds" 109)) + (object Attribute + tool "COM" + name "uuid" + value "") + (object Attribute + tool "COM" + name "version" + value "") + (object Attribute + tool "COM" + name "helpstring" + value "") + (object Attribute + tool "COM" + name "helpcontext" + value "") + (object Attribute + tool "COM" + name "attributes" + value "") + (object Attribute + tool "COM" + name "dllname" + value "") + (object Attribute + tool "COM" + name "alias" + value ""))) + (object Attribute + tool "COM" + name "default__Operation" + value (list Attribute_Set + (object Attribute + tool "COM" + name "Generate" + value TRUE) + (object Attribute + tool "COM" + name "id" + value "") + (object Attribute + tool "COM" + name "helpstring" + value "") + (object Attribute + tool "COM" + name "attributes" + value ""))) + (object Attribute + tool "COM" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "COM" + name "Generate" + value TRUE) + (object Attribute + tool "COM" + name "id" + value "") + (object Attribute + tool "COM" + name "helpstring" + value "") + (object Attribute + tool "COM" + name "attributes" + value ""))) + (object Attribute + tool "COM" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "COM" + name "Generate" + value TRUE) + (object Attribute + tool "COM" + name "filename" + value "") + (object Attribute + tool "COM" + name "library" + value "") + (object Attribute + tool "COM" + name "uuid" + value "") + (object Attribute + tool "COM" + name "version" + value "") + (object Attribute + tool "COM" + name "helpstring" + value "") + (object Attribute + tool "COM" + name "helpfile" + value "") + (object Attribute + tool "COM" + name "helpcontext" + value "") + (object Attribute + tool "COM" + name "lcid" + value "") + (object Attribute + tool "COM" + name "attributes" + value ""))) + (object Attribute + tool "COM" + name "default__Param" + value (list Attribute_Set + (object Attribute + tool "COM" + name "attributes" + value ""))) + (object Attribute + tool "COM" + name "HiddenTool" + value FALSE) + (object Attribute + tool "VC++" + name "propertyId" + value "809135966") + (object Attribute + tool "VC++" + name "default__Project" + value (list Attribute_Set + (object Attribute + tool "VC++" + name "UpdateATL" + value TRUE) + (object Attribute + tool "VC++" + name "SmartPointersOnAssoc" + value TRUE) + (object Attribute + tool "VC++" + name "GenerateImports" + value TRUE) + (object Attribute + tool "VC++" + name "PutImportsIn" + value "stdafx.h") + (object Attribute + tool "VC++" + name "FullPathInImports" + value TRUE) + (object Attribute + tool "VC++" + name "UseImportAttributes" + value TRUE) + (object Attribute + tool "VC++" + name "ImportAttributes" + value "no_namespace named_guids") + (object Attribute + tool "VC++" + name "ImportProjTypeLib" + value TRUE) + (object Attribute + tool "VC++" + name "DefaultTypeLib" + value TRUE) + (object Attribute + tool "VC++" + name "TypeLibLocation" + value "") + (object Attribute + tool "VC++" + name "CompileProjTypeLib" + value TRUE) + (object Attribute + tool "VC++" + name "IdlInterfaceAttributes" + value (value Text +|endpoint("") +|local +|object +|pointer_default() +|uuid("") +|version("") +|encode +|decode +|auto_handle +|implicit_handle("") +|code +|nocode + )) + (object Attribute + tool "VC++" + name "IdlCoClassAttributes" + value (value Text +|uuid("") +|helpstring("") +|helpcontext("") +|licensed +|version("") +|control +|hidden +|appobject + )) + (object Attribute + tool "VC++" + name "IdlCoClassInterfaceAttributes" + value (value Text +|default +|source + )) + (object Attribute + tool "VC++" + name "IdlParameterAttributes" + value (value Text +|in +|out +|retval + )) + (object Attribute + tool "VC++" + name "IdlMethodAttributes" + value (value Text +|id(1) +|helpstring("") +|call_as("") +|callback +|helpcontext("") +|hidden +|local +|restricted +|source +|vararg + )) + (object Attribute + tool "VC++" + name "IdlPropertyAttributes" + value (value Text +|id() +|helpstring("") +|call_as("") +|helpcontext("") +|hidden +|local +|restricted +|source +|vararg +|bindable +|defaultbind +|defaultcallelem +|displaybind +|immediatebind +|nonbrowseable +|requestedit + )) + (object Attribute + tool "VC++" + name "RvcPtyVersion" + value "1.3") + (object Attribute + tool "VC++" + name "ModelIDStyle" + value 2) + (object Attribute + tool "VC++" + name "DocStyle" + value 1) + (object Attribute + tool "VC++" + name "GenerateIncludes" + value TRUE) + (object Attribute + tool "VC++" + name "ApplyPattern" + value FALSE) + (object Attribute + tool "VC++" + name "CreateBackupFiles" + value TRUE) + (object Attribute + tool "VC++" + name "SupportCodeName" + value FALSE) + (object Attribute + tool "VC++" + name "DocRevEngineer" + value TRUE) + (object Attribute + tool "VC++" + name "CreateOverviewDiagrams" + value TRUE) + (object Attribute + tool "VC++" + name "UpdateModelIDsInCode" + value TRUE) + (object Attribute + tool "VC++" + name "AttributeTypes" + value (value Text +|attr1=bool +|attr2=short +|attr3=int +|attr4=long +|attr5=char +|attr6=float +|attr7=double +|attr8=void +|attr9=clock_t +|attr10=_complex +|attr11=_dev_t +|attr12=div_t +|attr13=_exception +|attr14=FILE +|attr15=_finddata_t +|attr16=_FPIEEE_RECORD +|attr17=fpos_t +|attr18=_HEAPINFO +|attr19=jmp_buf +|attr20=lconv +|attr21=ldiv_t +|attr22=_off_t +|attr23=_onexit_t +|attr24=_PNH +|attr25=ptrdiff_t +|attr26=sig_atomic_t +|attr27=size_t +|attr28=_stat +|attr29=time_t +|attr30=_timeb +|attr31=tm +|attr32=_utimbuf +|attr33=va_list +|attr34=wchar_t +|attr35=wctrans_t +|attr36=wctype_t +|attr37=_wfinddata_t +|attr38=_wfinddatai64_t +|attr39=wint_t +|attr40=ABORTPROC +|attr41=ACMDRIVERENUMCB +|attr42=ACMDRIVERPROC +|attr43=ACMFILTERCHOOSEHOOKPROC +|attr44=ACMFILTERENUMCB +|attr45=ACMFILTERTAGENUMCB +|attr46=ACMFORMATCHOOSEHOOKPROC +|attr47=ACMFORMATENUMCB +|attr48=ACMFORMATTAGENUMCB +|attr49=APPLET_PROC +|attr50=ATOM +|attr51=BOOL +|attr52=BOOLEAN +|attr53=BYTE +|attr54=CALINFO_ENUMPROC +|attr55=CALLBACK +|attr56=CHAR +|attr57=COLORREF +|attr58=CONST +|attr59=CRITICAL_SECTION +|attr60=CTRYID +|attr61=DATEFMT_ENUMPROC +|attr62=DESKTOPENUMPROC +|attr63=DLGPROC +|attr64=DRAWSTATEPROC +|attr65=DWORD +|attr66=EDITWORDBREAKPROC +|attr67=ENHMFENUMPROC +|attr68=ENUMRESLANGPROC +|attr69=ENUMRESNAMEPROC +|attr70=ENUMRESTYPEPROC +|attr71=FARPROC +|attr72=FILE_SEGMENT_ELEMENT +|attr73=FLOAT +|attr74=FONTENUMPROC +|attr75=GOBJENUMPROC +|attr76=GRAYSTRINGPROC +|attr77=HACCEL +|attr78=HANDLE +|attr79=HBITMAP +|attr80=HBRUSH +|attr81=HCOLORSPACE +|attr82=HCONV +|attr83=HCONVLIST +|attr84=HCURSOR +|attr85=HDC +|attr86=HDDEDATA +|attr87=HDESK +|attr88=HDROP +|attr89=HDWP +|attr90=HENHMETAFILE +|attr91=HFILE +|attr92=HFONT +|attr93=HGDIOBJ +|attr94=HGLOBAL +|attr95=HHOOK +|attr96=HICON +|attr97=HIMAGELIST +|attr98=HIMC +|attr99=HINSTANCE +|attr100=HKEY +|attr101=HKL +|attr102=HLOCAL +|attr103=HMENU +|attr104=HMETAFILE +|attr105=HMODULE +|attr106=HMONITOR +|attr107=HOOKPROC +|attr108=HPALETTE +|attr109=HPEN +|attr110=HRGN +|attr111=HRSRC +|attr112=HSZ +|attr113=HTREEITEM +|attr114=HWINSTA +|attr115=HWND +|attr116=INT +|attr117=IPADDR +|attr118=LANGID +|attr119=LCID +|attr120=LCSCSTYPE +|attr121=LCSGAMUTMATCH +|attr122=LCTYPE +|attr123=LINEDDAPROC +|attr124=LOCALE_ENUMPROC +|attr125=LONG +|attr126=LONGLONG +|attr127=LPARAM +|attr128=LPBOOL +|attr129=LPBYTE +|attr130=LPCCHOOKPROC +|attr131=LPCFHOOKPROC +|attr132=LPCOLORREF +|attr133=LPCRITICAL_SECTION +|attr134=LPCSTR +|attr135=LPCTSTR +|attr136=LPCVOID +|attr137=LPCWSTR +|attr138=LPDWORD +|attr139=LPFIBER_START_ROUTINE +|attr140=LPFRHOOKPROC +|attr141=LPHANDLE +|attr142=LPHANDLER_FUNCTION +|attr143=LPINT +|attr144=LPLONG +|attr145=LPOFNHOOKPROC +|attr146=LPPAGEPAINTHOOK +|attr147=LPPAGESETUPHOOK +|attr148=LPPRINTHOOKPROC +|attr149=LPPROGRESS_ROUTINE +|attr150=LPSETUPHOOKPROC +|attr151=LPSTR +|attr152=LPSTREAM +|attr153=LPTHREAD_START_ROUTINE +|attr154=LPTSTR +|attr155=LPVOID +|attr156=LPWORD +|attr157=LPWSTR +|attr158=LRESULT +|attr159=LUID +|attr160=PBOOL +|attr161=PBOOLEAN +|attr162=PBYTE +|attr163=PCHAR +|attr164=PCRITICAL_SECTION +|attr165=PCSTR +|attr166=PCTSTR +|attr167=PCWCH +|attr168=PCWSTR +|attr169=PDWORD +|attr170=PFLOAT +|attr171=PFNCALLBACK +|attr172=PHANDLE +|attr173=PHANDLER_ROUTINE +|attr174=PHKEY +|attr175=PINT +|attr176=PLCID +|attr177=PLONG +|attr178=PLUID +|attr179=PROPENUMPROC +|attr180=PROPENUMPROCEX +|attr181=PSHORT +|attr182=PSTR +|attr183=PTBYTE +|attr184=PTCHAR +|attr185=PTIMERAPCROUTINE +|attr186=PTSTR +|attr187=PUCHAR +|attr188=PUINT +|attr189=PULONG +|attr190=PUSHORT +|attr191=PVOID +|attr192=PWCHAR +|attr193=PWORD +|attr194=PWSTR +|attr195=REGISTERWORDENUMPROC +|attr196=REGSAM +|attr197=SC_HANDLE +|attr198=SC_LOCK +|attr199=SENDASYNCPROC +|attr200=SERVICE_STATUS_HANDLE +|attr201=SHORT +|attr202=TBYTE +|attr203=TCHAR +|attr204=TIMEFMT_ENUMPROC +|attr205=TIMERPROC +|attr206=UCHAR +|attr207=UINT +|attr208=ULONG +|attr209=ULONGLONG +|attr210=UNSIGNED +|attr211=USHORT +|attr212=VOID +|attr213=WCHAR +|attr214=WINAPI +|attr215=WINSTAENUMPROC +|attr216=WNDENUMPROC +|attr217=WNDPROC +|attr218=WORD +|attr219=WPARAM +|attr220=YIELDPROC +|attr221=CPoint +|attr222=CRect +|attr223=CSize +|attr224=CString +|attr225=CTime +|attr226=CTimeSpan +|attr227=CCreateContext +|attr228=CMemoryState +|attr229=COleSafeArray +|attr230=CPrintInfo +|attr231=HRESULT + )) + (object Attribute + tool "VC++" + name "Containers" + value (value Text +|cont1=CArray<$TYPE, $TYPE&> +|cont2=CByteArray +|cont3=CDWordArray +|cont4=CObArray +|cont5=CPtrArray +|cont6=CStringArray +|cont7=CUIntArray +|cont8=CWordArray +|cont9=CList<$TYPE, $TYPE&> +|cont10=CPtrList +|cont11=CObList +|cont12=CStringList +|cont13=CMapWordToPtr +|cont14=CMapPtrToWord +|cont15=CMapPtrToPtr +|cont16=CMapWordToOb +|cont17=CMapStringToPtr +|cont18=CMapStringToOb +|cont19=CMapStringToString +|cont20=CTypedPtrArray +|cont21=CTypedPtrArray +|cont22=CTypedPtrList +|cont23=CTypedPtrList +|cont24=CComObject<$TYPE> +|cont25=CComPtr<$TYPE> +|cont26=CComQIPtr<$TYPE> +|cont27=CComQIPtr<$TYPE, IID*> + )) + (object Attribute + tool "VC++" + name "ClassMethods" + value (value Text +|*_body=// ToDo: Add your specialized code here and/or call the base class +|cm1=$NAME() +|cm2=$NAME(orig:const $NAME&) +|cm3=<> ~$NAME() +|cm4=operator=(rhs:$NAME&):$NAME& +|cm4_body=// ToDo: Add your specialized code here and/or call the base class||return rhs; +|cm5=<> operator==(rhs:const $NAME&):bool +|cm5_body=// ToDo: Add your specialized code here and/or call the base class||return false; +|cm6=<> operator!=(rhs:$NAME&):bool +|cm6_body=// ToDo: Add your specialized code here and/or call the base class||return false; +|cm7=<> operator<(rhs:$NAME&):bool +|cm7_body=// ToDo: Add your specialized code here and/or call the base class||return false; +|cm8=<> operator>(rhs:$NAME&):bool +|cm8_body=// ToDo: Add your specialized code here and/or call the base class||return false; +|cm9=<> operator<=(rhs:$NAME&):bool +|cm9_body=// ToDo: Add your specialized code here and/or call the base class||return false; +|cm10=<> operator>=(rhs:$NAME&):bool +|cm10_body=// ToDo: Add your specialized code here and/or call the base class||return false; +|cm11=<> operator>>(i:istream&, rhs:$NAME&):istream& +|cm11_body=// ToDo: Add your specialized code here and/or call the base class||return i; +|cm12=<> operator<<(o:ostream&, rhs:const $NAME&):ostream& +|cm12_body=// ToDo: Add your specialized code here and/or call the base class||return o; + )) + (object Attribute + tool "VC++" + name "Accessors" + value (value Text +|agf=<> get_$BASICNAME():const $TYPE +|agf_body=return $NAME; +|asf=set_$BASICNAME(value:$TYPE):void +|asf_body=$NAME = value;|return; +|agv=<> get_$BASICNAME():const $TYPE& +|agv_body=return $NAME; +|asv=set_$BASICNAME(value:$TYPE&):void +|asv_body=$NAME = value;|return; +|agp=<> get_$BASICNAME():const $TYPE +|agp_body=return $NAME; +|asp=set_$BASICNAME(value:$TYPE):void +|asp_body=$NAME = value;|return; +|agr=<> get_$BASICNAME():const $TYPE +|agr_body=return $NAME; +|asr=set_$BASICNAME(value:$TYPE):void +|asr_body=$NAME = value;|return; +|aga=<> get_$BASICNAME(index:int):const $TYPE +|aga_body=return $NAME[index]; +|asa=set_$BASICNAME(index:int, value:$TYPE):void +|asa_body=$NAME[index] = value;|return; + )) + (object Attribute + tool "VC++" + name "Conditionals" + value (value Text +|*_decl=#ifdef _DEBUG +|*_base=CObject +|cond1=<> AssertValid():void +|cond1_body=$SUPERNAME::AssertValid(); +|cond2=<> Dump(dc:CDumpContext&):void +|cond2_body=$SUPERNAME::Dump(dc); + )) + (object Attribute + tool "VC++" + name "Patterns" + value (value Text +|patrn1=cm1,cm3,cond1,cond2 +|Patrn1_name=Default + )) + (object Attribute + tool "VC++" + name "AtlClassPrefix" + value "C") + (object Attribute + tool "VC++" + name "AtlInterfacePrefix" + value "I") + (object Attribute + tool "VC++" + name "AtlTypeDescription" + value "Class") + (object Attribute + tool "VC++" + name "DefaultLogicalPackage" + value "$language Reverse Engineered/$component") + (object Attribute + tool "VC++" + name "DefaultComponentPackage" + value ""))) + (object Attribute + tool "VC++" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "VC++" + name "Generate" + value TRUE) + (object Attribute + tool "VC++" + name "HeaderFileName" + value "") + (object Attribute + tool "VC++" + name "CodeFileName" + value ""))) + (object Attribute + tool "VC++" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "VC++" + name "InternalMap" + value (value Text +|*:AUTO:AUTO +| + )) + (object Attribute + tool "VC++" + name "ExportMap" + value (value Text +|*:AUTO:AUTO +| + )) + (object Attribute + tool "VC++" + name "InitialSourceIncludes" + value (value Text +|"stdafx.h" + )) + (object Attribute + tool "VC++" + name "InitialHeaderIncludes" + value (value Text "")) + (object Attribute + tool "VC++" + name "Copyright" + value (value Text "Copyright (C) 1991 - 1999 Rational Software Corporation")) + (object Attribute + tool "VC++" + name "KindSet" + value (list Attribute_Set + (object Attribute + tool "VC++" + name "(none)" + value 300) + (object Attribute + tool "VC++" + name "DLL" + value 301) + (object Attribute + tool "VC++" + name "EXE" + value 302) + (object Attribute + tool "VC++" + name "MIDL" + value 303))) + (object Attribute + tool "VC++" + name "Kind" + value ("KindSet" 300)) + (object Attribute + tool "VC++" + name "BodyExtensions" + value (value Text +|.cpp +|.cxx +|.inl + )) + (object Attribute + tool "VC++" + name "HeaderExtensions" + value (value Text +|.h +|.hpp +|.hxx +|inl + )) + (object Attribute + tool "VC++" + name "ProjectFolders" + value (value Text +|Source Files +|Header Files + )) + (object Attribute + tool "VC++" + name "UsePathMap" + value FALSE))) + (object Attribute + tool "VC++" + name "default__Role" + value (list Attribute_Set + (object Attribute + tool "VC++" + name "Const" + value FALSE) + (object Attribute + tool "VC++" + name "Generate" + value TRUE) + (object Attribute + tool "VC++" + name "InitialValue" + value ""))) + (object Attribute + tool "VC++" + name "default__Uses" + value (list Attribute_Set + (object Attribute + tool "VC++" + name "Generate" + value TRUE))) + (object Attribute + tool "VC++" + name "default__Category" + value (list Attribute_Set + (object Attribute + tool "VC++" + name "IsDirectory" + value FALSE) + (object Attribute + tool "VC++" + name "Directory" + value ""))) + (object Attribute + tool "VC++" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "VC++" + name "Generate" + value TRUE))) + (object Attribute + tool "VC++" + name "default__Operation" + value (list Attribute_Set + (object Attribute + tool "VC++" + name "Generate" + value TRUE) + (object Attribute + tool "VC++" + name "Inline" + value FALSE) + (object Attribute + tool "VC++" + name "DefaultBody" + value (value Text "")) + (object Attribute + tool "VC++" + name "GenerateSet" + value (list Attribute_Set + (object Attribute + tool "VC++" + name "DoNotGenerate" + value 400) + (object Attribute + tool "VC++" + name "DeclareAndDefine" + value 401) + (object Attribute + tool "VC++" + name "DeclareOnly" + value 402))))) + (object Attribute + tool "VC++" + name "HiddenTool" + value FALSE) + (object Attribute + tool "VisualStudio" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Web Modeler" + name "HiddenTool" + value FALSE) + (object Attribute + tool "XML_DTD" + name "propertyId" + value "809135966") + (object Attribute + tool "XML_DTD" + name "default__Project" + value (list Attribute_Set + (object Attribute + tool "XML_DTD" + name "CreateMissingDirectories" + value TRUE) + (object Attribute + tool "XML_DTD" + name "Editor" + value ("EditorType" 100)) + (object Attribute + tool "XML_DTD" + name "StopOnError" + value TRUE) + (object Attribute + tool "XML_DTD" + name "EditorType" + value (list Attribute_Set + (object Attribute + tool "XML_DTD" + name "BuiltIn" + value 100) + (object Attribute + tool "XML_DTD" + name "WindowsShell" + value 101))))) + (object Attribute + tool "XML_DTD" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "XML_DTD" + name "Entity_SystemID" + value "") + (object Attribute + tool "XML_DTD" + name "Entity_PublicID" + value "") + (object Attribute + tool "XML_DTD" + name "NotationValue" + value "") + (object Attribute + tool "XML_DTD" + name "InternalValue" + value "") + (object Attribute + tool "XML_DTD" + name "ParameterEntity" + value FALSE) + (object Attribute + tool "XML_DTD" + name "ExternalEntity" + value FALSE) + (object Attribute + tool "XML_DTD" + name "Notation_SystemID" + value "") + (object Attribute + tool "XML_DTD" + name "Notation_PublicID" + value ""))) + (object Attribute + tool "XML_DTD" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "XML_DTD" + name "DefaultDeclType" + value ""))) + (object Attribute + tool "XML_DTD" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "XML_DTD" + name "Assign All" + value FALSE) + (object Attribute + tool "XML_DTD" + name "ComponentPath" + value ""))) + (object Attribute + tool "XML_DTD" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Cplusplus" + name "propertyId" + value "809135966") + (object Attribute + tool "Cplusplus" + name "default__Role" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE) + (object Attribute + tool "Cplusplus" + name "CodeName" + value "") + (object Attribute + tool "Cplusplus" + name "InitialValue" + value ""))) + (object Attribute + tool "Cplusplus" + name "default__Inherit" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE))) + (object Attribute + tool "Cplusplus" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE) + (object Attribute + tool "Cplusplus" + name "RevEngRootDirectory" + value "") + (object Attribute + tool "Cplusplus" + name "RootPackage" + value "C++ Reverse Engineered") + (object Attribute + tool "Cplusplus" + name "RevEngDirectoriesAsPackages" + value FALSE) + (object Attribute + tool "Cplusplus" + name "HeaderFileExtension" + value ".h") + (object Attribute + tool "Cplusplus" + name "ImplementationFileExtension" + value ".cpp") + (object Attribute + tool "Cplusplus" + name "NewHeaderFileDirectory" + value "") + (object Attribute + tool "Cplusplus" + name "NewImplementationFileDirectory" + value "") + (object Attribute + tool "Cplusplus" + name "FileCapitalization" + value ("FileCapitalizationSet" 0)) + (object Attribute + tool "Cplusplus" + name "CodeGenExtraDirectories" + value ("CodeGenExtraDirectoriesSet" 0)) + (object Attribute + tool "Cplusplus" + name "StripClassPrefix" + value "") + (object Attribute + tool "Cplusplus" + name "UseTabs" + value FALSE) + (object Attribute + tool "Cplusplus" + name "TabWidth" + value 8) + (object Attribute + tool "Cplusplus" + name "IndentWidth" + value 4) + (object Attribute + tool "Cplusplus" + name "AccessIndentation" + value -2) + (object Attribute + tool "Cplusplus" + name "CreateBackupFiles" + value FALSE) + (object Attribute + tool "Cplusplus" + name "ModelIdCommentRules" + value ("ModelIdCommentRulesSet" 1)) + (object Attribute + tool "Cplusplus" + name "CommentRules" + value ("CommentRulesSet" 1)) + (object Attribute + tool "Cplusplus" + name "PageWidth" + value 80) + (object Attribute + tool "Cplusplus" + name "ClassMemberOrder" + value ("MemberOrderSet" 1)) + (object Attribute + tool "Cplusplus" + name "OneParameterPerLine" + value FALSE) + (object Attribute + tool "Cplusplus" + name "NamespaceBraceStyle" + value ("BraceStyleSet" 1)) + (object Attribute + tool "Cplusplus" + name "ClassBraceStyle" + value ("BraceStyleSet" 2)) + (object Attribute + tool "Cplusplus" + name "FunctionBraceStyle" + value ("BraceStyleSet" 2)) + (object Attribute + tool "Cplusplus" + name "CommentStyleProperty" + value ("CommentStyleSet" 1)) + (object Attribute + tool "Cplusplus" + name "Copyright" + value (value Text "")) + (object Attribute + tool "Cplusplus" + name "InitialHeaderIncludes" + value (value Text "")) + (object Attribute + tool "Cplusplus" + name "InitialBodyIncludes" + value (value Text "")) + (object Attribute + tool "Cplusplus" + name "CodeGenExtraDirectoriesSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "None" + value 0) + (object Attribute + tool "Cplusplus" + name "Namespaces" + value 1) + (object Attribute + tool "Cplusplus" + name "Packages" + value 2))) + (object Attribute + tool "Cplusplus" + name "FileCapitalizationSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Same as model" + value 0) + (object Attribute + tool "Cplusplus" + name "Lower case" + value 1) + (object Attribute + tool "Cplusplus" + name "Upper case" + value 2) + (object Attribute + tool "Cplusplus" + name "Lower case with underscores" + value 3))) + (object Attribute + tool "Cplusplus" + name "CommentStyleSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "C++ Comment" + value 1) + (object Attribute + tool "Cplusplus" + name "C Comment" + value 2) + (object Attribute + tool "Cplusplus" + name "XML Comment" + value 3) + (object Attribute + tool "Cplusplus" + name "JavaDoc Comment" + value 4))) + (object Attribute + tool "Cplusplus" + name "BraceStyleSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "B1" + value 1) + (object Attribute + tool "Cplusplus" + name "B2" + value 2) + (object Attribute + tool "Cplusplus" + name "B3" + value 3) + (object Attribute + tool "Cplusplus" + name "B4" + value 4) + (object Attribute + tool "Cplusplus" + name "B5" + value 5))) + (object Attribute + tool "Cplusplus" + name "MemberOrderSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Public First" + value 1) + (object Attribute + tool "Cplusplus" + name "Private First" + value 2) + (object Attribute + tool "Cplusplus" + name "Order by kind" + value 3) + (object Attribute + tool "Cplusplus" + name "Unordered" + value 4))) + (object Attribute + tool "Cplusplus" + name "ModelIdCommentRulesSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Code generation only" + value 1) + (object Attribute + tool "Cplusplus" + name "Code generation and reverse engineering" + value 2) + (object Attribute + tool "Cplusplus" + name "Never generate model IDs" + value 3))) + (object Attribute + tool "Cplusplus" + name "CommentRulesSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Always synchronize" + value 1) + (object Attribute + tool "Cplusplus" + name "Code generation only" + value 2) + (object Attribute + tool "Cplusplus" + name "Reverse engineering only" + value 3) + (object Attribute + tool "Cplusplus" + name "Never synchronize" + value 4))))) + (object Attribute + tool "Cplusplus" + name "default__Module-Body" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE) + (object Attribute + tool "Cplusplus" + name "RevEngRootDirectory" + value "") + (object Attribute + tool "Cplusplus" + name "RootPackage" + value "C++ Reverse Engineered") + (object Attribute + tool "Cplusplus" + name "RevEngDirectoriesAsPackages" + value FALSE) + (object Attribute + tool "Cplusplus" + name "HeaderFileExtension" + value ".h") + (object Attribute + tool "Cplusplus" + name "ImplementationFileExtension" + value ".cpp") + (object Attribute + tool "Cplusplus" + name "NewHeaderFileDirectory" + value "") + (object Attribute + tool "Cplusplus" + name "NewImplementationFileDirectory" + value "") + (object Attribute + tool "Cplusplus" + name "FileCapitalization" + value ("FileCapitalizationSet" 0)) + (object Attribute + tool "Cplusplus" + name "CodeGenExtraDirectories" + value ("CodeGenExtraDirectoriesSet" 0)) + (object Attribute + tool "Cplusplus" + name "StripClassPrefix" + value "") + (object Attribute + tool "Cplusplus" + name "UseTabs" + value FALSE) + (object Attribute + tool "Cplusplus" + name "TabWidth" + value 8) + (object Attribute + tool "Cplusplus" + name "IndentWidth" + value 4) + (object Attribute + tool "Cplusplus" + name "AccessIndentation" + value -2) + (object Attribute + tool "Cplusplus" + name "CreateBackupFiles" + value FALSE) + (object Attribute + tool "Cplusplus" + name "ModelIdCommentRules" + value ("ModelIdCommentRulesSet" 1)) + (object Attribute + tool "Cplusplus" + name "CommentRules" + value ("CommentRulesSet" 1)) + (object Attribute + tool "Cplusplus" + name "PageWidth" + value 80) + (object Attribute + tool "Cplusplus" + name "ClassMemberOrder" + value ("MemberOrderSet" 1)) + (object Attribute + tool "Cplusplus" + name "OneParameterPerLine" + value FALSE) + (object Attribute + tool "Cplusplus" + name "NamespaceBraceStyle" + value ("BraceStyleSet" 2)) + (object Attribute + tool "Cplusplus" + name "ClassBraceStyle" + value ("BraceStyleSet" 2)) + (object Attribute + tool "Cplusplus" + name "FunctionBraceStyle" + value ("BraceStyleSet" 2)) + (object Attribute + tool "Cplusplus" + name "CommentStyleProperty" + value ("CommentStyleSet" 1)) + (object Attribute + tool "Cplusplus" + name "Copyright" + value (value Text "")) + (object Attribute + tool "Cplusplus" + name "InitialHeaderIncludes" + value (value Text "")) + (object Attribute + tool "Cplusplus" + name "InitialBodyIncludes" + value (value Text "")) + (object Attribute + tool "Cplusplus" + name "CodeGenExtraDirectoriesSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "None" + value 0) + (object Attribute + tool "Cplusplus" + name "Namespaces" + value 1) + (object Attribute + tool "Cplusplus" + name "Packages" + value 2))) + (object Attribute + tool "Cplusplus" + name "FileCapitalizationSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Same as model" + value 0) + (object Attribute + tool "Cplusplus" + name "Lower case" + value 1) + (object Attribute + tool "Cplusplus" + name "Upper case" + value 2) + (object Attribute + tool "Cplusplus" + name "Lower case with underscores" + value 3))) + (object Attribute + tool "Cplusplus" + name "CommentStyleSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "C++ Comment" + value 1) + (object Attribute + tool "Cplusplus" + name "C Comment" + value 2) + (object Attribute + tool "Cplusplus" + name "XML Comment" + value 3) + (object Attribute + tool "Cplusplus" + name "JavaDoc Comment" + value 4))) + (object Attribute + tool "Cplusplus" + name "BraceStyleSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "B1" + value 1) + (object Attribute + tool "Cplusplus" + name "B2" + value 2) + (object Attribute + tool "Cplusplus" + name "B3" + value 3) + (object Attribute + tool "Cplusplus" + name "B4" + value 4) + (object Attribute + tool "Cplusplus" + name "B5" + value 5))) + (object Attribute + tool "Cplusplus" + name "MemberOrderSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Public First" + value 1) + (object Attribute + tool "Cplusplus" + name "Private First" + value 2) + (object Attribute + tool "Cplusplus" + name "Order by kind" + value 3) + (object Attribute + tool "Cplusplus" + name "Unordered" + value 4))) + (object Attribute + tool "Cplusplus" + name "ModelIdCommentRulesSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Code generation only" + value 1) + (object Attribute + tool "Cplusplus" + name "Code generation and reverse engineering" + value 2) + (object Attribute + tool "Cplusplus" + name "Never generate model IDs" + value 3))) + (object Attribute + tool "Cplusplus" + name "CommentRulesSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Always synchronize" + value 1) + (object Attribute + tool "Cplusplus" + name "Code generation only" + value 2) + (object Attribute + tool "Cplusplus" + name "Reverse engineering only" + value 3) + (object Attribute + tool "Cplusplus" + name "Never synchronize" + value 4))))) + (object Attribute + tool "Cplusplus" + name "default__Param" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "CodeName" + value ""))) + (object Attribute + tool "Cplusplus" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE) + (object Attribute + tool "Cplusplus" + name "CodeName" + value ""))) + (object Attribute + tool "Cplusplus" + name "default__Operation" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE) + (object Attribute + tool "Cplusplus" + name "CodeName" + value "") + (object Attribute + tool "Cplusplus" + name "InitialCodeBody" + value "") + (object Attribute + tool "Cplusplus" + name "Inline" + value FALSE) + (object Attribute + tool "Cplusplus" + name "GenerateFunctionBody" + value ("GenerateFunctionBodySet" 2)) + (object Attribute + tool "Cplusplus" + name "GenerateFunctionBodySet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Default" + value 2) + (object Attribute + tool "Cplusplus" + name "True" + value 1) + (object Attribute + tool "Cplusplus" + name "False" + value 0))))) + (object Attribute + tool "Cplusplus" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE) + (object Attribute + tool "Cplusplus" + name "CodeName" + value "") + (object Attribute + tool "Cplusplus" + name "ImplementationType" + value "") + (object Attribute + tool "Cplusplus" + name "HeaderSourceFile" + value "") + (object Attribute + tool "Cplusplus" + name "BodySourceFile" + value ""))) + (object Attribute + tool "Cplusplus" + name "default__Category" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "CodeName" + value "") + (object Attribute + tool "Cplusplus" + name "IsNamespace" + value FALSE))) + (object Attribute + tool "Cplusplus" + name "default__Uses" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "BodyReferenceOnly" + value FALSE))) + (object Attribute + tool "Cplusplus" + name "HiddenTool" + value FALSE) + (object Attribute + tool "ANSIConvert" + name "HiddenTool" + value FALSE) + (object Attribute + tool "CORBA" + name "default__Param" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "Direction" + value ("ParamDirectionTypeSet" 102)) + (object Attribute + tool "CORBA" + name "ParamDirectionTypeSet" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "in" + value 102) + (object Attribute + tool "CORBA" + name "inout" + value 103) + (object Attribute + tool "CORBA" + name "out" + value 104))))) + (object Attribute + tool "Deploy" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Oracle8" + name "propertyId" + value "360000002") + (object Attribute + tool "Oracle8" + name "default__Project" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "DDLScriptFilename" + value "DDL1.SQL") + (object Attribute + tool "Oracle8" + name "DropClause" + value FALSE) + (object Attribute + tool "Oracle8" + name "PrimaryKeyColumnName" + value "_ID") + (object Attribute + tool "Oracle8" + name "PrimaryKeyColumnType" + value "NUMBER(5,0)") + (object Attribute + tool "Oracle8" + name "SchemaNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "SchemaNameSuffix" + value "") + (object Attribute + tool "Oracle8" + name "TableNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "TableNameSuffix" + value "") + (object Attribute + tool "Oracle8" + name "TypeNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "TypeNameSuffix" + value "") + (object Attribute + tool "Oracle8" + name "ViewNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "ViewNameSuffix" + value "") + (object Attribute + tool "Oracle8" + name "VarrayNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "VarrayNameSuffix" + value "") + (object Attribute + tool "Oracle8" + name "NestedTableNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "NestedTableNameSuffix" + value "") + (object Attribute + tool "Oracle8" + name "ObjectTableNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "ObjectTableNameSuffix" + value ""))) + (object Attribute + tool "Oracle8" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "IsSchema" + value FALSE))) + (object Attribute + tool "Oracle8" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "OID" + value "") + (object Attribute + tool "Oracle8" + name "WhereClause" + value "") + (object Attribute + tool "Oracle8" + name "CheckConstraint" + value "") + (object Attribute + tool "Oracle8" + name "CollectionTypeLength" + value "") + (object Attribute + tool "Oracle8" + name "CollectionTypePrecision" + value "") + (object Attribute + tool "Oracle8" + name "CollectionTypeScale" + value "") + (object Attribute + tool "Oracle8" + name "CollectionOfREFS" + value FALSE))) + (object Attribute + tool "Oracle8" + name "default__Operation" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "MethodKind" + value ("MethodKindSet" 1903)) + (object Attribute + tool "Oracle8" + name "OverloadID" + value "") + (object Attribute + tool "Oracle8" + name "OrderNumber" + value "") + (object Attribute + tool "Oracle8" + name "IsReadNoDataState" + value FALSE) + (object Attribute + tool "Oracle8" + name "IsReadNoProcessState" + value FALSE) + (object Attribute + tool "Oracle8" + name "IsWriteNoDataState" + value FALSE) + (object Attribute + tool "Oracle8" + name "IsWriteNoProcessState" + value FALSE) + (object Attribute + tool "Oracle8" + name "IsSelfish" + value FALSE) + (object Attribute + tool "Oracle8" + name "TriggerType" + value ("TriggerTypeSet" 1801)) + (object Attribute + tool "Oracle8" + name "TriggerEvent" + value ("TriggerEventSet" 1601)) + (object Attribute + tool "Oracle8" + name "TriggerText" + value "") + (object Attribute + tool "Oracle8" + name "TriggerReferencingNames" + value "") + (object Attribute + tool "Oracle8" + name "TriggerForEach" + value ("TriggerForEachSet" 1701)) + (object Attribute + tool "Oracle8" + name "TriggerWhenClause" + value "") + (object Attribute + tool "Oracle8" + name "MethodKindSet" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "MapMethod" + value 1901) + (object Attribute + tool "Oracle8" + name "OrderMethod" + value 1902) + (object Attribute + tool "Oracle8" + name "Function" + value 1903) + (object Attribute + tool "Oracle8" + name "Procedure" + value 1904) + (object Attribute + tool "Oracle8" + name "Operator" + value 1905) + (object Attribute + tool "Oracle8" + name "Constructor" + value 1906) + (object Attribute + tool "Oracle8" + name "Destructor" + value 1907) + (object Attribute + tool "Oracle8" + name "Trigger" + value 1908) + (object Attribute + tool "Oracle8" + name "Calculated" + value 1909))) + (object Attribute + tool "Oracle8" + name "TriggerTypeSet" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "AFTER" + value 1801) + (object Attribute + tool "Oracle8" + name "BEFORE" + value 1802) + (object Attribute + tool "Oracle8" + name "INSTEAD OF" + value 1803))) + (object Attribute + tool "Oracle8" + name "TriggerForEachSet" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "ROW" + value 1701) + (object Attribute + tool "Oracle8" + name "STATEMENT" + value 1702))) + (object Attribute + tool "Oracle8" + name "TriggerEventSet" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "INSERT" + value 1601) + (object Attribute + tool "Oracle8" + name "UPDATE" + value 1602) + (object Attribute + tool "Oracle8" + name "DELETE" + value 1603) + (object Attribute + tool "Oracle8" + name "INSERT OR UPDATE" + value 1604) + (object Attribute + tool "Oracle8" + name "INSERT OR DELETE" + value 1605) + (object Attribute + tool "Oracle8" + name "UPDATE OR DELETE" + value 1606) + (object Attribute + tool "Oracle8" + name "INSERT OR UPDATE OR DELETE" + value 1607))))) + (object Attribute + tool "Oracle8" + name "default__Role" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "OrderNumber" + value ""))) + (object Attribute + tool "Oracle8" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "OrderNumber" + value "") + (object Attribute + tool "Oracle8" + name "IsUnique" + value FALSE) + (object Attribute + tool "Oracle8" + name "NullsAllowed" + value TRUE) + (object Attribute + tool "Oracle8" + name "Length" + value "") + (object Attribute + tool "Oracle8" + name "Precision" + value "2") + (object Attribute + tool "Oracle8" + name "Scale" + value "6") + (object Attribute + tool "Oracle8" + name "IsIndex" + value FALSE) + (object Attribute + tool "Oracle8" + name "IsPrimaryKey" + value FALSE) + (object Attribute + tool "Oracle8" + name "CompositeUnique" + value FALSE) + (object Attribute + tool "Oracle8" + name "CheckConstraint" + value ""))) + (object Attribute + tool "Oracle8" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Rose Model Integrator" + name "HiddenTool" + value FALSE) + (object Attribute + tool "TopLink" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Version Control" + name "HiddenTool" + value FALSE)) + quid "39C9260C00D9")) diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\345\215\217\344\275\234\345\233\276.png" "b/Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\345\215\217\344\275\234\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..8b4ce00e4267ce9db112c66c2d8d4e040a09e024 GIT binary patch literal 14792 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 VaSC@ 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 literal 0 HcmV?d00001 diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\345\272\217\345\210\227\345\233\276.png" "b/Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\345\272\217\345\210\227\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..290480808bd907907573982e9eb04db564ab9797 GIT binary patch literal 18941 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 literal 0 HcmV?d00001 diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\346\236\204\344\273\266\345\233\276.png" "b/Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\346\236\204\344\273\266\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..d9dd6aa2596233b4561389858eacad789369f66a GIT binary patch literal 22224 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 literal 0 HcmV?d00001 diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\346\264\273\345\212\250\345\233\276.png" "b/Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\346\264\273\345\212\250\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..bb9e57f33865b200896c1c920c6985f6066b26bb GIT binary patch literal 39551 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 literal 0 HcmV?d00001 diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\347\212\266\346\200\201\345\233\276.png" "b/Feat_16\347\247\221\344\272\2147\347\273\204/UML\345\233\276/\347\212\266\346\200\201\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..7357c9dae9c84084d75efa7cf9bbb2ce5cea5c6c GIT binary patch literal 13472 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 pRgac2!5RJkBW9T8eP?PyRU* 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 literal 0 HcmV?d00001 diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android.zip" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android.zip" new file mode 100644 index 0000000000000000000000000000000000000000..c18b6f6b39bbc4751e0cef30f0664f8f1e571d0c GIT binary patch literal 404588 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�*E?@u+GZZV7zBA^xTS`IX~BXOLfe0t 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

uSk8N0Zy#r;6&vi8=tS83hTbSDSeT0jI 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 QVA@5Xb+)tI?BDakxI2Md>8mVvo)?j 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 literal 0 HcmV?d00001 diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/.gitignore" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/.gitignore" new file mode 100644 index 0000000..d245ab6 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/.gitignore" @@ -0,0 +1,29 @@ +# This file is based on https://github.com/github/gitignore/blob/master/Android.gitignore +*.iml +.idea/compiler.xml +.idea/copyright +.idea/dictionaries +.idea/gradle.xml +.idea/libraries +.idea/inspectionProfiles +.idea/misc.xml +.idea/modules.xml +.idea/runConfigurations.xml +.idea/tasks.xml +.idea/workspace.xml +.gradle +local.properties +.DS_Store +build/ +gradleBuild/ +*.apk +*.ap_ +*.dex +*.class +bin/ +gen/ +out/ +*.log +.navigation/ +/captures +.externalNativeBuild diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/AndroidManifest.xml" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/AndroidManifest.xml" new file mode 100644 index 0000000..5c47ce6 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/AndroidManifest.xml" @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/BUILD" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/BUILD" new file mode 100644 index 0000000..f5f0d7c --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/BUILD" @@ -0,0 +1,123 @@ +# Description: +# TensorFlow camera demo app for Android. + +load("@build_bazel_rules_android//android:rules.bzl", "android_binary") + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) # Apache 2.0 + +load( + "//tensorflow:tensorflow.bzl", + "tf_copts", + "tf_opts_nortti_if_android", +) + +exports_files(["LICENSE"]) + +LINKER_SCRIPT = "//tensorflow/contrib/android:jni/version_script.lds" + +# libtensorflow_demo.so contains the native code for image colorspace conversion +# and object tracking used by the demo. It does not require TF as a dependency +# to build if STANDALONE_DEMO_LIB is defined. +# TF support for the demo is provided separately by libtensorflow_inference.so. +cc_binary( + name = "libtensorflow_demo.so", + srcs = glob([ + "jni/**/*.cc", + "jni/**/*.h", + ]), + copts = tf_copts(), + defines = ["STANDALONE_DEMO_LIB"], + linkopts = [ + "-landroid", + "-ldl", + "-ljnigraphics", + "-llog", + "-lm", + "-z defs", + "-s", + "-Wl,--version-script", # This line must be directly followed by LINKER_SCRIPT. + "$(location {})".format(LINKER_SCRIPT), + ], + linkshared = 1, + linkstatic = 1, + tags = [ + "manual", + "notap", + ], + deps = [ + LINKER_SCRIPT, + ], +) + +cc_library( + name = "tensorflow_native_libs", + srcs = [ + ":libtensorflow_demo.so", + "//tensorflow/contrib/android:libtensorflow_inference.so", + ], + tags = [ + "manual", + "notap", + ], +) + +android_binary( + name = "tensorflow_demo", + srcs = glob([ + "src/**/*.java", + ]), + aapt_version = "aapt", + # Package assets from assets dir as well as all model targets. Remove undesired models + # (and corresponding Activities in source) to reduce APK size. + assets = [ + "//tensorflow/examples/android/assets:asset_files", + ":external_assets", + ], + assets_dir = "", + custom_package = "org.tensorflow.demo", + inline_constants = 1, + manifest = "AndroidManifest.xml", + resource_files = glob(["res/**"]), + tags = [ + "manual", + "notap", + ], + deps = [ + ":tensorflow_native_libs", + "//tensorflow/contrib/android:android_tensorflow_inference_java", + ], +) + +# LINT.IfChange +filegroup( + name = "external_assets", + srcs = [ + "@inception_v1//:model_files", + "@mobile_ssd//:model_files", + "@speech_commands//:model_files", + "@stylize//:model_files", + ], +) +# LINT.ThenChange(//tensorflow/examples/android/download-models.gradle) + +filegroup( + name = "java_files", + srcs = glob(["src/**/*.java"]), +) + +filegroup( + name = "jni_files", + srcs = glob([ + "jni/**/*.cc", + "jni/**/*.h", + ]), +) + +filegroup( + name = "resource_files", + srcs = glob(["res/**"]), +) + +exports_files(["AndroidManifest.xml"]) diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/README.md" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/README.md" new file mode 100644 index 0000000..4e4e168 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/README.md" @@ -0,0 +1,213 @@ +# TensorFlow Android Camera Demo + +This folder contains an example application utilizing TensorFlow for Android +devices. + +## Description + +The demos in this folder are designed to give straightforward samples of using +TensorFlow in mobile applications. + +Inference is done using the [TensorFlow Android Inference +Interface](../../../tensorflow/contrib/android), which may be built separately +if you want a standalone library to drop into your existing application. Object +tracking and efficient YUV -> RGB conversion are handled by +`libtensorflow_demo.so`. + +A device running Android 5.0 (API 21) or higher is required to run the demo due +to the use of the camera2 API, although the native libraries themselves can run +on API >= 14 devices. + +## Current samples: + +1. [TF Classify](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/android/src/org/tensorflow/demo/ClassifierActivity.java): + Uses the [Google Inception](https://arxiv.org/abs/1409.4842) + model to classify camera frames in real-time, displaying the top results + in an overlay on the camera image. +2. [TF Detect](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/android/src/org/tensorflow/demo/DetectorActivity.java): + Demonstrates an SSD-Mobilenet model trained using the + [Tensorflow Object Detection API](https://github.com/tensorflow/models/tree/master/research/object_detection/) + introduced in [Speed/accuracy trade-offs for modern convolutional object detectors](https://arxiv.org/abs/1611.10012) to + localize and track objects (from 80 categories) in the camera preview + in real-time. +3. [TF Stylize](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/android/src/org/tensorflow/demo/StylizeActivity.java): + Uses a model based on [A Learned Representation For Artistic + Style](https://arxiv.org/abs/1610.07629) to restyle the camera preview + image to that of a number of different artists. +4. [TF + Speech](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/android/src/org/tensorflow/demo/SpeechActivity.java): + Runs a simple speech recognition model built by the [audio training + tutorial](https://www.tensorflow.org/versions/master/tutorials/audio_recognition). Listens + for a small set of words, and highlights them in the UI when they are + recognized. + + + +## Prebuilt Components: + +The fastest path to trying the demo is to download the [prebuilt demo APK](http://download.tensorflow.org/deps/tflite/TfLiteCameraDemo.apk). + +Also available are precompiled native libraries, and a jcenter package that you +may simply drop into your own applications. See +[tensorflow/contrib/android/README.md](../../../tensorflow/contrib/android/README.md) +for more details. + +## Running the Demo + +Once the app is installed it can be started via the "TF Classify", "TF Detect", +"TF Stylize", and "TF Speech" icons, which have the orange TensorFlow logo as +their icon. + +While running the activities, pressing the volume keys on your device will +toggle debug visualizations on/off, rendering additional info to the screen that +may be useful for development purposes. + +## Building in Android Studio using the TensorFlow AAR from JCenter + +The simplest way to compile the demo app yourself, and try out changes to the +project code is to use AndroidStudio. Simply set this `android` directory as the +project root. + +Then edit the `build.gradle` file and change the value of `nativeBuildSystem` to +`'none'` so that the project is built in the simplest way possible: + +```None +def nativeBuildSystem = 'none' +``` + +While this project includes full build integration for TensorFlow, this setting +disables it, and uses the TensorFlow Inference Interface package from JCenter. + +Note: Currently, in this build mode, YUV -> RGB is done using a less efficient +Java implementation, and object tracking is not available in the "TF Detect" +activity. Setting the build system to `'cmake'` currently only builds +`libtensorflow_demo.so`, which provides fast YUV -> RGB conversion and object +tracking, while still acquiring TensorFlow support via the downloaded AAR, so it +may be a lightweight way to enable these features. + +For any project that does not include custom low level TensorFlow code, this is +likely sufficient. + +For details on how to include this JCenter package in your own project see +[tensorflow/contrib/android/README.md](../../../tensorflow/contrib/android/README.md) + +## Building the Demo with TensorFlow from Source + +Pick your preferred approach below. At the moment, we have full support for +Bazel, and partial support for gradle, cmake, make, and Android Studio. + +As a first step for all build types, clone the TensorFlow repo with: + +``` +git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git +``` + +Note that `--recurse-submodules` is necessary to prevent some issues with +protobuf compilation. + +### Bazel + +NOTE: Bazel does not currently support building for Android on Windows. Full +support for gradle/cmake builds is coming soon, but in the meantime we suggest +that Windows users download the [prebuilt demo APK](http://download.tensorflow.org/deps/tflite/TfLiteCameraDemo.apk) instead. + +##### Install Bazel and Android Prerequisites + +Bazel is the primary build system for TensorFlow. To build with Bazel, it and +the Android NDK and SDK must be installed on your system. + +1. Install the latest version of Bazel as per the instructions [on the Bazel + website](https://bazel.build/versions/master/docs/install.html). +2. The Android NDK is required to build the native (C/C++) TensorFlow code. The + current recommended version is 14b, which may be found + [here](https://developer.android.com/ndk/downloads/older_releases.html#ndk-14b-downloads). +3. The Android SDK and build tools may be obtained + [here](https://developer.android.com/tools/revisions/build-tools.html), or + alternatively as part of [Android + Studio](https://developer.android.com/studio/index.html). Build tools API >= + 23 is required to build the TF Android demo (though it will run on API >= 21 + devices). + +##### Edit WORKSPACE + +NOTE: As long as you have the SDK and NDK installed, the `./configure` script +will create these rules for you. Answer "Yes" when the script asks to +automatically configure the `./WORKSPACE`. + +The Android entries in +[`/WORKSPACE`](../../../WORKSPACE#L19-L36) must be uncommented +with the paths filled in appropriately depending on where you installed the NDK +and SDK. Otherwise an error such as: "The external label +'//external:android/sdk' is not bound to anything" will be reported. + +Also edit the API levels for the SDK in WORKSPACE to the highest level you have +installed in your SDK. This must be >= 23 (this is completely independent of the +API level of the demo, which is defined in AndroidManifest.xml). The NDK API +level may remain at 14. + +##### Install Model Files (optional) + +The TensorFlow `GraphDef`s that contain the model definitions and weights are +not packaged in the repo because of their size. They are downloaded +automatically and packaged with the APK by Bazel via a new_http_archive defined +in `WORKSPACE` during the build process, and by Gradle via +download-models.gradle. + +**Optional**: If you wish to place the models in your assets manually, remove +all of the `model_files` entries from the `assets` list in `tensorflow_demo` +found in the [`BUILD`](BUILD#L92) file. Then download and extract the archives +yourself to the `assets` directory in the source tree: + +```bash +BASE_URL=https://storage.googleapis.com/download.tensorflow.org/models +for MODEL_ZIP in inception5h.zip ssd_mobilenet_v1_android_export.zip stylize_v1.zip +do + curl -L ${BASE_URL}/${MODEL_ZIP} -o /tmp/${MODEL_ZIP} + unzip /tmp/${MODEL_ZIP} -d tensorflow/examples/android/assets/ +done +``` + +This will extract the models and their associated metadata files to the local +assets/ directory. + +If you are using Gradle, make sure to remove download-models.gradle reference +from build.gradle after your manually download models; otherwise gradle might +download models again and overwrite your models. + +##### Build + +After editing your WORKSPACE file to update the SDK/NDK configuration, you may +build the APK. Run this from your workspace root: + +```bash +bazel build --cxxopt='--std=c++11' -c opt //tensorflow/examples/android:tensorflow_demo +``` + +##### Install + +Make sure that adb debugging is enabled on your Android 5.0 (API 21) or later +device, then after building use the following command from your workspace root +to install the APK: + +```bash +adb install -r bazel-bin/tensorflow/examples/android/tensorflow_demo.apk +``` + +### Android Studio with Bazel + +Android Studio may be used to build the demo in conjunction with Bazel. First, +make sure that you can build with Bazel following the above directions. Then, +look at [build.gradle](build.gradle) and make sure that the path to Bazel +matches that of your system. + +At this point you can add the tensorflow/examples/android directory as a new +Android Studio project. Click through installing all the Gradle extensions it +requests, and you should be able to have Android Studio build the demo like any +other application (it will call out to Bazel to build the native code with the +NDK). + +### CMake + +Full CMake support for the demo is coming soon, but for now it is possible to +build the TensorFlow Android Inference library using +[tensorflow/contrib/android/cmake](../../../tensorflow/contrib/android/cmake). diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/__init__.py" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/__init__.py" new file mode 100644 index 0000000..e69de29 diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/assets/BUILD" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/assets/BUILD" new file mode 100644 index 0000000..c827de7 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/assets/BUILD" @@ -0,0 +1,15 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) # Apache 2.0 + +# It is necessary to use this filegroup rather than globbing the files in this +# folder directly the examples/android:tensorflow_demo target due to the fact +# that assets_dir is necessarily set to "" there (to allow using other +# arbitrary targets as assets). +filegroup( + name = "asset_files", + srcs = glob( + ["**/*"], + exclude = ["BUILD"], + ), +) diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/build.gradle" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/build.gradle" new file mode 100644 index 0000000..0767726 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/build.gradle" @@ -0,0 +1,194 @@ +// This file provides basic support for building the TensorFlow demo +// in Android Studio with Gradle. +// +// Note that Bazel is still used by default to compile the native libs, +// and should be installed at the location noted below. This build file +// automates the process of calling out to it and copying the compiled +// libraries back into the appropriate directory. +// +// Alternatively, experimental support for Makefile builds is provided by +// setting nativeBuildSystem below to 'makefile'. This will allow building the demo +// on Windows machines, but note that full equivalence with the Bazel +// build is not yet guaranteed. See comments below for caveats and tips +// for speeding up the build, such as enabling ccache. +// NOTE: Running a make build will cause subsequent Bazel builds to *fail* +// unless the contrib/makefile/downloads/ and gen/ dirs are deleted afterwards. + +// The cmake build only creates libtensorflow_demo.so. In this situation, +// libtensorflow_inference.so will be acquired via the tensorflow.aar dependency. + +// It is necessary to customize Gradle's build directory, as otherwise +// it will conflict with the BUILD file used by Bazel on case-insensitive OSs. +project.buildDir = 'gradleBuild' +getProject().setBuildDir('gradleBuild') + +buildscript { + repositories { + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.0.1' + classpath 'org.apache.httpcomponents:httpclient:4.5.4' + } +} + +allprojects { + repositories { + jcenter() + } +} + +// set to 'bazel', 'cmake', 'makefile', 'none' +def nativeBuildSystem = 'bazel' + +// Controls output directory in APK and CPU type for Bazel builds. +// NOTE: Does not affect the Makefile build target API (yet), which currently +// assumes armeabi-v7a. If building with make, changing this will require +// editing the Makefile as well. +// The CMake build has only been tested with armeabi-v7a; others may not work. +def cpuType = 'armeabi-v7a' + +// Output directory in the local directory for packaging into the APK. +def nativeOutDir = 'libs/' + cpuType + +// Default to building with Bazel and override with make if requested. +def nativeBuildRule = 'buildNativeBazel' +def demoLibPath = '../../../bazel-bin/tensorflow/examples/android/libtensorflow_demo.so' +def inferenceLibPath = '../../../bazel-bin/tensorflow/contrib/android/libtensorflow_inference.so' + +// Override for Makefile builds. +if (nativeBuildSystem == 'makefile') { + nativeBuildRule = 'buildNativeMake' + demoLibPath = '../../../tensorflow/contrib/makefile/gen/lib/android_' + cpuType + '/libtensorflow_demo.so' + inferenceLibPath = '../../../tensorflow/contrib/makefile/gen/lib/android_' + cpuType + '/libtensorflow_inference.so' +} + +// If building with Bazel, this is the location of the bazel binary. +// NOTE: Bazel does not yet support building for Android on Windows, +// so in this case the Makefile build must be used as described above. +def bazelLocation = '/usr/local/bin/bazel' + +// import DownloadModels task +project.ext.ASSET_DIR = projectDir.toString() + '/assets' +project.ext.TMP_DIR = project.buildDir.toString() + '/downloads' + +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion '26.0.2' + + if (nativeBuildSystem == 'cmake') { + defaultConfig { + applicationId = 'org.tensorflow.demo' + minSdkVersion 21 + targetSdkVersion 23 + ndk { + abiFilters "${cpuType}" + } + externalNativeBuild { + cmake { + arguments '-DANDROID_TOOLCHAIN=gcc', '-DANDROID_STL=gnustl_static' + } + } + } + externalNativeBuild { + cmake { + path './jni/CMakeLists.txt' + } + } + } + + lintOptions { + abortOnError false + } + + sourceSets { + main { + if (nativeBuildSystem == 'bazel' || nativeBuildSystem == 'makefile') { + // TensorFlow Java API sources. + java { + srcDir '../../java/src/main/java' + exclude '**/examples/**' + } + + // Android TensorFlow wrappers, etc. + java { + srcDir '../../contrib/android/java' + } + } + // Android demo app sources. + java { + srcDir 'src' + } + + manifest.srcFile 'AndroidManifest.xml' + resources.srcDirs = ['src'] + aidl.srcDirs = ['src'] + renderscript.srcDirs = ['src'] + res.srcDirs = ['res'] + assets.srcDirs = [project.ext.ASSET_DIR] + jniLibs.srcDirs = ['libs'] + } + + debug.setRoot('build-types/debug') + release.setRoot('build-types/release') + } +} + +task buildNativeBazel(type: Exec) { + workingDir '../../..' + commandLine bazelLocation, 'build', '-c', 'opt', \ + 'tensorflow/examples/android:tensorflow_native_libs', \ + '--crosstool_top=//external:android/crosstool', \ + '--cpu=' + cpuType, \ + '--host_crosstool_top=@bazel_tools//tools/cpp:toolchain' +} + +task buildNativeMake(type: Exec) { + environment "NDK_ROOT", android.ndkDirectory + // Tip: install ccache and uncomment the following to speed up + // builds significantly. + // environment "CC_PREFIX", 'ccache' + workingDir '../../..' + commandLine 'tensorflow/contrib/makefile/build_all_android.sh', \ + '-s', \ + 'tensorflow/contrib/makefile/sub_makefiles/android/Makefile.in', \ + '-t', \ + 'libtensorflow_inference.so libtensorflow_demo.so all' \ + , '-a', cpuType \ + //, '-T' // Uncomment to skip protobuf and speed up subsequent builds. +} + + +task copyNativeLibs(type: Copy) { + from demoLibPath + from inferenceLibPath + into nativeOutDir + duplicatesStrategy = 'include' + dependsOn nativeBuildRule + fileMode 0644 +} + +tasks.whenTaskAdded { task -> + if (nativeBuildSystem == 'bazel' || nativeBuildSystem == 'makefile') { + if (task.name == 'assembleDebug') { + task.dependsOn 'copyNativeLibs' + } + if (task.name == 'assembleRelease') { + task.dependsOn 'copyNativeLibs' + } + } +} + +// Download default models; if you wish to use your own models then +// place them in the "assets" directory and comment out this line. +apply from: "download-models.gradle" + + +dependencies { + if (nativeBuildSystem == 'cmake' || nativeBuildSystem == 'none') { + compile 'org.tensorflow:tensorflow-android:+' + } +} diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/download-models.gradle" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/download-models.gradle" new file mode 100644 index 0000000..d3b67ea --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/download-models.gradle" @@ -0,0 +1,70 @@ +/* + * download-models.gradle + * Downloads model files from ${MODEL_URL} into application's asset folder + * Input: + * project.ext.TMP_DIR: absolute path to hold downloaded zip files + * project.ext.ASSET_DIR: absolute path to save unzipped model files + * Output: + * 3 model files will be downloaded into given folder of ext.ASSET_DIR + */ +// hard coded model files +// LINT.IfChange +def models = ['inception_v1.zip', + 'object_detection/ssd_mobilenet_v1_android_export.zip', + 'stylize_v1.zip', + 'speech_commands_conv_actions.zip'] +// LINT.ThenChange(//tensorflow/examples/android/BUILD) + +// Root URL for model archives +def MODEL_URL = 'https://storage.googleapis.com/download.tensorflow.org/models' + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'de.undercouch:gradle-download-task:3.2.0' + } +} + +import de.undercouch.gradle.tasks.download.Download +task downloadFile(type: Download){ + for (f in models) { + src "${MODEL_URL}/" + f + } + dest new File(project.ext.TMP_DIR) + overwrite true +} + +task extractModels(type: Copy) { + for (f in models) { + def localFile = f.split("/")[-1] + from zipTree(project.ext.TMP_DIR + '/' + localFile) + } + + into file(project.ext.ASSET_DIR) + fileMode 0644 + exclude '**/LICENSE' + + def needDownload = false + for (f in models) { + def localFile = f.split("/")[-1] + if (!(new File(project.ext.TMP_DIR + '/' + localFile)).exists()) { + needDownload = true + } + } + + if (needDownload) { + dependsOn downloadFile + } +} + +tasks.whenTaskAdded { task -> + if (task.name == 'assembleDebug') { + task.dependsOn 'extractModels' + } + if (task.name == 'assembleRelease') { + task.dependsOn 'extractModels' + } +} + diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradle/wrapper/gradle-wrapper.jar" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradle/wrapper/gradle-wrapper.jar" new file mode 100644 index 0000000000000000000000000000000000000000..13372aef5e24af05341d49695ee84e5f9b594659 GIT binary patch literal 53636 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ⅅ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 H-+%o-(+5aQ literal 0 HcmV?d00001 diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradle/wrapper/gradle-wrapper.properties" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradle/wrapper/gradle-wrapper.properties" new file mode 100644 index 0000000..bd9ee87 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradle/wrapper/gradle-wrapper.properties" @@ -0,0 +1,6 @@ +#Sat Nov 18 15:06:47 CET 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradlew" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradlew" new file mode 100644 index 0000000..9d82f78 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradlew" @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradlew.bat" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradlew.bat" new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/gradlew.bat" @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/CMakeLists.txt" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/CMakeLists.txt" new file mode 100644 index 0000000..c823846 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/CMakeLists.txt" @@ -0,0 +1,51 @@ +# +# Copyright (C) 2016 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +project(TENSORFLOW_DEMO) +cmake_minimum_required(VERSION 3.4.1) + +set(CMAKE_VERBOSE_MAKEFILE on) + +get_filename_component(TF_SRC_ROOT ${CMAKE_SOURCE_DIR}/../../../.. ABSOLUTE) +get_filename_component(SAMPLE_SRC_DIR ${CMAKE_SOURCE_DIR}/.. ABSOLUTE) + +if (ANDROID_ABI MATCHES "^armeabi-v7a$") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfloat-abi=softfp -mfpu=neon") +elseif(ANDROID_ABI MATCHES "^arm64-v8a") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -ftree-vectorize") +endif() + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTANDALONE_DEMO_LIB \ + -std=c++11 -fno-exceptions -fno-rtti -O2 -Wno-narrowing \ + -fPIE") +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} \ + -Wl,--allow-multiple-definition \ + -Wl,--whole-archive -fPIE -v") + +file(GLOB_RECURSE tensorflow_demo_sources ${SAMPLE_SRC_DIR}/jni/*.*) +add_library(tensorflow_demo SHARED + ${tensorflow_demo_sources}) +target_include_directories(tensorflow_demo PRIVATE + ${TF_SRC_ROOT} + ${CMAKE_SOURCE_DIR}) + +target_link_libraries(tensorflow_demo + android + log + jnigraphics + m + atomic + z) diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/__init__.py" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/__init__.py" new file mode 100644 index 0000000..e69de29 diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/imageutils_jni.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/imageutils_jni.cc" new file mode 100644 index 0000000..a7b39bd --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/imageutils_jni.cc" @@ -0,0 +1,163 @@ +/* Copyright 2015 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// This file binds the native image utility code to the Java class +// which exposes them. + +#include +#include +#include + +#include "tensorflow/examples/android/jni/rgb2yuv.h" +#include "tensorflow/examples/android/jni/yuv2rgb.h" + +#define IMAGEUTILS_METHOD(METHOD_NAME) \ + Java_org_tensorflow_demo_env_ImageUtils_##METHOD_NAME // NOLINT + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT void JNICALL +IMAGEUTILS_METHOD(convertYUV420SPToARGB8888)( + JNIEnv* env, jclass clazz, jbyteArray input, jintArray output, + jint width, jint height, jboolean halfSize); + +JNIEXPORT void JNICALL IMAGEUTILS_METHOD(convertYUV420ToARGB8888)( + JNIEnv* env, jclass clazz, jbyteArray y, jbyteArray u, jbyteArray v, + jintArray output, jint width, jint height, jint y_row_stride, + jint uv_row_stride, jint uv_pixel_stride, jboolean halfSize); + +JNIEXPORT void JNICALL IMAGEUTILS_METHOD(convertYUV420SPToRGB565)( + JNIEnv* env, jclass clazz, jbyteArray input, jbyteArray output, jint width, + jint height); + +JNIEXPORT void JNICALL +IMAGEUTILS_METHOD(convertARGB8888ToYUV420SP)( + JNIEnv* env, jclass clazz, jintArray input, jbyteArray output, + jint width, jint height); + +JNIEXPORT void JNICALL +IMAGEUTILS_METHOD(convertRGB565ToYUV420SP)( + JNIEnv* env, jclass clazz, jbyteArray input, jbyteArray output, + jint width, jint height); + +#ifdef __cplusplus +} +#endif + +JNIEXPORT void JNICALL +IMAGEUTILS_METHOD(convertYUV420SPToARGB8888)( + JNIEnv* env, jclass clazz, jbyteArray input, jintArray output, + jint width, jint height, jboolean halfSize) { + jboolean inputCopy = JNI_FALSE; + jbyte* const i = env->GetByteArrayElements(input, &inputCopy); + + jboolean outputCopy = JNI_FALSE; + jint* const o = env->GetIntArrayElements(output, &outputCopy); + + if (halfSize) { + ConvertYUV420SPToARGB8888HalfSize(reinterpret_cast(i), + reinterpret_cast(o), width, + height); + } else { + ConvertYUV420SPToARGB8888(reinterpret_cast(i), + reinterpret_cast(i) + width * height, + reinterpret_cast(o), width, height); + } + + env->ReleaseByteArrayElements(input, i, JNI_ABORT); + env->ReleaseIntArrayElements(output, o, 0); +} + +JNIEXPORT void JNICALL IMAGEUTILS_METHOD(convertYUV420ToARGB8888)( + JNIEnv* env, jclass clazz, jbyteArray y, jbyteArray u, jbyteArray v, + jintArray output, jint width, jint height, jint y_row_stride, + jint uv_row_stride, jint uv_pixel_stride, jboolean halfSize) { + jboolean inputCopy = JNI_FALSE; + jbyte* const y_buff = env->GetByteArrayElements(y, &inputCopy); + jboolean outputCopy = JNI_FALSE; + jint* const o = env->GetIntArrayElements(output, &outputCopy); + + if (halfSize) { + ConvertYUV420SPToARGB8888HalfSize(reinterpret_cast(y_buff), + reinterpret_cast(o), width, + height); + } else { + jbyte* const u_buff = env->GetByteArrayElements(u, &inputCopy); + jbyte* const v_buff = env->GetByteArrayElements(v, &inputCopy); + + ConvertYUV420ToARGB8888( + reinterpret_cast(y_buff), reinterpret_cast(u_buff), + reinterpret_cast(v_buff), reinterpret_cast(o), + width, height, y_row_stride, uv_row_stride, uv_pixel_stride); + + env->ReleaseByteArrayElements(u, u_buff, JNI_ABORT); + env->ReleaseByteArrayElements(v, v_buff, JNI_ABORT); + } + + env->ReleaseByteArrayElements(y, y_buff, JNI_ABORT); + env->ReleaseIntArrayElements(output, o, 0); +} + +JNIEXPORT void JNICALL IMAGEUTILS_METHOD(convertYUV420SPToRGB565)( + JNIEnv* env, jclass clazz, jbyteArray input, jbyteArray output, jint width, + jint height) { + jboolean inputCopy = JNI_FALSE; + jbyte* const i = env->GetByteArrayElements(input, &inputCopy); + + jboolean outputCopy = JNI_FALSE; + jbyte* const o = env->GetByteArrayElements(output, &outputCopy); + + ConvertYUV420SPToRGB565(reinterpret_cast(i), + reinterpret_cast(o), width, height); + + env->ReleaseByteArrayElements(input, i, JNI_ABORT); + env->ReleaseByteArrayElements(output, o, 0); +} + +JNIEXPORT void JNICALL +IMAGEUTILS_METHOD(convertARGB8888ToYUV420SP)( + JNIEnv* env, jclass clazz, jintArray input, jbyteArray output, + jint width, jint height) { + jboolean inputCopy = JNI_FALSE; + jint* const i = env->GetIntArrayElements(input, &inputCopy); + + jboolean outputCopy = JNI_FALSE; + jbyte* const o = env->GetByteArrayElements(output, &outputCopy); + + ConvertARGB8888ToYUV420SP(reinterpret_cast(i), + reinterpret_cast(o), width, height); + + env->ReleaseIntArrayElements(input, i, JNI_ABORT); + env->ReleaseByteArrayElements(output, o, 0); +} + +JNIEXPORT void JNICALL +IMAGEUTILS_METHOD(convertRGB565ToYUV420SP)( + JNIEnv* env, jclass clazz, jbyteArray input, jbyteArray output, + jint width, jint height) { + jboolean inputCopy = JNI_FALSE; + jbyte* const i = env->GetByteArrayElements(input, &inputCopy); + + jboolean outputCopy = JNI_FALSE; + jbyte* const o = env->GetByteArrayElements(output, &outputCopy); + + ConvertRGB565ToYUV420SP(reinterpret_cast(i), + reinterpret_cast(o), width, height); + + env->ReleaseByteArrayElements(input, i, JNI_ABORT); + env->ReleaseByteArrayElements(output, o, 0); +} diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/config.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/config.h" new file mode 100644 index 0000000..47de2d2 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/config.h" @@ -0,0 +1,300 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_CONFIG_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_CONFIG_H_ + +#include + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" + +namespace tf_tracking { + +// Arbitrary keypoint type ids for labeling the origin of tracked keypoints. +enum KeypointType { + KEYPOINT_TYPE_DEFAULT = 0, + KEYPOINT_TYPE_FAST = 1, + KEYPOINT_TYPE_INTEREST = 2 +}; + +// Struct that can be used to more richly store the results of a detection +// than a single number, while still maintaining comparability. +struct MatchScore { + explicit MatchScore(double val) : value(val) {} + MatchScore() { value = 0.0; } + + double value; + + MatchScore& operator+(const MatchScore& rhs) { + value += rhs.value; + return *this; + } + + friend std::ostream& operator<<(std::ostream& stream, + const MatchScore& detection) { + stream << detection.value; + return stream; + } +}; +inline bool operator< (const MatchScore& cC1, const MatchScore& cC2) { + return cC1.value < cC2.value; +} +inline bool operator> (const MatchScore& cC1, const MatchScore& cC2) { + return cC1.value > cC2.value; +} +inline bool operator>= (const MatchScore& cC1, const MatchScore& cC2) { + return cC1.value >= cC2.value; +} +inline bool operator<= (const MatchScore& cC1, const MatchScore& cC2) { + return cC1.value <= cC2.value; +} + +// Fixed seed used for all random number generators. +static const int kRandomNumberSeed = 11111; + +// TODO(andrewharp): Move as many of these settings as possible into a settings +// object which can be passed in from Java at runtime. + +// Whether or not to use ESM instead of LK flow. +static const bool kUseEsm = false; + +// This constant gets added to the diagonal of the Hessian +// before solving for translation in 2dof ESM. +// It ensures better behavior especially in the absence of +// strong texture. +static const int kEsmRegularizer = 20; + +// Do we want to brightness-normalize each keypoint patch when we compute +// its flow using ESM? +static const bool kDoBrightnessNormalize = true; + +// Whether or not to use fixed-point interpolated pixel lookups in optical flow. +#define USE_FIXED_POINT_FLOW 1 + +// Whether to normalize keypoint windows for intensity in LK optical flow. +// This is a define for now because it helps keep the code streamlined. +#define NORMALIZE 1 + +// Number of keypoints to store per frame. +static const int kMaxKeypoints = 76; + +// Keypoint detection. +static const int kMaxTempKeypoints = 1024; + +// Number of floats each keypoint takes up when exporting to an array. +static const int kKeypointStep = 7; + +// Number of frame deltas to keep around in the circular queue. +static const int kNumFrames = 512; + +// Number of iterations to do tracking on each keypoint at each pyramid level. +static const int kNumIterations = 3; + +// The number of bins (on a side) to divide each bin from the previous +// cache level into. Higher numbers will decrease performance by increasing +// cache misses, but mean that cache hits are more locally relevant. +static const int kCacheBranchFactor = 2; + +// Number of levels to put in the cache. +// Each level of the cache is a square grid of bins, length: +// branch_factor^(level - 1) on each side. +// +// This may be greater than kNumPyramidLevels. Setting it to 0 means no +// caching is enabled. +static const int kNumCacheLevels = 3; + +// The level at which the cache pyramid gets cut off and replaced by a matrix +// transform if such a matrix has been provided to the cache. +static const int kCacheCutoff = 1; + +static const int kNumPyramidLevels = 4; + +// The minimum number of keypoints needed in an object's area. +static const int kMaxKeypointsForObject = 16; + +// Minimum number of pyramid levels to use after getting cached value. +// This allows fine-scale adjustment from the cached value, which is taken +// from the center of the corresponding top cache level box. +// Can be [0, kNumPyramidLevels). +static const int kMinNumPyramidLevelsToUseForAdjustment = 1; + +// Window size to integrate over to find local image derivative. +static const int kFlowIntegrationWindowSize = 3; + +// Total area of integration windows. +static const int kFlowArraySize = + (2 * kFlowIntegrationWindowSize + 1) * (2 * kFlowIntegrationWindowSize + 1); + +// Error that's considered good enough to early abort tracking. +static const float kTrackingAbortThreshold = 0.03f; + +// Maximum number of deviations a keypoint-correspondence delta can be from the +// weighted average before being thrown out for region-based queries. +static const float kNumDeviations = 2.0f; + +// The length of the allowed delta between the forward and the backward +// flow deltas in terms of the length of the forward flow vector. +static const float kMaxForwardBackwardErrorAllowed = 0.5f; + +// Threshold for pixels to be considered different. +static const int kFastDiffAmount = 10; + +// How far from edge of frame to stop looking for FAST keypoints. +static const int kFastBorderBuffer = 10; + +// Determines if non-detected arbitrary keypoints should be added to regions. +// This will help if no keypoints have been detected in the region yet. +static const bool kAddArbitraryKeypoints = true; + +// How many arbitrary keypoints to add along each axis as candidates for each +// region? +static const int kNumToAddAsCandidates = 1; + +// In terms of region dimensions, how closely can we place keypoints +// next to each other? +static const float kClosestPercent = 0.6f; + +// How many FAST qualifying pixels must be connected to a pixel for it to be +// considered a candidate keypoint for Harris filtering. +static const int kMinNumConnectedForFastKeypoint = 8; + +// Size of the window to integrate over for Harris filtering. +// Compare to kFlowIntegrationWindowSize. +static const int kHarrisWindowSize = 2; + + +// DETECTOR PARAMETERS + +// Before relocalizing, make sure the new proposed position is better than +// the existing position by a small amount to prevent thrashing. +static const MatchScore kMatchScoreBuffer(0.01f); + +// Minimum score a tracked object can have and still be considered a match. +// TODO(andrewharp): Make this a per detector thing. +static const MatchScore kMinimumMatchScore(0.5f); + +static const float kMinimumCorrelationForTracking = 0.4f; + +static const MatchScore kMatchScoreForImmediateTermination(0.0f); + +// Run the detector every N frames. +static const int kDetectEveryNFrames = 4; + +// How many features does each feature_set contain? +static const int kFeaturesPerFeatureSet = 10; + +// The number of FeatureSets managed by the object detector. +// More FeatureSets can increase recall at the cost of performance. +static const int kNumFeatureSets = 7; + +// How many FeatureSets must respond affirmatively for a candidate descriptor +// and position to be given more thorough attention? +static const int kNumFeatureSetsForCandidate = 2; + +// How large the thumbnails used for correlation validation are. Used for both +// width and height. +static const int kNormalizedThumbnailSize = 11; + +// The area of intersection divided by union for the bounding boxes that tells +// if this tracking has slipped enough to invalidate all unlocked examples. +static const float kPositionOverlapThreshold = 0.6f; + +// The number of detection failures allowed before an object goes invisible. +// Tracking will still occur, so if it is actually still being tracked and +// comes back into a detectable position, it's likely to be found. +static const int kMaxNumDetectionFailures = 4; + + +// Minimum square size to scan with sliding window. +static const float kScanMinSquareSize = 16.0f; + +// Minimum square size to scan with sliding window. +static const float kScanMaxSquareSize = 64.0f; + +// Scale difference for consecutive scans of the sliding window. +static const float kScanScaleFactor = sqrtf(2.0f); + +// Step size for sliding window. +static const int kScanStepSize = 10; + + +// How tightly to pack the descriptor boxes for confirmed exemplars. +static const float kLockedScaleFactor = 1 / sqrtf(2.0f); + +// How tightly to pack the descriptor boxes for unconfirmed exemplars. +static const float kUnlockedScaleFactor = 1 / 2.0f; + +// How tightly the boxes to scan centered at the last known position will be +// packed. +static const float kLastKnownPositionScaleFactor = 1.0f / sqrtf(2.0f); + +// The bounds on how close a new object example must be to existing object +// examples for detection to be valid. +static const float kMinCorrelationForNewExample = 0.75f; +static const float kMaxCorrelationForNewExample = 0.99f; + + +// The number of safe tries an exemplar has after being created before +// missed detections count against it. +static const int kFreeTries = 5; + +// A false positive is worth this many missed detections. +static const int kFalsePositivePenalty = 5; + +struct ObjectDetectorConfig { + const Size image_size; + + explicit ObjectDetectorConfig(const Size& image_size) + : image_size(image_size) {} + virtual ~ObjectDetectorConfig() = default; +}; + +struct KeypointDetectorConfig { + const Size image_size; + + bool detect_skin; + + explicit KeypointDetectorConfig(const Size& image_size) + : image_size(image_size), + detect_skin(false) {} +}; + + +struct OpticalFlowConfig { + const Size image_size; + + explicit OpticalFlowConfig(const Size& image_size) + : image_size(image_size) {} +}; + +struct TrackerConfig { + const Size image_size; + KeypointDetectorConfig keypoint_detector_config; + OpticalFlowConfig flow_config; + bool always_track; + + float object_box_scale_factor_for_features; + + explicit TrackerConfig(const Size& image_size) + : image_size(image_size), + keypoint_detector_config(image_size), + flow_config(image_size), + always_track(false), + object_box_scale_factor_for_features(1.0f) {} +}; + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_CONFIG_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/flow_cache.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/flow_cache.h" new file mode 100644 index 0000000..b62e334 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/flow_cache.h" @@ -0,0 +1,306 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_FLOW_CACHE_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_FLOW_CACHE_H_ + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +#include "tensorflow/examples/android/jni/object_tracking/config.h" +#include "tensorflow/examples/android/jni/object_tracking/optical_flow.h" + +namespace tf_tracking { + +// Class that helps OpticalFlow to speed up flow computation +// by caching coarse-grained flow. +class FlowCache { + public: + explicit FlowCache(const OpticalFlowConfig* const config) + : config_(config), + image_size_(config->image_size), + optical_flow_(config), + fullframe_matrix_(NULL) { + for (int i = 0; i < kNumCacheLevels; ++i) { + const int curr_dims = BlockDimForCacheLevel(i); + has_cache_[i] = new Image(curr_dims, curr_dims); + displacements_[i] = new Image(curr_dims, curr_dims); + } + } + + ~FlowCache() { + for (int i = 0; i < kNumCacheLevels; ++i) { + SAFE_DELETE(has_cache_[i]); + SAFE_DELETE(displacements_[i]); + } + delete[](fullframe_matrix_); + fullframe_matrix_ = NULL; + } + + void NextFrame(ImageData* const new_frame, + const float* const align_matrix23) { + ClearCache(); + SetFullframeAlignmentMatrix(align_matrix23); + optical_flow_.NextFrame(new_frame); + } + + void ClearCache() { + for (int i = 0; i < kNumCacheLevels; ++i) { + has_cache_[i]->Clear(false); + } + delete[](fullframe_matrix_); + fullframe_matrix_ = NULL; + } + + // Finds the flow at a point, using the cache for performance. + bool FindFlowAtPoint(const float u_x, const float u_y, + float* const flow_x, float* const flow_y) const { + // Get the best guess from the cache. + const Point2f guess_from_cache = LookupGuess(u_x, u_y); + + *flow_x = guess_from_cache.x; + *flow_y = guess_from_cache.y; + + // Now refine the guess using the image pyramid. + for (int pyramid_level = kMinNumPyramidLevelsToUseForAdjustment - 1; + pyramid_level >= 0; --pyramid_level) { + if (!optical_flow_.FindFlowAtPointSingleLevel( + pyramid_level, u_x, u_y, false, flow_x, flow_y)) { + return false; + } + } + + return true; + } + + // Determines the displacement of a point, and uses that to calculate a new + // position. + // Returns true iff the displacement determination worked and the new position + // is in the image. + bool FindNewPositionOfPoint(const float u_x, const float u_y, + float* final_x, float* final_y) const { + float flow_x; + float flow_y; + if (!FindFlowAtPoint(u_x, u_y, &flow_x, &flow_y)) { + return false; + } + + // Add in the displacement to get the final position. + *final_x = u_x + flow_x; + *final_y = u_y + flow_y; + + // Assign the best guess, if we're still in the image. + if (InRange(*final_x, 0.0f, static_cast(image_size_.width) - 1) && + InRange(*final_y, 0.0f, static_cast(image_size_.height) - 1)) { + return true; + } else { + return false; + } + } + + // Comparison function for qsort. + static int Compare(const void* a, const void* b) { + return *reinterpret_cast(a) - + *reinterpret_cast(b); + } + + // Returns the median flow within the given bounding box as determined + // by a grid_width x grid_height grid. + Point2f GetMedianFlow(const BoundingBox& bounding_box, + const bool filter_by_fb_error, + const int grid_width, + const int grid_height) const { + const int kMaxPoints = 100; + SCHECK(grid_width * grid_height <= kMaxPoints, + "Too many points for Median flow!"); + + const BoundingBox valid_box = bounding_box.Intersect( + BoundingBox(0, 0, image_size_.width - 1, image_size_.height - 1)); + + if (valid_box.GetArea() <= 0.0f) { + return Point2f(0, 0); + } + + float x_deltas[kMaxPoints]; + float y_deltas[kMaxPoints]; + + int curr_offset = 0; + for (int i = 0; i < grid_width; ++i) { + for (int j = 0; j < grid_height; ++j) { + const float x_in = valid_box.left_ + + (valid_box.GetWidth() * i) / (grid_width - 1); + + const float y_in = valid_box.top_ + + (valid_box.GetHeight() * j) / (grid_height - 1); + + float curr_flow_x; + float curr_flow_y; + const bool success = FindNewPositionOfPoint(x_in, y_in, + &curr_flow_x, &curr_flow_y); + + if (success) { + x_deltas[curr_offset] = curr_flow_x; + y_deltas[curr_offset] = curr_flow_y; + ++curr_offset; + } else { + LOGW("Tracking failure!"); + } + } + } + + if (curr_offset > 0) { + qsort(x_deltas, curr_offset, sizeof(*x_deltas), Compare); + qsort(y_deltas, curr_offset, sizeof(*y_deltas), Compare); + + return Point2f(x_deltas[curr_offset / 2], y_deltas[curr_offset / 2]); + } + + LOGW("No points were valid!"); + return Point2f(0, 0); + } + + void SetFullframeAlignmentMatrix(const float* const align_matrix23) { + if (align_matrix23 != NULL) { + if (fullframe_matrix_ == NULL) { + fullframe_matrix_ = new float[6]; + } + + memcpy(fullframe_matrix_, align_matrix23, + 6 * sizeof(fullframe_matrix_[0])); + } + } + + private: + Point2f LookupGuessFromLevel( + const int cache_level, const float x, const float y) const { + // LOGE("Looking up guess at %5.2f %5.2f for level %d.", x, y, cache_level); + + // Cutoff at the target level and use the matrix transform instead. + if (fullframe_matrix_ != NULL && cache_level == kCacheCutoff) { + const float xnew = x * fullframe_matrix_[0] + + y * fullframe_matrix_[1] + + fullframe_matrix_[2]; + const float ynew = x * fullframe_matrix_[3] + + y * fullframe_matrix_[4] + + fullframe_matrix_[5]; + + return Point2f(xnew - x, ynew - y); + } + + const int level_dim = BlockDimForCacheLevel(cache_level); + const int pixels_per_cache_block_x = + (image_size_.width + level_dim - 1) / level_dim; + const int pixels_per_cache_block_y = + (image_size_.height + level_dim - 1) / level_dim; + const int index_x = x / pixels_per_cache_block_x; + const int index_y = y / pixels_per_cache_block_y; + + Point2f displacement; + if (!(*has_cache_[cache_level])[index_y][index_x]) { + (*has_cache_[cache_level])[index_y][index_x] = true; + + // Get the lower cache level's best guess, if it exists. + displacement = cache_level >= kNumCacheLevels - 1 ? + Point2f(0, 0) : LookupGuessFromLevel(cache_level + 1, x, y); + // LOGI("Best guess at cache level %d is %5.2f, %5.2f.", cache_level, + // best_guess.x, best_guess.y); + + // Find the center of the block. + const float center_x = (index_x + 0.5f) * pixels_per_cache_block_x; + const float center_y = (index_y + 0.5f) * pixels_per_cache_block_y; + const int pyramid_level = PyramidLevelForCacheLevel(cache_level); + + // LOGI("cache level %d: [%d, %d (%5.2f / %d, %5.2f / %d)] " + // "Querying %5.2f, %5.2f at pyramid level %d, ", + // cache_level, index_x, index_y, + // x, pixels_per_cache_block_x, y, pixels_per_cache_block_y, + // center_x, center_y, pyramid_level); + + // TODO(andrewharp): Turn on FB error filtering. + const bool success = optical_flow_.FindFlowAtPointSingleLevel( + pyramid_level, center_x, center_y, false, + &displacement.x, &displacement.y); + + if (!success) { + LOGV("Computation of cached value failed for level %d!", cache_level); + } + + // Store the value for later use. + (*displacements_[cache_level])[index_y][index_x] = displacement; + } else { + displacement = (*displacements_[cache_level])[index_y][index_x]; + } + + // LOGI("Returning %5.2f, %5.2f for level %d", + // displacement.x, displacement.y, cache_level); + return displacement; + } + + Point2f LookupGuess(const float x, const float y) const { + if (x < 0 || x >= image_size_.width || y < 0 || y >= image_size_.height) { + return Point2f(0, 0); + } + + // LOGI("Looking up guess at %5.2f %5.2f.", x, y); + if (kNumCacheLevels > 0) { + return LookupGuessFromLevel(0, x, y); + } else { + return Point2f(0, 0); + } + } + + // Returns the number of cache bins in each dimension for a given level + // of the cache. + int BlockDimForCacheLevel(const int cache_level) const { + // The highest (coarsest) cache level has a block dim of kCacheBranchFactor, + // thus if there are 4 cache levels, requesting level 3 (0-based) should + // return kCacheBranchFactor, level 2 should return kCacheBranchFactor^2, + // and so on. + int block_dim = kNumCacheLevels; + for (int curr_level = kNumCacheLevels - 1; curr_level > cache_level; + --curr_level) { + block_dim *= kCacheBranchFactor; + } + return block_dim; + } + + // Returns the level of the image pyramid that a given cache level maps to. + int PyramidLevelForCacheLevel(const int cache_level) const { + // Higher cache and pyramid levels have smaller dimensions. The highest + // cache level should refer to the highest image pyramid level. The + // lower, finer image pyramid levels are uncached (assuming + // kNumCacheLevels < kNumPyramidLevels). + return cache_level + (kNumPyramidLevels - kNumCacheLevels); + } + + const OpticalFlowConfig* const config_; + + const Size image_size_; + OpticalFlow optical_flow_; + + float* fullframe_matrix_; + + // Whether this value is currently present in the cache. + Image* has_cache_[kNumCacheLevels]; + + // The cached displacement values. + Image* displacements_[kNumCacheLevels]; + + TF_DISALLOW_COPY_AND_ASSIGN(FlowCache); +}; + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_FLOW_CACHE_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/frame_pair.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/frame_pair.cc" new file mode 100644 index 0000000..b1a4db6 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/frame_pair.cc" @@ -0,0 +1,308 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include + +#include "tensorflow/examples/android/jni/object_tracking/config.h" +#include "tensorflow/examples/android/jni/object_tracking/frame_pair.h" + +namespace tf_tracking { + +void FramePair::Init(const int64_t start_time, const int64_t end_time) { + start_time_ = start_time; + end_time_ = end_time; + memset(optical_flow_found_keypoint_, false, + sizeof(*optical_flow_found_keypoint_) * kMaxKeypoints); + number_of_keypoints_ = 0; +} + +void FramePair::AdjustBox(const BoundingBox box, + float* const translation_x, + float* const translation_y, + float* const scale_x, + float* const scale_y) const { + static float weights[kMaxKeypoints]; + static Point2f deltas[kMaxKeypoints]; + memset(weights, 0.0f, sizeof(*weights) * kMaxKeypoints); + + BoundingBox resized_box(box); + resized_box.Scale(0.4f, 0.4f); + FillWeights(resized_box, weights); + FillTranslations(deltas); + + const Point2f translation = GetWeightedMedian(weights, deltas); + + *translation_x = translation.x; + *translation_y = translation.y; + + const Point2f old_center = box.GetCenter(); + const int good_scale_points = + FillScales(old_center, translation, weights, deltas); + + // Default scale factor is 1 for x and y. + *scale_x = 1.0f; + *scale_y = 1.0f; + + // The assumption is that all deltas that make it to this stage with a + // correspondending optical_flow_found_keypoint_[i] == true are not in + // themselves degenerate. + // + // The degeneracy with scale arose because if the points are too close to the + // center of the objects, the scale ratio determination might be incalculable. + // + // The check for kMinNumInRange is not a degeneracy check, but merely an + // attempt to ensure some sort of stability. The actual degeneracy check is in + // the comparison to EPSILON in FillScales (which I've updated to return the + // number good remaining as well). + static const int kMinNumInRange = 5; + if (good_scale_points >= kMinNumInRange) { + const float scale_factor = GetWeightedMedianScale(weights, deltas); + + if (scale_factor > 0.0f) { + *scale_x = scale_factor; + *scale_y = scale_factor; + } + } +} + +int FramePair::FillWeights(const BoundingBox& box, + float* const weights) const { + // Compute the max score. + float max_score = -FLT_MAX; + float min_score = FLT_MAX; + for (int i = 0; i < kMaxKeypoints; ++i) { + if (optical_flow_found_keypoint_[i]) { + max_score = MAX(max_score, frame1_keypoints_[i].score_); + min_score = MIN(min_score, frame1_keypoints_[i].score_); + } + } + + int num_in_range = 0; + for (int i = 0; i < kMaxKeypoints; ++i) { + if (!optical_flow_found_keypoint_[i]) { + weights[i] = 0.0f; + continue; + } + + const bool in_box = box.Contains(frame1_keypoints_[i].pos_); + if (in_box) { + ++num_in_range; + } + + // The weighting based off distance. Anything within the bounding box + // has a weight of 1, and everything outside of that is within the range + // [0, kOutOfBoxMultiplier), falling off with the squared distance ratio. + float distance_score = 1.0f; + if (!in_box) { + const Point2f initial = box.GetCenter(); + const float sq_x_dist = + Square(initial.x - frame1_keypoints_[i].pos_.x); + const float sq_y_dist = + Square(initial.y - frame1_keypoints_[i].pos_.y); + const float squared_half_width = Square(box.GetWidth() / 2.0f); + const float squared_half_height = Square(box.GetHeight() / 2.0f); + + static const float kOutOfBoxMultiplier = 0.5f; + distance_score = kOutOfBoxMultiplier * + MIN(squared_half_height / sq_y_dist, squared_half_width / sq_x_dist); + } + + // The weighting based on relative score strength. kBaseScore - 1.0f. + float intrinsic_score = 1.0f; + if (max_score > min_score) { + static const float kBaseScore = 0.5f; + intrinsic_score = ((frame1_keypoints_[i].score_ - min_score) / + (max_score - min_score)) * (1.0f - kBaseScore) + kBaseScore; + } + + // The final score will be in the range [0, 1]. + weights[i] = distance_score * intrinsic_score; + } + + return num_in_range; +} + +void FramePair::FillTranslations(Point2f* const translations) const { + for (int i = 0; i < kMaxKeypoints; ++i) { + if (!optical_flow_found_keypoint_[i]) { + continue; + } + translations[i].x = + frame2_keypoints_[i].pos_.x - frame1_keypoints_[i].pos_.x; + translations[i].y = + frame2_keypoints_[i].pos_.y - frame1_keypoints_[i].pos_.y; + } +} + +int FramePair::FillScales(const Point2f& old_center, + const Point2f& translation, + float* const weights, + Point2f* const scales) const { + int num_good = 0; + for (int i = 0; i < kMaxKeypoints; ++i) { + if (!optical_flow_found_keypoint_[i]) { + continue; + } + + const Keypoint keypoint1 = frame1_keypoints_[i]; + const Keypoint keypoint2 = frame2_keypoints_[i]; + + const float dist1_x = keypoint1.pos_.x - old_center.x; + const float dist1_y = keypoint1.pos_.y - old_center.y; + + const float dist2_x = (keypoint2.pos_.x - translation.x) - old_center.x; + const float dist2_y = (keypoint2.pos_.y - translation.y) - old_center.y; + + // Make sure that the scale makes sense; points too close to the center + // will result in either NaNs or infinite results for scale due to + // limited tracking and floating point resolution. + // Also check that the parity of the points is the same with respect to + // x and y, as we can't really make sense of data that has flipped. + if (((dist2_x > EPSILON && dist1_x > EPSILON) || + (dist2_x < -EPSILON && dist1_x < -EPSILON)) && + ((dist2_y > EPSILON && dist1_y > EPSILON) || + (dist2_y < -EPSILON && dist1_y < -EPSILON))) { + scales[i].x = dist2_x / dist1_x; + scales[i].y = dist2_y / dist1_y; + ++num_good; + } else { + weights[i] = 0.0f; + scales[i].x = 1.0f; + scales[i].y = 1.0f; + } + } + return num_good; +} + +struct WeightedDelta { + float weight; + float delta; +}; + +// Sort by delta, not by weight. +inline int WeightedDeltaCompare(const void* const a, const void* const b) { + return (reinterpret_cast(a)->delta - + reinterpret_cast(b)->delta) <= 0 ? 1 : -1; +} + +// Returns the median delta from a sorted set of weighted deltas. +static float GetMedian(const int num_items, + const WeightedDelta* const weighted_deltas, + const float sum) { + if (num_items == 0 || sum < EPSILON) { + return 0.0f; + } + + float current_weight = 0.0f; + const float target_weight = sum / 2.0f; + for (int i = 0; i < num_items; ++i) { + if (weighted_deltas[i].weight > 0.0f) { + current_weight += weighted_deltas[i].weight; + if (current_weight >= target_weight) { + return weighted_deltas[i].delta; + } + } + } + LOGW("Median not found! %d points, sum of %.2f", num_items, sum); + return 0.0f; +} + +Point2f FramePair::GetWeightedMedian( + const float* const weights, const Point2f* const deltas) const { + Point2f median_delta; + + // TODO(andrewharp): only sort deltas that could possibly have an effect. + static WeightedDelta weighted_deltas[kMaxKeypoints]; + + // Compute median X value. + { + float total_weight = 0.0f; + + // Compute weighted mean and deltas. + for (int i = 0; i < kMaxKeypoints; ++i) { + weighted_deltas[i].delta = deltas[i].x; + const float weight = weights[i]; + weighted_deltas[i].weight = weight; + if (weight > 0.0f) { + total_weight += weight; + } + } + qsort(weighted_deltas, kMaxKeypoints, sizeof(WeightedDelta), + WeightedDeltaCompare); + median_delta.x = GetMedian(kMaxKeypoints, weighted_deltas, total_weight); + } + + // Compute median Y value. + { + float total_weight = 0.0f; + + // Compute weighted mean and deltas. + for (int i = 0; i < kMaxKeypoints; ++i) { + const float weight = weights[i]; + weighted_deltas[i].weight = weight; + weighted_deltas[i].delta = deltas[i].y; + if (weight > 0.0f) { + total_weight += weight; + } + } + qsort(weighted_deltas, kMaxKeypoints, sizeof(WeightedDelta), + WeightedDeltaCompare); + median_delta.y = GetMedian(kMaxKeypoints, weighted_deltas, total_weight); + } + + return median_delta; +} + +float FramePair::GetWeightedMedianScale( + const float* const weights, const Point2f* const deltas) const { + float median_delta; + + // TODO(andrewharp): only sort deltas that could possibly have an effect. + static WeightedDelta weighted_deltas[kMaxKeypoints * 2]; + + // Compute median scale value across x and y. + { + float total_weight = 0.0f; + + // Add X values. + for (int i = 0; i < kMaxKeypoints; ++i) { + weighted_deltas[i].delta = deltas[i].x; + const float weight = weights[i]; + weighted_deltas[i].weight = weight; + if (weight > 0.0f) { + total_weight += weight; + } + } + + // Add Y values. + for (int i = 0; i < kMaxKeypoints; ++i) { + weighted_deltas[i + kMaxKeypoints].delta = deltas[i].y; + const float weight = weights[i]; + weighted_deltas[i + kMaxKeypoints].weight = weight; + if (weight > 0.0f) { + total_weight += weight; + } + } + + qsort(weighted_deltas, kMaxKeypoints * 2, sizeof(WeightedDelta), + WeightedDeltaCompare); + + median_delta = GetMedian(kMaxKeypoints * 2, weighted_deltas, total_weight); + } + + return median_delta; +} + +} // namespace tf_tracking diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/frame_pair.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/frame_pair.h" new file mode 100644 index 0000000..6c8ac9b --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/frame_pair.h" @@ -0,0 +1,103 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_FRAME_PAIR_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_FRAME_PAIR_H_ + +#include "tensorflow/examples/android/jni/object_tracking/keypoint.h" + +namespace tf_tracking { + +// A class that records keypoint correspondences from pairs of +// consecutive frames. +class FramePair { + public: + FramePair() + : start_time_(0), + end_time_(0), + number_of_keypoints_(0) {} + + // Cleans up the FramePair so that they can be reused. + void Init(const int64_t start_time, const int64_t end_time); + + void AdjustBox(const BoundingBox box, + float* const translation_x, + float* const translation_y, + float* const scale_x, + float* const scale_y) const; + + private: + // Returns the weighted median of the given deltas, computed independently on + // x and y. Returns 0,0 in case of failure. The assumption is that a + // translation of 0.0 in the degenerate case is the best that can be done, and + // should not be considered an error. + // + // In the case of scale, a slight exception is made just to be safe and + // there is a check for 0.0 explicitly, but that shouldn't ever be possible to + // happen naturally because of the non-zero + parity checks in FillScales. + Point2f GetWeightedMedian(const float* const weights, + const Point2f* const deltas) const; + + float GetWeightedMedianScale(const float* const weights, + const Point2f* const deltas) const; + + // Weights points based on the query_point and cutoff_dist. + int FillWeights(const BoundingBox& box, + float* const weights) const; + + // Fills in the array of deltas with the translations of the points + // between frames. + void FillTranslations(Point2f* const translations) const; + + // Fills in the array of deltas with the relative scale factor of points + // relative to a given center. Has the ability to override the weight to 0 if + // a degenerate scale is detected. + // Translation is the amount the center of the box has moved from one frame to + // the next. + int FillScales(const Point2f& old_center, + const Point2f& translation, + float* const weights, + Point2f* const scales) const; + + // TODO(andrewharp): Make these private. + public: + // The time at frame1. + int64_t start_time_; + + // The time at frame2. + int64_t end_time_; + + // This array will contain the keypoints found in frame 1. + Keypoint frame1_keypoints_[kMaxKeypoints]; + + // Contain the locations of the keypoints from frame 1 in frame 2. + Keypoint frame2_keypoints_[kMaxKeypoints]; + + // The number of keypoints in frame 1. + int number_of_keypoints_; + + // Keeps track of which keypoint correspondences were actually found from one + // frame to another. + // The i-th element of this array will be non-zero if and only if the i-th + // keypoint of frame 1 was found in frame 2. + bool optical_flow_found_keypoint_[kMaxKeypoints]; + + private: + TF_DISALLOW_COPY_AND_ASSIGN(FramePair); +}; + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_FRAME_PAIR_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/geom.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/geom.h" new file mode 100644 index 0000000..c975e40 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/geom.h" @@ -0,0 +1,319 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_GEOM_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_GEOM_H_ + +#include "tensorflow/examples/android/jni/object_tracking/logging.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +namespace tf_tracking { + +struct Size { + Size(const int width, const int height) : width(width), height(height) {} + + int width; + int height; +}; + + +class Point2f { + public: + Point2f() : x(0.0f), y(0.0f) {} + Point2f(const float x, const float y) : x(x), y(y) {} + + inline Point2f operator- (const Point2f& that) const { + return Point2f(this->x - that.x, this->y - that.y); + } + + inline Point2f operator+ (const Point2f& that) const { + return Point2f(this->x + that.x, this->y + that.y); + } + + inline Point2f& operator+= (const Point2f& that) { + this->x += that.x; + this->y += that.y; + return *this; + } + + inline Point2f& operator-= (const Point2f& that) { + this->x -= that.x; + this->y -= that.y; + return *this; + } + + inline Point2f operator- (const Point2f& that) { + return Point2f(this->x - that.x, this->y - that.y); + } + + inline float LengthSquared() { + return Square(this->x) + Square(this->y); + } + + inline float Length() { + return sqrtf(LengthSquared()); + } + + inline float DistanceSquared(const Point2f& that) { + return Square(this->x - that.x) + Square(this->y - that.y); + } + + inline float Distance(const Point2f& that) { + return sqrtf(DistanceSquared(that)); + } + + float x; + float y; +}; + +inline std::ostream& operator<<(std::ostream& stream, const Point2f& point) { + stream << point.x << "," << point.y; + return stream; +} + +class BoundingBox { + public: + BoundingBox() + : left_(0), + top_(0), + right_(0), + bottom_(0) {} + + BoundingBox(const BoundingBox& bounding_box) + : left_(bounding_box.left_), + top_(bounding_box.top_), + right_(bounding_box.right_), + bottom_(bounding_box.bottom_) { + SCHECK(left_ < right_, "Bounds out of whack! %.2f vs %.2f!", left_, right_); + SCHECK(top_ < bottom_, "Bounds out of whack! %.2f vs %.2f!", top_, bottom_); + } + + BoundingBox(const float left, + const float top, + const float right, + const float bottom) + : left_(left), + top_(top), + right_(right), + bottom_(bottom) { + SCHECK(left_ < right_, "Bounds out of whack! %.2f vs %.2f!", left_, right_); + SCHECK(top_ < bottom_, "Bounds out of whack! %.2f vs %.2f!", top_, bottom_); + } + + BoundingBox(const Point2f& point1, const Point2f& point2) + : left_(MIN(point1.x, point2.x)), + top_(MIN(point1.y, point2.y)), + right_(MAX(point1.x, point2.x)), + bottom_(MAX(point1.y, point2.y)) {} + + inline void CopyToArray(float* const bounds_array) const { + bounds_array[0] = left_; + bounds_array[1] = top_; + bounds_array[2] = right_; + bounds_array[3] = bottom_; + } + + inline float GetWidth() const { + return right_ - left_; + } + + inline float GetHeight() const { + return bottom_ - top_; + } + + inline float GetArea() const { + const float width = GetWidth(); + const float height = GetHeight(); + if (width <= 0 || height <= 0) { + return 0.0f; + } + + return width * height; + } + + inline Point2f GetCenter() const { + return Point2f((left_ + right_) / 2.0f, + (top_ + bottom_) / 2.0f); + } + + inline bool ValidBox() const { + return GetArea() > 0.0f; + } + + // Returns a bounding box created from the overlapping area of these two. + inline BoundingBox Intersect(const BoundingBox& that) const { + const float new_left = MAX(this->left_, that.left_); + const float new_right = MIN(this->right_, that.right_); + + if (new_left >= new_right) { + return BoundingBox(); + } + + const float new_top = MAX(this->top_, that.top_); + const float new_bottom = MIN(this->bottom_, that.bottom_); + + if (new_top >= new_bottom) { + return BoundingBox(); + } + + return BoundingBox(new_left, new_top, new_right, new_bottom); + } + + // Returns a bounding box that can contain both boxes. + inline BoundingBox Union(const BoundingBox& that) const { + return BoundingBox(MIN(this->left_, that.left_), + MIN(this->top_, that.top_), + MAX(this->right_, that.right_), + MAX(this->bottom_, that.bottom_)); + } + + inline float PascalScore(const BoundingBox& that) const { + SCHECK(GetArea() > 0.0f, "Empty bounding box!"); + SCHECK(that.GetArea() > 0.0f, "Empty bounding box!"); + + const float intersect_area = this->Intersect(that).GetArea(); + + if (intersect_area <= 0) { + return 0; + } + + const float score = + intersect_area / (GetArea() + that.GetArea() - intersect_area); + SCHECK(InRange(score, 0.0f, 1.0f), "Invalid score! %.2f", score); + return score; + } + + inline bool Intersects(const BoundingBox& that) const { + return InRange(that.left_, left_, right_) + || InRange(that.right_, left_, right_) + || InRange(that.top_, top_, bottom_) + || InRange(that.bottom_, top_, bottom_); + } + + // Returns whether another bounding box is completely inside of this bounding + // box. Sharing edges is ok. + inline bool Contains(const BoundingBox& that) const { + return that.left_ >= left_ && + that.right_ <= right_ && + that.top_ >= top_ && + that.bottom_ <= bottom_; + } + + inline bool Contains(const Point2f& point) const { + return InRange(point.x, left_, right_) && InRange(point.y, top_, bottom_); + } + + inline void Shift(const Point2f shift_amount) { + left_ += shift_amount.x; + top_ += shift_amount.y; + right_ += shift_amount.x; + bottom_ += shift_amount.y; + } + + inline void ScaleOrigin(const float scale_x, const float scale_y) { + left_ *= scale_x; + right_ *= scale_x; + top_ *= scale_y; + bottom_ *= scale_y; + } + + inline void Scale(const float scale_x, const float scale_y) { + const Point2f center = GetCenter(); + const float half_width = GetWidth() / 2.0f; + const float half_height = GetHeight() / 2.0f; + + left_ = center.x - half_width * scale_x; + right_ = center.x + half_width * scale_x; + + top_ = center.y - half_height * scale_y; + bottom_ = center.y + half_height * scale_y; + } + + float left_; + float top_; + float right_; + float bottom_; +}; +inline std::ostream& operator<<(std::ostream& stream, const BoundingBox& box) { + stream << "[" << box.left_ << " - " << box.right_ + << ", " << box.top_ << " - " << box.bottom_ + << ", w:" << box.GetWidth() << " h:" << box.GetHeight() << "]"; + return stream; +} + + +class BoundingSquare { + public: + BoundingSquare(const float x, const float y, const float size) + : x_(x), y_(y), size_(size) {} + + explicit BoundingSquare(const BoundingBox& box) + : x_(box.left_), y_(box.top_), size_(box.GetWidth()) { +#ifdef SANITY_CHECKS + if (std::abs(box.GetWidth() - box.GetHeight()) > 0.1f) { + LOG(WARNING) << "This is not a square: " << box << std::endl; + } +#endif + } + + inline BoundingBox ToBoundingBox() const { + return BoundingBox(x_, y_, x_ + size_, y_ + size_); + } + + inline bool ValidBox() { + return size_ > 0.0f; + } + + inline void Shift(const Point2f shift_amount) { + x_ += shift_amount.x; + y_ += shift_amount.y; + } + + inline void Scale(const float scale) { + const float new_size = size_ * scale; + const float position_diff = (new_size - size_) / 2.0f; + x_ -= position_diff; + y_ -= position_diff; + size_ = new_size; + } + + float x_; + float y_; + float size_; +}; +inline std::ostream& operator<<(std::ostream& stream, + const BoundingSquare& square) { + stream << "[" << square.x_ << "," << square.y_ << " " << square.size_ << "]"; + return stream; +} + + +inline BoundingSquare GetCenteredSquare(const BoundingBox& original_box, + const float size) { + const float width_diff = (original_box.GetWidth() - size) / 2.0f; + const float height_diff = (original_box.GetHeight() - size) / 2.0f; + return BoundingSquare(original_box.left_ + width_diff, + original_box.top_ + height_diff, + size); +} + +inline BoundingSquare GetCenteredSquare(const BoundingBox& original_box) { + return GetCenteredSquare( + original_box, MIN(original_box.GetWidth(), original_box.GetHeight())); +} + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_GEOM_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/gl_utils.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/gl_utils.h" new file mode 100644 index 0000000..a29e677 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/gl_utils.h" @@ -0,0 +1,55 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_GL_UTILS_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_GL_UTILS_H_ + +#include +#include + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" + +namespace tf_tracking { + +// Draws a box at the given position. +inline static void DrawBox(const BoundingBox& bounding_box) { + const GLfloat line[] = { + bounding_box.left_, bounding_box.bottom_, + bounding_box.left_, bounding_box.top_, + bounding_box.left_, bounding_box.top_, + bounding_box.right_, bounding_box.top_, + bounding_box.right_, bounding_box.top_, + bounding_box.right_, bounding_box.bottom_, + bounding_box.right_, bounding_box.bottom_, + bounding_box.left_, bounding_box.bottom_ + }; + + glVertexPointer(2, GL_FLOAT, 0, line); + glEnableClientState(GL_VERTEX_ARRAY); + + glDrawArrays(GL_LINES, 0, 8); +} + + +// Changes the coordinate system such that drawing to an arbitrary square in +// the world can thereafter be drawn to using coordinates 0 - 1. +inline static void MapWorldSquareToUnitSquare(const BoundingSquare& square) { + glScalef(square.size_, square.size_, 1.0f); + glTranslatef(square.x_ / square.size_, square.y_ / square.size_, 0.0f); +} + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_GL_UTILS_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image-inl.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image-inl.h" new file mode 100644 index 0000000..61d6990 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image-inl.h" @@ -0,0 +1,644 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_IMAGE_INL_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_IMAGE_INL_H_ + +#include + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +namespace tf_tracking { + +template +Image::Image(const int width, const int height) + : width_less_one_(width - 1), + height_less_one_(height - 1), + data_size_(width * height), + own_data_(true), + width_(width), + height_(height), + stride_(width) { + Allocate(); +} + +template +Image::Image(const Size& size) + : width_less_one_(size.width - 1), + height_less_one_(size.height - 1), + data_size_(size.width * size.height), + own_data_(true), + width_(size.width), + height_(size.height), + stride_(size.width) { + Allocate(); +} + +// Constructor that creates an image from preallocated data. +// Note: The image takes ownership of the data lifecycle, unless own_data is +// set to false. +template +Image::Image(const int width, const int height, T* const image_data, + const bool own_data) : + width_less_one_(width - 1), + height_less_one_(height - 1), + data_size_(width * height), + own_data_(own_data), + width_(width), + height_(height), + stride_(width) { + image_data_ = image_data; + SCHECK(image_data_ != NULL, "Can't create image with NULL data!"); +} + +template +Image::~Image() { + if (own_data_) { + delete[] image_data_; + } + image_data_ = NULL; +} + +template +template +bool Image::ExtractPatchAtSubpixelFixed1616(const int fp_x, + const int fp_y, + const int patchwidth, + const int patchheight, + DstType* to_data) const { + // Calculate weights. + const int trunc_x = fp_x >> 16; + const int trunc_y = fp_y >> 16; + + if (trunc_x < 0 || trunc_y < 0 || + (trunc_x + patchwidth) >= width_less_one_ || + (trunc_y + patchheight) >= height_less_one_) { + return false; + } + + // Now walk over destination patch and fill from interpolated source image. + for (int y = 0; y < patchheight; ++y, to_data += patchwidth) { + for (int x = 0; x < patchwidth; ++x) { + to_data[x] = + static_cast(GetPixelInterpFixed1616(fp_x + (x << 16), + fp_y + (y << 16))); + } + } + + return true; +} + +template +Image* Image::Crop( + const int left, const int top, const int right, const int bottom) const { + SCHECK(left >= 0 && left < width_, "out of bounds at %d!", left); + SCHECK(right >= 0 && right < width_, "out of bounds at %d!", right); + SCHECK(top >= 0 && top < height_, "out of bounds at %d!", top); + SCHECK(bottom >= 0 && bottom < height_, "out of bounds at %d!", bottom); + + SCHECK(left <= right, "mismatch!"); + SCHECK(top <= bottom, "mismatch!"); + + const int new_width = right - left + 1; + const int new_height = bottom - top + 1; + + Image* const cropped_image = new Image(new_width, new_height); + + for (int y = 0; y < new_height; ++y) { + memcpy((*cropped_image)[y], ((*this)[y + top] + left), + new_width * sizeof(T)); + } + + return cropped_image; +} + +template +inline float Image::GetPixelInterp(const float x, const float y) const { + // Do int conversion one time. + const int floored_x = static_cast(x); + const int floored_y = static_cast(y); + + // Note: it might be the case that the *_[min|max] values are clipped, and + // these (the a b c d vals) aren't (for speed purposes), but that doesn't + // matter. We'll just be blending the pixel with itself in that case anyway. + const float b = x - floored_x; + const float a = 1.0f - b; + + const float d = y - floored_y; + const float c = 1.0f - d; + + SCHECK(ValidInterpPixel(x, y), + "x or y out of bounds! %.2f [0 - %d), %.2f [0 - %d)", + x, width_less_one_, y, height_less_one_); + + const T* const pix_ptr = (*this)[floored_y] + floored_x; + + // Get the pixel values surrounding this point. + const T& p1 = pix_ptr[0]; + const T& p2 = pix_ptr[1]; + const T& p3 = pix_ptr[width_]; + const T& p4 = pix_ptr[width_ + 1]; + + // Simple bilinear interpolation between four reference pixels. + // If x is the value requested: + // a b + // ------- + // c |p1 p2| + // | x | + // d |p3 p4| + // ------- + return c * ((a * p1) + (b * p2)) + + d * ((a * p3) + (b * p4)); +} + + +template +inline T Image::GetPixelInterpFixed1616( + const int fp_x_whole, const int fp_y_whole) const { + static const int kFixedPointOne = 0x00010000; + static const int kFixedPointHalf = 0x00008000; + static const int kFixedPointTruncateMask = 0xFFFF0000; + + int trunc_x = fp_x_whole & kFixedPointTruncateMask; + int trunc_y = fp_y_whole & kFixedPointTruncateMask; + const int fp_x = fp_x_whole - trunc_x; + const int fp_y = fp_y_whole - trunc_y; + + // Scale the truncated values back to regular ints. + trunc_x >>= 16; + trunc_y >>= 16; + + const int one_minus_fp_x = kFixedPointOne - fp_x; + const int one_minus_fp_y = kFixedPointOne - fp_y; + + const T* trunc_start = (*this)[trunc_y] + trunc_x; + + const T a = trunc_start[0]; + const T b = trunc_start[1]; + const T c = trunc_start[stride_]; + const T d = trunc_start[stride_ + 1]; + + return ( + (one_minus_fp_y * static_cast(one_minus_fp_x * a + fp_x * b) + + fp_y * static_cast(one_minus_fp_x * c + fp_x * d) + + kFixedPointHalf) >> + 32); +} + +template +inline bool Image::ValidPixel(const int x, const int y) const { + return InRange(x, ZERO, width_less_one_) && + InRange(y, ZERO, height_less_one_); +} + +template +inline BoundingBox Image::GetContainingBox() const { + return BoundingBox( + 0, 0, width_less_one_ - EPSILON, height_less_one_ - EPSILON); +} + +template +inline bool Image::Contains(const BoundingBox& bounding_box) const { + // TODO(andrewharp): Come up with a more elegant way of ensuring that bounds + // are ok. + return GetContainingBox().Contains(bounding_box); +} + +template +inline bool Image::ValidInterpPixel(const float x, const float y) const { + // Exclusive of max because we can be more efficient if we don't handle + // interpolating on or past the last pixel. + return (x >= ZERO) && (x < width_less_one_) && + (y >= ZERO) && (y < height_less_one_); +} + +template +void Image::DownsampleAveraged(const T* const original, const int stride, + const int factor) { +#ifdef __ARM_NEON + if (factor == 4 || factor == 2) { + DownsampleAveragedNeon(original, stride, factor); + return; + } +#endif + + // TODO(andrewharp): delete or enable this for non-uint8_t downsamples. + const int pixels_per_block = factor * factor; + + // For every pixel in resulting image. + for (int y = 0; y < height_; ++y) { + const int orig_y = y * factor; + const int y_bound = orig_y + factor; + + // Sum up the original pixels. + for (int x = 0; x < width_; ++x) { + const int orig_x = x * factor; + const int x_bound = orig_x + factor; + + // Making this int32_t because type U or T might overflow. + int32_t pixel_sum = 0; + + // Grab all the pixels that make up this pixel. + for (int curr_y = orig_y; curr_y < y_bound; ++curr_y) { + const T* p = original + curr_y * stride + orig_x; + + for (int curr_x = orig_x; curr_x < x_bound; ++curr_x) { + pixel_sum += *p++; + } + } + + (*this)[y][x] = pixel_sum / pixels_per_block; + } + } +} + +template +void Image::DownsampleInterpolateNearest(const Image& original) { + // Calculating the scaling factors based on target image size. + const float factor_x = static_cast(original.GetWidth()) / + static_cast(width_); + const float factor_y = static_cast(original.GetHeight()) / + static_cast(height_); + + // Calculating initial offset in x-axis. + const float offset_x = 0.5f * (original.GetWidth() - width_) / width_; + + // Calculating initial offset in y-axis. + const float offset_y = 0.5f * (original.GetHeight() - height_) / height_; + + float orig_y = offset_y; + + // For every pixel in resulting image. + for (int y = 0; y < height_; ++y) { + float orig_x = offset_x; + + // Finding nearest pixel on y-axis. + const int nearest_y = static_cast(orig_y + 0.5f); + const T* row_data = original[nearest_y]; + + T* pixel_ptr = (*this)[y]; + + for (int x = 0; x < width_; ++x) { + // Finding nearest pixel on x-axis. + const int nearest_x = static_cast(orig_x + 0.5f); + + *pixel_ptr++ = row_data[nearest_x]; + + orig_x += factor_x; + } + + orig_y += factor_y; + } +} + +template +void Image::DownsampleInterpolateLinear(const Image& original) { + // TODO(andrewharp): Turn this into a general compare sizes/bulk + // copy method. + if (original.GetWidth() == GetWidth() && + original.GetHeight() == GetHeight() && + original.stride() == stride()) { + memcpy(image_data_, original.data(), data_size_ * sizeof(T)); + return; + } + + // Calculating the scaling factors based on target image size. + const float factor_x = static_cast(original.GetWidth()) / + static_cast(width_); + const float factor_y = static_cast(original.GetHeight()) / + static_cast(height_); + + // Calculating initial offset in x-axis. + const float offset_x = 0; + const int offset_x_fp = RealToFixed1616(offset_x); + + // Calculating initial offset in y-axis. + const float offset_y = 0; + const int offset_y_fp = RealToFixed1616(offset_y); + + // Get the fixed point scaling factor value. + // Shift by 8 so we can fit everything into a 4 byte int later for speed + // reasons. This means the precision is limited to 1 / 256th of a pixel, + // but this should be good enough. + const int factor_x_fp = RealToFixed1616(factor_x) >> 8; + const int factor_y_fp = RealToFixed1616(factor_y) >> 8; + + int src_y_fp = offset_y_fp >> 8; + + static const int kFixedPointOne8 = 0x00000100; + static const int kFixedPointHalf8 = 0x00000080; + static const int kFixedPointTruncateMask8 = 0xFFFFFF00; + + // For every pixel in resulting image. + for (int y = 0; y < height_; ++y) { + int src_x_fp = offset_x_fp >> 8; + + int trunc_y = src_y_fp & kFixedPointTruncateMask8; + const int fp_y = src_y_fp - trunc_y; + + // Scale the truncated values back to regular ints. + trunc_y >>= 8; + + const int one_minus_fp_y = kFixedPointOne8 - fp_y; + + T* pixel_ptr = (*this)[y]; + + // Make sure not to read from an invalid row. + const int trunc_y_b = MIN(original.height_less_one_, trunc_y + 1); + const T* other_top_ptr = original[trunc_y]; + const T* other_bot_ptr = original[trunc_y_b]; + + int last_trunc_x = -1; + int trunc_x = -1; + + T a = 0; + T b = 0; + T c = 0; + T d = 0; + + for (int x = 0; x < width_; ++x) { + trunc_x = src_x_fp & kFixedPointTruncateMask8; + + const int fp_x = (src_x_fp - trunc_x) >> 8; + + // Scale the truncated values back to regular ints. + trunc_x >>= 8; + + // It's possible we're reading from the same pixels + if (trunc_x != last_trunc_x) { + // Make sure not to read from an invalid column. + const int trunc_x_b = MIN(original.width_less_one_, trunc_x + 1); + a = other_top_ptr[trunc_x]; + b = other_top_ptr[trunc_x_b]; + c = other_bot_ptr[trunc_x]; + d = other_bot_ptr[trunc_x_b]; + last_trunc_x = trunc_x; + } + + const int one_minus_fp_x = kFixedPointOne8 - fp_x; + + const int32_t value = + ((one_minus_fp_y * one_minus_fp_x * a + fp_x * b) + + (fp_y * one_minus_fp_x * c + fp_x * d) + kFixedPointHalf8) >> + 16; + + *pixel_ptr++ = value; + + src_x_fp += factor_x_fp; + } + src_y_fp += factor_y_fp; + } +} + +template +void Image::DownsampleSmoothed3x3(const Image& original) { + for (int y = 0; y < height_; ++y) { + const int orig_y = Clip(2 * y, ZERO, original.height_less_one_); + const int min_y = Clip(orig_y - 1, ZERO, original.height_less_one_); + const int max_y = Clip(orig_y + 1, ZERO, original.height_less_one_); + + for (int x = 0; x < width_; ++x) { + const int orig_x = Clip(2 * x, ZERO, original.width_less_one_); + const int min_x = Clip(orig_x - 1, ZERO, original.width_less_one_); + const int max_x = Clip(orig_x + 1, ZERO, original.width_less_one_); + + // Center. + int32_t pixel_sum = original[orig_y][orig_x] * 4; + + // Sides. + pixel_sum += (original[orig_y][max_x] + + original[orig_y][min_x] + + original[max_y][orig_x] + + original[min_y][orig_x]) * 2; + + // Diagonals. + pixel_sum += (original[min_y][max_x] + + original[min_y][min_x] + + original[max_y][max_x] + + original[max_y][min_x]); + + (*this)[y][x] = pixel_sum >> 4; // 16 + } + } +} + +template +void Image::DownsampleSmoothed5x5(const Image& original) { + const int max_x = original.width_less_one_; + const int max_y = original.height_less_one_; + + // The JY Bouget paper on Lucas-Kanade recommends a + // [1/16 1/4 3/8 1/4 1/16]^2 filter. + // This works out to a [1 4 6 4 1]^2 / 256 array, precomputed below. + static const int window_radius = 2; + static const int window_size = window_radius*2 + 1; + static const int window_weights[] = {1, 4, 6, 4, 1, // 16 + + 4, 16, 24, 16, 4, // 64 + + 6, 24, 36, 24, 6, // 96 + + 4, 16, 24, 16, 4, // 64 + + 1, 4, 6, 4, 1}; // 16 = 256 + + // We'll multiply and sum with the whole numbers first, then divide by + // the total weight to normalize at the last moment. + for (int y = 0; y < height_; ++y) { + for (int x = 0; x < width_; ++x) { + int32_t pixel_sum = 0; + + const int* w = window_weights; + const int start_x = Clip((x << 1) - window_radius, ZERO, max_x); + + // Clip the boundaries to the size of the image. + for (int window_y = 0; window_y < window_size; ++window_y) { + const int start_y = + Clip((y << 1) - window_radius + window_y, ZERO, max_y); + + const T* p = original[start_y] + start_x; + + for (int window_x = 0; window_x < window_size; ++window_x) { + pixel_sum += *p++ * *w++; + } + } + + // Conversion to type T will happen here after shifting right 8 bits to + // divide by 256. + (*this)[y][x] = pixel_sum >> 8; + } + } +} + +template +template +inline T Image::ScharrPixelX(const Image& original, + const int center_x, const int center_y) const { + const int min_x = Clip(center_x - 1, ZERO, original.width_less_one_); + const int max_x = Clip(center_x + 1, ZERO, original.width_less_one_); + const int min_y = Clip(center_y - 1, ZERO, original.height_less_one_); + const int max_y = Clip(center_y + 1, ZERO, original.height_less_one_); + + // Convolution loop unrolled for performance... + return (3 * (original[min_y][max_x] + + original[max_y][max_x] + - original[min_y][min_x] + - original[max_y][min_x]) + + 10 * (original[center_y][max_x] + - original[center_y][min_x])) / 32; +} + +template +template +inline T Image::ScharrPixelY(const Image& original, + const int center_x, const int center_y) const { + const int min_x = Clip(center_x - 1, 0, original.width_less_one_); + const int max_x = Clip(center_x + 1, 0, original.width_less_one_); + const int min_y = Clip(center_y - 1, 0, original.height_less_one_); + const int max_y = Clip(center_y + 1, 0, original.height_less_one_); + + // Convolution loop unrolled for performance... + return (3 * (original[max_y][min_x] + + original[max_y][max_x] + - original[min_y][min_x] + - original[min_y][max_x]) + + 10 * (original[max_y][center_x] + - original[min_y][center_x])) / 32; +} + +template +template +inline void Image::ScharrX(const Image& original) { + for (int y = 0; y < height_; ++y) { + for (int x = 0; x < width_; ++x) { + SetPixel(x, y, ScharrPixelX(original, x, y)); + } + } +} + +template +template +inline void Image::ScharrY(const Image& original) { + for (int y = 0; y < height_; ++y) { + for (int x = 0; x < width_; ++x) { + SetPixel(x, y, ScharrPixelY(original, x, y)); + } + } +} + +template +template +void Image::DerivativeX(const Image& original) { + for (int y = 0; y < height_; ++y) { + const U* const source_row = original[y]; + T* const dest_row = (*this)[y]; + + // Compute first pixel. Approximated with forward difference. + dest_row[0] = source_row[1] - source_row[0]; + + // All the pixels in between. Central difference method. + const U* source_prev_pixel = source_row; + T* dest_pixel = dest_row + 1; + const U* source_next_pixel = source_row + 2; + for (int x = 1; x < width_less_one_; ++x) { + *dest_pixel++ = HalfDiff(*source_prev_pixel++, *source_next_pixel++); + } + + // Last pixel. Approximated with backward difference. + dest_row[width_less_one_] = + source_row[width_less_one_] - source_row[width_less_one_ - 1]; + } +} + +template +template +void Image::DerivativeY(const Image& original) { + const int src_stride = original.stride(); + + // Compute 1st row. Approximated with forward difference. + { + const U* const src_row = original[0]; + T* dest_row = (*this)[0]; + for (int x = 0; x < width_; ++x) { + dest_row[x] = src_row[x + src_stride] - src_row[x]; + } + } + + // Compute all rows in between using central difference. + for (int y = 1; y < height_less_one_; ++y) { + T* dest_row = (*this)[y]; + + const U* source_prev_pixel = original[y - 1]; + const U* source_next_pixel = original[y + 1]; + for (int x = 0; x < width_; ++x) { + *dest_row++ = HalfDiff(*source_prev_pixel++, *source_next_pixel++); + } + } + + // Compute last row. Approximated with backward difference. + { + const U* const src_row = original[height_less_one_]; + T* dest_row = (*this)[height_less_one_]; + for (int x = 0; x < width_; ++x) { + dest_row[x] = src_row[x] - src_row[x - src_stride]; + } + } +} + +template +template +inline T Image::ConvolvePixel3x3(const Image& original, + const int* const filter, + const int center_x, const int center_y, + const int total) const { + int32_t sum = 0; + for (int filter_y = 0; filter_y < 3; ++filter_y) { + const int y = Clip(center_y - 1 + filter_y, 0, original.GetHeight()); + for (int filter_x = 0; filter_x < 3; ++filter_x) { + const int x = Clip(center_x - 1 + filter_x, 0, original.GetWidth()); + sum += original[y][x] * filter[filter_y * 3 + filter_x]; + } + } + return sum / total; +} + +template +template +inline void Image::Convolve3x3(const Image& original, + const int32_t* const filter) { + int32_t sum = 0; + for (int i = 0; i < 9; ++i) { + sum += abs(filter[i]); + } + for (int y = 0; y < height_; ++y) { + for (int x = 0; x < width_; ++x) { + SetPixel(x, y, ConvolvePixel3x3(original, filter, x, y, sum)); + } + } +} + +template +inline void Image::FromArray(const T* const pixels, const int stride, + const int factor) { + if (factor == 1 && stride == width_) { + // If not subsampling, memcpy per line should be faster. + memcpy(this->image_data_, pixels, data_size_ * sizeof(T)); + return; + } + + DownsampleAveraged(pixels, stride, factor); +} + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_IMAGE_INL_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image.h" new file mode 100644 index 0000000..a436f0e --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image.h" @@ -0,0 +1,341 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_IMAGE_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_IMAGE_H_ + +#include + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +// TODO(andrewharp): Make this a cast to uint32_t if/when we go unsigned for +// operations. +#define ZERO 0 + +#ifdef SANITY_CHECKS + #define CHECK_PIXEL(IMAGE, X, Y) {\ + SCHECK((IMAGE)->ValidPixel((X), (Y)), \ + "CHECK_PIXEL(%d,%d) in %dx%d image.", \ + static_cast(X), static_cast(Y), \ + (IMAGE)->GetWidth(), (IMAGE)->GetHeight());\ + } + + #define CHECK_PIXEL_INTERP(IMAGE, X, Y) {\ + SCHECK((IMAGE)->validInterpPixel((X), (Y)), \ + "CHECK_PIXEL_INTERP(%.2f, %.2f) in %dx%d image.", \ + static_cast(X), static_cast(Y), \ + (IMAGE)->GetWidth(), (IMAGE)->GetHeight());\ + } +#else + #define CHECK_PIXEL(image, x, y) {} + #define CHECK_PIXEL_INTERP(IMAGE, X, Y) {} +#endif + +namespace tf_tracking { + +#ifdef SANITY_CHECKS +// Class which exists solely to provide bounds checking for array-style image +// data access. +template +class RowData { + public: + RowData(T* const row_data, const int max_col) + : row_data_(row_data), max_col_(max_col) {} + + inline T& operator[](const int col) const { + SCHECK(InRange(col, 0, max_col_), + "Column out of range: %d (%d max)", col, max_col_); + return row_data_[col]; + } + + inline operator T*() const { + return row_data_; + } + + private: + T* const row_data_; + const int max_col_; +}; +#endif + +// Naive templated sorting function. +template +int Comp(const void* a, const void* b) { + const T val1 = *reinterpret_cast(a); + const T val2 = *reinterpret_cast(b); + + if (val1 == val2) { + return 0; + } else if (val1 < val2) { + return -1; + } else { + return 1; + } +} + +// TODO(andrewharp): Make explicit which operations support negative numbers or +// struct/class types in image data (possibly create fast multi-dim array class +// for data where pixel arithmetic does not make sense). + +// Image class optimized for working on numeric arrays as grayscale image data. +// Supports other data types as a 2D array class, so long as no pixel math +// operations are called (convolution, downsampling, etc). +template +class Image { + public: + Image(const int width, const int height); + explicit Image(const Size& size); + + // Constructor that creates an image from preallocated data. + // Note: The image takes ownership of the data lifecycle, unless own_data is + // set to false. + Image(const int width, const int height, T* const image_data, + const bool own_data = true); + + ~Image(); + + // Extract a pixel patch from this image, starting at a subpixel location. + // Uses 16:16 fixed point format for representing real values and doing the + // bilinear interpolation. + // + // Arguments fp_x and fp_y tell the subpixel position in fixed point format, + // patchwidth/patchheight give the size of the patch in pixels and + // to_data must be a valid pointer to a *contiguous* destination data array. + template + bool ExtractPatchAtSubpixelFixed1616(const int fp_x, + const int fp_y, + const int patchwidth, + const int patchheight, + DstType* to_data) const; + + Image* Crop( + const int left, const int top, const int right, const int bottom) const; + + inline int GetWidth() const { return width_; } + inline int GetHeight() const { return height_; } + + // Bilinearly sample a value between pixels. Values must be within the image. + inline float GetPixelInterp(const float x, const float y) const; + + // Bilinearly sample a pixels at a subpixel position using fixed point + // arithmetic. + // Avoids float<->int conversions. + // Values must be within the image. + // Arguments fp_x and fp_y tell the subpixel position in + // 16:16 fixed point format. + // + // Important: This function only makes sense for integer-valued images, such + // as Image or Image etc. + inline T GetPixelInterpFixed1616(const int fp_x_whole, + const int fp_y_whole) const; + + // Returns true iff the pixel is in the image's boundaries. + inline bool ValidPixel(const int x, const int y) const; + + inline BoundingBox GetContainingBox() const; + + inline bool Contains(const BoundingBox& bounding_box) const; + + inline T GetMedianValue() { + qsort(image_data_, data_size_, sizeof(image_data_[0]), Comp); + return image_data_[data_size_ >> 1]; + } + + // Returns true iff the pixel is in the image's boundaries for interpolation + // purposes. + // TODO(andrewharp): check in interpolation follow-up change. + inline bool ValidInterpPixel(const float x, const float y) const; + + // Safe lookup with boundary enforcement. + inline T GetPixelClipped(const int x, const int y) const { + return (*this)[Clip(y, ZERO, height_less_one_)] + [Clip(x, ZERO, width_less_one_)]; + } + +#ifdef SANITY_CHECKS + inline RowData operator[](const int row) { + SCHECK(InRange(row, 0, height_less_one_), + "Row out of range: %d (%d max)", row, height_less_one_); + return RowData(image_data_ + row * stride_, width_less_one_); + } + + inline const RowData operator[](const int row) const { + SCHECK(InRange(row, 0, height_less_one_), + "Row out of range: %d (%d max)", row, height_less_one_); + return RowData(image_data_ + row * stride_, width_less_one_); + } +#else + inline T* operator[](const int row) { + return image_data_ + row * stride_; + } + + inline const T* operator[](const int row) const { + return image_data_ + row * stride_; + } +#endif + + const T* data() const { return image_data_; } + + inline int stride() const { return stride_; } + + // Clears image to a single value. + inline void Clear(const T& val) { + memset(image_data_, val, sizeof(*image_data_) * data_size_); + } + +#ifdef __ARM_NEON + void Downsample2x32ColumnsNeon(const uint8_t* const original, + const int stride, const int orig_x); + + void Downsample4x32ColumnsNeon(const uint8_t* const original, + const int stride, const int orig_x); + + void DownsampleAveragedNeon(const uint8_t* const original, const int stride, + const int factor); +#endif + + // Naive downsampler that reduces image size by factor by averaging pixels in + // blocks of size factor x factor. + void DownsampleAveraged(const T* const original, const int stride, + const int factor); + + // Naive downsampler that reduces image size by factor by averaging pixels in + // blocks of size factor x factor. + inline void DownsampleAveraged(const Image& original, const int factor) { + DownsampleAveraged(original.data(), original.GetWidth(), factor); + } + + // Native downsampler that reduces image size using nearest interpolation + void DownsampleInterpolateNearest(const Image& original); + + // Native downsampler that reduces image size using fixed-point bilinear + // interpolation + void DownsampleInterpolateLinear(const Image& original); + + // Relatively efficient downsampling of an image by a factor of two with a + // low-pass 3x3 smoothing operation thrown in. + void DownsampleSmoothed3x3(const Image& original); + + // Relatively efficient downsampling of an image by a factor of two with a + // low-pass 5x5 smoothing operation thrown in. + void DownsampleSmoothed5x5(const Image& original); + + // Optimized Scharr filter on a single pixel in the X direction. + // Scharr filters are like central-difference operators, but have more + // rotational symmetry in their response because they also consider the + // diagonal neighbors. + template + inline T ScharrPixelX(const Image& original, + const int center_x, const int center_y) const; + + // Optimized Scharr filter on a single pixel in the X direction. + // Scharr filters are like central-difference operators, but have more + // rotational symmetry in their response because they also consider the + // diagonal neighbors. + template + inline T ScharrPixelY(const Image& original, + const int center_x, const int center_y) const; + + // Convolve the image with a Scharr filter in the X direction. + // Much faster than an equivalent generic convolution. + template + inline void ScharrX(const Image& original); + + // Convolve the image with a Scharr filter in the Y direction. + // Much faster than an equivalent generic convolution. + template + inline void ScharrY(const Image& original); + + static inline T HalfDiff(int32_t first, int32_t second) { + return (second - first) / 2; + } + + template + void DerivativeX(const Image& original); + + template + void DerivativeY(const Image& original); + + // Generic function for convolving pixel with 3x3 filter. + // Filter pixels should be in row major order. + template + inline T ConvolvePixel3x3(const Image& original, + const int* const filter, + const int center_x, const int center_y, + const int total) const; + + // Generic function for convolving an image with a 3x3 filter. + // TODO(andrewharp): Generalize this for any size filter. + template + inline void Convolve3x3(const Image& original, + const int32_t* const filter); + + // Load this image's data from a data array. The data at pixels is assumed to + // have dimensions equivalent to this image's dimensions * factor. + inline void FromArray(const T* const pixels, const int stride, + const int factor = 1); + + // Copy the image back out to an appropriately sized data array. + inline void ToArray(T* const pixels) const { + // If not subsampling, memcpy should be faster. + memcpy(pixels, this->image_data_, data_size_ * sizeof(T)); + } + + // Precompute these for efficiency's sake as they're used by a lot of + // clipping code and loop code. + // TODO(andrewharp): make these only accessible by other Images. + const int width_less_one_; + const int height_less_one_; + + // The raw size of the allocated data. + const int data_size_; + + private: + inline void Allocate() { + image_data_ = new T[data_size_]; + if (image_data_ == NULL) { + LOGE("Couldn't allocate image data!"); + } + } + + T* image_data_; + + bool own_data_; + + const int width_; + const int height_; + + // The image stride (offset to next row). + // TODO(andrewharp): Make sure that stride is honored in all code. + const int stride_; + + TF_DISALLOW_COPY_AND_ASSIGN(Image); +}; + +template +inline std::ostream& operator<<(std::ostream& stream, const Image& image) { + for (int y = 0; y < image.GetHeight(); ++y) { + for (int x = 0; x < image.GetWidth(); ++x) { + stream << image[y][x] << " "; + } + stream << std::endl; + } + return stream; +} + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_IMAGE_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image_data.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image_data.h" new file mode 100644 index 0000000..c4f91d8 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image_data.h" @@ -0,0 +1,264 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_IMAGE_DATA_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_IMAGE_DATA_H_ + +#include +#include + +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/image_utils.h" +#include "tensorflow/examples/android/jni/object_tracking/integral_image.h" +#include "tensorflow/examples/android/jni/object_tracking/time_log.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +#include "tensorflow/examples/android/jni/object_tracking/config.h" + +namespace tf_tracking { + +// Class that encapsulates all bulky processed data for a frame. +class ImageData { + public: + explicit ImageData(const int width, const int height) + : uv_frame_width_(width << 1), + uv_frame_height_(height << 1), + timestamp_(0), + image_(width, height) { + InitPyramid(width, height); + ResetComputationCache(); + } + + private: + void ResetComputationCache() { + uv_data_computed_ = false; + integral_image_computed_ = false; + for (int i = 0; i < kNumPyramidLevels; ++i) { + spatial_x_computed_[i] = false; + spatial_y_computed_[i] = false; + pyramid_sqrt2_computed_[i * 2] = false; + pyramid_sqrt2_computed_[i * 2 + 1] = false; + } + } + + void InitPyramid(const int width, const int height) { + int level_width = width; + int level_height = height; + + for (int i = 0; i < kNumPyramidLevels; ++i) { + pyramid_sqrt2_[i * 2] = NULL; + pyramid_sqrt2_[i * 2 + 1] = NULL; + spatial_x_[i] = NULL; + spatial_y_[i] = NULL; + + level_width /= 2; + level_height /= 2; + } + + // Alias the first pyramid level to image_. + pyramid_sqrt2_[0] = &image_; + } + + public: + ~ImageData() { + // The first pyramid level is actually an alias to image_, + // so make sure it doesn't get deleted here. + pyramid_sqrt2_[0] = NULL; + + for (int i = 0; i < kNumPyramidLevels; ++i) { + SAFE_DELETE(pyramid_sqrt2_[i * 2]); + SAFE_DELETE(pyramid_sqrt2_[i * 2 + 1]); + SAFE_DELETE(spatial_x_[i]); + SAFE_DELETE(spatial_y_[i]); + } + } + + void SetData(const uint8_t* const new_frame, const int stride, + const int64_t timestamp, const int downsample_factor) { + SetData(new_frame, NULL, stride, timestamp, downsample_factor); + } + + void SetData(const uint8_t* const new_frame, const uint8_t* const uv_frame, + const int stride, const int64_t timestamp, + const int downsample_factor) { + ResetComputationCache(); + + timestamp_ = timestamp; + + TimeLog("SetData!"); + + pyramid_sqrt2_[0]->FromArray(new_frame, stride, downsample_factor); + pyramid_sqrt2_computed_[0] = true; + TimeLog("Downsampled image"); + + if (uv_frame != NULL) { + if (u_data_.get() == NULL) { + u_data_.reset(new Image(uv_frame_width_, uv_frame_height_)); + v_data_.reset(new Image(uv_frame_width_, uv_frame_height_)); + } + + GetUV(uv_frame, u_data_.get(), v_data_.get()); + uv_data_computed_ = true; + TimeLog("Copied UV data"); + } else { + LOGV("No uv data!"); + } + +#ifdef LOG_TIME + // If profiling is enabled, precompute here to make it easier to distinguish + // total costs. + Precompute(); +#endif + } + + inline const uint64_t GetTimestamp() const { return timestamp_; } + + inline const Image* GetImage() const { + SCHECK(pyramid_sqrt2_computed_[0], "image not set!"); + return pyramid_sqrt2_[0]; + } + + const Image* GetPyramidSqrt2Level(const int level) const { + if (!pyramid_sqrt2_computed_[level]) { + SCHECK(level != 0, "Level equals 0!"); + if (level == 1) { + const Image& upper_level = *GetPyramidSqrt2Level(0); + if (pyramid_sqrt2_[level] == NULL) { + const int new_width = + (static_cast(upper_level.GetWidth() / sqrtf(2)) + 1) / 2 * 2; + const int new_height = + (static_cast(upper_level.GetHeight() / sqrtf(2)) + 1) / 2 * + 2; + + pyramid_sqrt2_[level] = new Image(new_width, new_height); + } + pyramid_sqrt2_[level]->DownsampleInterpolateLinear(upper_level); + } else { + const Image& upper_level = *GetPyramidSqrt2Level(level - 2); + if (pyramid_sqrt2_[level] == NULL) { + pyramid_sqrt2_[level] = new Image( + upper_level.GetWidth() / 2, upper_level.GetHeight() / 2); + } + pyramid_sqrt2_[level]->DownsampleAveraged( + upper_level.data(), upper_level.stride(), 2); + } + pyramid_sqrt2_computed_[level] = true; + } + return pyramid_sqrt2_[level]; + } + + inline const Image* GetSpatialX(const int level) const { + if (!spatial_x_computed_[level]) { + const Image& src = *GetPyramidSqrt2Level(level * 2); + if (spatial_x_[level] == NULL) { + spatial_x_[level] = new Image(src.GetWidth(), src.GetHeight()); + } + spatial_x_[level]->DerivativeX(src); + spatial_x_computed_[level] = true; + } + return spatial_x_[level]; + } + + inline const Image* GetSpatialY(const int level) const { + if (!spatial_y_computed_[level]) { + const Image& src = *GetPyramidSqrt2Level(level * 2); + if (spatial_y_[level] == NULL) { + spatial_y_[level] = new Image(src.GetWidth(), src.GetHeight()); + } + spatial_y_[level]->DerivativeY(src); + spatial_y_computed_[level] = true; + } + return spatial_y_[level]; + } + + // The integral image is currently only used for object detection, so lazily + // initialize it on request. + inline const IntegralImage* GetIntegralImage() const { + if (integral_image_.get() == NULL) { + integral_image_.reset(new IntegralImage(image_)); + } else if (!integral_image_computed_) { + integral_image_->Recompute(image_); + } + integral_image_computed_ = true; + return integral_image_.get(); + } + + inline const Image* GetU() const { + SCHECK(uv_data_computed_, "UV data not provided!"); + return u_data_.get(); + } + + inline const Image* GetV() const { + SCHECK(uv_data_computed_, "UV data not provided!"); + return v_data_.get(); + } + + private: + void Precompute() { + // Create the smoothed pyramids. + for (int i = 0; i < kNumPyramidLevels * 2; i += 2) { + (void) GetPyramidSqrt2Level(i); + } + TimeLog("Created smoothed pyramids"); + + // Create the smoothed pyramids. + for (int i = 1; i < kNumPyramidLevels * 2; i += 2) { + (void) GetPyramidSqrt2Level(i); + } + TimeLog("Created smoothed sqrt pyramids"); + + // Create the spatial derivatives for frame 1. + for (int i = 0; i < kNumPyramidLevels; ++i) { + (void) GetSpatialX(i); + (void) GetSpatialY(i); + } + TimeLog("Created spatial derivatives"); + + (void) GetIntegralImage(); + TimeLog("Got integral image!"); + } + + const int uv_frame_width_; + const int uv_frame_height_; + + int64_t timestamp_; + + Image image_; + + bool uv_data_computed_; + std::unique_ptr > u_data_; + std::unique_ptr > v_data_; + + mutable bool spatial_x_computed_[kNumPyramidLevels]; + mutable Image* spatial_x_[kNumPyramidLevels]; + + mutable bool spatial_y_computed_[kNumPyramidLevels]; + mutable Image* spatial_y_[kNumPyramidLevels]; + + // Mutable so the lazy initialization can work when this class is const. + // Whether or not the integral image has been computed for the current image. + mutable bool integral_image_computed_; + mutable std::unique_ptr integral_image_; + + mutable bool pyramid_sqrt2_computed_[kNumPyramidLevels * 2]; + mutable Image* pyramid_sqrt2_[kNumPyramidLevels * 2]; + + TF_DISALLOW_COPY_AND_ASSIGN(ImageData); +}; + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_IMAGE_DATA_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image_neon.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image_neon.cc" new file mode 100644 index 0000000..5f1023c --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image_neon.cc" @@ -0,0 +1,269 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// NEON implementations of Image methods for compatible devices. Control +// should never enter this compilation unit on incompatible devices. + +#ifdef __ARM_NEON + +#include + +#include + +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/image_utils.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +namespace tf_tracking { + +// This function does the bulk of the work. +template <> +void Image::Downsample2x32ColumnsNeon(const uint8_t* const original, + const int stride, + const int orig_x) { + // Divide input x offset by 2 to find output offset. + const int new_x = orig_x >> 1; + + // Initial offset into top row. + const uint8_t* offset = original + orig_x; + + // This points to the leftmost pixel of our 8 horizontally arranged + // pixels in the destination data. + uint8_t* ptr_dst = (*this)[0] + new_x; + + // Sum along vertical columns. + // Process 32x2 input pixels and 16x1 output pixels per iteration. + for (int new_y = 0; new_y < height_; ++new_y) { + uint16x8_t accum1 = vdupq_n_u16(0); + uint16x8_t accum2 = vdupq_n_u16(0); + + // Go top to bottom across the four rows of input pixels that make up + // this output row. + for (int row_num = 0; row_num < 2; ++row_num) { + // First 16 bytes. + { + // Load 16 bytes of data from current offset. + const uint8x16_t curr_data1 = vld1q_u8(offset); + + // Pairwise add and accumulate into accum vectors (16 bit to account + // for values above 255). + accum1 = vpadalq_u8(accum1, curr_data1); + } + + // Second 16 bytes. + { + // Load 16 bytes of data from current offset. + const uint8x16_t curr_data2 = vld1q_u8(offset + 16); + + // Pairwise add and accumulate into accum vectors (16 bit to account + // for values above 255). + accum2 = vpadalq_u8(accum2, curr_data2); + } + + // Move offset down one row. + offset += stride; + } + + // Divide by 4 (number of input pixels per output + // pixel) and narrow data from 16 bits per pixel to 8 bpp. + const uint8x8_t tmp_pix1 = vqshrn_n_u16(accum1, 2); + const uint8x8_t tmp_pix2 = vqshrn_n_u16(accum2, 2); + + // Concatenate 8x1 pixel strips into 16x1 pixel strip. + const uint8x16_t allpixels = vcombine_u8(tmp_pix1, tmp_pix2); + + // Copy all pixels from composite 16x1 vector into output strip. + vst1q_u8(ptr_dst, allpixels); + + ptr_dst += stride_; + } +} + +// This function does the bulk of the work. +template <> +void Image::Downsample4x32ColumnsNeon(const uint8_t* const original, + const int stride, + const int orig_x) { + // Divide input x offset by 4 to find output offset. + const int new_x = orig_x >> 2; + + // Initial offset into top row. + const uint8_t* offset = original + orig_x; + + // This points to the leftmost pixel of our 8 horizontally arranged + // pixels in the destination data. + uint8_t* ptr_dst = (*this)[0] + new_x; + + // Sum along vertical columns. + // Process 32x4 input pixels and 8x1 output pixels per iteration. + for (int new_y = 0; new_y < height_; ++new_y) { + uint16x8_t accum1 = vdupq_n_u16(0); + uint16x8_t accum2 = vdupq_n_u16(0); + + // Go top to bottom across the four rows of input pixels that make up + // this output row. + for (int row_num = 0; row_num < 4; ++row_num) { + // First 16 bytes. + { + // Load 16 bytes of data from current offset. + const uint8x16_t curr_data1 = vld1q_u8(offset); + + // Pairwise add and accumulate into accum vectors (16 bit to account + // for values above 255). + accum1 = vpadalq_u8(accum1, curr_data1); + } + + // Second 16 bytes. + { + // Load 16 bytes of data from current offset. + const uint8x16_t curr_data2 = vld1q_u8(offset + 16); + + // Pairwise add and accumulate into accum vectors (16 bit to account + // for values above 255). + accum2 = vpadalq_u8(accum2, curr_data2); + } + + // Move offset down one row. + offset += stride; + } + + // Add and widen, then divide by 16 (number of input pixels per output + // pixel) and narrow data from 32 bits per pixel to 16 bpp. + const uint16x4_t tmp_pix1 = vqshrn_n_u32(vpaddlq_u16(accum1), 4); + const uint16x4_t tmp_pix2 = vqshrn_n_u32(vpaddlq_u16(accum2), 4); + + // Combine 4x1 pixel strips into 8x1 pixel strip and narrow from + // 16 bits to 8 bits per pixel. + const uint8x8_t allpixels = vmovn_u16(vcombine_u16(tmp_pix1, tmp_pix2)); + + // Copy all pixels from composite 8x1 vector into output strip. + vst1_u8(ptr_dst, allpixels); + + ptr_dst += stride_; + } +} + + +// Hardware accelerated downsampling method for supported devices. +// Requires that image size be a multiple of 16 pixels in each dimension, +// and that downsampling be by a factor of 2 or 4. +template <> +void Image::DownsampleAveragedNeon(const uint8_t* const original, + const int stride, + const int factor) { + // TODO(andrewharp): stride is a bad approximation for the src image's width. + // Better to pass that in directly. + SCHECK(width_ * factor <= stride, "Uh oh!"); + const int last_starting_index = width_ * factor - 32; + + // We process 32 input pixels lengthwise at a time. + // The output per pass of this loop is an 8 wide by downsampled height tall + // pixel strip. + int orig_x = 0; + for (; orig_x <= last_starting_index; orig_x += 32) { + if (factor == 2) { + Downsample2x32ColumnsNeon(original, stride, orig_x); + } else { + Downsample4x32ColumnsNeon(original, stride, orig_x); + } + } + + // If a last pass is required, push it to the left enough so that it never + // goes out of bounds. This will result in some extra computation on devices + // whose frame widths are multiples of 16 and not 32. + if (orig_x < last_starting_index + 32) { + if (factor == 2) { + Downsample2x32ColumnsNeon(original, stride, last_starting_index); + } else { + Downsample4x32ColumnsNeon(original, stride, last_starting_index); + } + } +} + + +// Puts the image gradient matrix about a pixel into the 2x2 float array G. +// vals_x should be an array of the window x gradient values, whose indices +// can be in any order but are parallel to the vals_y entries. +// See http://robots.stanford.edu/cs223b04/algo_tracking.pdf for more details. +void CalculateGNeon(const float* const vals_x, const float* const vals_y, + const int num_vals, float* const G) { + const float32_t* const arm_vals_x = (const float32_t*) vals_x; + const float32_t* const arm_vals_y = (const float32_t*) vals_y; + + // Running sums. + float32x4_t xx = vdupq_n_f32(0.0f); + float32x4_t xy = vdupq_n_f32(0.0f); + float32x4_t yy = vdupq_n_f32(0.0f); + + // Maximum index we can load 4 consecutive values from. + // e.g. if there are 81 values, our last full pass can be from index 77: + // 81-4=>77 (77, 78, 79, 80) + const int max_i = num_vals - 4; + + // Defined here because we want to keep track of how many values were + // processed by NEON, so that we can finish off the remainder the normal + // way. + int i = 0; + + // Process values 4 at a time, accumulating the sums of + // the pixel-wise x*x, x*y, and y*y values. + for (; i <= max_i; i += 4) { + // Load xs + float32x4_t x = vld1q_f32(arm_vals_x + i); + + // Multiply x*x and accumulate. + xx = vmlaq_f32(xx, x, x); + + // Load ys + float32x4_t y = vld1q_f32(arm_vals_y + i); + + // Multiply x*y and accumulate. + xy = vmlaq_f32(xy, x, y); + + // Multiply y*y and accumulate. + yy = vmlaq_f32(yy, y, y); + } + + static float32_t xx_vals[4]; + static float32_t xy_vals[4]; + static float32_t yy_vals[4]; + + vst1q_f32(xx_vals, xx); + vst1q_f32(xy_vals, xy); + vst1q_f32(yy_vals, yy); + + // Accumulated values are store in sets of 4, we have to manually add + // the last bits together. + for (int j = 0; j < 4; ++j) { + G[0] += xx_vals[j]; + G[1] += xy_vals[j]; + G[3] += yy_vals[j]; + } + + // Finishes off last few values (< 4) from above. + for (; i < num_vals; ++i) { + G[0] += Square(vals_x[i]); + G[1] += vals_x[i] * vals_y[i]; + G[3] += Square(vals_y[i]); + } + + // The matrix is symmetric, so this is a given. + G[2] = G[1]; +} + +} // namespace tf_tracking + +#endif diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image_utils.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image_utils.h" new file mode 100644 index 0000000..b4ad700 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/image_utils.h" @@ -0,0 +1,298 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_IMAGE_UTILS_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_IMAGE_UTILS_H_ + +#include + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + + +namespace tf_tracking { + +inline void GetUV(const uint8_t* const input, Image* const u, + Image* const v) { + const uint8_t* pUV = input; + + for (int row = 0; row < u->GetHeight(); ++row) { + uint8_t* u_curr = (*u)[row]; + uint8_t* v_curr = (*v)[row]; + for (int col = 0; col < u->GetWidth(); ++col) { +#ifdef __APPLE__ + *u_curr++ = *pUV++; + *v_curr++ = *pUV++; +#else + *v_curr++ = *pUV++; + *u_curr++ = *pUV++; +#endif + } + } +} + +// Marks every point within a circle of a given radius on the given boolean +// image true. +template +inline static void MarkImage(const int x, const int y, const int radius, + Image* const img) { + SCHECK(img->ValidPixel(x, y), "Marking invalid pixel in image! %d, %d", x, y); + + // Precomputed for efficiency. + const int squared_radius = Square(radius); + + // Mark every row in the circle. + for (int d_y = 0; d_y <= radius; ++d_y) { + const int squared_y_dist = Square(d_y); + + const int min_y = MAX(y - d_y, 0); + const int max_y = MIN(y + d_y, img->height_less_one_); + + // The max d_x of the circle must be strictly greater or equal to + // radius - d_y for any positive d_y. Thus, starting from radius - d_y will + // reduce the number of iterations required as compared to starting from + // either 0 and counting up or radius and counting down. + for (int d_x = radius - d_y; d_x <= radius; ++d_x) { + // The first time this criteria is met, we know the width of the circle at + // this row (without using sqrt). + if (squared_y_dist + Square(d_x) >= squared_radius) { + const int min_x = MAX(x - d_x, 0); + const int max_x = MIN(x + d_x, img->width_less_one_); + + // Mark both above and below the center row. + bool* const top_row_start = (*img)[min_y] + min_x; + bool* const bottom_row_start = (*img)[max_y] + min_x; + + const int x_width = max_x - min_x + 1; + memset(top_row_start, true, sizeof(*top_row_start) * x_width); + memset(bottom_row_start, true, sizeof(*bottom_row_start) * x_width); + + // This row is marked, time to move on to the next row. + break; + } + } + } +} + +#ifdef __ARM_NEON +void CalculateGNeon( + const float* const vals_x, const float* const vals_y, + const int num_vals, float* const G); +#endif + +// Puts the image gradient matrix about a pixel into the 2x2 float array G. +// vals_x should be an array of the window x gradient values, whose indices +// can be in any order but are parallel to the vals_y entries. +// See http://robots.stanford.edu/cs223b04/algo_tracking.pdf for more details. +inline void CalculateG(const float* const vals_x, const float* const vals_y, + const int num_vals, float* const G) { +#ifdef __ARM_NEON + CalculateGNeon(vals_x, vals_y, num_vals, G); + return; +#endif + + // Non-accelerated version. + for (int i = 0; i < num_vals; ++i) { + G[0] += Square(vals_x[i]); + G[1] += vals_x[i] * vals_y[i]; + G[3] += Square(vals_y[i]); + } + + // The matrix is symmetric, so this is a given. + G[2] = G[1]; +} + +inline void CalculateGInt16(const int16_t* const vals_x, + const int16_t* const vals_y, const int num_vals, + int* const G) { + // Non-accelerated version. + for (int i = 0; i < num_vals; ++i) { + G[0] += Square(vals_x[i]); + G[1] += vals_x[i] * vals_y[i]; + G[3] += Square(vals_y[i]); + } + + // The matrix is symmetric, so this is a given. + G[2] = G[1]; +} + + +// Puts the image gradient matrix about a pixel into the 2x2 float array G. +// Looks up interpolated pixels, then calls above method for implementation. +inline void CalculateG(const int window_radius, const float center_x, + const float center_y, const Image& I_x, + const Image& I_y, float* const G) { + SCHECK(I_x.ValidPixel(center_x, center_y), "Problem in calculateG!"); + + // Hardcoded to allow for a max window radius of 5 (9 pixels x 9 pixels). + static const int kMaxWindowRadius = 5; + SCHECK(window_radius <= kMaxWindowRadius, + "Window %d > %d!", window_radius, kMaxWindowRadius); + + // Diameter of window is 2 * radius + 1 for center pixel. + static const int kWindowBufferSize = + (kMaxWindowRadius * 2 + 1) * (kMaxWindowRadius * 2 + 1); + + // Preallocate buffers statically for efficiency. + static int16_t vals_x[kWindowBufferSize]; + static int16_t vals_y[kWindowBufferSize]; + + const int src_left_fixed = RealToFixed1616(center_x - window_radius); + const int src_top_fixed = RealToFixed1616(center_y - window_radius); + + int16_t* vals_x_ptr = vals_x; + int16_t* vals_y_ptr = vals_y; + + const int window_size = 2 * window_radius + 1; + for (int y = 0; y < window_size; ++y) { + const int fp_y = src_top_fixed + (y << 16); + + for (int x = 0; x < window_size; ++x) { + const int fp_x = src_left_fixed + (x << 16); + + *vals_x_ptr++ = I_x.GetPixelInterpFixed1616(fp_x, fp_y); + *vals_y_ptr++ = I_y.GetPixelInterpFixed1616(fp_x, fp_y); + } + } + + int32_t g_temp[] = {0, 0, 0, 0}; + CalculateGInt16(vals_x, vals_y, window_size * window_size, g_temp); + + for (int i = 0; i < 4; ++i) { + G[i] = g_temp[i]; + } +} + +inline float ImageCrossCorrelation(const Image& image1, + const Image& image2, + const int x_offset, const int y_offset) { + SCHECK(image1.GetWidth() == image2.GetWidth() && + image1.GetHeight() == image2.GetHeight(), + "Dimension mismatch! %dx%d vs %dx%d", + image1.GetWidth(), image1.GetHeight(), + image2.GetWidth(), image2.GetHeight()); + + const int num_pixels = image1.GetWidth() * image1.GetHeight(); + const float* data1 = image1.data(); + const float* data2 = image2.data(); + return ComputeCrossCorrelation(data1, data2, num_pixels); +} + +// Copies an arbitrary region of an image to another (floating point) +// image, scaling as it goes using bilinear interpolation. +inline void CopyArea(const Image& image, + const BoundingBox& area_to_copy, + Image* const patch_image) { + VLOG(2) << "Copying from: " << area_to_copy << std::endl; + + const int patch_width = patch_image->GetWidth(); + const int patch_height = patch_image->GetHeight(); + + const float x_dist_between_samples = patch_width > 0 ? + area_to_copy.GetWidth() / (patch_width - 1) : 0; + + const float y_dist_between_samples = patch_height > 0 ? + area_to_copy.GetHeight() / (patch_height - 1) : 0; + + for (int y_index = 0; y_index < patch_height; ++y_index) { + const float sample_y = + y_index * y_dist_between_samples + area_to_copy.top_; + + for (int x_index = 0; x_index < patch_width; ++x_index) { + const float sample_x = + x_index * x_dist_between_samples + area_to_copy.left_; + + if (image.ValidInterpPixel(sample_x, sample_y)) { + // TODO(andrewharp): Do area averaging when downsampling. + (*patch_image)[y_index][x_index] = + image.GetPixelInterp(sample_x, sample_y); + } else { + (*patch_image)[y_index][x_index] = -1.0f; + } + } + } +} + + +// Takes a floating point image and normalizes it in-place. +// +// First, negative values will be set to the mean of the non-negative pixels +// in the image. +// +// Then, the resulting will be normalized such that it has mean value of 0.0 and +// a standard deviation of 1.0. +inline void NormalizeImage(Image* const image) { + const float* const data_ptr = image->data(); + + // Copy only the non-negative values to some temp memory. + float running_sum = 0.0f; + int num_data_gte_zero = 0; + { + float* const curr_data = (*image)[0]; + for (int i = 0; i < image->data_size_; ++i) { + if (curr_data[i] >= 0.0f) { + running_sum += curr_data[i]; + ++num_data_gte_zero; + } else { + curr_data[i] = -1.0f; + } + } + } + + // If none of the pixels are valid, just set the entire thing to 0.0f. + if (num_data_gte_zero == 0) { + image->Clear(0.0f); + return; + } + + const float corrected_mean = running_sum / num_data_gte_zero; + + float* curr_data = (*image)[0]; + for (int i = 0; i < image->data_size_; ++i) { + const float curr_val = *curr_data; + *curr_data++ = curr_val < 0 ? 0 : curr_val - corrected_mean; + } + + const float std_dev = ComputeStdDev(data_ptr, image->data_size_, 0.0f); + + if (std_dev > 0.0f) { + curr_data = (*image)[0]; + for (int i = 0; i < image->data_size_; ++i) { + *curr_data++ /= std_dev; + } + +#ifdef SANITY_CHECKS + LOGV("corrected_mean: %1.2f std_dev: %1.2f", corrected_mean, std_dev); + const float correlation = + ComputeCrossCorrelation(image->data(), + image->data(), + image->data_size_); + + if (std::abs(correlation - 1.0f) > EPSILON) { + LOG(ERROR) << "Bad image!" << std::endl; + LOG(ERROR) << *image << std::endl; + } + + SCHECK(std::abs(correlation - 1.0f) < EPSILON, + "Correlation wasn't 1.0f: %.10f", correlation); +#endif + } +} + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_IMAGE_UTILS_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/integral_image.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/integral_image.h" new file mode 100644 index 0000000..caf9b7d --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/integral_image.h" @@ -0,0 +1,187 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_INTEGRAL_IMAGE_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_INTEGRAL_IMAGE_H_ + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +namespace tf_tracking { + +typedef uint8_t Code; + +class IntegralImage : public Image { + public: + explicit IntegralImage(const Image& image_base) + : Image(image_base.GetWidth(), image_base.GetHeight()) { + Recompute(image_base); + } + + IntegralImage(const int width, const int height) + : Image(width, height) {} + + void Recompute(const Image& image_base) { + SCHECK(image_base.GetWidth() == GetWidth() && + image_base.GetHeight() == GetHeight(), "Dimensions don't match!"); + + // Sum along first row. + { + int x_sum = 0; + for (int x = 0; x < image_base.GetWidth(); ++x) { + x_sum += image_base[0][x]; + (*this)[0][x] = x_sum; + } + } + + // Sum everything else. + for (int y = 1; y < image_base.GetHeight(); ++y) { + uint32_t* curr_sum = (*this)[y]; + + // Previously summed pointers. + const uint32_t* up_one = (*this)[y - 1]; + + // Current value pointer. + const uint8_t* curr_delta = image_base[y]; + + uint32_t row_till_now = 0; + + for (int x = 0; x < GetWidth(); ++x) { + // Add the one above and the one to the left. + row_till_now += *curr_delta; + *curr_sum = *up_one + row_till_now; + + // Scoot everything along. + ++curr_sum; + ++up_one; + ++curr_delta; + } + } + + SCHECK(VerifyData(image_base), "Images did not match!"); + } + + bool VerifyData(const Image& image_base) { + for (int y = 0; y < GetHeight(); ++y) { + for (int x = 0; x < GetWidth(); ++x) { + uint32_t curr_val = (*this)[y][x]; + + if (x > 0) { + curr_val -= (*this)[y][x - 1]; + } + + if (y > 0) { + curr_val -= (*this)[y - 1][x]; + } + + if (x > 0 && y > 0) { + curr_val += (*this)[y - 1][x - 1]; + } + + if (curr_val != image_base[y][x]) { + LOGE("Mismatch! %d vs %d", curr_val, image_base[y][x]); + return false; + } + + if (GetRegionSum(x, y, x, y) != curr_val) { + LOGE("Mismatch!"); + } + } + } + + return true; + } + + // Returns the sum of all pixels in the specified region. + inline uint32_t GetRegionSum(const int x1, const int y1, const int x2, + const int y2) const { + SCHECK(x1 >= 0 && y1 >= 0 && + x2 >= x1 && y2 >= y1 && x2 < GetWidth() && y2 < GetHeight(), + "indices out of bounds! %d-%d / %d, %d-%d / %d, ", + x1, x2, GetWidth(), y1, y2, GetHeight()); + + const uint32_t everything = (*this)[y2][x2]; + + uint32_t sum = everything; + if (x1 > 0 && y1 > 0) { + // Most common case. + const uint32_t left = (*this)[y2][x1 - 1]; + const uint32_t top = (*this)[y1 - 1][x2]; + const uint32_t top_left = (*this)[y1 - 1][x1 - 1]; + + sum = everything - left - top + top_left; + SCHECK(sum >= 0, "Both: %d - %d - %d + %d => %d! indices: %d %d %d %d", + everything, left, top, top_left, sum, x1, y1, x2, y2); + } else if (x1 > 0) { + // Flush against top of image. + // Subtract out the region to the left only. + const uint32_t top = (*this)[y2][x1 - 1]; + sum = everything - top; + SCHECK(sum >= 0, "Top: %d - %d => %d!", everything, top, sum); + } else if (y1 > 0) { + // Flush against left side of image. + // Subtract out the region above only. + const uint32_t left = (*this)[y1 - 1][x2]; + sum = everything - left; + SCHECK(sum >= 0, "Left: %d - %d => %d!", everything, left, sum); + } + + SCHECK(sum >= 0, "Negative sum!"); + + return sum; + } + + // Returns the 2bit code associated with this region, which represents + // the overall gradient. + inline Code GetCode(const BoundingBox& bounding_box) const { + return GetCode(bounding_box.left_, bounding_box.top_, + bounding_box.right_, bounding_box.bottom_); + } + + inline Code GetCode(const int x1, const int y1, + const int x2, const int y2) const { + SCHECK(x1 < x2 && y1 < y2, "Bounds out of order!! TL:%d,%d BR:%d,%d", + x1, y1, x2, y2); + + // Gradient computed vertically. + const int box_height = (y2 - y1) / 2; + const int top_sum = GetRegionSum(x1, y1, x2, y1 + box_height); + const int bottom_sum = GetRegionSum(x1, y2 - box_height, x2, y2); + const bool vertical_code = top_sum > bottom_sum; + + // Gradient computed horizontally. + const int box_width = (x2 - x1) / 2; + const int left_sum = GetRegionSum(x1, y1, x1 + box_width, y2); + const int right_sum = GetRegionSum(x2 - box_width, y1, x2, y2); + const bool horizontal_code = left_sum > right_sum; + + const Code final_code = (vertical_code << 1) | horizontal_code; + + SCHECK(InRange(final_code, static_cast(0), static_cast(3)), + "Invalid code! %d", final_code); + + // Returns a value 0-3. + return final_code; + } + + private: + TF_DISALLOW_COPY_AND_ASSIGN(IntegralImage); +}; + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_INTEGRAL_IMAGE_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/jni_utils.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/jni_utils.h" new file mode 100644 index 0000000..06048ec --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/jni_utils.h" @@ -0,0 +1,63 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_JNI_UTILS_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_JNI_UTILS_H_ + +#include + +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +// The JniLongField class is used to access Java fields from native code. This +// technique of hiding pointers to native objects in opaque Java fields is how +// the Android hardware libraries work. This reduces the amount of static +// native methods and makes it easier to manage the lifetime of native objects. +class JniLongField { + public: + JniLongField(const char* field_name) + : field_name_(field_name), field_ID_(0) {} + + int64_t get(JNIEnv* env, jobject thiz) { + if (field_ID_ == 0) { + jclass cls = env->GetObjectClass(thiz); + CHECK_ALWAYS(cls != 0, "Unable to find class"); + field_ID_ = env->GetFieldID(cls, field_name_, "J"); + CHECK_ALWAYS(field_ID_ != 0, + "Unable to find field %s. (Check proguard cfg)", field_name_); + } + + return env->GetLongField(thiz, field_ID_); + } + + void set(JNIEnv* env, jobject thiz, int64_t value) { + if (field_ID_ == 0) { + jclass cls = env->GetObjectClass(thiz); + CHECK_ALWAYS(cls != 0, "Unable to find class"); + field_ID_ = env->GetFieldID(cls, field_name_, "J"); + CHECK_ALWAYS(field_ID_ != 0, + "Unable to find field %s (Check proguard cfg)", field_name_); + } + + env->SetLongField(thiz, field_ID_, value); + } + + private: + const char* const field_name_; + + // This is just a cache + jfieldID field_ID_; +}; + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_JNI_UTILS_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/keypoint.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/keypoint.h" new file mode 100644 index 0000000..93405a5 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/keypoint.h" @@ -0,0 +1,48 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_KEYPOINT_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_KEYPOINT_H_ + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/logging.h" +#include "tensorflow/examples/android/jni/object_tracking/time_log.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +#include "tensorflow/examples/android/jni/object_tracking/config.h" + +namespace tf_tracking { + +// For keeping track of keypoints. +struct Keypoint { + Keypoint() : pos_(0.0f, 0.0f), score_(0.0f), type_(0) {} + Keypoint(const float x, const float y) + : pos_(x, y), score_(0.0f), type_(0) {} + + Point2f pos_; + float score_; + uint8_t type_; +}; + +inline std::ostream& operator<<(std::ostream& stream, const Keypoint keypoint) { + return stream << "[" << keypoint.pos_ << ", " + << keypoint.score_ << ", " << keypoint.type_ << "]"; +} + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_KEYPOINT_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/keypoint_detector.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/keypoint_detector.cc" new file mode 100644 index 0000000..fc60d2a --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/keypoint_detector.cc" @@ -0,0 +1,548 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// Various keypoint detecting functions. + +#include + +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/time_log.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +#include "tensorflow/examples/android/jni/object_tracking/config.h" +#include "tensorflow/examples/android/jni/object_tracking/keypoint.h" +#include "tensorflow/examples/android/jni/object_tracking/keypoint_detector.h" + +namespace tf_tracking { + +static inline int GetDistSquaredBetween(const int* vec1, const int* vec2) { + return Square(vec1[0] - vec2[0]) + Square(vec1[1] - vec2[1]); +} + +void KeypointDetector::ScoreKeypoints(const ImageData& image_data, + const int num_candidates, + Keypoint* const candidate_keypoints) { + const Image& I_x = *image_data.GetSpatialX(0); + const Image& I_y = *image_data.GetSpatialY(0); + + if (config_->detect_skin) { + const Image& u_data = *image_data.GetU(); + const Image& v_data = *image_data.GetV(); + + static const int reference[] = {111, 155}; + + // Score all the keypoints. + for (int i = 0; i < num_candidates; ++i) { + Keypoint* const keypoint = candidate_keypoints + i; + + const int x_pos = keypoint->pos_.x * 2; + const int y_pos = keypoint->pos_.y * 2; + + const int curr_color[] = {u_data[y_pos][x_pos], v_data[y_pos][x_pos]}; + keypoint->score_ = + HarrisFilter(I_x, I_y, keypoint->pos_.x, keypoint->pos_.y) / + GetDistSquaredBetween(reference, curr_color); + } + } else { + // Score all the keypoints. + for (int i = 0; i < num_candidates; ++i) { + Keypoint* const keypoint = candidate_keypoints + i; + keypoint->score_ = + HarrisFilter(I_x, I_y, keypoint->pos_.x, keypoint->pos_.y); + } + } +} + + +inline int KeypointCompare(const void* const a, const void* const b) { + return (reinterpret_cast(a)->score_ - + reinterpret_cast(b)->score_) <= 0 ? 1 : -1; +} + + +// Quicksorts detected keypoints by score. +void KeypointDetector::SortKeypoints(const int num_candidates, + Keypoint* const candidate_keypoints) const { + qsort(candidate_keypoints, num_candidates, sizeof(Keypoint), KeypointCompare); + +#ifdef SANITY_CHECKS + // Verify that the array got sorted. + float last_score = FLT_MAX; + for (int i = 0; i < num_candidates; ++i) { + const float curr_score = candidate_keypoints[i].score_; + + // Scores should be monotonically increasing. + SCHECK(last_score >= curr_score, + "Quicksort failure! %d: %.5f > %d: %.5f (%d total)", + i - 1, last_score, i, curr_score, num_candidates); + + last_score = curr_score; + } +#endif +} + + +int KeypointDetector::SelectKeypointsInBox( + const BoundingBox& box, + const Keypoint* const candidate_keypoints, + const int num_candidates, + const int max_keypoints, + const int num_existing_keypoints, + const Keypoint* const existing_keypoints, + Keypoint* const final_keypoints) const { + if (max_keypoints <= 0) { + return 0; + } + + // This is the distance within which keypoints may be placed to each other + // within this box, roughly based on the box dimensions. + const int distance = + MAX(1, MIN(box.GetWidth(), box.GetHeight()) * kClosestPercent / 2.0f); + + // First, mark keypoints that already happen to be inside this region. Ignore + // keypoints that are outside it, however close they might be. + interest_map_->Clear(false); + for (int i = 0; i < num_existing_keypoints; ++i) { + const Keypoint& candidate = existing_keypoints[i]; + + const int x_pos = candidate.pos_.x; + const int y_pos = candidate.pos_.y; + if (box.Contains(candidate.pos_)) { + MarkImage(x_pos, y_pos, distance, interest_map_.get()); + } + } + + // Now, go through and check which keypoints will still fit in the box. + int num_keypoints_selected = 0; + for (int i = 0; i < num_candidates; ++i) { + const Keypoint& candidate = candidate_keypoints[i]; + + const int x_pos = candidate.pos_.x; + const int y_pos = candidate.pos_.y; + + if (!box.Contains(candidate.pos_) || + !interest_map_->ValidPixel(x_pos, y_pos)) { + continue; + } + + if (!(*interest_map_)[y_pos][x_pos]) { + final_keypoints[num_keypoints_selected++] = candidate; + if (num_keypoints_selected >= max_keypoints) { + break; + } + MarkImage(x_pos, y_pos, distance, interest_map_.get()); + } + } + return num_keypoints_selected; +} + + +void KeypointDetector::SelectKeypoints( + const std::vector& boxes, + const Keypoint* const candidate_keypoints, + const int num_candidates, + FramePair* const curr_change) const { + // Now select all the interesting keypoints that fall insider our boxes. + curr_change->number_of_keypoints_ = 0; + for (std::vector::const_iterator iter = boxes.begin(); + iter != boxes.end(); ++iter) { + const BoundingBox bounding_box = *iter; + + // Count up keypoints that have already been selected, and fall within our + // box. + int num_keypoints_already_in_box = 0; + for (int i = 0; i < curr_change->number_of_keypoints_; ++i) { + if (bounding_box.Contains(curr_change->frame1_keypoints_[i].pos_)) { + ++num_keypoints_already_in_box; + } + } + + const int max_keypoints_to_find_in_box = + MIN(kMaxKeypointsForObject - num_keypoints_already_in_box, + kMaxKeypoints - curr_change->number_of_keypoints_); + + const int num_new_keypoints_in_box = SelectKeypointsInBox( + bounding_box, + candidate_keypoints, + num_candidates, + max_keypoints_to_find_in_box, + curr_change->number_of_keypoints_, + curr_change->frame1_keypoints_, + curr_change->frame1_keypoints_ + curr_change->number_of_keypoints_); + + curr_change->number_of_keypoints_ += num_new_keypoints_in_box; + + LOGV("Selected %d keypoints!", curr_change->number_of_keypoints_); + } +} + + +// Walks along the given circle checking for pixels above or below the center. +// Returns a score, or 0 if the keypoint did not pass the criteria. +// +// Parameters: +// circle_perimeter: the circumference in pixels of the circle. +// threshold: the minimum number of contiguous pixels that must be above or +// below the center value. +// center_ptr: the location of the center pixel in memory +// offsets: the relative offsets from the center pixel of the edge pixels. +inline int TestCircle(const int circle_perimeter, const int threshold, + const uint8_t* const center_ptr, const int* offsets) { + // Get the actual value of the center pixel for easier reference later on. + const int center_value = static_cast(*center_ptr); + + // Number of total pixels to check. Have to wrap around some in case + // the contiguous section is split by the array edges. + const int num_total = circle_perimeter + threshold - 1; + + int num_above = 0; + int above_diff = 0; + + int num_below = 0; + int below_diff = 0; + + // Used to tell when this is definitely not going to meet the threshold so we + // can early abort. + int minimum_by_now = threshold - num_total + 1; + + // Go through every pixel along the perimeter of the circle, and then around + // again a little bit. + for (int i = 0; i < num_total; ++i) { + // This should be faster than mod. + const int perim_index = i < circle_perimeter ? i : i - circle_perimeter; + + // This gets the value of the current pixel along the perimeter by using + // a precomputed offset. + const int curr_value = + static_cast(center_ptr[offsets[perim_index]]); + + const int difference = curr_value - center_value; + + if (difference > kFastDiffAmount) { + above_diff += difference; + ++num_above; + + num_below = 0; + below_diff = 0; + + if (num_above >= threshold) { + return above_diff; + } + } else if (difference < -kFastDiffAmount) { + below_diff += difference; + ++num_below; + + num_above = 0; + above_diff = 0; + + if (num_below >= threshold) { + return below_diff; + } + } else { + num_above = 0; + num_below = 0; + above_diff = 0; + below_diff = 0; + } + + // See if there's any chance of making the threshold. + if (MAX(num_above, num_below) < minimum_by_now) { + // Didn't pass. + return 0; + } + ++minimum_by_now; + } + + // Didn't pass. + return 0; +} + + +// Returns a score in the range [0.0, positive infinity) which represents the +// relative likelihood of a point being a corner. +float KeypointDetector::HarrisFilter(const Image& I_x, + const Image& I_y, const float x, + const float y) const { + if (I_x.ValidInterpPixel(x - kHarrisWindowSize, y - kHarrisWindowSize) && + I_x.ValidInterpPixel(x + kHarrisWindowSize, y + kHarrisWindowSize)) { + // Image gradient matrix. + float G[] = { 0, 0, 0, 0 }; + CalculateG(kHarrisWindowSize, x, y, I_x, I_y, G); + + const float dx = G[0]; + const float dy = G[3]; + const float dxy = G[1]; + + // Harris-Nobel corner score. + return (dx * dy - Square(dxy)) / (dx + dy + FLT_MIN); + } + + return 0.0f; +} + + +int KeypointDetector::AddExtraCandidatesForBoxes( + const std::vector& boxes, + const int max_num_keypoints, + Keypoint* const keypoints) const { + int num_keypoints_added = 0; + + for (std::vector::const_iterator iter = boxes.begin(); + iter != boxes.end(); ++iter) { + const BoundingBox box = *iter; + + for (int i = 0; i < kNumToAddAsCandidates; ++i) { + for (int j = 0; j < kNumToAddAsCandidates; ++j) { + if (num_keypoints_added >= max_num_keypoints) { + LOGW("Hit cap of %d for temporary keypoints!", max_num_keypoints); + return num_keypoints_added; + } + + Keypoint& curr_keypoint = keypoints[num_keypoints_added++]; + curr_keypoint.pos_ = Point2f( + box.left_ + box.GetWidth() * (i + 0.5f) / kNumToAddAsCandidates, + box.top_ + box.GetHeight() * (j + 0.5f) / kNumToAddAsCandidates); + curr_keypoint.type_ = KEYPOINT_TYPE_INTEREST; + } + } + } + + return num_keypoints_added; +} + + +void KeypointDetector::FindKeypoints(const ImageData& image_data, + const std::vector& rois, + const FramePair& prev_change, + FramePair* const curr_change) { + // Copy keypoints from second frame of last pass to temp keypoints of this + // pass. + int number_of_tmp_keypoints = CopyKeypoints(prev_change, tmp_keypoints_); + + const int max_num_fast = kMaxTempKeypoints - number_of_tmp_keypoints; + number_of_tmp_keypoints += + FindFastKeypoints(image_data, max_num_fast, + tmp_keypoints_ + number_of_tmp_keypoints); + + TimeLog("Found FAST keypoints"); + + if (number_of_tmp_keypoints >= kMaxTempKeypoints) { + LOGW("Hit cap of %d for temporary keypoints (FAST)! %d keypoints", + kMaxTempKeypoints, number_of_tmp_keypoints); + } + + if (kAddArbitraryKeypoints) { + // Add some for each object prior to scoring. + const int max_num_box_keypoints = + kMaxTempKeypoints - number_of_tmp_keypoints; + number_of_tmp_keypoints += + AddExtraCandidatesForBoxes(rois, max_num_box_keypoints, + tmp_keypoints_ + number_of_tmp_keypoints); + TimeLog("Added box keypoints"); + + if (number_of_tmp_keypoints >= kMaxTempKeypoints) { + LOGW("Hit cap of %d for temporary keypoints (boxes)! %d keypoints", + kMaxTempKeypoints, number_of_tmp_keypoints); + } + } + + // Score them... + LOGV("Scoring %d keypoints!", number_of_tmp_keypoints); + ScoreKeypoints(image_data, number_of_tmp_keypoints, tmp_keypoints_); + TimeLog("Scored keypoints"); + + // Now pare it down a bit. + SortKeypoints(number_of_tmp_keypoints, tmp_keypoints_); + TimeLog("Sorted keypoints"); + + LOGV("%d keypoints to select from!", number_of_tmp_keypoints); + + SelectKeypoints(rois, tmp_keypoints_, number_of_tmp_keypoints, curr_change); + TimeLog("Selected keypoints"); + + LOGV("Picked %d (%d max) final keypoints out of %d potential.", + curr_change->number_of_keypoints_, + kMaxKeypoints, number_of_tmp_keypoints); +} + + +int KeypointDetector::CopyKeypoints(const FramePair& prev_change, + Keypoint* const new_keypoints) { + int number_of_keypoints = 0; + + // Caching values from last pass, just copy and compact. + for (int i = 0; i < prev_change.number_of_keypoints_; ++i) { + if (prev_change.optical_flow_found_keypoint_[i]) { + new_keypoints[number_of_keypoints] = + prev_change.frame2_keypoints_[i]; + + new_keypoints[number_of_keypoints].score_ = + prev_change.frame1_keypoints_[i].score_; + + ++number_of_keypoints; + } + } + + TimeLog("Copied keypoints"); + return number_of_keypoints; +} + + +// FAST keypoint detector. +int KeypointDetector::FindFastKeypoints(const Image& frame, + const int quadrant, + const int downsample_factor, + const int max_num_keypoints, + Keypoint* const keypoints) { + /* + // Reference for a circle of diameter 7. + const int circle[] = {0, 0, 1, 1, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 1, + 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 1, 1, 0, 0}; + const int circle_offset[] = + {2, 3, 4, 8, 12, 14, 20, 21, 27, 28, 34, 36, 40, 44, 45, 46}; + */ + + // Quick test of compass directions. Any length 16 circle with a break of up + // to 4 pixels will have at least 3 of these 4 pixels active. + static const int short_circle_perimeter = 4; + static const int short_threshold = 3; + static const int short_circle_x[] = { -3, 0, +3, 0 }; + static const int short_circle_y[] = { 0, -3, 0, +3 }; + + // Precompute image offsets. + int short_offsets[short_circle_perimeter]; + for (int i = 0; i < short_circle_perimeter; ++i) { + short_offsets[i] = short_circle_x[i] + short_circle_y[i] * frame.GetWidth(); + } + + // Large circle values. + static const int full_circle_perimeter = 16; + static const int full_threshold = 12; + static const int full_circle_x[] = + { -1, 0, +1, +2, +3, +3, +3, +2, +1, +0, -1, -2, -3, -3, -3, -2 }; + static const int full_circle_y[] = + { -3, -3, -3, -2, -1, 0, +1, +2, +3, +3, +3, +2, +1, +0, -1, -2 }; + + // Precompute image offsets. + int full_offsets[full_circle_perimeter]; + for (int i = 0; i < full_circle_perimeter; ++i) { + full_offsets[i] = full_circle_x[i] + full_circle_y[i] * frame.GetWidth(); + } + + const int scratch_stride = frame.stride(); + + keypoint_scratch_->Clear(0); + + // Set up the bounds on the region to test based on the passed-in quadrant. + const int quadrant_width = (frame.GetWidth() / 2) - kFastBorderBuffer; + const int quadrant_height = (frame.GetHeight() / 2) - kFastBorderBuffer; + const int start_x = + kFastBorderBuffer + ((quadrant % 2 == 0) ? 0 : quadrant_width); + const int start_y = + kFastBorderBuffer + ((quadrant < 2) ? 0 : quadrant_height); + const int end_x = start_x + quadrant_width; + const int end_y = start_y + quadrant_height; + + // Loop through once to find FAST keypoint clumps. + for (int img_y = start_y; img_y < end_y; ++img_y) { + const uint8_t* curr_pixel_ptr = frame[img_y] + start_x; + + for (int img_x = start_x; img_x < end_x; ++img_x) { + // Only insert it if it meets the quick minimum requirements test. + if (TestCircle(short_circle_perimeter, short_threshold, + curr_pixel_ptr, short_offsets) != 0) { + // Longer test for actual keypoint score.. + const int fast_score = TestCircle(full_circle_perimeter, + full_threshold, + curr_pixel_ptr, + full_offsets); + + // Non-zero score means the keypoint was found. + if (fast_score != 0) { + uint8_t* const center_ptr = (*keypoint_scratch_)[img_y] + img_x; + + // Increase the keypoint count on this pixel and the pixels in all + // 4 cardinal directions. + *center_ptr += 5; + *(center_ptr - 1) += 1; + *(center_ptr + 1) += 1; + *(center_ptr - scratch_stride) += 1; + *(center_ptr + scratch_stride) += 1; + } + } + + ++curr_pixel_ptr; + } // x + } // y + + TimeLog("Found FAST keypoints."); + + int num_keypoints = 0; + // Loop through again and Harris filter pixels in the center of clumps. + // We can shrink the window by 1 pixel on every side. + for (int img_y = start_y + 1; img_y < end_y - 1; ++img_y) { + const uint8_t* curr_pixel_ptr = (*keypoint_scratch_)[img_y] + start_x; + + for (int img_x = start_x + 1; img_x < end_x - 1; ++img_x) { + if (*curr_pixel_ptr >= kMinNumConnectedForFastKeypoint) { + Keypoint* const keypoint = keypoints + num_keypoints; + keypoint->pos_ = Point2f( + img_x * downsample_factor, img_y * downsample_factor); + keypoint->score_ = 0; + keypoint->type_ = KEYPOINT_TYPE_FAST; + + ++num_keypoints; + if (num_keypoints >= max_num_keypoints) { + return num_keypoints; + } + } + + ++curr_pixel_ptr; + } // x + } // y + + TimeLog("Picked FAST keypoints."); + + return num_keypoints; +} + +int KeypointDetector::FindFastKeypoints(const ImageData& image_data, + const int max_num_keypoints, + Keypoint* const keypoints) { + int downsample_factor = 1; + int num_found = 0; + + // TODO(andrewharp): Get this working for multiple image scales. + for (int i = 0; i < 1; ++i) { + const Image& frame = *image_data.GetPyramidSqrt2Level(i); + num_found += FindFastKeypoints( + frame, fast_quadrant_, + downsample_factor, max_num_keypoints, keypoints + num_found); + downsample_factor *= 2; + } + + // Increment the current quadrant. + fast_quadrant_ = (fast_quadrant_ + 1) % 4; + + return num_found; +} + +} // namespace tf_tracking diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/keypoint_detector.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/keypoint_detector.h" new file mode 100644 index 0000000..2e85b83 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/keypoint_detector.h" @@ -0,0 +1,128 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_KEYPOINT_DETECTOR_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_KEYPOINT_DETECTOR_H_ + +#include +#include + +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/image_data.h" +#include "tensorflow/examples/android/jni/object_tracking/optical_flow.h" + +namespace tf_tracking { + +struct Keypoint; + +class KeypointDetector { + public: + explicit KeypointDetector(const KeypointDetectorConfig* const config) + : config_(config), + keypoint_scratch_(new Image(config_->image_size)), + interest_map_(new Image(config_->image_size)), + fast_quadrant_(0) { + interest_map_->Clear(false); + } + + ~KeypointDetector() {} + + // Finds a new set of keypoints for the current frame, picked from the current + // set of keypoints and also from a set discovered via a keypoint detector. + // Special attention is applied to make sure that keypoints are distributed + // within the supplied ROIs. + void FindKeypoints(const ImageData& image_data, + const std::vector& rois, + const FramePair& prev_change, + FramePair* const curr_change); + + private: + // Compute the corneriness of a point in the image. + float HarrisFilter(const Image& I_x, const Image& I_y, + const float x, const float y) const; + + // Adds a grid of candidate keypoints to the given box, up to + // max_num_keypoints or kNumToAddAsCandidates^2, whichever is lower. + int AddExtraCandidatesForBoxes( + const std::vector& boxes, + const int max_num_keypoints, + Keypoint* const keypoints) const; + + // Scan the frame for potential keypoints using the FAST keypoint detector. + // Quadrant is an argument 0-3 which refers to the quadrant of the image in + // which to detect keypoints. + int FindFastKeypoints(const Image& frame, const int quadrant, + const int downsample_factor, + const int max_num_keypoints, Keypoint* const keypoints); + + int FindFastKeypoints(const ImageData& image_data, + const int max_num_keypoints, + Keypoint* const keypoints); + + // Score a bunch of candidate keypoints. Assigns the scores to the input + // candidate_keypoints array entries. + void ScoreKeypoints(const ImageData& image_data, + const int num_candidates, + Keypoint* const candidate_keypoints); + + void SortKeypoints(const int num_candidates, + Keypoint* const candidate_keypoints) const; + + // Selects a set of keypoints falling within the supplied box such that the + // most highly rated keypoints are picked first, and so that none of them are + // too close together. + int SelectKeypointsInBox( + const BoundingBox& box, + const Keypoint* const candidate_keypoints, + const int num_candidates, + const int max_keypoints, + const int num_existing_keypoints, + const Keypoint* const existing_keypoints, + Keypoint* const final_keypoints) const; + + // Selects from the supplied sorted keypoint pool a set of keypoints that will + // best cover the given set of boxes, such that each box is covered at a + // resolution proportional to its size. + void SelectKeypoints( + const std::vector& boxes, + const Keypoint* const candidate_keypoints, + const int num_candidates, + FramePair* const frame_change) const; + + // Copies and compacts the found keypoints in the second frame of prev_change + // into the array at new_keypoints. + static int CopyKeypoints(const FramePair& prev_change, + Keypoint* const new_keypoints); + + const KeypointDetectorConfig* const config_; + + // Scratch memory for keypoint candidacy detection and non-max suppression. + std::unique_ptr > keypoint_scratch_; + + // Regions of the image to pay special attention to. + std::unique_ptr > interest_map_; + + // The current quadrant of the image to detect FAST keypoints in. + // Keypoint detection is staggered for performance reasons. Every four frames + // a full scan of the frame will have been performed. + int fast_quadrant_; + + Keypoint tmp_keypoints_[kMaxTempKeypoints]; +}; + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_KEYPOINT_DETECTOR_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/logging.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/logging.cc" new file mode 100644 index 0000000..0ba8a54 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/logging.cc" @@ -0,0 +1,140 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/examples/android/jni/object_tracking/logging.h" + +#ifdef STANDALONE_DEMO_LIB + +#include +#include +#include +#include +#include + +LogMessage::LogMessage(const char* fname, int line, int severity) + : fname_(fname), line_(line), severity_(severity) {} + +void LogMessage::GenerateLogMessage() { + int android_log_level; + switch (severity_) { + case INFO: + android_log_level = ANDROID_LOG_INFO; + break; + case WARNING: + android_log_level = ANDROID_LOG_WARN; + break; + case ERROR: + android_log_level = ANDROID_LOG_ERROR; + break; + case FATAL: + android_log_level = ANDROID_LOG_FATAL; + break; + default: + if (severity_ < INFO) { + android_log_level = ANDROID_LOG_VERBOSE; + } else { + android_log_level = ANDROID_LOG_ERROR; + } + break; + } + + std::stringstream ss; + const char* const partial_name = strrchr(fname_, '/'); + ss << (partial_name != nullptr ? partial_name + 1 : fname_) << ":" << line_ + << " " << str(); + __android_log_write(android_log_level, "native", ss.str().c_str()); + + // Also log to stderr (for standalone Android apps). + std::cerr << "native : " << ss.str() << std::endl; + + // Android logging at level FATAL does not terminate execution, so abort() + // is still required to stop the program. + if (severity_ == FATAL) { + abort(); + } +} + +namespace { + +// Parse log level (int64) from environment variable (char*) +int64_t LogLevelStrToInt(const char* tf_env_var_val) { + if (tf_env_var_val == nullptr) { + return 0; + } + + // Ideally we would use env_var / safe_strto64, but it is + // hard to use here without pulling in a lot of dependencies, + // so we use std:istringstream instead + std::string min_log_level(tf_env_var_val); + std::istringstream ss(min_log_level); + int64_t level; + if (!(ss >> level)) { + // Invalid vlog level setting, set level to default (0) + level = 0; + } + + return level; +} + +int64_t MinLogLevelFromEnv() { + const char* tf_env_var_val = getenv("TF_CPP_MIN_LOG_LEVEL"); + return LogLevelStrToInt(tf_env_var_val); +} + +int64_t MinVLogLevelFromEnv() { + const char* tf_env_var_val = getenv("TF_CPP_MIN_VLOG_LEVEL"); + return LogLevelStrToInt(tf_env_var_val); +} + +} // namespace + +LogMessage::~LogMessage() { + // Read the min log level once during the first call to logging. + static int64_t min_log_level = MinLogLevelFromEnv(); + if (TF_PREDICT_TRUE(severity_ >= min_log_level)) GenerateLogMessage(); +} + +int64_t LogMessage::MinVLogLevel() { + static const int64_t min_vlog_level = MinVLogLevelFromEnv(); + return min_vlog_level; +} + +LogMessageFatal::LogMessageFatal(const char* file, int line) + : LogMessage(file, line, ANDROID_LOG_FATAL) {} +LogMessageFatal::~LogMessageFatal() { + // abort() ensures we don't return (we promised we would not via + // ATTRIBUTE_NORETURN). + GenerateLogMessage(); + abort(); +} + +void LogString(const char* fname, int line, int severity, + const std::string& message) { + LogMessage(fname, line, severity) << message; +} + +void LogPrintF(const int severity, const char* format, ...) { + char message[1024]; + va_list argptr; + va_start(argptr, format); + vsnprintf(message, 1024, format, argptr); + va_end(argptr); + __android_log_write(severity, "native", message); + + // Also log to stderr (for standalone Android apps). + std::cerr << "native : " << message << std::endl; +} + +#endif diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/logging.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/logging.h" new file mode 100644 index 0000000..24d05e3 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/logging.h" @@ -0,0 +1,121 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_LOGGING_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_LOGGING_H_ + +#include +#include +#include +#include +#include + +// Allow this library to be built without depending on TensorFlow by +// defining STANDALONE_DEMO_LIB. Otherwise TensorFlow headers will be +// used. +#ifdef STANDALONE_DEMO_LIB + +// A macro to disallow the copy constructor and operator= functions +// This is usually placed in the private: declarations for a class. +#define TF_DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&) = delete; \ + void operator=(const TypeName&) = delete + +#if defined(COMPILER_GCC3) +#define TF_PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#define TF_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#else +#define TF_PREDICT_FALSE(x) (x) +#define TF_PREDICT_TRUE(x) (x) +#endif + +// Log levels equivalent to those defined by +// third_party/tensorflow/core/platform/logging.h +const int INFO = 0; // base_logging::INFO; +const int WARNING = 1; // base_logging::WARNING; +const int ERROR = 2; // base_logging::ERROR; +const int FATAL = 3; // base_logging::FATAL; +const int NUM_SEVERITIES = 4; // base_logging::NUM_SEVERITIES; + +class LogMessage : public std::basic_ostringstream { + public: + LogMessage(const char* fname, int line, int severity); + ~LogMessage(); + + // Returns the minimum log level for VLOG statements. + // E.g., if MinVLogLevel() is 2, then VLOG(2) statements will produce output, + // but VLOG(3) will not. Defaults to 0. + static int64_t MinVLogLevel(); + + protected: + void GenerateLogMessage(); + + private: + const char* fname_; + int line_; + int severity_; +}; + +// LogMessageFatal ensures the process will exit in failure after +// logging this message. +class LogMessageFatal : public LogMessage { + public: + LogMessageFatal(const char* file, int line); + ~LogMessageFatal(); +}; + +#define _TF_LOG_INFO \ + ::tensorflow::internal::LogMessage(__FILE__, __LINE__, tensorflow::INFO) +#define _TF_LOG_WARNING \ + ::tensorflow::internal::LogMessage(__FILE__, __LINE__, tensorflow::WARNING) +#define _TF_LOG_ERROR \ + ::tensorflow::internal::LogMessage(__FILE__, __LINE__, tensorflow::ERROR) +#define _TF_LOG_FATAL \ + ::tensorflow::internal::LogMessageFatal(__FILE__, __LINE__) + +#define _TF_LOG_QFATAL _TF_LOG_FATAL + +#define LOG(severity) _TF_LOG_##severity + +#define VLOG_IS_ON(lvl) ((lvl) <= LogMessage::MinVLogLevel()) + +#define VLOG(lvl) \ + if (TF_PREDICT_FALSE(VLOG_IS_ON(lvl))) \ + LogMessage(__FILE__, __LINE__, ANDROID_LOG_INFO) + +void LogPrintF(const int severity, const char* format, ...); + +// Support for printf style logging. +#define LOGV(...) +#define LOGD(...) +#define LOGI(...) LogPrintF(ANDROID_LOG_INFO, __VA_ARGS__); +#define LOGW(...) LogPrintF(ANDROID_LOG_INFO, __VA_ARGS__); +#define LOGE(...) LogPrintF(ANDROID_LOG_ERROR, __VA_ARGS__); + +#else + +#include "tensorflow/core/lib/strings/stringprintf.h" +#include "tensorflow/core/platform/logging.h" + +// Support for printf style logging. +#define LOGV(...) +#define LOGD(...) +#define LOGI(...) LOG(INFO) << tensorflow::strings::Printf(__VA_ARGS__); +#define LOGW(...) LOG(INFO) << tensorflow::strings::Printf(__VA_ARGS__); +#define LOGE(...) LOG(INFO) << tensorflow::strings::Printf(__VA_ARGS__); + +#endif + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_LOGGING_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_detector.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_detector.cc" new file mode 100644 index 0000000..7f65716 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_detector.cc" @@ -0,0 +1,27 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// NOTE: no native object detectors are currently provided or used by the code +// in this directory. This class remains mainly for historical reasons. +// Detection in the TF demo is done through TensorFlowMultiBoxDetector.java. + +#include "tensorflow/examples/android/jni/object_tracking/object_detector.h" + +namespace tf_tracking { + +// This is here so that the vtable gets created properly. +ObjectDetectorBase::~ObjectDetectorBase() {} + +} // namespace tf_tracking diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_detector.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_detector.h" new file mode 100644 index 0000000..a65c7b0 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_detector.h" @@ -0,0 +1,230 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// NOTE: no native object detectors are currently provided or used by the code +// in this directory. This class remains mainly for historical reasons. +// Detection in the TF demo is done through TensorFlowMultiBoxDetector.java. + +// Defines the ObjectDetector class that is the main interface for detecting +// ObjectModelBases in frames. + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OBJECT_DETECTOR_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OBJECT_DETECTOR_H_ + +#include +#include +#include +#include +#include +#include + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/integral_image.h" +#ifdef __RENDER_OPENGL__ +#include "tensorflow/examples/android/jni/object_tracking/sprite.h" +#endif +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +#include "tensorflow/examples/android/jni/object_tracking/config.h" +#include "tensorflow/examples/android/jni/object_tracking/image_data.h" +#include "tensorflow/examples/android/jni/object_tracking/object_model.h" + +namespace tf_tracking { + +// Adds BoundingSquares to a vector such that the first square added is centered +// in the position given and of square_size, and the remaining squares are added +// concentrentically, scaling down by scale_factor until the minimum threshold +// size is passed. +// Squares that do not fall completely within image_bounds will not be added. +static inline void FillWithSquares( + const BoundingBox& image_bounds, + const BoundingBox& position, + const float starting_square_size, + const float smallest_square_size, + const float scale_factor, + std::vector* const squares) { + BoundingSquare descriptor_area = + GetCenteredSquare(position, starting_square_size); + + SCHECK(scale_factor < 1.0f, "Scale factor too large at %.2f!", scale_factor); + + // Use a do/while loop to ensure that at least one descriptor is created. + do { + if (image_bounds.Contains(descriptor_area.ToBoundingBox())) { + squares->push_back(descriptor_area); + } + descriptor_area.Scale(scale_factor); + } while (descriptor_area.size_ >= smallest_square_size - EPSILON); + LOGV("Created %zu squares starting from size %.2f to min size %.2f " + "using scale factor: %.2f", + squares->size(), starting_square_size, smallest_square_size, + scale_factor); +} + + +// Represents a potential detection of a specific ObjectExemplar and Descriptor +// at a specific position in the image. +class Detection { + public: + explicit Detection(const ObjectModelBase* const object_model, + const MatchScore match_score, + const BoundingBox& bounding_box) + : object_model_(object_model), + match_score_(match_score), + bounding_box_(bounding_box) {} + + Detection(const Detection& other) + : object_model_(other.object_model_), + match_score_(other.match_score_), + bounding_box_(other.bounding_box_) {} + + virtual ~Detection() {} + + inline BoundingBox GetObjectBoundingBox() const { + return bounding_box_; + } + + inline MatchScore GetMatchScore() const { + return match_score_; + } + + inline const ObjectModelBase* GetObjectModel() const { + return object_model_; + } + + inline bool Intersects(const Detection& other) { + // Check if any of the four axes separates us, there must be at least one. + return bounding_box_.Intersects(other.bounding_box_); + } + + struct Comp { + inline bool operator()(const Detection& a, const Detection& b) const { + return a.match_score_ > b.match_score_; + } + }; + + // TODO(andrewharp): add accessors to update these instead. + const ObjectModelBase* object_model_; + MatchScore match_score_; + BoundingBox bounding_box_; +}; + +inline std::ostream& operator<<(std::ostream& stream, + const Detection& detection) { + const BoundingBox actual_area = detection.GetObjectBoundingBox(); + stream << actual_area; + return stream; +} + +class ObjectDetectorBase { + public: + explicit ObjectDetectorBase(const ObjectDetectorConfig* const config) + : config_(config), + image_data_(NULL) {} + + virtual ~ObjectDetectorBase(); + + // Sets the current image data. All calls to ObjectDetector other than + // FillDescriptors use the image data last set. + inline void SetImageData(const ImageData* const image_data) { + image_data_ = image_data; + } + + // Main entry point into the detection algorithm. + // Scans the frame for candidates, tweaks them, and fills in the + // given std::vector of Detection objects with acceptable matches. + virtual void Detect(const std::vector& positions, + std::vector* const detections) const = 0; + + virtual ObjectModelBase* CreateObjectModel(const std::string& name) = 0; + + virtual void DeleteObjectModel(const std::string& name) = 0; + + virtual void GetObjectModels( + std::vector* models) const = 0; + + // Creates a new ObjectExemplar from the given position in the context of + // the last frame passed to NextFrame. + // Will return null in the case that there's no room for a descriptor to be + // created in the example area, or the example area is not completely + // contained within the frame. + virtual void UpdateModel(const Image& base_image, + const IntegralImage& integral_image, + const BoundingBox& bounding_box, const bool locked, + ObjectModelBase* model) const = 0; + + virtual void Draw() const = 0; + + virtual bool AllowSpontaneousDetections() = 0; + + protected: + const std::unique_ptr config_; + + // The latest frame data, upon which all detections will be performed. + // Not owned by this object, just provided for reference by ObjectTracker + // via SetImageData(). + const ImageData* image_data_; + + private: + TF_DISALLOW_COPY_AND_ASSIGN(ObjectDetectorBase); +}; + +template +class ObjectDetector : public ObjectDetectorBase { + public: + explicit ObjectDetector(const ObjectDetectorConfig* const config) + : ObjectDetectorBase(config) {} + + virtual ~ObjectDetector() { + typename std::map::const_iterator it = + object_models_.begin(); + for (; it != object_models_.end(); ++it) { + ModelType* model = it->second; + delete model; + } + } + + virtual void DeleteObjectModel(const std::string& name) { + ModelType* model = object_models_[name]; + CHECK_ALWAYS(model != NULL, "Model was null!"); + object_models_.erase(name); + SAFE_DELETE(model); + } + + virtual void GetObjectModels( + std::vector* models) const { + typename std::map::const_iterator it = + object_models_.begin(); + for (; it != object_models_.end(); ++it) { + models->push_back(it->second); + } + } + + virtual bool AllowSpontaneousDetections() { + return false; + } + + protected: + std::map object_models_; + + private: + TF_DISALLOW_COPY_AND_ASSIGN(ObjectDetector); +}; + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OBJECT_DETECTOR_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_model.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_model.h" new file mode 100644 index 0000000..4bc4d5b --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_model.h" @@ -0,0 +1,102 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// NOTE: no native object detectors are currently provided or used by the code +// in this directory. This class remains mainly for historical reasons. +// Detection in the TF demo is done through TensorFlowMultiBoxDetector.java. + +// Contains ObjectModelBase declaration. + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OBJECT_MODEL_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OBJECT_MODEL_H_ + +#ifdef __RENDER_OPENGL__ +#include +#include +#endif + +#include + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/integral_image.h" +#ifdef __RENDER_OPENGL__ +#include "tensorflow/examples/android/jni/object_tracking/sprite.h" +#endif +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +#include "tensorflow/examples/android/jni/object_tracking/config.h" +#include "tensorflow/examples/android/jni/object_tracking/image_data.h" +#include "tensorflow/examples/android/jni/object_tracking/keypoint.h" + +namespace tf_tracking { + +// The ObjectModelBase class represents all the known appearance information for +// an object. It is not a specific instance of the object in the world, +// but just the general appearance information that enables detection. An +// ObjectModelBase can be reused across multiple-instances of TrackedObjects. +class ObjectModelBase { + public: + ObjectModelBase(const std::string& name) : name_(name) {} + + virtual ~ObjectModelBase() {} + + // Called when the next step in an ongoing track occurs. + virtual void TrackStep(const BoundingBox& position, + const Image& image, + const IntegralImage& integral_image, + const bool authoritative) {} + + // Called when an object track is lost. + virtual void TrackLost() {} + + // Called when an object track is confirmed as legitimate. + virtual void TrackConfirmed() {} + + virtual float GetMaxCorrelation(const Image& patch_image) const = 0; + + virtual MatchScore GetMatchScore( + const BoundingBox& position, const ImageData& image_data) const = 0; + + virtual void Draw(float* const depth) const = 0; + + inline const std::string& GetName() const { + return name_; + } + + protected: + const std::string name_; + + private: + TF_DISALLOW_COPY_AND_ASSIGN(ObjectModelBase); +}; + +template +class ObjectModel : public ObjectModelBase { + public: + ObjectModel(const DetectorType* const detector, + const std::string& name) + : ObjectModelBase(name), detector_(detector) {} + + protected: + const DetectorType* const detector_; + + TF_DISALLOW_COPY_AND_ASSIGN(ObjectModel); +}; + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OBJECT_MODEL_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_tracker.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_tracker.cc" new file mode 100644 index 0000000..aa67acd --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_tracker.cc" @@ -0,0 +1,682 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifdef __RENDER_OPENGL__ +#include +#include +#endif + +#include +#include + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/integral_image.h" +#include "tensorflow/examples/android/jni/object_tracking/logging.h" +#include "tensorflow/examples/android/jni/object_tracking/time_log.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +#include "tensorflow/examples/android/jni/object_tracking/config.h" +#include "tensorflow/examples/android/jni/object_tracking/flow_cache.h" +#include "tensorflow/examples/android/jni/object_tracking/keypoint_detector.h" +#include "tensorflow/examples/android/jni/object_tracking/object_detector.h" +#include "tensorflow/examples/android/jni/object_tracking/object_tracker.h" +#include "tensorflow/examples/android/jni/object_tracking/optical_flow.h" + +namespace tf_tracking { + +ObjectTracker::ObjectTracker(const TrackerConfig* const config, + ObjectDetectorBase* const detector) + : config_(config), + frame_width_(config->image_size.width), + frame_height_(config->image_size.height), + curr_time_(0), + num_frames_(0), + flow_cache_(&config->flow_config), + keypoint_detector_(&config->keypoint_detector_config), + curr_num_frame_pairs_(0), + first_frame_index_(0), + frame1_(new ImageData(frame_width_, frame_height_)), + frame2_(new ImageData(frame_width_, frame_height_)), + detector_(detector), + num_detected_(0) { + for (int i = 0; i < kNumFrames; ++i) { + frame_pairs_[i].Init(-1, -1); + } +} + + +ObjectTracker::~ObjectTracker() { + for (TrackedObjectMap::iterator iter = objects_.begin(); + iter != objects_.end(); iter++) { + TrackedObject* object = iter->second; + SAFE_DELETE(object); + } +} + + +// Finds the correspondences for all the points in the current pair of frames. +// Stores the results in the given FramePair. +void ObjectTracker::FindCorrespondences(FramePair* const frame_pair) const { + // Keypoints aren't found until they're found. + memset(frame_pair->optical_flow_found_keypoint_, false, + sizeof(*frame_pair->optical_flow_found_keypoint_) * kMaxKeypoints); + TimeLog("Cleared old found keypoints"); + + int num_keypoints_found = 0; + + // For every keypoint... + for (int i_feat = 0; i_feat < frame_pair->number_of_keypoints_; ++i_feat) { + Keypoint* const keypoint1 = frame_pair->frame1_keypoints_ + i_feat; + Keypoint* const keypoint2 = frame_pair->frame2_keypoints_ + i_feat; + + if (flow_cache_.FindNewPositionOfPoint( + keypoint1->pos_.x, keypoint1->pos_.y, + &keypoint2->pos_.x, &keypoint2->pos_.y)) { + frame_pair->optical_flow_found_keypoint_[i_feat] = true; + ++num_keypoints_found; + } + } + + TimeLog("Found correspondences"); + + LOGV("Found %d of %d keypoint correspondences", + num_keypoints_found, frame_pair->number_of_keypoints_); +} + +void ObjectTracker::NextFrame(const uint8_t* const new_frame, + const uint8_t* const uv_frame, + const int64_t timestamp, + const float* const alignment_matrix_2x3) { + IncrementFrameIndex(); + LOGV("Received frame %d", num_frames_); + + FramePair* const curr_change = frame_pairs_ + GetNthIndexFromEnd(0); + curr_change->Init(curr_time_, timestamp); + + CHECK_ALWAYS(curr_time_ < timestamp, + "Timestamp must monotonically increase! Went from %lld to %lld" + " on frame %d.", + curr_time_, timestamp, num_frames_); + curr_time_ = timestamp; + + // Swap the frames. + frame1_.swap(frame2_); + + frame2_->SetData(new_frame, uv_frame, frame_width_, timestamp, 1); + + if (detector_.get() != NULL) { + detector_->SetImageData(frame2_.get()); + } + + flow_cache_.NextFrame(frame2_.get(), alignment_matrix_2x3); + + if (num_frames_ == 1) { + // This must be the first frame, so abort. + return; + } + + if (config_->always_track || objects_.size() > 0) { + LOGV("Tracking %zu targets", objects_.size()); + ComputeKeypoints(true); + TimeLog("Keypoints computed!"); + + FindCorrespondences(curr_change); + TimeLog("Flow computed!"); + + TrackObjects(); + } + TimeLog("Targets tracked!"); + + if (detector_.get() != NULL && num_frames_ % kDetectEveryNFrames == 0) { + DetectTargets(); + } + TimeLog("Detected objects."); +} + +TrackedObject* ObjectTracker::MaybeAddObject( + const std::string& id, const Image& source_image, + const BoundingBox& bounding_box, const ObjectModelBase* object_model) { + // Train the detector if this is a new object. + if (objects_.find(id) != objects_.end()) { + return objects_[id]; + } + + // Need to get a non-const version of the model, or create a new one if it + // wasn't given. + ObjectModelBase* model = NULL; + if (detector_ != NULL) { + // If a detector is registered, then this new object must have a model. + CHECK_ALWAYS(object_model != NULL, "No model given!"); + model = detector_->CreateObjectModel(object_model->GetName()); + } + TrackedObject* const object = + new TrackedObject(id, source_image, bounding_box, model); + + objects_[id] = object; + return object; +} + +void ObjectTracker::RegisterNewObjectWithAppearance( + const std::string& id, const uint8_t* const new_frame, + const BoundingBox& bounding_box) { + ObjectModelBase* object_model = NULL; + + Image image(frame_width_, frame_height_); + image.FromArray(new_frame, frame_width_, 1); + + if (detector_ != NULL) { + object_model = detector_->CreateObjectModel(id); + CHECK_ALWAYS(object_model != NULL, "Null object model!"); + + const IntegralImage integral_image(image); + object_model->TrackStep(bounding_box, image, integral_image, true); + } + + // Create an object at this position. + CHECK_ALWAYS(!HaveObject(id), "Already have this object!"); + if (objects_.find(id) == objects_.end()) { + TrackedObject* const object = + MaybeAddObject(id, image, bounding_box, object_model); + CHECK_ALWAYS(object != NULL, "Object not created!"); + } +} + +void ObjectTracker::SetPreviousPositionOfObject(const std::string& id, + const BoundingBox& bounding_box, + const int64_t timestamp) { + CHECK_ALWAYS(timestamp > 0, "Timestamp too low! %lld", timestamp); + CHECK_ALWAYS(timestamp <= curr_time_, + "Timestamp too great! %lld vs %lld", timestamp, curr_time_); + + TrackedObject* const object = GetObject(id); + + // Track this bounding box from the past to the current time. + const BoundingBox current_position = TrackBox(bounding_box, timestamp); + + object->UpdatePosition(current_position, curr_time_, *frame2_, false); + + VLOG(2) << "Set tracked position for " << id << " to " << bounding_box + << std::endl; +} + + +void ObjectTracker::SetCurrentPositionOfObject( + const std::string& id, const BoundingBox& bounding_box) { + SetPreviousPositionOfObject(id, bounding_box, curr_time_); +} + + +void ObjectTracker::ForgetTarget(const std::string& id) { + LOGV("Forgetting object %s", id.c_str()); + TrackedObject* const object = GetObject(id); + delete object; + objects_.erase(id); + + if (detector_ != NULL) { + detector_->DeleteObjectModel(id); + } +} + +int ObjectTracker::GetKeypointsPacked(uint16_t* const out_data, + const float scale) const { + const FramePair& change = frame_pairs_[GetNthIndexFromEnd(0)]; + uint16_t* curr_data = out_data; + int num_keypoints = 0; + + for (int i = 0; i < change.number_of_keypoints_; ++i) { + if (change.optical_flow_found_keypoint_[i]) { + ++num_keypoints; + const Point2f& point1 = change.frame1_keypoints_[i].pos_; + *curr_data++ = RealToFixed115(point1.x * scale); + *curr_data++ = RealToFixed115(point1.y * scale); + + const Point2f& point2 = change.frame2_keypoints_[i].pos_; + *curr_data++ = RealToFixed115(point2.x * scale); + *curr_data++ = RealToFixed115(point2.y * scale); + } + } + + return num_keypoints; +} + + +int ObjectTracker::GetKeypoints(const bool only_found, + float* const out_data) const { + int curr_keypoint = 0; + const FramePair& change = frame_pairs_[GetNthIndexFromEnd(0)]; + + for (int i = 0; i < change.number_of_keypoints_; ++i) { + if (!only_found || change.optical_flow_found_keypoint_[i]) { + const int base = curr_keypoint * kKeypointStep; + out_data[base + 0] = change.frame1_keypoints_[i].pos_.x; + out_data[base + 1] = change.frame1_keypoints_[i].pos_.y; + + out_data[base + 2] = + change.optical_flow_found_keypoint_[i] ? 1.0f : -1.0f; + out_data[base + 3] = change.frame2_keypoints_[i].pos_.x; + out_data[base + 4] = change.frame2_keypoints_[i].pos_.y; + + out_data[base + 5] = change.frame1_keypoints_[i].score_; + out_data[base + 6] = change.frame1_keypoints_[i].type_; + ++curr_keypoint; + } + } + + LOGV("Got %d keypoints.", curr_keypoint); + + return curr_keypoint; +} + + +BoundingBox ObjectTracker::TrackBox(const BoundingBox& region, + const FramePair& frame_pair) const { + float translation_x; + float translation_y; + + float scale_x; + float scale_y; + + BoundingBox tracked_box(region); + frame_pair.AdjustBox( + tracked_box, &translation_x, &translation_y, &scale_x, &scale_y); + + tracked_box.Shift(Point2f(translation_x, translation_y)); + + if (scale_x > 0 && scale_y > 0) { + tracked_box.Scale(scale_x, scale_y); + } + return tracked_box; +} + +BoundingBox ObjectTracker::TrackBox(const BoundingBox& region, + const int64_t timestamp) const { + CHECK_ALWAYS(timestamp > 0, "Timestamp too low! %lld", timestamp); + CHECK_ALWAYS(timestamp <= curr_time_, "Timestamp is in the future!"); + + // Anything that ended before the requested timestamp is of no concern to us. + bool found_it = false; + int num_frames_back = -1; + for (int i = 0; i < curr_num_frame_pairs_; ++i) { + const FramePair& frame_pair = + frame_pairs_[GetNthIndexFromEnd(i)]; + + if (frame_pair.end_time_ <= timestamp) { + num_frames_back = i - 1; + + if (num_frames_back > 0) { + LOGV("Went %d out of %d frames before finding frame. (index: %d)", + num_frames_back, curr_num_frame_pairs_, GetNthIndexFromEnd(i)); + } + + found_it = true; + break; + } + } + + if (!found_it) { + LOGW("History did not go back far enough! %lld vs %lld", + frame_pairs_[GetNthIndexFromEnd(0)].end_time_ - + frame_pairs_[GetNthIndexFromStart(0)].end_time_, + frame_pairs_[GetNthIndexFromEnd(0)].end_time_ - timestamp); + } + + // Loop over all the frames in the queue, tracking the accumulated delta + // of the point from frame to frame. It's possible the point could + // go out of frame, but keep tracking as best we can, using points near + // the edge of the screen where it went out of bounds. + BoundingBox tracked_box(region); + for (int i = num_frames_back; i >= 0; --i) { + const FramePair& frame_pair = frame_pairs_[GetNthIndexFromEnd(i)]; + SCHECK(frame_pair.end_time_ >= timestamp, "Frame timestamp was too early!"); + tracked_box = TrackBox(tracked_box, frame_pair); + } + return tracked_box; +} + + +// Converts a row-major 3x3 2d transformation matrix to a column-major 4x4 +// 3d transformation matrix. +inline void Convert3x3To4x4( + const float* const in_matrix, float* const out_matrix) { + // X + out_matrix[0] = in_matrix[0]; + out_matrix[1] = in_matrix[3]; + out_matrix[2] = 0.0f; + out_matrix[3] = 0.0f; + + // Y + out_matrix[4] = in_matrix[1]; + out_matrix[5] = in_matrix[4]; + out_matrix[6] = 0.0f; + out_matrix[7] = 0.0f; + + // Z + out_matrix[8] = 0.0f; + out_matrix[9] = 0.0f; + out_matrix[10] = 1.0f; + out_matrix[11] = 0.0f; + + // Translation + out_matrix[12] = in_matrix[2]; + out_matrix[13] = in_matrix[5]; + out_matrix[14] = 0.0f; + out_matrix[15] = 1.0f; +} + + +void ObjectTracker::Draw(const int canvas_width, const int canvas_height, + const float* const frame_to_canvas) const { +#ifdef __RENDER_OPENGL__ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glOrthof(0.0f, canvas_width, 0.0f, canvas_height, 0.0f, 1.0f); + + // To make Y go the right direction (0 at top of frame). + glScalef(1.0f, -1.0f, 1.0f); + glTranslatef(0.0f, -canvas_height, 0.0f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glPushMatrix(); + + // Apply the frame to canvas transformation. + static GLfloat transformation[16]; + Convert3x3To4x4(frame_to_canvas, transformation); + glMultMatrixf(transformation); + + // Draw tracked object bounding boxes. + for (TrackedObjectMap::const_iterator iter = objects_.begin(); + iter != objects_.end(); ++iter) { + TrackedObject* tracked_object = iter->second; + tracked_object->Draw(); + } + + static const bool kRenderDebugPyramid = false; + if (kRenderDebugPyramid) { + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + for (int i = 0; i < kNumPyramidLevels * 2; ++i) { + Sprite(*frame1_->GetPyramidSqrt2Level(i)).Draw(); + } + } + + static const bool kRenderDebugDerivative = false; + if (kRenderDebugDerivative) { + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + for (int i = 0; i < kNumPyramidLevels; ++i) { + const Image& dx = *frame1_->GetSpatialX(i); + Image render_image(dx.GetWidth(), dx.GetHeight()); + for (int y = 0; y < dx.GetHeight(); ++y) { + const int32_t* dx_ptr = dx[y]; + uint8_t* dst_ptr = render_image[y]; + for (int x = 0; x < dx.GetWidth(); ++x) { + *dst_ptr++ = Clip(-(*dx_ptr++), 0, 255); + } + } + + Sprite(render_image).Draw(); + } + } + + if (detector_ != NULL) { + glDisable(GL_CULL_FACE); + detector_->Draw(); + } + glPopMatrix(); +#endif +} + +static void AddQuadrants(const BoundingBox& box, + std::vector* boxes) { + const Point2f center = box.GetCenter(); + + float x1 = box.left_; + float x2 = center.x; + float x3 = box.right_; + + float y1 = box.top_; + float y2 = center.y; + float y3 = box.bottom_; + + // Upper left. + boxes->push_back(BoundingBox(x1, y1, x2, y2)); + + // Upper right. + boxes->push_back(BoundingBox(x2, y1, x3, y2)); + + // Bottom left. + boxes->push_back(BoundingBox(x1, y2, x2, y3)); + + // Bottom right. + boxes->push_back(BoundingBox(x2, y2, x3, y3)); + + // Whole thing. + boxes->push_back(box); +} + +void ObjectTracker::ComputeKeypoints(const bool cached_ok) { + const FramePair& prev_change = frame_pairs_[GetNthIndexFromEnd(1)]; + FramePair* const curr_change = &frame_pairs_[GetNthIndexFromEnd(0)]; + + std::vector boxes; + + for (TrackedObjectMap::iterator object_iter = objects_.begin(); + object_iter != objects_.end(); ++object_iter) { + BoundingBox box = object_iter->second->GetPosition(); + box.Scale(config_->object_box_scale_factor_for_features, + config_->object_box_scale_factor_for_features); + AddQuadrants(box, &boxes); + } + + AddQuadrants(frame1_->GetImage()->GetContainingBox(), &boxes); + + keypoint_detector_.FindKeypoints(*frame1_, boxes, prev_change, curr_change); +} + + +// Given a vector of detections and a model, simply returns the Detection for +// that model with the highest correlation. +bool ObjectTracker::GetBestObjectForDetection( + const Detection& detection, TrackedObject** match) const { + TrackedObject* best_match = NULL; + float best_overlap = -FLT_MAX; + + LOGV("Looking for matches in %zu objects!", objects_.size()); + for (TrackedObjectMap::const_iterator object_iter = objects_.begin(); + object_iter != objects_.end(); ++object_iter) { + TrackedObject* const tracked_object = object_iter->second; + + const float overlap = tracked_object->GetPosition().PascalScore( + detection.GetObjectBoundingBox()); + + if (!detector_->AllowSpontaneousDetections() && + (detection.GetObjectModel() != tracked_object->GetModel())) { + if (overlap > 0.0f) { + return false; + } + continue; + } + + const float jump_distance = + (tracked_object->GetPosition().GetCenter() - + detection.GetObjectBoundingBox().GetCenter()).LengthSquared(); + + const float allowed_distance = + tracked_object->GetAllowableDistanceSquared(); + + LOGV("Distance: %.2f, Allowed distance %.2f, Overlap: %.2f", + jump_distance, allowed_distance, overlap); + + // TODO(andrewharp): No need to do this verification twice, eliminate + // one of the score checks (the other being in OnDetection). + if (jump_distance < allowed_distance && + overlap > best_overlap && + tracked_object->GetMatchScore() + kMatchScoreBuffer < + detection.GetMatchScore()) { + best_match = tracked_object; + best_overlap = overlap; + } else if (overlap > 0.0f) { + return false; + } + } + + *match = best_match; + return true; +} + + +void ObjectTracker::ProcessDetections( + std::vector* const detections) { + LOGV("Initial detection done, iterating over %zu detections now.", + detections->size()); + + const bool spontaneous_detections_allowed = + detector_->AllowSpontaneousDetections(); + for (std::vector::const_iterator it = detections->begin(); + it != detections->end(); ++it) { + const Detection& detection = *it; + SCHECK(frame2_->GetImage()->Contains(detection.GetObjectBoundingBox()), + "Frame does not contain bounding box!"); + + TrackedObject* best_match = NULL; + + const bool no_collisions = + GetBestObjectForDetection(detection, &best_match); + + // Need to get a non-const version of the model, or create a new one if it + // wasn't given. + ObjectModelBase* model = + const_cast(detection.GetObjectModel()); + + if (best_match != NULL) { + if (model != best_match->GetModel()) { + CHECK_ALWAYS(detector_->AllowSpontaneousDetections(), + "Model for object changed but spontaneous detections not allowed!"); + } + best_match->OnDetection(model, + detection.GetObjectBoundingBox(), + detection.GetMatchScore(), + curr_time_, *frame2_); + } else if (no_collisions && spontaneous_detections_allowed) { + if (detection.GetMatchScore() > kMinimumMatchScore) { + LOGV("No match, adding it!"); + const ObjectModelBase* model = detection.GetObjectModel(); + std::ostringstream ss; + // TODO(andrewharp): Generate this in a more general fashion. + ss << "hand_" << num_detected_++; + std::string object_name = ss.str(); + MaybeAddObject(object_name, *frame2_->GetImage(), + detection.GetObjectBoundingBox(), model); + } + } + } +} + + +void ObjectTracker::DetectTargets() { + // Detect all object model types that we're currently tracking. + std::vector object_models; + detector_->GetObjectModels(&object_models); + if (object_models.size() == 0) { + LOGV("No objects to search for, aborting."); + return; + } + + LOGV("Trying to detect %zu models", object_models.size()); + + LOGV("Creating test vector!"); + std::vector positions; + + for (TrackedObjectMap::iterator object_iter = objects_.begin(); + object_iter != objects_.end(); ++object_iter) { + TrackedObject* const tracked_object = object_iter->second; + +#if DEBUG_PREDATOR + positions.push_back(GetCenteredSquare( + frame2_->GetImage()->GetContainingBox(), 32.0f)); +#else + const BoundingBox& position = tracked_object->GetPosition(); + + const float square_size = MAX( + kScanMinSquareSize / (kLastKnownPositionScaleFactor * + kLastKnownPositionScaleFactor), + MIN(position.GetWidth(), + position.GetHeight())) / kLastKnownPositionScaleFactor; + + FillWithSquares(frame2_->GetImage()->GetContainingBox(), + tracked_object->GetPosition(), + square_size, + kScanMinSquareSize, + kLastKnownPositionScaleFactor, + &positions); + } +#endif + + LOGV("Created test vector!"); + + std::vector detections; + LOGV("Detecting!"); + detector_->Detect(positions, &detections); + LOGV("Found %zu detections", detections.size()); + + TimeLog("Finished detection."); + + ProcessDetections(&detections); + + TimeLog("iterated over detections"); + + LOGV("Done detecting!"); +} + + +void ObjectTracker::TrackObjects() { + // TODO(andrewharp): Correlation should be allowed to remove objects too. + const bool automatic_removal_allowed = detector_.get() != NULL ? + detector_->AllowSpontaneousDetections() : false; + + LOGV("Tracking %zu objects!", objects_.size()); + std::vector dead_objects; + for (TrackedObjectMap::iterator iter = objects_.begin(); + iter != objects_.end(); iter++) { + TrackedObject* object = iter->second; + const BoundingBox tracked_position = TrackBox( + object->GetPosition(), frame_pairs_[GetNthIndexFromEnd(0)]); + object->UpdatePosition(tracked_position, curr_time_, *frame2_, false); + + if (automatic_removal_allowed && + object->GetNumConsecutiveFramesBelowThreshold() > + kMaxNumDetectionFailures * 5) { + dead_objects.push_back(iter->first); + } + } + + if (detector_ != NULL && automatic_removal_allowed) { + for (std::vector::iterator iter = dead_objects.begin(); + iter != dead_objects.end(); iter++) { + LOGE("Removing object! %s", iter->c_str()); + ForgetTarget(*iter); + } + } + TimeLog("Tracked all objects."); + + LOGV("%zu objects tracked!", objects_.size()); +} + +} // namespace tf_tracking diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_tracker.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_tracker.h" new file mode 100644 index 0000000..20c7627 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_tracker.h" @@ -0,0 +1,270 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OBJECT_TRACKER_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OBJECT_TRACKER_H_ + +#include +#include + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" +#include "tensorflow/examples/android/jni/object_tracking/integral_image.h" +#include "tensorflow/examples/android/jni/object_tracking/logging.h" +#include "tensorflow/examples/android/jni/object_tracking/time_log.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +#include "tensorflow/examples/android/jni/object_tracking/config.h" +#include "tensorflow/examples/android/jni/object_tracking/flow_cache.h" +#include "tensorflow/examples/android/jni/object_tracking/keypoint_detector.h" +#include "tensorflow/examples/android/jni/object_tracking/object_model.h" +#include "tensorflow/examples/android/jni/object_tracking/optical_flow.h" +#include "tensorflow/examples/android/jni/object_tracking/tracked_object.h" + +namespace tf_tracking { + +typedef std::map TrackedObjectMap; + +inline std::ostream& operator<<(std::ostream& stream, + const TrackedObjectMap& map) { + for (TrackedObjectMap::const_iterator iter = map.begin(); + iter != map.end(); ++iter) { + const TrackedObject& tracked_object = *iter->second; + const std::string& key = iter->first; + stream << key << ": " << tracked_object; + } + return stream; +} + + +// ObjectTracker is the highest-level class in the tracking/detection framework. +// It handles basic image processing, keypoint detection, keypoint tracking, +// object tracking, and object detection/relocalization. +class ObjectTracker { + public: + ObjectTracker(const TrackerConfig* const config, + ObjectDetectorBase* const detector); + virtual ~ObjectTracker(); + + virtual void NextFrame(const uint8_t* const new_frame, + const int64_t timestamp, + const float* const alignment_matrix_2x3) { + NextFrame(new_frame, NULL, timestamp, alignment_matrix_2x3); + } + + // Called upon the arrival of a new frame of raw data. + // Does all image processing, keypoint detection, and object + // tracking/detection for registered objects. + // Argument alignment_matrix_2x3 is a 2x3 matrix (stored row-wise) that + // represents the main transformation that has happened between the last + // and the current frame. + // Argument align_level is the pyramid level (where 0 == finest) that + // the matrix is valid for. + virtual void NextFrame(const uint8_t* const new_frame, + const uint8_t* const uv_frame, const int64_t timestamp, + const float* const alignment_matrix_2x3); + + virtual void RegisterNewObjectWithAppearance(const std::string& id, + const uint8_t* const new_frame, + const BoundingBox& bounding_box); + + // Updates the position of a tracked object, given that it was known to be at + // a certain position at some point in the past. + virtual void SetPreviousPositionOfObject(const std::string& id, + const BoundingBox& bounding_box, + const int64_t timestamp); + + // Sets the current position of the object in the most recent frame provided. + virtual void SetCurrentPositionOfObject(const std::string& id, + const BoundingBox& bounding_box); + + // Tells the ObjectTracker to stop tracking a target. + void ForgetTarget(const std::string& id); + + // Fills the given out_data buffer with the latest detected keypoint + // correspondences, first scaled by scale_factor (to adjust for downsampling + // that may have occurred elsewhere), then packed in a fixed-point format. + int GetKeypointsPacked(uint16_t* const out_data, + const float scale_factor) const; + + // Copy the keypoint arrays after computeFlow is called. + // out_data should be at least kMaxKeypoints * kKeypointStep long. + // Currently, its format is [x1 y1 found x2 y2 score] repeated N times, + // where N is the number of keypoints tracked. N is returned as the result. + int GetKeypoints(const bool only_found, float* const out_data) const; + + // Returns the current position of a box, given that it was at a certain + // position at the given time. + BoundingBox TrackBox(const BoundingBox& region, + const int64_t timestamp) const; + + // Returns the number of frames that have been passed to NextFrame(). + inline int GetNumFrames() const { + return num_frames_; + } + + inline bool HaveObject(const std::string& id) const { + return objects_.find(id) != objects_.end(); + } + + // Returns the TrackedObject associated with the given id. + inline const TrackedObject* GetObject(const std::string& id) const { + TrackedObjectMap::const_iterator iter = objects_.find(id); + CHECK_ALWAYS(iter != objects_.end(), + "Unknown object key! \"%s\"", id.c_str()); + TrackedObject* const object = iter->second; + return object; + } + + // Returns the TrackedObject associated with the given id. + inline TrackedObject* GetObject(const std::string& id) { + TrackedObjectMap::iterator iter = objects_.find(id); + CHECK_ALWAYS(iter != objects_.end(), + "Unknown object key! \"%s\"", id.c_str()); + TrackedObject* const object = iter->second; + return object; + } + + bool IsObjectVisible(const std::string& id) const { + SCHECK(HaveObject(id), "Don't have this object."); + + const TrackedObject* object = GetObject(id); + return object->IsVisible(); + } + + virtual void Draw(const int canvas_width, const int canvas_height, + const float* const frame_to_canvas) const; + + protected: + // Creates a new tracked object at the given position. + // If an object model is provided, then that model will be associated with the + // object. If not, a new model may be created from the appearance at the + // initial position and registered with the object detector. + virtual TrackedObject* MaybeAddObject(const std::string& id, + const Image& image, + const BoundingBox& bounding_box, + const ObjectModelBase* object_model); + + // Find the keypoints in the frame before the current frame. + // If only one frame exists, keypoints will be found in that frame. + void ComputeKeypoints(const bool cached_ok = false); + + // Finds the correspondences for all the points in the current pair of frames. + // Stores the results in the given FramePair. + void FindCorrespondences(FramePair* const curr_change) const; + + inline int GetNthIndexFromEnd(const int offset) const { + return GetNthIndexFromStart(curr_num_frame_pairs_ - 1 - offset); + } + + BoundingBox TrackBox(const BoundingBox& region, + const FramePair& frame_pair) const; + + inline void IncrementFrameIndex() { + // Move the current framechange index up. + ++num_frames_; + ++curr_num_frame_pairs_; + + // If we've got too many, push up the start of the queue. + if (curr_num_frame_pairs_ > kNumFrames) { + first_frame_index_ = GetNthIndexFromStart(1); + --curr_num_frame_pairs_; + } + } + + inline int GetNthIndexFromStart(const int offset) const { + SCHECK(offset >= 0 && offset < curr_num_frame_pairs_, + "Offset out of range! %d out of %d.", offset, curr_num_frame_pairs_); + return (first_frame_index_ + offset) % kNumFrames; + } + + void TrackObjects(); + + const std::unique_ptr config_; + + const int frame_width_; + const int frame_height_; + + int64_t curr_time_; + + int num_frames_; + + TrackedObjectMap objects_; + + FlowCache flow_cache_; + + KeypointDetector keypoint_detector_; + + int curr_num_frame_pairs_; + int first_frame_index_; + + std::unique_ptr frame1_; + std::unique_ptr frame2_; + + FramePair frame_pairs_[kNumFrames]; + + std::unique_ptr detector_; + + int num_detected_; + + private: + void TrackTarget(TrackedObject* const object); + + bool GetBestObjectForDetection( + const Detection& detection, TrackedObject** match) const; + + void ProcessDetections(std::vector* const detections); + + void DetectTargets(); + + // Temp object used in ObjectTracker::CreateNewExample. + mutable std::vector squares; + + friend std::ostream& operator<<(std::ostream& stream, + const ObjectTracker& tracker); + + TF_DISALLOW_COPY_AND_ASSIGN(ObjectTracker); +}; + +inline std::ostream& operator<<(std::ostream& stream, + const ObjectTracker& tracker) { + stream << "Frame size: " << tracker.frame_width_ << "x" + << tracker.frame_height_ << std::endl; + + stream << "Num frames: " << tracker.num_frames_ << std::endl; + + stream << "Curr time: " << tracker.curr_time_ << std::endl; + + const int first_frame_index = tracker.GetNthIndexFromStart(0); + const FramePair& first_frame_pair = tracker.frame_pairs_[first_frame_index]; + + const int last_frame_index = tracker.GetNthIndexFromEnd(0); + const FramePair& last_frame_pair = tracker.frame_pairs_[last_frame_index]; + + stream << "first frame: " << first_frame_index << "," + << first_frame_pair.end_time_ << " " + << "last frame: " << last_frame_index << "," + << last_frame_pair.end_time_ << " diff: " + << last_frame_pair.end_time_ - first_frame_pair.end_time_ << "ms" + << std::endl; + + stream << "Tracked targets:"; + stream << tracker.objects_; + + return stream; +} + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OBJECT_TRACKER_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_tracker_jni.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_tracker_jni.cc" new file mode 100644 index 0000000..745b8ff --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/object_tracker_jni.cc" @@ -0,0 +1,459 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include +#include +#include +#include +#include +#include + +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/jni_utils.h" +#include "tensorflow/examples/android/jni/object_tracking/time_log.h" + +#include "tensorflow/examples/android/jni/object_tracking/config.h" +#include "tensorflow/examples/android/jni/object_tracking/object_tracker.h" + +namespace tf_tracking { + +#define OBJECT_TRACKER_METHOD(METHOD_NAME) \ + Java_org_tensorflow_demo_tracking_ObjectTracker_##METHOD_NAME // NOLINT + +JniLongField object_tracker_field("nativeObjectTracker"); + +ObjectTracker* get_object_tracker(JNIEnv* env, jobject thiz) { + ObjectTracker* const object_tracker = + reinterpret_cast(object_tracker_field.get(env, thiz)); + CHECK_ALWAYS(object_tracker != NULL, "null object tracker!"); + return object_tracker; +} + +void set_object_tracker(JNIEnv* env, jobject thiz, + const ObjectTracker* object_tracker) { + object_tracker_field.set(env, thiz, + reinterpret_cast(object_tracker)); +} + +#ifdef __cplusplus +extern "C" { +#endif +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(initNative)(JNIEnv* env, jobject thiz, + jint width, jint height, + jboolean always_track); + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(releaseMemoryNative)(JNIEnv* env, + jobject thiz); + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(registerNewObjectWithAppearanceNative)( + JNIEnv* env, jobject thiz, jstring object_id, jfloat x1, jfloat y1, + jfloat x2, jfloat y2, jbyteArray frame_data); + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(setPreviousPositionNative)( + JNIEnv* env, jobject thiz, jstring object_id, jfloat x1, jfloat y1, + jfloat x2, jfloat y2, jlong timestamp); + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(setCurrentPositionNative)( + JNIEnv* env, jobject thiz, jstring object_id, jfloat x1, jfloat y1, + jfloat x2, jfloat y2); + +JNIEXPORT +jboolean JNICALL OBJECT_TRACKER_METHOD(haveObject)(JNIEnv* env, jobject thiz, + jstring object_id); + +JNIEXPORT +jboolean JNICALL OBJECT_TRACKER_METHOD(isObjectVisible)(JNIEnv* env, + jobject thiz, + jstring object_id); + +JNIEXPORT +jstring JNICALL OBJECT_TRACKER_METHOD(getModelIdNative)(JNIEnv* env, + jobject thiz, + jstring object_id); + +JNIEXPORT +jfloat JNICALL OBJECT_TRACKER_METHOD(getCurrentCorrelation)(JNIEnv* env, + jobject thiz, + jstring object_id); + +JNIEXPORT +jfloat JNICALL OBJECT_TRACKER_METHOD(getMatchScore)(JNIEnv* env, jobject thiz, + jstring object_id); + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(getTrackedPositionNative)( + JNIEnv* env, jobject thiz, jstring object_id, jfloatArray rect_array); + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(nextFrameNative)(JNIEnv* env, jobject thiz, + jbyteArray y_data, + jbyteArray uv_data, + jlong timestamp, + jfloatArray vg_matrix_2x3); + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(forgetNative)(JNIEnv* env, jobject thiz, + jstring object_id); + +JNIEXPORT +jbyteArray JNICALL OBJECT_TRACKER_METHOD(getKeypointsPacked)( + JNIEnv* env, jobject thiz, jfloat scale_factor); + +JNIEXPORT +jfloatArray JNICALL OBJECT_TRACKER_METHOD(getKeypointsNative)( + JNIEnv* env, jobject thiz, jboolean only_found_); + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(getCurrentPositionNative)( + JNIEnv* env, jobject thiz, jlong timestamp, jfloat position_x1, + jfloat position_y1, jfloat position_x2, jfloat position_y2, + jfloatArray delta); + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(drawNative)(JNIEnv* env, jobject obj, + jint view_width, + jint view_height, + jfloatArray delta); + +JNIEXPORT void JNICALL OBJECT_TRACKER_METHOD(downsampleImageNative)( + JNIEnv* env, jobject thiz, jint width, jint height, jint row_stride, + jbyteArray input, jint factor, jbyteArray output); + +#ifdef __cplusplus +} +#endif + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(initNative)(JNIEnv* env, jobject thiz, + jint width, jint height, + jboolean always_track) { + LOGI("Initializing object tracker. %dx%d @%p", width, height, thiz); + const Size image_size(width, height); + TrackerConfig* const tracker_config = new TrackerConfig(image_size); + tracker_config->always_track = always_track; + + // XXX detector + ObjectTracker* const tracker = new ObjectTracker(tracker_config, NULL); + set_object_tracker(env, thiz, tracker); + LOGI("Initialized!"); + + CHECK_ALWAYS(get_object_tracker(env, thiz) == tracker, + "Failure to set hand tracker!"); +} + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(releaseMemoryNative)(JNIEnv* env, + jobject thiz) { + delete get_object_tracker(env, thiz); + set_object_tracker(env, thiz, NULL); +} + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(registerNewObjectWithAppearanceNative)( + JNIEnv* env, jobject thiz, jstring object_id, jfloat x1, jfloat y1, + jfloat x2, jfloat y2, jbyteArray frame_data) { + const char* const id_str = env->GetStringUTFChars(object_id, 0); + + LOGI("Registering the position of %s at %.2f,%.2f,%.2f,%.2f", id_str, x1, y1, + x2, y2); + + jboolean iCopied = JNI_FALSE; + + // Copy image into currFrame. + jbyte* pixels = env->GetByteArrayElements(frame_data, &iCopied); + + BoundingBox bounding_box(x1, y1, x2, y2); + get_object_tracker(env, thiz)->RegisterNewObjectWithAppearance( + id_str, reinterpret_cast(pixels), bounding_box); + + env->ReleaseByteArrayElements(frame_data, pixels, JNI_ABORT); + + env->ReleaseStringUTFChars(object_id, id_str); +} + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(setPreviousPositionNative)( + JNIEnv* env, jobject thiz, jstring object_id, jfloat x1, jfloat y1, + jfloat x2, jfloat y2, jlong timestamp) { + const char* const id_str = env->GetStringUTFChars(object_id, 0); + + LOGI( + "Registering the position of %s at %.2f,%.2f,%.2f,%.2f" + " at time %lld", + id_str, x1, y1, x2, y2, static_cast(timestamp)); + + get_object_tracker(env, thiz)->SetPreviousPositionOfObject( + id_str, BoundingBox(x1, y1, x2, y2), timestamp); + + env->ReleaseStringUTFChars(object_id, id_str); +} + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(setCurrentPositionNative)( + JNIEnv* env, jobject thiz, jstring object_id, jfloat x1, jfloat y1, + jfloat x2, jfloat y2) { + const char* const id_str = env->GetStringUTFChars(object_id, 0); + + LOGI("Registering the position of %s at %.2f,%.2f,%.2f,%.2f", id_str, x1, y1, + x2, y2); + + get_object_tracker(env, thiz)->SetCurrentPositionOfObject( + id_str, BoundingBox(x1, y1, x2, y2)); + + env->ReleaseStringUTFChars(object_id, id_str); +} + +JNIEXPORT +jboolean JNICALL OBJECT_TRACKER_METHOD(haveObject)(JNIEnv* env, jobject thiz, + jstring object_id) { + const char* const id_str = env->GetStringUTFChars(object_id, 0); + + const bool haveObject = get_object_tracker(env, thiz)->HaveObject(id_str); + env->ReleaseStringUTFChars(object_id, id_str); + return haveObject; +} + +JNIEXPORT +jboolean JNICALL OBJECT_TRACKER_METHOD(isObjectVisible)(JNIEnv* env, + jobject thiz, + jstring object_id) { + const char* const id_str = env->GetStringUTFChars(object_id, 0); + + const bool visible = get_object_tracker(env, thiz)->IsObjectVisible(id_str); + env->ReleaseStringUTFChars(object_id, id_str); + return visible; +} + +JNIEXPORT +jstring JNICALL OBJECT_TRACKER_METHOD(getModelIdNative)(JNIEnv* env, + jobject thiz, + jstring object_id) { + const char* const id_str = env->GetStringUTFChars(object_id, 0); + const TrackedObject* const object = + get_object_tracker(env, thiz)->GetObject(id_str); + env->ReleaseStringUTFChars(object_id, id_str); + jstring model_name = env->NewStringUTF(object->GetModel()->GetName().c_str()); + return model_name; +} + +JNIEXPORT +jfloat JNICALL OBJECT_TRACKER_METHOD(getCurrentCorrelation)(JNIEnv* env, + jobject thiz, + jstring object_id) { + const char* const id_str = env->GetStringUTFChars(object_id, 0); + + const float correlation = + get_object_tracker(env, thiz)->GetObject(id_str)->GetCorrelation(); + env->ReleaseStringUTFChars(object_id, id_str); + return correlation; +} + +JNIEXPORT +jfloat JNICALL OBJECT_TRACKER_METHOD(getMatchScore)(JNIEnv* env, jobject thiz, + jstring object_id) { + const char* const id_str = env->GetStringUTFChars(object_id, 0); + + const float match_score = + get_object_tracker(env, thiz)->GetObject(id_str)->GetMatchScore().value; + env->ReleaseStringUTFChars(object_id, id_str); + return match_score; +} + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(getTrackedPositionNative)( + JNIEnv* env, jobject thiz, jstring object_id, jfloatArray rect_array) { + jboolean iCopied = JNI_FALSE; + const char* const id_str = env->GetStringUTFChars(object_id, 0); + + const BoundingBox bounding_box = + get_object_tracker(env, thiz)->GetObject(id_str)->GetPosition(); + env->ReleaseStringUTFChars(object_id, id_str); + + jfloat* rect = env->GetFloatArrayElements(rect_array, &iCopied); + bounding_box.CopyToArray(reinterpret_cast(rect)); + env->ReleaseFloatArrayElements(rect_array, rect, 0); +} + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(nextFrameNative)(JNIEnv* env, jobject thiz, + jbyteArray y_data, + jbyteArray uv_data, + jlong timestamp, + jfloatArray vg_matrix_2x3) { + TimeLog("Starting object tracker"); + + jboolean iCopied = JNI_FALSE; + + float vision_gyro_matrix_array[6]; + jfloat* jmat = NULL; + + if (vg_matrix_2x3 != NULL) { + // Copy the alignment matrix into a float array. + jmat = env->GetFloatArrayElements(vg_matrix_2x3, &iCopied); + for (int i = 0; i < 6; ++i) { + vision_gyro_matrix_array[i] = static_cast(jmat[i]); + } + } + // Copy image into currFrame. + jbyte* pixels = env->GetByteArrayElements(y_data, &iCopied); + jbyte* uv_pixels = + uv_data != NULL ? env->GetByteArrayElements(uv_data, &iCopied) : NULL; + + TimeLog("Got elements"); + + // Add the frame to the object tracker object. + get_object_tracker(env, thiz)->NextFrame( + reinterpret_cast(pixels), reinterpret_cast(uv_pixels), + timestamp, vg_matrix_2x3 != NULL ? vision_gyro_matrix_array : NULL); + + env->ReleaseByteArrayElements(y_data, pixels, JNI_ABORT); + + if (uv_data != NULL) { + env->ReleaseByteArrayElements(uv_data, uv_pixels, JNI_ABORT); + } + + if (vg_matrix_2x3 != NULL) { + env->ReleaseFloatArrayElements(vg_matrix_2x3, jmat, JNI_ABORT); + } + + TimeLog("Released elements"); + + PrintTimeLog(); + ResetTimeLog(); +} + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(forgetNative)(JNIEnv* env, jobject thiz, + jstring object_id) { + const char* const id_str = env->GetStringUTFChars(object_id, 0); + + get_object_tracker(env, thiz)->ForgetTarget(id_str); + + env->ReleaseStringUTFChars(object_id, id_str); +} + +JNIEXPORT +jfloatArray JNICALL OBJECT_TRACKER_METHOD(getKeypointsNative)( + JNIEnv* env, jobject thiz, jboolean only_found) { + jfloat keypoint_arr[kMaxKeypoints * kKeypointStep]; + + const int number_of_keypoints = + get_object_tracker(env, thiz)->GetKeypoints(only_found, keypoint_arr); + + // Create and return the array that will be passed back to Java. + jfloatArray keypoints = + env->NewFloatArray(number_of_keypoints * kKeypointStep); + if (keypoints == NULL) { + LOGE("null array!"); + return NULL; + } + env->SetFloatArrayRegion(keypoints, 0, number_of_keypoints * kKeypointStep, + keypoint_arr); + + return keypoints; +} + +JNIEXPORT +jbyteArray JNICALL OBJECT_TRACKER_METHOD(getKeypointsPacked)( + JNIEnv* env, jobject thiz, jfloat scale_factor) { + // 2 bytes to a uint16_t and two pairs of xy coordinates per keypoint. + const int bytes_per_keypoint = sizeof(uint16_t) * 2 * 2; + jbyte keypoint_arr[kMaxKeypoints * bytes_per_keypoint]; + + const int number_of_keypoints = + get_object_tracker(env, thiz)->GetKeypointsPacked( + reinterpret_cast(keypoint_arr), scale_factor); + + // Create and return the array that will be passed back to Java. + jbyteArray keypoints = + env->NewByteArray(number_of_keypoints * bytes_per_keypoint); + + if (keypoints == NULL) { + LOGE("null array!"); + return NULL; + } + + env->SetByteArrayRegion( + keypoints, 0, number_of_keypoints * bytes_per_keypoint, keypoint_arr); + + return keypoints; +} + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(getCurrentPositionNative)( + JNIEnv* env, jobject thiz, jlong timestamp, jfloat position_x1, + jfloat position_y1, jfloat position_x2, jfloat position_y2, + jfloatArray delta) { + jfloat point_arr[4]; + + const BoundingBox new_position = get_object_tracker(env, thiz)->TrackBox( + BoundingBox(position_x1, position_y1, position_x2, position_y2), + timestamp); + + new_position.CopyToArray(point_arr); + env->SetFloatArrayRegion(delta, 0, 4, point_arr); +} + +JNIEXPORT +void JNICALL OBJECT_TRACKER_METHOD(drawNative)( + JNIEnv* env, jobject thiz, jint view_width, jint view_height, + jfloatArray frame_to_canvas_arr) { + ObjectTracker* object_tracker = get_object_tracker(env, thiz); + if (object_tracker != NULL) { + jfloat* frame_to_canvas = + env->GetFloatArrayElements(frame_to_canvas_arr, NULL); + + object_tracker->Draw(view_width, view_height, frame_to_canvas); + env->ReleaseFloatArrayElements(frame_to_canvas_arr, frame_to_canvas, + JNI_ABORT); + } +} + +JNIEXPORT void JNICALL OBJECT_TRACKER_METHOD(downsampleImageNative)( + JNIEnv* env, jobject thiz, jint width, jint height, jint row_stride, + jbyteArray input, jint factor, jbyteArray output) { + if (input == NULL || output == NULL) { + LOGW("Received null arrays, hopefully this is a test!"); + return; + } + + jbyte* const input_array = env->GetByteArrayElements(input, 0); + jbyte* const output_array = env->GetByteArrayElements(output, 0); + + { + tf_tracking::Image full_image( + width, height, reinterpret_cast(input_array), false); + + const int new_width = (width + factor - 1) / factor; + const int new_height = (height + factor - 1) / factor; + + tf_tracking::Image downsampled_image( + new_width, new_height, reinterpret_cast(output_array), false); + + downsampled_image.DownsampleAveraged( + reinterpret_cast(input_array), row_stride, factor); + } + + env->ReleaseByteArrayElements(input, input_array, JNI_ABORT); + env->ReleaseByteArrayElements(output, output_array, 0); +} + +} // namespace tf_tracking diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/optical_flow.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/optical_flow.cc" new file mode 100644 index 0000000..53c7b73 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/optical_flow.cc" @@ -0,0 +1,482 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/time_log.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +#include "tensorflow/examples/android/jni/object_tracking/config.h" +#include "tensorflow/examples/android/jni/object_tracking/flow_cache.h" +#include "tensorflow/examples/android/jni/object_tracking/frame_pair.h" +#include "tensorflow/examples/android/jni/object_tracking/image_data.h" +#include "tensorflow/examples/android/jni/object_tracking/keypoint.h" +#include "tensorflow/examples/android/jni/object_tracking/keypoint_detector.h" +#include "tensorflow/examples/android/jni/object_tracking/optical_flow.h" + +namespace tf_tracking { + +OpticalFlow::OpticalFlow(const OpticalFlowConfig* const config) + : config_(config), + frame1_(NULL), + frame2_(NULL), + working_size_(config->image_size) {} + + +void OpticalFlow::NextFrame(const ImageData* const image_data) { + // Special case for the first frame: make sure the image ends up in + // frame1_ so that keypoint detection can be done on it if desired. + frame1_ = (frame1_ == NULL) ? image_data : frame2_; + frame2_ = image_data; +} + + +// Static heart of the optical flow computation. +// Lucas Kanade algorithm. +bool OpticalFlow::FindFlowAtPoint_LK(const Image& img_I, + const Image& img_J, + const Image& I_x, + const Image& I_y, const float p_x, + const float p_y, float* out_g_x, + float* out_g_y) { + float g_x = *out_g_x; + float g_y = *out_g_y; + // Get values for frame 1. They remain constant through the inner + // iteration loop. + float vals_I[kFlowArraySize]; + float vals_I_x[kFlowArraySize]; + float vals_I_y[kFlowArraySize]; + + const int kPatchSize = 2 * kFlowIntegrationWindowSize + 1; + const float kWindowSizeFloat = static_cast(kFlowIntegrationWindowSize); + +#if USE_FIXED_POINT_FLOW + const int fixed_x_max = RealToFixed1616(img_I.width_less_one_) - 1; + const int fixed_y_max = RealToFixed1616(img_I.height_less_one_) - 1; +#else + const float real_x_max = I_x.width_less_one_ - EPSILON; + const float real_y_max = I_x.height_less_one_ - EPSILON; +#endif + + // Get the window around the original point. + const float src_left_real = p_x - kWindowSizeFloat; + const float src_top_real = p_y - kWindowSizeFloat; + float* vals_I_ptr = vals_I; + float* vals_I_x_ptr = vals_I_x; + float* vals_I_y_ptr = vals_I_y; +#if USE_FIXED_POINT_FLOW + // Source integer coordinates. + const int src_left_fixed = RealToFixed1616(src_left_real); + const int src_top_fixed = RealToFixed1616(src_top_real); + + for (int y = 0; y < kPatchSize; ++y) { + const int fp_y = Clip(src_top_fixed + (y << 16), 0, fixed_y_max); + + for (int x = 0; x < kPatchSize; ++x) { + const int fp_x = Clip(src_left_fixed + (x << 16), 0, fixed_x_max); + + *vals_I_ptr++ = img_I.GetPixelInterpFixed1616(fp_x, fp_y); + *vals_I_x_ptr++ = I_x.GetPixelInterpFixed1616(fp_x, fp_y); + *vals_I_y_ptr++ = I_y.GetPixelInterpFixed1616(fp_x, fp_y); + } + } +#else + for (int y = 0; y < kPatchSize; ++y) { + const float y_pos = Clip(src_top_real + y, 0.0f, real_y_max); + + for (int x = 0; x < kPatchSize; ++x) { + const float x_pos = Clip(src_left_real + x, 0.0f, real_x_max); + + *vals_I_ptr++ = img_I.GetPixelInterp(x_pos, y_pos); + *vals_I_x_ptr++ = I_x.GetPixelInterp(x_pos, y_pos); + *vals_I_y_ptr++ = I_y.GetPixelInterp(x_pos, y_pos); + } + } +#endif + + // Compute the spatial gradient matrix about point p. + float G[] = { 0, 0, 0, 0 }; + CalculateG(vals_I_x, vals_I_y, kFlowArraySize, G); + + // Find the inverse of G. + float G_inv[4]; + if (!Invert2x2(G, G_inv)) { + return false; + } + +#if NORMALIZE + const float mean_I = ComputeMean(vals_I, kFlowArraySize); + const float std_dev_I = ComputeStdDev(vals_I, kFlowArraySize, mean_I); +#endif + + // Iterate kNumIterations times or until we converge. + for (int iteration = 0; iteration < kNumIterations; ++iteration) { + // Get values for frame 2. + float vals_J[kFlowArraySize]; + + // Get the window around the destination point. + const float left_real = p_x + g_x - kWindowSizeFloat; + const float top_real = p_y + g_y - kWindowSizeFloat; + float* vals_J_ptr = vals_J; +#if USE_FIXED_POINT_FLOW + // The top-left sub-pixel is set for the current iteration (in 16:16 + // fixed). This is constant over one iteration. + const int left_fixed = RealToFixed1616(left_real); + const int top_fixed = RealToFixed1616(top_real); + + for (int win_y = 0; win_y < kPatchSize; ++win_y) { + const int fp_y = Clip(top_fixed + (win_y << 16), 0, fixed_y_max); + for (int win_x = 0; win_x < kPatchSize; ++win_x) { + const int fp_x = Clip(left_fixed + (win_x << 16), 0, fixed_x_max); + *vals_J_ptr++ = img_J.GetPixelInterpFixed1616(fp_x, fp_y); + } + } +#else + for (int win_y = 0; win_y < kPatchSize; ++win_y) { + const float y_pos = Clip(top_real + win_y, 0.0f, real_y_max); + for (int win_x = 0; win_x < kPatchSize; ++win_x) { + const float x_pos = Clip(left_real + win_x, 0.0f, real_x_max); + *vals_J_ptr++ = img_J.GetPixelInterp(x_pos, y_pos); + } + } +#endif + +#if NORMALIZE + const float mean_J = ComputeMean(vals_J, kFlowArraySize); + const float std_dev_J = ComputeStdDev(vals_J, kFlowArraySize, mean_J); + + // TODO(andrewharp): Probably better to completely detect and handle the + // "corner case" where the patch is fully outside the image diagonally. + const float std_dev_ratio = std_dev_J > 0.0f ? std_dev_I / std_dev_J : 1.0f; +#endif + + // Compute image mismatch vector. + float b_x = 0.0f; + float b_y = 0.0f; + + vals_I_ptr = vals_I; + vals_J_ptr = vals_J; + vals_I_x_ptr = vals_I_x; + vals_I_y_ptr = vals_I_y; + + for (int win_y = 0; win_y < kPatchSize; ++win_y) { + for (int win_x = 0; win_x < kPatchSize; ++win_x) { +#if NORMALIZE + // Normalized Image difference. + const float dI = + (*vals_I_ptr++ - mean_I) - (*vals_J_ptr++ - mean_J) * std_dev_ratio; +#else + const float dI = *vals_I_ptr++ - *vals_J_ptr++; +#endif + b_x += dI * *vals_I_x_ptr++; + b_y += dI * *vals_I_y_ptr++; + } + } + + // Optical flow... solve n = G^-1 * b + const float n_x = (G_inv[0] * b_x) + (G_inv[1] * b_y); + const float n_y = (G_inv[2] * b_x) + (G_inv[3] * b_y); + + // Update best guess with residual displacement from this level and + // iteration. + g_x += n_x; + g_y += n_y; + + // LOGV("Iteration %d: delta (%.3f, %.3f)", iteration, n_x, n_y); + + // Abort early if we're already below the threshold. + if (Square(n_x) + Square(n_y) < Square(kTrackingAbortThreshold)) { + break; + } + } // Iteration. + + // Copy value back into output. + *out_g_x = g_x; + *out_g_y = g_y; + return true; +} + + +// Pointwise flow using translational 2dof ESM. +bool OpticalFlow::FindFlowAtPoint_ESM( + const Image& img_I, const Image& img_J, + const Image& I_x, const Image& I_y, + const Image& J_x, const Image& J_y, const float p_x, + const float p_y, float* out_g_x, float* out_g_y) { + float g_x = *out_g_x; + float g_y = *out_g_y; + const float area_inv = 1.0f / static_cast(kFlowArraySize); + + // Get values for frame 1. They remain constant through the inner + // iteration loop. + uint8_t vals_I[kFlowArraySize]; + uint8_t vals_J[kFlowArraySize]; + int16_t src_gradient_x[kFlowArraySize]; + int16_t src_gradient_y[kFlowArraySize]; + + // TODO(rspring): try out the IntegerPatchAlign() method once + // the code for that is in ../common. + const float wsize_float = static_cast(kFlowIntegrationWindowSize); + const int src_left_fixed = RealToFixed1616(p_x - wsize_float); + const int src_top_fixed = RealToFixed1616(p_y - wsize_float); + const int patch_size = 2 * kFlowIntegrationWindowSize + 1; + + // Create the keypoint template patch from a subpixel location. + if (!img_I.ExtractPatchAtSubpixelFixed1616(src_left_fixed, src_top_fixed, + patch_size, patch_size, vals_I) || + !I_x.ExtractPatchAtSubpixelFixed1616(src_left_fixed, src_top_fixed, + patch_size, patch_size, + src_gradient_x) || + !I_y.ExtractPatchAtSubpixelFixed1616(src_left_fixed, src_top_fixed, + patch_size, patch_size, + src_gradient_y)) { + return false; + } + + int bright_offset = 0; + int sum_diff = 0; + + // The top-left sub-pixel is set for the current iteration (in 16:16 fixed). + // This is constant over one iteration. + int left_fixed = RealToFixed1616(p_x + g_x - wsize_float); + int top_fixed = RealToFixed1616(p_y + g_y - wsize_float); + + // The truncated version gives the most top-left pixel that is used. + int left_trunc = left_fixed >> 16; + int top_trunc = top_fixed >> 16; + + // Compute an initial brightness offset. + if (kDoBrightnessNormalize && + left_trunc >= 0 && top_trunc >= 0 && + (left_trunc + patch_size) < img_J.width_less_one_ && + (top_trunc + patch_size) < img_J.height_less_one_) { + int templ_index = 0; + const uint8_t* j_row = img_J[top_trunc] + left_trunc; + + const int j_stride = img_J.stride(); + + for (int y = 0; y < patch_size; ++y, j_row += j_stride) { + for (int x = 0; x < patch_size; ++x) { + sum_diff += static_cast(j_row[x]) - vals_I[templ_index++]; + } + } + + bright_offset = static_cast(static_cast(sum_diff) * area_inv); + } + + // Iterate kNumIterations times or until we go out of image. + for (int iteration = 0; iteration < kNumIterations; ++iteration) { + int jtj[3] = { 0, 0, 0 }; + int jtr[2] = { 0, 0 }; + sum_diff = 0; + + // Extract the target image values. + // Extract the gradient from the target image patch and accumulate to + // the gradient of the source image patch. + if (!img_J.ExtractPatchAtSubpixelFixed1616(left_fixed, top_fixed, + patch_size, patch_size, + vals_J)) { + break; + } + + const uint8_t* templ_row = vals_I; + const uint8_t* extract_row = vals_J; + const int16_t* src_dx_row = src_gradient_x; + const int16_t* src_dy_row = src_gradient_y; + + for (int y = 0; y < patch_size; ++y, templ_row += patch_size, + src_dx_row += patch_size, src_dy_row += patch_size, + extract_row += patch_size) { + const int fp_y = top_fixed + (y << 16); + for (int x = 0; x < patch_size; ++x) { + const int fp_x = left_fixed + (x << 16); + int32_t target_dx = J_x.GetPixelInterpFixed1616(fp_x, fp_y); + int32_t target_dy = J_y.GetPixelInterpFixed1616(fp_x, fp_y); + + // Combine the two Jacobians. + // Right-shift by one to account for the fact that we add + // two Jacobians. + int32_t dx = (src_dx_row[x] + target_dx) >> 1; + int32_t dy = (src_dy_row[x] + target_dy) >> 1; + + // The current residual b - h(q) == extracted - (template + offset) + int32_t diff = static_cast(extract_row[x]) - + static_cast(templ_row[x]) - bright_offset; + + jtj[0] += dx * dx; + jtj[1] += dx * dy; + jtj[2] += dy * dy; + + jtr[0] += dx * diff; + jtr[1] += dy * diff; + + sum_diff += diff; + } + } + + const float jtr1_float = static_cast(jtr[0]); + const float jtr2_float = static_cast(jtr[1]); + + // Add some baseline stability to the system. + jtj[0] += kEsmRegularizer; + jtj[2] += kEsmRegularizer; + + const int64_t prod1 = static_cast(jtj[0]) * jtj[2]; + const int64_t prod2 = static_cast(jtj[1]) * jtj[1]; + + // One ESM step. + const float jtj_1[4] = { static_cast(jtj[2]), + static_cast(-jtj[1]), + static_cast(-jtj[1]), + static_cast(jtj[0]) }; + const double det_inv = 1.0 / static_cast(prod1 - prod2); + + g_x -= det_inv * (jtj_1[0] * jtr1_float + jtj_1[1] * jtr2_float); + g_y -= det_inv * (jtj_1[2] * jtr1_float + jtj_1[3] * jtr2_float); + + if (kDoBrightnessNormalize) { + bright_offset += + static_cast(area_inv * static_cast(sum_diff) + 0.5f); + } + + // Update top left position. + left_fixed = RealToFixed1616(p_x + g_x - wsize_float); + top_fixed = RealToFixed1616(p_y + g_y - wsize_float); + + left_trunc = left_fixed >> 16; + top_trunc = top_fixed >> 16; + + // Abort iterations if we go out of borders. + if (left_trunc < 0 || top_trunc < 0 || + (left_trunc + patch_size) >= J_x.width_less_one_ || + (top_trunc + patch_size) >= J_y.height_less_one_) { + break; + } + } // Iteration. + + // Copy value back into output. + *out_g_x = g_x; + *out_g_y = g_y; + return true; +} + + +bool OpticalFlow::FindFlowAtPointReversible( + const int level, const float u_x, const float u_y, + const bool reverse_flow, + float* flow_x, float* flow_y) const { + const ImageData& frame_a = reverse_flow ? *frame2_ : *frame1_; + const ImageData& frame_b = reverse_flow ? *frame1_ : *frame2_; + + // Images I (prev) and J (next). + const Image& img_I = *frame_a.GetPyramidSqrt2Level(level * 2); + const Image& img_J = *frame_b.GetPyramidSqrt2Level(level * 2); + + // Computed gradients. + const Image& I_x = *frame_a.GetSpatialX(level); + const Image& I_y = *frame_a.GetSpatialY(level); + const Image& J_x = *frame_b.GetSpatialX(level); + const Image& J_y = *frame_b.GetSpatialY(level); + + // Shrink factor from original. + const float shrink_factor = (1 << level); + + // Image position vector (p := u^l), scaled for this level. + const float scaled_p_x = u_x / shrink_factor; + const float scaled_p_y = u_y / shrink_factor; + + float scaled_flow_x = *flow_x / shrink_factor; + float scaled_flow_y = *flow_y / shrink_factor; + + // LOGE("FindFlowAtPoint level %d: %5.2f, %5.2f (%5.2f, %5.2f)", level, + // scaled_p_x, scaled_p_y, &scaled_flow_x, &scaled_flow_y); + + const bool success = kUseEsm ? + FindFlowAtPoint_ESM(img_I, img_J, I_x, I_y, J_x, J_y, + scaled_p_x, scaled_p_y, + &scaled_flow_x, &scaled_flow_y) : + FindFlowAtPoint_LK(img_I, img_J, I_x, I_y, + scaled_p_x, scaled_p_y, + &scaled_flow_x, &scaled_flow_y); + + *flow_x = scaled_flow_x * shrink_factor; + *flow_y = scaled_flow_y * shrink_factor; + + return success; +} + + +bool OpticalFlow::FindFlowAtPointSingleLevel( + const int level, + const float u_x, const float u_y, + const bool filter_by_fb_error, + float* flow_x, float* flow_y) const { + if (!FindFlowAtPointReversible(level, u_x, u_y, false, flow_x, flow_y)) { + return false; + } + + if (filter_by_fb_error) { + const float new_position_x = u_x + *flow_x; + const float new_position_y = u_y + *flow_y; + + float reverse_flow_x = 0.0f; + float reverse_flow_y = 0.0f; + + // Now find the backwards flow and confirm it lines up with the original + // starting point. + if (!FindFlowAtPointReversible(level, new_position_x, new_position_y, + true, + &reverse_flow_x, &reverse_flow_y)) { + LOGE("Backward error!"); + return false; + } + + const float discrepancy_length = + sqrtf(Square(*flow_x + reverse_flow_x) + + Square(*flow_y + reverse_flow_y)); + + const float flow_length = sqrtf(Square(*flow_x) + Square(*flow_y)); + + return discrepancy_length < + (kMaxForwardBackwardErrorAllowed * flow_length); + } + + return true; +} + + +// An implementation of the Pyramidal Lucas-Kanade Optical Flow algorithm. +// See http://robots.stanford.edu/cs223b04/algo_tracking.pdf for details. +bool OpticalFlow::FindFlowAtPointPyramidal(const float u_x, const float u_y, + const bool filter_by_fb_error, + float* flow_x, float* flow_y) const { + const int max_level = MAX(kMinNumPyramidLevelsToUseForAdjustment, + kNumPyramidLevels - kNumCacheLevels); + + // For every level in the pyramid, update the coordinates of the best match. + for (int l = max_level - 1; l >= 0; --l) { + if (!FindFlowAtPointSingleLevel(l, u_x, u_y, + filter_by_fb_error, flow_x, flow_y)) { + return false; + } + } + + return true; +} + +} // namespace tf_tracking diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/optical_flow.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/optical_flow.h" new file mode 100644 index 0000000..f98ae22 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/optical_flow.h" @@ -0,0 +1,100 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OPTICAL_FLOW_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OPTICAL_FLOW_H_ + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +#include "tensorflow/examples/android/jni/object_tracking/config.h" +#include "tensorflow/examples/android/jni/object_tracking/frame_pair.h" +#include "tensorflow/examples/android/jni/object_tracking/image_data.h" +#include "tensorflow/examples/android/jni/object_tracking/keypoint.h" + +namespace tf_tracking { + +class FlowCache; + +// Class encapsulating all the data and logic necessary for performing optical +// flow. +class OpticalFlow { + public: + explicit OpticalFlow(const OpticalFlowConfig* const config); + + // Add a new frame to the optical flow. Will update all the non-keypoint + // related member variables. + // + // new_frame should be a buffer of grayscale values, one byte per pixel, + // at the original frame_width and frame_height used to initialize the + // OpticalFlow object. Downsampling will be handled internally. + // + // time_stamp should be a time in milliseconds that later calls to this and + // other methods will be relative to. + void NextFrame(const ImageData* const image_data); + + // An implementation of the Lucas-Kanade Optical Flow algorithm. + static bool FindFlowAtPoint_LK(const Image& img_I, + const Image& img_J, + const Image& I_x, + const Image& I_y, const float p_x, + const float p_y, float* out_g_x, + float* out_g_y); + + // Pointwise flow using translational 2dof ESM. + static bool FindFlowAtPoint_ESM( + const Image& img_I, const Image& img_J, + const Image& I_x, const Image& I_y, + const Image& J_x, const Image& J_y, const float p_x, + const float p_y, float* out_g_x, float* out_g_y); + + // Finds the flow using a specific level, in either direction. + // If reversed, the coordinates are in the context of the latest + // frame, not the frame before it. + // All coordinates used in parameters are global, not scaled. + bool FindFlowAtPointReversible( + const int level, const float u_x, const float u_y, + const bool reverse_flow, + float* final_x, float* final_y) const; + + // Finds the flow using a specific level, filterable by forward-backward + // error. All coordinates used in parameters are global, not scaled. + bool FindFlowAtPointSingleLevel(const int level, + const float u_x, const float u_y, + const bool filter_by_fb_error, + float* flow_x, float* flow_y) const; + + // Pyramidal optical-flow using all levels. + bool FindFlowAtPointPyramidal(const float u_x, const float u_y, + const bool filter_by_fb_error, + float* flow_x, float* flow_y) const; + + private: + const OpticalFlowConfig* const config_; + + const ImageData* frame1_; + const ImageData* frame2_; + + // Size of the internally allocated images (after original is downsampled). + const Size working_size_; + + TF_DISALLOW_COPY_AND_ASSIGN(OpticalFlow); +}; + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_OPTICAL_FLOW_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/sprite.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/sprite.h" new file mode 100644 index 0000000..b54a684 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/sprite.h" @@ -0,0 +1,202 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_SPRITE_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_SPRITE_H_ + +#include +#include + +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" + +#ifndef __RENDER_OPENGL__ +#error sprite.h should not included if OpenGL is not enabled by platform.h +#endif + +namespace tf_tracking { + +// This class encapsulates the logic necessary to load an render image data +// at the same aspect ratio as the original source. +class Sprite { + public: + // Only create Sprites when you have an OpenGl context. + explicit Sprite(const Image& image) { LoadTexture(image, NULL); } + + Sprite(const Image& image, const BoundingBox* const area) { + LoadTexture(image, area); + } + + // Also, try to only delete a Sprite when holding an OpenGl context. + ~Sprite() { + glDeleteTextures(1, &texture_); + } + + inline int GetWidth() const { + return actual_width_; + } + + inline int GetHeight() const { + return actual_height_; + } + + // Draw the sprite at 0,0 - original width/height in the current reference + // frame. Any transformations desired must be applied before calling this + // function. + void Draw() const { + const float float_width = static_cast(actual_width_); + const float float_height = static_cast(actual_height_); + + // Where it gets rendered to. + const float vertices[] = { 0.0f, 0.0f, 0.0f, + 0.0f, float_height, 0.0f, + float_width, 0.0f, 0.0f, + float_width, float_height, 0.0f, + }; + + // The coordinates the texture gets drawn from. + const float max_x = float_width / texture_width_; + const float max_y = float_height / texture_height_; + const float textureVertices[] = { + 0, 0, + 0, max_y, + max_x, 0, + max_x, max_y, + }; + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texture_); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glVertexPointer(3, GL_FLOAT, 0, vertices); + glTexCoordPointer(2, GL_FLOAT, 0, textureVertices); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + + private: + inline int GetNextPowerOfTwo(const int number) const { + int power_of_two = 1; + while (power_of_two < number) { + power_of_two *= 2; + } + return power_of_two; + } + + // TODO(andrewharp): Allow sprites to have their textures reloaded. + void LoadTexture(const Image& texture_source, + const BoundingBox* const area) { + glEnable(GL_TEXTURE_2D); + + glGenTextures(1, &texture_); + + glBindTexture(GL_TEXTURE_2D, texture_); + + int left = 0; + int top = 0; + + if (area != NULL) { + // If a sub-region was provided to pull the texture from, use that. + left = area->left_; + top = area->top_; + actual_width_ = area->GetWidth(); + actual_height_ = area->GetHeight(); + } else { + actual_width_ = texture_source.GetWidth(); + actual_height_ = texture_source.GetHeight(); + } + + // The textures must be a power of two, so find the sizes that are large + // enough to contain the image data. + texture_width_ = GetNextPowerOfTwo(actual_width_); + texture_height_ = GetNextPowerOfTwo(actual_height_); + + bool allocated_data = false; + uint8_t* texture_data; + + // Except in the lucky case where we're not using a sub-region of the + // original image AND the source data has dimensions that are power of two, + // care must be taken to copy data at the appropriate source and destination + // strides so that the final block can be copied directly into texture + // memory. + // TODO(andrewharp): Figure out if data can be pulled directly from the + // source image with some alignment modifications. + if (left != 0 || top != 0 || + actual_width_ != texture_source.GetWidth() || + actual_height_ != texture_source.GetHeight()) { + texture_data = new uint8_t[actual_width_ * actual_height_]; + + for (int y = 0; y < actual_height_; ++y) { + memcpy(texture_data + actual_width_ * y, texture_source[top + y] + left, + actual_width_ * sizeof(uint8_t)); + } + allocated_data = true; + } else { + // Cast away const-ness because for some reason glTexSubImage2D wants + // a non-const data pointer. + texture_data = const_cast(texture_source.data()); + } + + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_LUMINANCE, + texture_width_, + texture_height_, + 0, + GL_LUMINANCE, + GL_UNSIGNED_BYTE, + NULL); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexSubImage2D(GL_TEXTURE_2D, + 0, + 0, + 0, + actual_width_, + actual_height_, + GL_LUMINANCE, + GL_UNSIGNED_BYTE, + texture_data); + + if (allocated_data) { + delete(texture_data); + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + + // The id for the texture on the GPU. + GLuint texture_; + + // The width and height to be used for display purposes, referring to the + // dimensions of the original texture. + int actual_width_; + int actual_height_; + + // The allocated dimensions of the texture data, which must be powers of 2. + int texture_width_; + int texture_height_; + + TF_DISALLOW_COPY_AND_ASSIGN(Sprite); +}; + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_SPRITE_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/time_log.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/time_log.cc" new file mode 100644 index 0000000..8fce78f --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/time_log.cc" @@ -0,0 +1,25 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/examples/android/jni/object_tracking/time_log.h" + +#ifdef LOG_TIME +// Storage for logging functionality. +int num_time_logs = 0; +LogEntry time_logs[NUM_LOGS]; + +int num_avg_entries = 0; +AverageEntry avg_entries[NUM_LOGS]; +#endif diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/time_log.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/time_log.h" new file mode 100644 index 0000000..0073e11 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/time_log.h" @@ -0,0 +1,137 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// Utility functions for performance profiling. + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_TIME_LOG_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_TIME_LOG_H_ + +#include + +#include "tensorflow/examples/android/jni/object_tracking/logging.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +#ifdef LOG_TIME + +// Blend constant for running average. +#define ALPHA 0.98f +#define NUM_LOGS 100 + +struct LogEntry { + const char* id; + int64_t time_stamp; +}; + +struct AverageEntry { + const char* id; + float average_duration; +}; + +// Storage for keeping track of this frame's values. +extern int num_time_logs; +extern LogEntry time_logs[NUM_LOGS]; + +// Storage for keeping track of average values (each entry may not be printed +// out each frame). +extern AverageEntry avg_entries[NUM_LOGS]; +extern int num_avg_entries; + +// Call this at the start of a logging phase. +inline static void ResetTimeLog() { + num_time_logs = 0; +} + + +// Log a message to be printed out when printTimeLog is called, along with the +// amount of time in ms that has passed since the last call to this function. +inline static void TimeLog(const char* const str) { + LOGV("%s", str); + if (num_time_logs >= NUM_LOGS) { + LOGE("Out of log entries!"); + return; + } + + time_logs[num_time_logs].id = str; + time_logs[num_time_logs].time_stamp = CurrentThreadTimeNanos(); + ++num_time_logs; +} + + +inline static float Blend(float old_val, float new_val) { + return ALPHA * old_val + (1.0f - ALPHA) * new_val; +} + + +inline static float UpdateAverage(const char* str, const float new_val) { + for (int entry_num = 0; entry_num < num_avg_entries; ++entry_num) { + AverageEntry* const entry = avg_entries + entry_num; + if (str == entry->id) { + entry->average_duration = Blend(entry->average_duration, new_val); + return entry->average_duration; + } + } + + if (num_avg_entries >= NUM_LOGS) { + LOGE("Too many log entries!"); + } + + // If it wasn't there already, add it. + avg_entries[num_avg_entries].id = str; + avg_entries[num_avg_entries].average_duration = new_val; + ++num_avg_entries; + + return new_val; +} + + +// Prints out all the timeLog statements in chronological order with the +// interval that passed between subsequent statements. The total time between +// the first and last statements is printed last. +inline static void PrintTimeLog() { + LogEntry* last_time = time_logs; + + float average_running_total = 0.0f; + + for (int i = 0; i < num_time_logs; ++i) { + LogEntry* const this_time = time_logs + i; + + const float curr_time = + (this_time->time_stamp - last_time->time_stamp) / 1000000.0f; + + const float avg_time = UpdateAverage(this_time->id, curr_time); + average_running_total += avg_time; + + LOGD("%32s: %6.3fms %6.4fms", this_time->id, curr_time, avg_time); + last_time = this_time; + } + + const float total_time = + (last_time->time_stamp - time_logs->time_stamp) / 1000000.0f; + + LOGD("TOTAL TIME: %6.3fms %6.4fms\n", + total_time, average_running_total); + LOGD(" "); +} +#else +inline static void ResetTimeLog() {} + +inline static void TimeLog(const char* const str) { + LOGV("%s", str); +} + +inline static void PrintTimeLog() {} +#endif + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_TIME_LOG_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/tracked_object.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/tracked_object.cc" new file mode 100644 index 0000000..d208575 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/tracked_object.cc" @@ -0,0 +1,162 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/examples/android/jni/object_tracking/tracked_object.h" + +namespace tf_tracking { + +static const float kInitialDistance = 20.0f; + +static void InitNormalized(const Image& src_image, + const BoundingBox& position, + Image* const dst_image) { + BoundingBox scaled_box(position); + CopyArea(src_image, scaled_box, dst_image); + NormalizeImage(dst_image); +} + +TrackedObject::TrackedObject(const std::string& id, const Image& image, + const BoundingBox& bounding_box, + ObjectModelBase* const model) + : id_(id), + last_known_position_(bounding_box), + last_detection_position_(bounding_box), + position_last_computed_time_(-1), + object_model_(model), + last_detection_thumbnail_(kNormalizedThumbnailSize, + kNormalizedThumbnailSize), + last_frame_thumbnail_(kNormalizedThumbnailSize, kNormalizedThumbnailSize), + tracked_correlation_(0.0f), + tracked_match_score_(0.0), + num_consecutive_frames_below_threshold_(0), + allowable_detection_distance_(Square(kInitialDistance)) { + InitNormalized(image, bounding_box, &last_detection_thumbnail_); +} + +TrackedObject::~TrackedObject() {} + +void TrackedObject::UpdatePosition(const BoundingBox& new_position, + const int64_t timestamp, + const ImageData& image_data, + const bool authoratative) { + last_known_position_ = new_position; + position_last_computed_time_ = timestamp; + + InitNormalized(*image_data.GetImage(), new_position, &last_frame_thumbnail_); + + const float last_localization_correlation = ComputeCrossCorrelation( + last_detection_thumbnail_.data(), + last_frame_thumbnail_.data(), + last_frame_thumbnail_.data_size_); + LOGV("Tracked correlation to last localization: %.6f", + last_localization_correlation); + + // Correlation to object model, if it exists. + if (object_model_ != NULL) { + tracked_correlation_ = + object_model_->GetMaxCorrelation(last_frame_thumbnail_); + LOGV("Tracked correlation to model: %.6f", + tracked_correlation_); + + tracked_match_score_ = + object_model_->GetMatchScore(new_position, image_data); + LOGV("Tracked match score with model: %.6f", + tracked_match_score_.value); + } else { + // If there's no model to check against, set the tracked correlation to + // simply be the correlation to the last set position. + tracked_correlation_ = last_localization_correlation; + tracked_match_score_ = MatchScore(0.0f); + } + + // Determine if it's still being tracked. + if (tracked_correlation_ >= kMinimumCorrelationForTracking && + tracked_match_score_ >= kMinimumMatchScore) { + num_consecutive_frames_below_threshold_ = 0; + + if (object_model_ != NULL) { + object_model_->TrackStep(last_known_position_, *image_data.GetImage(), + *image_data.GetIntegralImage(), authoratative); + } + } else if (tracked_match_score_ < kMatchScoreForImmediateTermination) { + if (num_consecutive_frames_below_threshold_ < 1000) { + LOGD("Tracked match score is way too low (%.6f), aborting track.", + tracked_match_score_.value); + } + + // Add an absurd amount of missed frames so that all heuristics will + // consider it a lost track. + num_consecutive_frames_below_threshold_ += 1000; + + if (object_model_ != NULL) { + object_model_->TrackLost(); + } + } else { + ++num_consecutive_frames_below_threshold_; + allowable_detection_distance_ *= 1.1f; + } +} + +void TrackedObject::OnDetection(ObjectModelBase* const model, + const BoundingBox& detection_position, + const MatchScore match_score, + const int64_t timestamp, + const ImageData& image_data) { + const float overlap = detection_position.PascalScore(last_known_position_); + if (overlap > kPositionOverlapThreshold) { + // If the position agreement with the current tracked position is good + // enough, lock all the current unlocked examples. + object_model_->TrackConfirmed(); + num_consecutive_frames_below_threshold_ = 0; + } + + // Before relocalizing, make sure the new proposed position is better than + // the existing position by a small amount to prevent thrashing. + if (match_score <= tracked_match_score_ + kMatchScoreBuffer) { + LOGI("Not relocalizing since new match is worse: %.6f < %.6f + %.6f", + match_score.value, tracked_match_score_.value, + kMatchScoreBuffer.value); + return; + } + + LOGI("Relocalizing! From (%.1f, %.1f)[%.1fx%.1f] to " + "(%.1f, %.1f)[%.1fx%.1f]: %.6f > %.6f", + last_known_position_.left_, last_known_position_.top_, + last_known_position_.GetWidth(), last_known_position_.GetHeight(), + detection_position.left_, detection_position.top_, + detection_position.GetWidth(), detection_position.GetHeight(), + match_score.value, tracked_match_score_.value); + + if (overlap < kPositionOverlapThreshold) { + // The path might be good, it might be bad, but it's no longer a path + // since we're moving the box to a new position, so just nuke it from + // orbit to be safe. + object_model_->TrackLost(); + } + + object_model_ = model; + + // Reset the last detected appearance. + InitNormalized( + *image_data.GetImage(), detection_position, &last_detection_thumbnail_); + + num_consecutive_frames_below_threshold_ = 0; + last_detection_position_ = detection_position; + + UpdatePosition(detection_position, timestamp, image_data, false); + allowable_detection_distance_ = Square(kInitialDistance); +} + +} // namespace tf_tracking diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/tracked_object.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/tracked_object.h" new file mode 100644 index 0000000..d7f1a70 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/tracked_object.h" @@ -0,0 +1,186 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_TRACKED_OBJECT_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_TRACKED_OBJECT_H_ + +#ifdef __RENDER_OPENGL__ +#include "tensorflow/examples/android/jni/object_tracking/gl_utils.h" +#endif +#include "tensorflow/examples/android/jni/object_tracking/object_detector.h" + +namespace tf_tracking { + +// A TrackedObject is a specific instance of an ObjectModel, with a known +// position in the world. +// It provides the last known position and number of recent detection failures, +// in addition to the more general appearance data associated with the object +// class (which is in ObjectModel). +// TODO(andrewharp): Make getters/setters follow styleguide. +class TrackedObject { + public: + TrackedObject(const std::string& id, const Image& image, + const BoundingBox& bounding_box, ObjectModelBase* const model); + + ~TrackedObject(); + + void UpdatePosition(const BoundingBox& new_position, const int64_t timestamp, + const ImageData& image_data, const bool authoratative); + + // This method is called when the tracked object is detected at a + // given position, and allows the associated Model to grow and/or prune + // itself based on where the detection occurred. + void OnDetection(ObjectModelBase* const model, + const BoundingBox& detection_position, + const MatchScore match_score, const int64_t timestamp, + const ImageData& image_data); + + // Called when there's no detection of the tracked object. This will cause + // a tracking failure after enough consecutive failures if the area under + // the current bounding box also doesn't meet a minimum correlation threshold + // with the model. + void OnDetectionFailure() {} + + inline bool IsVisible() const { + return tracked_correlation_ >= kMinimumCorrelationForTracking || + num_consecutive_frames_below_threshold_ < kMaxNumDetectionFailures; + } + + inline float GetCorrelation() { + return tracked_correlation_; + } + + inline MatchScore GetMatchScore() { + return tracked_match_score_; + } + + inline BoundingBox GetPosition() const { + return last_known_position_; + } + + inline BoundingBox GetLastDetectionPosition() const { + return last_detection_position_; + } + + inline const ObjectModelBase* GetModel() const { + return object_model_; + } + + inline const std::string& GetName() const { + return id_; + } + + inline void Draw() const { +#ifdef __RENDER_OPENGL__ + if (tracked_correlation_ < kMinimumCorrelationForTracking) { + glColor4f(MAX(0.0f, -tracked_correlation_), + MAX(0.0f, tracked_correlation_), + 0.0f, + 1.0f); + } else { + glColor4f(MAX(0.0f, -tracked_correlation_), + MAX(0.0f, tracked_correlation_), + 1.0f, + 1.0f); + } + + // Render the box itself. + BoundingBox temp_box(last_known_position_); + DrawBox(temp_box); + + // Render a box inside this one (in case the actual box is hidden). + const float kBufferSize = 1.0f; + temp_box.left_ -= kBufferSize; + temp_box.top_ -= kBufferSize; + temp_box.right_ += kBufferSize; + temp_box.bottom_ += kBufferSize; + DrawBox(temp_box); + + // Render one outside as well. + temp_box.left_ -= -2.0f * kBufferSize; + temp_box.top_ -= -2.0f * kBufferSize; + temp_box.right_ += -2.0f * kBufferSize; + temp_box.bottom_ += -2.0f * kBufferSize; + DrawBox(temp_box); +#endif + } + + // Get current object's num_consecutive_frames_below_threshold_. + inline int64_t GetNumConsecutiveFramesBelowThreshold() { + return num_consecutive_frames_below_threshold_; + } + + // Reset num_consecutive_frames_below_threshold_ to 0. + inline void resetNumConsecutiveFramesBelowThreshold() { + num_consecutive_frames_below_threshold_ = 0; + } + + inline float GetAllowableDistanceSquared() const { + return allowable_detection_distance_; + } + + private: + // The unique id used throughout the system to identify this + // tracked object. + const std::string id_; + + // The last known position of the object. + BoundingBox last_known_position_; + + // The last known position of the object. + BoundingBox last_detection_position_; + + // When the position was last computed. + int64_t position_last_computed_time_; + + // The object model this tracked object is representative of. + ObjectModelBase* object_model_; + + Image last_detection_thumbnail_; + + Image last_frame_thumbnail_; + + // The correlation of the object model with the preview frame at its last + // tracked position. + float tracked_correlation_; + + MatchScore tracked_match_score_; + + // The number of consecutive frames that the tracked position for this object + // has been under the correlation threshold. + int num_consecutive_frames_below_threshold_; + + float allowable_detection_distance_; + + friend std::ostream& operator<<(std::ostream& stream, + const TrackedObject& tracked_object); + + TF_DISALLOW_COPY_AND_ASSIGN(TrackedObject); +}; + +inline std::ostream& operator<<(std::ostream& stream, + const TrackedObject& tracked_object) { + stream << tracked_object.id_ + << " " << tracked_object.last_known_position_ + << " " << tracked_object.position_last_computed_time_ + << " " << tracked_object.num_consecutive_frames_below_threshold_ + << " " << tracked_object.object_model_ + << " " << tracked_object.tracked_correlation_; + return stream; +} + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_TRACKED_OBJECT_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/utils.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/utils.h" new file mode 100644 index 0000000..2e98734 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/utils.h" @@ -0,0 +1,381 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_UTILS_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_UTILS_H_ + +#include +#include +#include +#include + +#include // for std::abs(float) + +#ifndef HAVE_CLOCK_GETTIME +// Use gettimeofday() instead of clock_gettime(). +#include +#endif // ifdef HAVE_CLOCK_GETTIME + +#include "tensorflow/examples/android/jni/object_tracking/logging.h" + +// TODO(andrewharp): clean up these macros to use the codebase statndard. + +// A very small number, generally used as the tolerance for accumulated +// floating point errors in bounds-checks. +#define EPSILON 0.00001f + +#define SAFE_DELETE(pointer) {\ + if ((pointer) != NULL) {\ + LOGV("Safe deleting pointer: %s", #pointer);\ + delete (pointer);\ + (pointer) = NULL;\ + } else {\ + LOGV("Pointer already null: %s", #pointer);\ + }\ +} + + +#ifdef __GOOGLE__ + +#define CHECK_ALWAYS(condition, format, ...) {\ + CHECK(condition) << StringPrintf(format, ##__VA_ARGS__);\ +} + +#define SCHECK(condition, format, ...) {\ + DCHECK(condition) << StringPrintf(format, ##__VA_ARGS__);\ +} + +#else + +#define CHECK_ALWAYS(condition, format, ...) {\ + if (!(condition)) {\ + LOGE("CHECK FAILED (%s): " format, #condition, ##__VA_ARGS__);\ + abort();\ + }\ +} + +#ifdef SANITY_CHECKS +#define SCHECK(condition, format, ...) {\ + CHECK_ALWAYS(condition, format, ##__VA_ARGS__);\ +} +#else +#define SCHECK(condition, format, ...) {} +#endif // SANITY_CHECKS + +#endif // __GOOGLE__ + + +#ifndef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +#ifndef MIN +#define MIN(a, b) (((a) > (b)) ? (b) : (a)) +#endif + +inline static int64_t CurrentThreadTimeNanos() { +#ifdef HAVE_CLOCK_GETTIME + struct timespec tm; + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm); + return tm.tv_sec * 1000000000LL + tm.tv_nsec; +#else + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec * 1000000000 + tv.tv_usec * 1000; +#endif +} + +inline static int64_t CurrentRealTimeMillis() { +#ifdef HAVE_CLOCK_GETTIME + struct timespec tm; + clock_gettime(CLOCK_MONOTONIC, &tm); + return tm.tv_sec * 1000LL + tm.tv_nsec / 1000000LL; +#else + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +#endif +} + + +template +inline static T Square(const T a) { + return a * a; +} + + +template +inline static T Clip(const T a, const T floor, const T ceil) { + SCHECK(ceil >= floor, "Bounds mismatch!"); + return (a <= floor) ? floor : ((a >= ceil) ? ceil : a); +} + + +template +inline static int Floor(const T a) { + return static_cast(a); +} + + +template +inline static int Ceil(const T a) { + return Floor(a) + 1; +} + + +template +inline static bool InRange(const T a, const T min, const T max) { + return (a >= min) && (a <= max); +} + + +inline static bool ValidIndex(const int a, const int max) { + return (a >= 0) && (a < max); +} + + +inline bool NearlyEqual(const float a, const float b, const float tolerance) { + return std::abs(a - b) < tolerance; +} + + +inline bool NearlyEqual(const float a, const float b) { + return NearlyEqual(a, b, EPSILON); +} + + +template +inline static int Round(const float a) { + return (a - static_cast(floor(a) > 0.5f) ? ceil(a) : floor(a)); +} + + +template +inline static void Swap(T* const a, T* const b) { + // Cache out the VALUE of what's at a. + T tmp = *a; + *a = *b; + + *b = tmp; +} + + +static inline float randf() { + return rand() / static_cast(RAND_MAX); +} + +static inline float randf(const float min_value, const float max_value) { + return randf() * (max_value - min_value) + min_value; +} + +static inline uint16_t RealToFixed115(const float real_number) { + SCHECK(InRange(real_number, 0.0f, 2048.0f), + "Value out of range! %.2f", real_number); + + static const float kMult = 32.0f; + const float round_add = (real_number > 0.0f) ? 0.5f : -0.5f; + return static_cast(real_number * kMult + round_add); +} + +static inline float FixedToFloat115(const uint16_t fp_number) { + const float kDiv = 32.0f; + return (static_cast(fp_number) / kDiv); +} + +static inline int RealToFixed1616(const float real_number) { + static const float kMult = 65536.0f; + SCHECK(InRange(real_number, -kMult, kMult), + "Value out of range! %.2f", real_number); + + const float round_add = (real_number > 0.0f) ? 0.5f : -0.5f; + return static_cast(real_number * kMult + round_add); +} + +static inline float FixedToFloat1616(const int fp_number) { + const float kDiv = 65536.0f; + return (static_cast(fp_number) / kDiv); +} + +template +// produces numbers in range [0,2*M_PI] (rather than -PI,PI) +inline T FastAtan2(const T y, const T x) { + static const T coeff_1 = (T)(M_PI / 4.0); + static const T coeff_2 = (T)(3.0 * coeff_1); + const T abs_y = fabs(y); + T angle; + if (x >= 0) { + T r = (x - abs_y) / (x + abs_y); + angle = coeff_1 - coeff_1 * r; + } else { + T r = (x + abs_y) / (abs_y - x); + angle = coeff_2 - coeff_1 * r; + } + static const T PI_2 = 2.0 * M_PI; + return y < 0 ? PI_2 - angle : angle; +} + +#define NELEMS(X) (sizeof(X) / sizeof(X[0])) + +namespace tf_tracking { + +#ifdef __ARM_NEON +float ComputeMeanNeon(const float* const values, const int num_vals); + +float ComputeStdDevNeon(const float* const values, const int num_vals, + const float mean); + +float ComputeWeightedMeanNeon(const float* const values, + const float* const weights, const int num_vals); + +float ComputeCrossCorrelationNeon(const float* const values1, + const float* const values2, + const int num_vals); +#endif + +inline float ComputeMeanCpu(const float* const values, const int num_vals) { + // Get mean. + float sum = values[0]; + for (int i = 1; i < num_vals; ++i) { + sum += values[i]; + } + return sum / static_cast(num_vals); +} + + +inline float ComputeMean(const float* const values, const int num_vals) { + return +#ifdef __ARM_NEON + (num_vals >= 8) ? ComputeMeanNeon(values, num_vals) : +#endif + ComputeMeanCpu(values, num_vals); +} + + +inline float ComputeStdDevCpu(const float* const values, + const int num_vals, + const float mean) { + // Get Std dev. + float squared_sum = 0.0f; + for (int i = 0; i < num_vals; ++i) { + squared_sum += Square(values[i] - mean); + } + return sqrt(squared_sum / static_cast(num_vals)); +} + + +inline float ComputeStdDev(const float* const values, + const int num_vals, + const float mean) { + return +#ifdef __ARM_NEON + (num_vals >= 8) ? ComputeStdDevNeon(values, num_vals, mean) : +#endif + ComputeStdDevCpu(values, num_vals, mean); +} + + +// TODO(andrewharp): Accelerate with NEON. +inline float ComputeWeightedMean(const float* const values, + const float* const weights, + const int num_vals) { + float sum = 0.0f; + float total_weight = 0.0f; + for (int i = 0; i < num_vals; ++i) { + sum += values[i] * weights[i]; + total_weight += weights[i]; + } + return sum / num_vals; +} + + +inline float ComputeCrossCorrelationCpu(const float* const values1, + const float* const values2, + const int num_vals) { + float sxy = 0.0f; + for (int offset = 0; offset < num_vals; ++offset) { + sxy += values1[offset] * values2[offset]; + } + + const float cross_correlation = sxy / num_vals; + + return cross_correlation; +} + + +inline float ComputeCrossCorrelation(const float* const values1, + const float* const values2, + const int num_vals) { + return +#ifdef __ARM_NEON + (num_vals >= 8) ? ComputeCrossCorrelationNeon(values1, values2, num_vals) + : +#endif + ComputeCrossCorrelationCpu(values1, values2, num_vals); +} + + +inline void NormalizeNumbers(float* const values, const int num_vals) { + // Find the mean and then subtract so that the new mean is 0.0. + const float mean = ComputeMean(values, num_vals); + VLOG(2) << "Mean is " << mean; + float* curr_data = values; + for (int i = 0; i < num_vals; ++i) { + *curr_data -= mean; + curr_data++; + } + + // Now divide by the std deviation so the new standard deviation is 1.0. + // The numbers might all be identical (and thus shifted to 0.0 now), + // so only scale by the standard deviation if this is not the case. + const float std_dev = ComputeStdDev(values, num_vals, 0.0f); + if (std_dev > 0.0f) { + VLOG(2) << "Std dev is " << std_dev; + curr_data = values; + for (int i = 0; i < num_vals; ++i) { + *curr_data /= std_dev; + curr_data++; + } + } +} + + +// Returns the determinant of a 2x2 matrix. +template +inline T FindDeterminant2x2(const T* const a) { + // Determinant: (ad - bc) + return a[0] * a[3] - a[1] * a[2]; +} + + +// Finds the inverse of a 2x2 matrix. +// Returns true upon success, false if the matrix is not invertible. +template +inline bool Invert2x2(const T* const a, float* const a_inv) { + const float det = static_cast(FindDeterminant2x2(a)); + if (fabs(det) < EPSILON) { + return false; + } + const float inv_det = 1.0f / det; + + a_inv[0] = inv_det * static_cast(a[3]); // d + a_inv[1] = inv_det * static_cast(-a[1]); // -b + a_inv[2] = inv_det * static_cast(-a[2]); // -c + a_inv[3] = inv_det * static_cast(a[0]); // a + + return true; +} + +} // namespace tf_tracking + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_UTILS_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/utils_neon.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/utils_neon.cc" new file mode 100644 index 0000000..5a5250e --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/object_tracking/utils_neon.cc" @@ -0,0 +1,151 @@ +/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// NEON implementations of Image methods for compatible devices. Control +// should never enter this compilation unit on incompatible devices. + +#ifdef __ARM_NEON + +#include + +#include "tensorflow/examples/android/jni/object_tracking/geom.h" +#include "tensorflow/examples/android/jni/object_tracking/image-inl.h" +#include "tensorflow/examples/android/jni/object_tracking/image.h" +#include "tensorflow/examples/android/jni/object_tracking/utils.h" + +namespace tf_tracking { + +inline static float GetSum(const float32x4_t& values) { + static float32_t summed_values[4]; + vst1q_f32(summed_values, values); + return summed_values[0] + + summed_values[1] + + summed_values[2] + + summed_values[3]; +} + + +float ComputeMeanNeon(const float* const values, const int num_vals) { + SCHECK(num_vals >= 8, "Not enough values to merit NEON: %d", num_vals); + + const float32_t* const arm_vals = (const float32_t* const) values; + float32x4_t accum = vdupq_n_f32(0.0f); + + int offset = 0; + for (; offset <= num_vals - 4; offset += 4) { + accum = vaddq_f32(accum, vld1q_f32(&arm_vals[offset])); + } + + // Pull the accumulated values into a single variable. + float sum = GetSum(accum); + + // Get the remaining 1 to 3 values. + for (; offset < num_vals; ++offset) { + sum += values[offset]; + } + + const float mean_neon = sum / static_cast(num_vals); + +#ifdef SANITY_CHECKS + const float mean_cpu = ComputeMeanCpu(values, num_vals); + SCHECK(NearlyEqual(mean_neon, mean_cpu, EPSILON * num_vals), + "Neon mismatch with CPU mean! %.10f vs %.10f", + mean_neon, mean_cpu); +#endif + + return mean_neon; +} + + +float ComputeStdDevNeon(const float* const values, + const int num_vals, const float mean) { + SCHECK(num_vals >= 8, "Not enough values to merit NEON: %d", num_vals); + + const float32_t* const arm_vals = (const float32_t* const) values; + const float32x4_t mean_vec = vdupq_n_f32(-mean); + + float32x4_t accum = vdupq_n_f32(0.0f); + + int offset = 0; + for (; offset <= num_vals - 4; offset += 4) { + const float32x4_t deltas = + vaddq_f32(mean_vec, vld1q_f32(&arm_vals[offset])); + + accum = vmlaq_f32(accum, deltas, deltas); + } + + // Pull the accumulated values into a single variable. + float squared_sum = GetSum(accum); + + // Get the remaining 1 to 3 values. + for (; offset < num_vals; ++offset) { + squared_sum += Square(values[offset] - mean); + } + + const float std_dev_neon = sqrt(squared_sum / static_cast(num_vals)); + +#ifdef SANITY_CHECKS + const float std_dev_cpu = ComputeStdDevCpu(values, num_vals, mean); + SCHECK(NearlyEqual(std_dev_neon, std_dev_cpu, EPSILON * num_vals), + "Neon mismatch with CPU std dev! %.10f vs %.10f", + std_dev_neon, std_dev_cpu); +#endif + + return std_dev_neon; +} + + +float ComputeCrossCorrelationNeon(const float* const values1, + const float* const values2, + const int num_vals) { + SCHECK(num_vals >= 8, "Not enough values to merit NEON: %d", num_vals); + + const float32_t* const arm_vals1 = (const float32_t* const) values1; + const float32_t* const arm_vals2 = (const float32_t* const) values2; + + float32x4_t accum = vdupq_n_f32(0.0f); + + int offset = 0; + for (; offset <= num_vals - 4; offset += 4) { + accum = vmlaq_f32(accum, + vld1q_f32(&arm_vals1[offset]), + vld1q_f32(&arm_vals2[offset])); + } + + // Pull the accumulated values into a single variable. + float sxy = GetSum(accum); + + // Get the remaining 1 to 3 values. + for (; offset < num_vals; ++offset) { + sxy += values1[offset] * values2[offset]; + } + + const float cross_correlation_neon = sxy / num_vals; + +#ifdef SANITY_CHECKS + const float cross_correlation_cpu = + ComputeCrossCorrelationCpu(values1, values2, num_vals); + SCHECK(NearlyEqual(cross_correlation_neon, cross_correlation_cpu, + EPSILON * num_vals), + "Neon mismatch with CPU cross correlation! %.10f vs %.10f", + cross_correlation_neon, cross_correlation_cpu); +#endif + + return cross_correlation_neon; +} + +} // namespace tf_tracking + +#endif // __ARM_NEON diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/rgb2yuv.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/rgb2yuv.cc" new file mode 100644 index 0000000..b20ce58 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/rgb2yuv.cc" @@ -0,0 +1,99 @@ +/* Copyright 2015 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// These utility functions allow for the conversion of RGB data to YUV data. + +#include "tensorflow/examples/android/jni/rgb2yuv.h" + +static inline void WriteYUV(const int x, const int y, const int width, + const int r8, const int g8, const int b8, + uint8_t* const pY, uint8_t* const pUV) { + // Using formulas from http://msdn.microsoft.com/en-us/library/ms893078 + *pY = ((66 * r8 + 129 * g8 + 25 * b8 + 128) >> 8) + 16; + + // Odd widths get rounded up so that UV blocks on the side don't get cut off. + const int blocks_per_row = (width + 1) / 2; + + // 2 bytes per UV block + const int offset = 2 * (((y / 2) * blocks_per_row + (x / 2))); + + // U and V are the average values of all 4 pixels in the block. + if (!(x & 1) && !(y & 1)) { + // Explicitly clear the block if this is the first pixel in it. + pUV[offset] = 0; + pUV[offset + 1] = 0; + } + + // V (with divide by 4 factored in) +#ifdef __APPLE__ + const int u_offset = 0; + const int v_offset = 1; +#else + const int u_offset = 1; + const int v_offset = 0; +#endif + pUV[offset + v_offset] += ((112 * r8 - 94 * g8 - 18 * b8 + 128) >> 10) + 32; + + // U (with divide by 4 factored in) + pUV[offset + u_offset] += ((-38 * r8 - 74 * g8 + 112 * b8 + 128) >> 10) + 32; +} + +void ConvertARGB8888ToYUV420SP(const uint32_t* const input, + uint8_t* const output, int width, int height) { + uint8_t* pY = output; + uint8_t* pUV = output + (width * height); + const uint32_t* in = input; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + const uint32_t rgb = *in++; +#ifdef __APPLE__ + const int nB = (rgb >> 8) & 0xFF; + const int nG = (rgb >> 16) & 0xFF; + const int nR = (rgb >> 24) & 0xFF; +#else + const int nR = (rgb >> 16) & 0xFF; + const int nG = (rgb >> 8) & 0xFF; + const int nB = rgb & 0xFF; +#endif + WriteYUV(x, y, width, nR, nG, nB, pY++, pUV); + } + } +} + +void ConvertRGB565ToYUV420SP(const uint16_t* const input, uint8_t* const output, + const int width, const int height) { + uint8_t* pY = output; + uint8_t* pUV = output + (width * height); + const uint16_t* in = input; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + const uint32_t rgb = *in++; + + const int r5 = ((rgb >> 11) & 0x1F); + const int g6 = ((rgb >> 5) & 0x3F); + const int b5 = (rgb & 0x1F); + + // Shift left, then fill in the empty low bits with a copy of the high + // bits so we can stretch across the entire 0 - 255 range. + const int r8 = r5 << 3 | r5 >> 2; + const int g8 = g6 << 2 | g6 >> 4; + const int b8 = b5 << 3 | b5 >> 2; + + WriteYUV(x, y, width, r8, g8, b8, pY++, pUV); + } + } +} diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/rgb2yuv.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/rgb2yuv.h" new file mode 100644 index 0000000..ff720fd --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/rgb2yuv.h" @@ -0,0 +1,35 @@ +/* Copyright 2015 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_RGB2YUV_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_RGB2YUV_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void ConvertARGB8888ToYUV420SP(const uint32_t* const input, + uint8_t* const output, int width, int height); + +void ConvertRGB565ToYUV420SP(const uint16_t* const input, uint8_t* const output, + const int width, const int height); + +#ifdef __cplusplus +} +#endif + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_RGB2YUV_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/yuv2rgb.cc" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/yuv2rgb.cc" new file mode 100644 index 0000000..96d9632 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/yuv2rgb.cc" @@ -0,0 +1,191 @@ +/* Copyright 2015 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// This is a collection of routines which converts various YUV image formats +// to ARGB. + +#include "tensorflow/examples/android/jni/yuv2rgb.h" + +#ifndef MAX +#define MAX(a, b) ({__typeof__(a) _a = (a); __typeof__(b) _b = (b); _a > _b ? _a : _b; }) +#define MIN(a, b) ({__typeof__(a) _a = (a); __typeof__(b) _b = (b); _a < _b ? _a : _b; }) +#endif + +// This value is 2 ^ 18 - 1, and is used to clamp the RGB values before their ranges +// are normalized to eight bits. +static const int kMaxChannelValue = 262143; + +static inline uint32_t YUV2RGB(int nY, int nU, int nV) { + nY -= 16; + nU -= 128; + nV -= 128; + if (nY < 0) nY = 0; + + // This is the floating point equivalent. We do the conversion in integer + // because some Android devices do not have floating point in hardware. + // nR = (int)(1.164 * nY + 2.018 * nU); + // nG = (int)(1.164 * nY - 0.813 * nV - 0.391 * nU); + // nB = (int)(1.164 * nY + 1.596 * nV); + + int nR = 1192 * nY + 1634 * nV; + int nG = 1192 * nY - 833 * nV - 400 * nU; + int nB = 1192 * nY + 2066 * nU; + + nR = MIN(kMaxChannelValue, MAX(0, nR)); + nG = MIN(kMaxChannelValue, MAX(0, nG)); + nB = MIN(kMaxChannelValue, MAX(0, nB)); + + nR = (nR >> 10) & 0xff; + nG = (nG >> 10) & 0xff; + nB = (nB >> 10) & 0xff; + + return 0xff000000 | (nR << 16) | (nG << 8) | nB; +} + +// Accepts a YUV 4:2:0 image with a plane of 8 bit Y samples followed by +// separate u and v planes with arbitrary row and column strides, +// containing 8 bit 2x2 subsampled chroma samples. +// Converts to a packed ARGB 32 bit output of the same pixel dimensions. +void ConvertYUV420ToARGB8888(const uint8_t* const yData, + const uint8_t* const uData, + const uint8_t* const vData, uint32_t* const output, + const int width, const int height, + const int y_row_stride, const int uv_row_stride, + const int uv_pixel_stride) { + uint32_t* out = output; + + for (int y = 0; y < height; y++) { + const uint8_t* pY = yData + y_row_stride * y; + + const int uv_row_start = uv_row_stride * (y >> 1); + const uint8_t* pU = uData + uv_row_start; + const uint8_t* pV = vData + uv_row_start; + + for (int x = 0; x < width; x++) { + const int uv_offset = (x >> 1) * uv_pixel_stride; + *out++ = YUV2RGB(pY[x], pU[uv_offset], pV[uv_offset]); + } + } +} + +// Accepts a YUV 4:2:0 image with a plane of 8 bit Y samples followed by an +// interleaved U/V plane containing 8 bit 2x2 subsampled chroma samples, +// except the interleave order of U and V is reversed. Converts to a packed +// ARGB 32 bit output of the same pixel dimensions. +void ConvertYUV420SPToARGB8888(const uint8_t* const yData, + const uint8_t* const uvData, + uint32_t* const output, const int width, + const int height) { + const uint8_t* pY = yData; + const uint8_t* pUV = uvData; + uint32_t* out = output; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int nY = *pY++; + int offset = (y >> 1) * width + 2 * (x >> 1); +#ifdef __APPLE__ + int nU = pUV[offset]; + int nV = pUV[offset + 1]; +#else + int nV = pUV[offset]; + int nU = pUV[offset + 1]; +#endif + + *out++ = YUV2RGB(nY, nU, nV); + } + } +} + +// The same as above, but downsamples each dimension to half size. +void ConvertYUV420SPToARGB8888HalfSize(const uint8_t* const input, + uint32_t* const output, int width, + int height) { + const uint8_t* pY = input; + const uint8_t* pUV = input + (width * height); + uint32_t* out = output; + int stride = width; + width >>= 1; + height >>= 1; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int nY = (pY[0] + pY[1] + pY[stride] + pY[stride + 1]) >> 2; + pY += 2; +#ifdef __APPLE__ + int nU = *pUV++; + int nV = *pUV++; +#else + int nV = *pUV++; + int nU = *pUV++; +#endif + + *out++ = YUV2RGB(nY, nU, nV); + } + pY += stride; + } +} + +// Accepts a YUV 4:2:0 image with a plane of 8 bit Y samples followed by an +// interleaved U/V plane containing 8 bit 2x2 subsampled chroma samples, +// except the interleave order of U and V is reversed. Converts to a packed +// RGB 565 bit output of the same pixel dimensions. +void ConvertYUV420SPToRGB565(const uint8_t* const input, uint16_t* const output, + const int width, const int height) { + const uint8_t* pY = input; + const uint8_t* pUV = input + (width * height); + uint16_t* out = output; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int nY = *pY++; + int offset = (y >> 1) * width + 2 * (x >> 1); +#ifdef __APPLE__ + int nU = pUV[offset]; + int nV = pUV[offset + 1]; +#else + int nV = pUV[offset]; + int nU = pUV[offset + 1]; +#endif + + nY -= 16; + nU -= 128; + nV -= 128; + if (nY < 0) nY = 0; + + // This is the floating point equivalent. We do the conversion in integer + // because some Android devices do not have floating point in hardware. + // nR = (int)(1.164 * nY + 2.018 * nU); + // nG = (int)(1.164 * nY - 0.813 * nV - 0.391 * nU); + // nB = (int)(1.164 * nY + 1.596 * nV); + + int nR = 1192 * nY + 1634 * nV; + int nG = 1192 * nY - 833 * nV - 400 * nU; + int nB = 1192 * nY + 2066 * nU; + + nR = MIN(kMaxChannelValue, MAX(0, nR)); + nG = MIN(kMaxChannelValue, MAX(0, nG)); + nB = MIN(kMaxChannelValue, MAX(0, nB)); + + // Shift more than for ARGB8888 and apply appropriate bitmask. + nR = (nR >> 13) & 0x1f; + nG = (nG >> 12) & 0x3f; + nB = (nB >> 13) & 0x1f; + + // R is high 5 bits, G is middle 6 bits, and B is low 5 bits. + *out++ = (nR << 11) | (nG << 5) | nB; + } + } +} diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/yuv2rgb.h" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/yuv2rgb.h" new file mode 100644 index 0000000..fab462f --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/jni/yuv2rgb.h" @@ -0,0 +1,57 @@ +/* Copyright 2015 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// This is a collection of routines which converts various YUV image formats +// to (A)RGB. + +#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_YUV2RGB_H_ +#define TENSORFLOW_EXAMPLES_ANDROID_JNI_YUV2RGB_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void ConvertYUV420ToARGB8888(const uint8_t* const yData, + const uint8_t* const uData, + const uint8_t* const vData, uint32_t* const output, + const int width, const int height, + const int y_row_stride, const int uv_row_stride, + const int uv_pixel_stride); + +// Converts YUV420 semi-planar data to ARGB 8888 data using the supplied width +// and height. The input and output must already be allocated and non-null. +// For efficiency, no error checking is performed. +void ConvertYUV420SPToARGB8888(const uint8_t* const pY, + const uint8_t* const pUV, uint32_t* const output, + const int width, const int height); + +// The same as above, but downsamples each dimension to half size. +void ConvertYUV420SPToARGB8888HalfSize(const uint8_t* const input, + uint32_t* const output, int width, + int height); + +// Converts YUV420 semi-planar data to RGB 565 data using the supplied width +// and height. The input and output must already be allocated and non-null. +// For efficiency, no error checking is performed. +void ConvertYUV420SPToRGB565(const uint8_t* const input, uint16_t* const output, + const int width, const int height); + +#ifdef __cplusplus +} +#endif + +#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_YUV2RGB_H_ diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/animator/color_animation.xml" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/animator/color_animation.xml" new file mode 100644 index 0000000..891d8cc --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/animator/color_animation.xml" @@ -0,0 +1,30 @@ + + + + + diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-hdpi/ic_action_info.png" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-hdpi/ic_action_info.png" new file mode 100644 index 0000000000000000000000000000000000000000..32bd1aabcabb85ded957230533c00e735183a323 GIT binary patch literal 1025 zcmV+c1pfPpP)UDI7BaW>`N=bRlk|E2%^dB8hrR55et*8d|IcHT75QTnx&CD( z0RP&9B@dK5;L-x65HcIEwzf8qPN%o}e7;SFVXWg@h5G(8m&<)+eJL+59~&4LNV_!r zJh>+x2#3Sl{CdQ#bT}>ywQR&8iWzy)M+Q2ECY~)rE;`M%!}m*2L~T%H1|=Rs$~z==CdX= z48rmho`|t8O+~w5HL)!Nz)I((+8|_dYHF%o7dC|2VU#(bK)xovUn~V!!l|;d@(MD7 z$QZ@DcdfYA5&%`_FTxPs#yu+u3*fUT6H!Ve0B~QYkR&!V=On%G_H8SD!V&>jgyx}+Knp;|1FUifM$%zBVA`u=>gGED zq&&B>W-!17-PoZ8pu*>pbXb_S!SK5k1xd4g)>g@d_8I_WOpy-#W+|Ck0J!uB4ECW!8~_iN3BVZu zM3MEDkbUMBz)2YFhG8#Z(6Jl<2)`3DFCpta03QGM0E#<=iav?WWt8LK<;7mY% z3dxyac6RorXJyoBBXbJC^F}6?buvmg1pu84baGnrW|R;B`7n}q8^hfEjBmA(6>OMO zoz?C*-2~m-v6H8ldj5Q=dS1|RS_C^d&`6ihclsRfvKD*(IM9&9?Zd;vNh?iLJ4%?D z6zE845IW5TKT_s_(B@n7HxeEl>YLS3QbfqjMBxtg3WS%}Dot{PRD74`S|#s^V!qg# zPm9H_7TGYtTG>~N=HxEg%iV=#PR0&OU=>NZ*?hgu`!uJkZ!7kC-AcVK)E--XpioM< v;adXW#(G}RmOS8v72WVCdBBbJyrBIJ%ovMLu~&(q00000NkvXXu0mjfpn%#$ literal 0 HcmV?d00001 diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-hdpi/ic_launcher.png" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-hdpi/ic_launcher.png" new file mode 100644 index 0000000000000000000000000000000000000000..b3113cd15c3255405ee34c622a1e83674e6e5487 GIT binary patch literal 4312 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 literal 0 HcmV?d00001 diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-xhdpi/ic_launcher.png" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-xhdpi/ic_launcher.png" new file mode 100644 index 0000000000000000000000000000000000000000..6361d792dacd8ce09a14258878b5ce6db5e0debb GIT binary patch literal 6683 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

i~@`6sv7S6=V4 zM=#w&dZClNGDzWMLIlEt6x}&s9{=J1ylrY+QVj#%73SuSVL?mnva&WP-=t=d{puU` zickG@zde0vlQ{B;v)(QHhSAug`grcRuP0xL_N=QDUde*rZ=cx!V4V@&0AK@vb(X+7 l-+n^_HUL;>39R$&|34>RdNZ>cMG*i1002ovPDHLkV1kjqwtWBq literal 0 HcmV?d00001 diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-xxhdpi/ic_action_info.png" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/drawable-xxhdpi/ic_action_info.png" new file mode 100644 index 0000000000000000000000000000000000000000..394eb7e534905e36fd24c3defac92c09b403ee39 GIT binary patch literal 2265 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 + + + + diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/layout/activity_camera.xml" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/layout/activity_camera.xml" new file mode 100644 index 0000000..1a22d4b --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/layout/activity_camera.xml" @@ -0,0 +1,22 @@ + + diff --git "a/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/layout/activity_speech.xml" "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/layout/activity_speech.xml" new file mode 100644 index 0000000..2fe1338 --- /dev/null +++ "b/Feat_16\347\247\221\344\272\2147\347\273\204/\344\273\243\347\240\201/android/res/layout/activity_speech.xml" @@ -0,0 +1,55 @@ + + + + + + + +