leoxing1996 commited on
Commit
b18cfd3
·
1 Parent(s): bd4d838

add midas manually

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. live2diff/MiDaS/.gitignore +110 -0
  2. live2diff/MiDaS/Dockerfile +29 -0
  3. live2diff/MiDaS/LICENSE +21 -0
  4. live2diff/MiDaS/README.md +161 -0
  5. live2diff/MiDaS/hubconf.py +154 -0
  6. live2diff/MiDaS/input/.placeholder +0 -0
  7. live2diff/MiDaS/midas/base_model.py +16 -0
  8. live2diff/MiDaS/midas/blocks.py +342 -0
  9. live2diff/MiDaS/midas/dpt_depth.py +109 -0
  10. live2diff/MiDaS/midas/midas_net.py +76 -0
  11. live2diff/MiDaS/midas/midas_net_custom.py +128 -0
  12. live2diff/MiDaS/midas/transforms.py +234 -0
  13. live2diff/MiDaS/midas/vit.py +503 -0
  14. live2diff/MiDaS/mobile/README.md +70 -0
  15. live2diff/MiDaS/mobile/android/.gitignore +13 -0
  16. live2diff/MiDaS/mobile/android/EXPLORE_THE_CODE.md +414 -0
  17. live2diff/MiDaS/mobile/android/LICENSE +21 -0
  18. live2diff/MiDaS/mobile/android/README.md +21 -0
  19. live2diff/MiDaS/mobile/android/app/.gitignore +3 -0
  20. live2diff/MiDaS/mobile/android/app/build.gradle +56 -0
  21. live2diff/MiDaS/mobile/android/app/proguard-rules.pro +21 -0
  22. live2diff/MiDaS/mobile/android/app/src/androidTest/assets/fox-mobilenet_v1_1.0_224_support.txt +3 -0
  23. live2diff/MiDaS/mobile/android/app/src/androidTest/assets/fox-mobilenet_v1_1.0_224_task_api.txt +3 -0
  24. live2diff/MiDaS/mobile/android/app/src/androidTest/java/AndroidManifest.xml +5 -0
  25. live2diff/MiDaS/mobile/android/app/src/androidTest/java/org/tensorflow/lite/examples/classification/ClassifierTest.java +121 -0
  26. live2diff/MiDaS/mobile/android/app/src/main/AndroidManifest.xml +28 -0
  27. live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/CameraActivity.java +717 -0
  28. live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/CameraConnectionFragment.java +575 -0
  29. live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/ClassifierActivity.java +238 -0
  30. live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/LegacyCameraConnectionFragment.java +203 -0
  31. live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/customview/AutoFitTextureView.java +72 -0
  32. live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/customview/OverlayView.java +48 -0
  33. live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/customview/RecognitionScoreView.java +67 -0
  34. live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/customview/ResultsView.java +23 -0
  35. live2diff/MiDaS/mobile/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +34 -0
  36. live2diff/MiDaS/mobile/android/app/src/main/res/drawable/bottom_sheet_bg.xml +9 -0
  37. live2diff/MiDaS/mobile/android/app/src/main/res/drawable/ic_baseline_add.xml +9 -0
  38. live2diff/MiDaS/mobile/android/app/src/main/res/drawable/ic_baseline_remove.xml +9 -0
  39. live2diff/MiDaS/mobile/android/app/src/main/res/drawable/ic_launcher_background.xml +170 -0
  40. live2diff/MiDaS/mobile/android/app/src/main/res/drawable/rectangle.xml +13 -0
  41. live2diff/MiDaS/mobile/android/app/src/main/res/layout/tfe_ic_activity_camera.xml +56 -0
  42. live2diff/MiDaS/mobile/android/app/src/main/res/layout/tfe_ic_camera_connection_fragment.xml +32 -0
  43. live2diff/MiDaS/mobile/android/app/src/main/res/layout/tfe_ic_layout_bottom_sheet.xml +321 -0
  44. live2diff/MiDaS/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
  45. live2diff/MiDaS/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
  46. live2diff/MiDaS/mobile/android/app/src/main/res/values/colors.xml +8 -0
  47. live2diff/MiDaS/mobile/android/app/src/main/res/values/dimens.xml +5 -0
  48. live2diff/MiDaS/mobile/android/app/src/main/res/values/strings.xml +21 -0
  49. live2diff/MiDaS/mobile/android/app/src/main/res/values/styles.xml +11 -0
  50. live2diff/MiDaS/mobile/android/build.gradle +27 -0
live2diff/MiDaS/.gitignore ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+ MANIFEST
27
+
28
+ # PyInstaller
29
+ # Usually these files are written by a python script from a template
30
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
31
+ *.manifest
32
+ *.spec
33
+
34
+ # Installer logs
35
+ pip-log.txt
36
+ pip-delete-this-directory.txt
37
+
38
+ # Unit test / coverage reports
39
+ htmlcov/
40
+ .tox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ .hypothesis/
48
+ .pytest_cache/
49
+
50
+ # Translations
51
+ *.mo
52
+ *.pot
53
+
54
+ # Django stuff:
55
+ *.log
56
+ local_settings.py
57
+ db.sqlite3
58
+
59
+ # Flask stuff:
60
+ instance/
61
+ .webassets-cache
62
+
63
+ # Scrapy stuff:
64
+ .scrapy
65
+
66
+ # Sphinx documentation
67
+ docs/_build/
68
+
69
+ # PyBuilder
70
+ target/
71
+
72
+ # Jupyter Notebook
73
+ .ipynb_checkpoints
74
+
75
+ # pyenv
76
+ .python-version
77
+
78
+ # celery beat schedule file
79
+ celerybeat-schedule
80
+
81
+ # SageMath parsed files
82
+ *.sage.py
83
+
84
+ # Environments
85
+ .env
86
+ .venv
87
+ env/
88
+ venv/
89
+ ENV/
90
+ env.bak/
91
+ venv.bak/
92
+
93
+ # Spyder project settings
94
+ .spyderproject
95
+ .spyproject
96
+
97
+ # Rope project settings
98
+ .ropeproject
99
+
100
+ # mkdocs documentation
101
+ /site
102
+
103
+ # mypy
104
+ .mypy_cache/
105
+
106
+ *.png
107
+ *.pfm
108
+ *.jpg
109
+ *.jpeg
110
+ *.pt
live2diff/MiDaS/Dockerfile ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # enables cuda support in docker
2
+ FROM nvidia/cuda:10.2-cudnn7-runtime-ubuntu18.04
3
+
4
+ # install python 3.6, pip and requirements for opencv-python
5
+ # (see https://github.com/NVIDIA/nvidia-docker/issues/864)
6
+ RUN apt-get update && apt-get -y install \
7
+ python3 \
8
+ python3-pip \
9
+ libsm6 \
10
+ libxext6 \
11
+ libxrender-dev \
12
+ curl \
13
+ && rm -rf /var/lib/apt/lists/*
14
+
15
+ # install python dependencies
16
+ RUN pip3 install --upgrade pip
17
+ RUN pip3 install torch~=1.8 torchvision opencv-python-headless~=3.4 timm
18
+
19
+ # copy inference code
20
+ WORKDIR /opt/MiDaS
21
+ COPY ./midas ./midas
22
+ COPY ./*.py ./
23
+
24
+ # download model weights so the docker image can be used offline
25
+ RUN cd weights && {curl -OL https://github.com/AlexeyAB/MiDaS/releases/download/midas_dpt/dpt_hybrid-midas-501f0c75.pt; cd -; }
26
+ RUN python3 run.py --model_type dpt_hybrid; exit 0
27
+
28
+ # entrypoint (dont forget to mount input and output directories)
29
+ CMD python3 run.py --model_type dpt_hybrid
live2diff/MiDaS/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Intel ISL (Intel Intelligent Systems Lab)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
live2diff/MiDaS/README.md ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer
2
+
3
+ This repository contains code to compute depth from a single image. It accompanies our [paper](https://arxiv.org/abs/1907.01341v3):
4
+
5
+ >Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer
6
+ René Ranftl, Katrin Lasinger, David Hafner, Konrad Schindler, Vladlen Koltun
7
+
8
+
9
+ and our [preprint](https://arxiv.org/abs/2103.13413):
10
+
11
+ > Vision Transformers for Dense Prediction
12
+ > René Ranftl, Alexey Bochkovskiy, Vladlen Koltun
13
+
14
+
15
+ MiDaS was trained on 10 datasets (ReDWeb, DIML, Movies, MegaDepth, WSVD, TartanAir, HRWSI, ApolloScape, BlendedMVS, IRS) with
16
+ multi-objective optimization.
17
+ The original model that was trained on 5 datasets (`MIX 5` in the paper) can be found [here](https://github.com/intel-isl/MiDaS/releases/tag/v2).
18
+
19
+
20
+ ### Changelog
21
+ * [Sep 2021] Integrated to [Huggingface Spaces](https://huggingface.co/spaces) with [Gradio](https://github.com/gradio-app/gradio). See [Gradio Web Demo](https://huggingface.co/spaces/akhaliq/DPT-Large).
22
+ * [Apr 2021] Released MiDaS v3.0:
23
+ - New models based on [Dense Prediction Transformers](https://arxiv.org/abs/2103.13413) are on average [21% more accurate](#Accuracy) than MiDaS v2.1
24
+ - Additional models can be found [here](https://github.com/intel-isl/DPT)
25
+ * [Nov 2020] Released MiDaS v2.1:
26
+ - New model that was trained on 10 datasets and is on average about [10% more accurate](#Accuracy) than [MiDaS v2.0](https://github.com/intel-isl/MiDaS/releases/tag/v2)
27
+ - New light-weight model that achieves [real-time performance](https://github.com/intel-isl/MiDaS/tree/master/mobile) on mobile platforms.
28
+ - Sample applications for [iOS](https://github.com/intel-isl/MiDaS/tree/master/mobile/ios) and [Android](https://github.com/intel-isl/MiDaS/tree/master/mobile/android)
29
+ - [ROS package](https://github.com/intel-isl/MiDaS/tree/master/ros) for easy deployment on robots
30
+ * [Jul 2020] Added TensorFlow and ONNX code. Added [online demo](http://35.202.76.57/).
31
+ * [Dec 2019] Released new version of MiDaS - the new model is significantly more accurate and robust
32
+ * [Jul 2019] Initial release of MiDaS ([Link](https://github.com/intel-isl/MiDaS/releases/tag/v1))
33
+
34
+ ### Setup
35
+
36
+ 1) Pick one or more models and download corresponding weights to the `weights` folder:
37
+
38
+ - For highest quality: [dpt_large](https://github.com/intel-isl/DPT/releases/download/1_0/dpt_large-midas-2f21e586.pt)
39
+ - For moderately less quality, but better speed on CPU and slower GPUs: [dpt_hybrid](https://github.com/intel-isl/DPT/releases/download/1_0/dpt_hybrid-midas-501f0c75.pt)
40
+ - For real-time applications on resource-constrained devices: [midas_v21_small](https://github.com/AlexeyAB/MiDaS/releases/download/midas_dpt/midas_v21_small-70d6b9c8.pt)
41
+ - Legacy convolutional model: [midas_v21](https://github.com/AlexeyAB/MiDaS/releases/download/midas_dpt/midas_v21-f6b98070.pt)
42
+
43
+ 2) Set up dependencies:
44
+
45
+ ```shell
46
+ conda install pytorch torchvision opencv
47
+ pip install timm
48
+ ```
49
+
50
+ The code was tested with Python 3.7, PyTorch 1.8.0, OpenCV 4.5.1, and timm 0.4.5.
51
+
52
+
53
+ ### Usage
54
+
55
+ 1) Place one or more input images in the folder `input`.
56
+
57
+ 2) Run the model:
58
+
59
+ ```shell
60
+ python run.py --model_type dpt_large
61
+ python run.py --model_type dpt_hybrid
62
+ python run.py --model_type midas_v21_small
63
+ python run.py --model_type midas_v21
64
+ ```
65
+
66
+ 3) The resulting inverse depth maps are written to the `output` folder.
67
+
68
+
69
+ #### via Docker
70
+
71
+ 1) Make sure you have installed Docker and the
72
+ [NVIDIA Docker runtime](https://github.com/NVIDIA/nvidia-docker/wiki/Installation-\(Native-GPU-Support\)).
73
+
74
+ 2) Build the Docker image:
75
+
76
+ ```shell
77
+ docker build -t midas .
78
+ ```
79
+
80
+ 3) Run inference:
81
+
82
+ ```shell
83
+ docker run --rm --gpus all -v $PWD/input:/opt/MiDaS/input -v $PWD/output:/opt/MiDaS/output midas
84
+ ```
85
+
86
+ This command passes through all of your NVIDIA GPUs to the container, mounts the
87
+ `input` and `output` directories and then runs the inference.
88
+
89
+ #### via PyTorch Hub
90
+
91
+ The pretrained model is also available on [PyTorch Hub](https://pytorch.org/hub/intelisl_midas_v2/)
92
+
93
+ #### via TensorFlow or ONNX
94
+
95
+ See [README](https://github.com/intel-isl/MiDaS/tree/master/tf) in the `tf` subdirectory.
96
+
97
+ Currently only supports MiDaS v2.1. DPT-based models to be added.
98
+
99
+
100
+ #### via Mobile (iOS / Android)
101
+
102
+ See [README](https://github.com/intel-isl/MiDaS/tree/master/mobile) in the `mobile` subdirectory.
103
+
104
+ #### via ROS1 (Robot Operating System)
105
+
106
+ See [README](https://github.com/intel-isl/MiDaS/tree/master/ros) in the `ros` subdirectory.
107
+
108
+ Currently only supports MiDaS v2.1. DPT-based models to be added.
109
+
110
+
111
+ ### Accuracy
112
+
113
+ Zero-shot error (the lower - the better) and speed (FPS):
114
+
115
+ | Model | DIW, WHDR | Eth3d, AbsRel | Sintel, AbsRel | Kitti, δ>1.25 | NyuDepthV2, δ>1.25 | TUM, δ>1.25 | Speed, FPS |
116
+ |---|---|---|---|---|---|---|---|
117
+ | **Small models:** | | | | | | | iPhone 11 |
118
+ | MiDaS v2 small | **0.1248** | 0.1550 | **0.3300** | **21.81** | 15.73 | 17.00 | 0.6 |
119
+ | MiDaS v2.1 small [URL]() | 0.1344 | **0.1344** | 0.3370 | 29.27 | **13.43** | **14.53** | 30 |
120
+ | | | | | | | |
121
+ | **Big models:** | | | | | | | GPU RTX 3090 |
122
+ | MiDaS v2 large [URL](https://github.com/intel-isl/MiDaS/releases/download/v2/model-f46da743.pt) | 0.1246 | 0.1290 | 0.3270 | 23.90 | 9.55 | 14.29 | 51 |
123
+ | MiDaS v2.1 large [URL](https://github.com/AlexeyAB/MiDaS/releases/download/midas_dpt/midas_v21-f6b98070.pt) | 0.1295 | 0.1155 | 0.3285 | 16.08 | 8.71 | 12.51 | 51 |
124
+ | MiDaS v3.0 DPT-Hybrid [URL](https://github.com/intel-isl/DPT/releases/download/1_0/dpt_hybrid-midas-501f0c75.pt) | 0.1106 | 0.0934 | 0.2741 | 11.56 | 8.69 | 10.89 | 46 |
125
+ | MiDaS v3.0 DPT-Large [URL](https://github.com/intel-isl/DPT/releases/download/1_0/dpt_large-midas-2f21e586.pt) | **0.1082** | **0.0888** | **0.2697** | **8.46** | **8.32** | **9.97** | 47 |
126
+
127
+
128
+
129
+ ### Citation
130
+
131
+ Please cite our paper if you use this code or any of the models:
132
+ ```
133
+ @ARTICLE {Ranftl2022,
134
+ author = "Ren\'{e} Ranftl and Katrin Lasinger and David Hafner and Konrad Schindler and Vladlen Koltun",
135
+ title = "Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-Shot Cross-Dataset Transfer",
136
+ journal = "IEEE Transactions on Pattern Analysis and Machine Intelligence",
137
+ year = "2022",
138
+ volume = "44",
139
+ number = "3"
140
+ }
141
+ ```
142
+
143
+ If you use a DPT-based model, please also cite:
144
+
145
+ ```
146
+ @article{Ranftl2021,
147
+ author = {Ren\'{e} Ranftl and Alexey Bochkovskiy and Vladlen Koltun},
148
+ title = {Vision Transformers for Dense Prediction},
149
+ journal = {ICCV},
150
+ year = {2021},
151
+ }
152
+ ```
153
+
154
+ ### Acknowledgements
155
+
156
+ Our work builds on and uses code from [timm](https://github.com/rwightman/pytorch-image-models).
157
+ We'd like to thank the author for making these libraries available.
158
+
159
+ ### License
160
+
161
+ MIT License
live2diff/MiDaS/hubconf.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ dependencies = ["torch"]
2
+
3
+ import torch
4
+
5
+ from midas.dpt_depth import DPTDepthModel
6
+ from midas.midas_net import MidasNet
7
+ from midas.midas_net_custom import MidasNet_small
8
+
9
+ def DPT_Large(pretrained=True, **kwargs):
10
+ """ # This docstring shows up in hub.help()
11
+ MiDaS DPT-Large model for monocular depth estimation
12
+ pretrained (bool): load pretrained weights into model
13
+ """
14
+
15
+ model = DPTDepthModel(
16
+ path=None,
17
+ backbone="vitl16_384",
18
+ non_negative=True,
19
+ )
20
+
21
+ if pretrained:
22
+ checkpoint = (
23
+ "https://github.com/intel-isl/DPT/releases/download/1_0/dpt_large-midas-2f21e586.pt"
24
+ )
25
+ state_dict = torch.hub.load_state_dict_from_url(
26
+ checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True
27
+ )
28
+ model.load_state_dict(state_dict)
29
+
30
+ return model
31
+
32
+ def DPT_Hybrid(pretrained=True, **kwargs):
33
+ """ # This docstring shows up in hub.help()
34
+ MiDaS DPT-Hybrid model for monocular depth estimation
35
+ pretrained (bool): load pretrained weights into model
36
+ """
37
+
38
+ model = DPTDepthModel(
39
+ path=None,
40
+ backbone="vitb_rn50_384",
41
+ non_negative=True,
42
+ )
43
+
44
+ if pretrained:
45
+ checkpoint = (
46
+ "https://github.com/intel-isl/DPT/releases/download/1_0/dpt_hybrid-midas-501f0c75.pt"
47
+ )
48
+ state_dict = torch.hub.load_state_dict_from_url(
49
+ checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True
50
+ )
51
+ model.load_state_dict(state_dict)
52
+
53
+ return model
54
+
55
+ def MiDaS(pretrained=True, **kwargs):
56
+ """ # This docstring shows up in hub.help()
57
+ MiDaS v2.1 model for monocular depth estimation
58
+ pretrained (bool): load pretrained weights into model
59
+ """
60
+
61
+ model = MidasNet()
62
+
63
+ if pretrained:
64
+ checkpoint = (
65
+ "https://github.com/intel-isl/MiDaS/releases/download/v2_1/model-f6b98070.pt"
66
+ )
67
+ state_dict = torch.hub.load_state_dict_from_url(
68
+ checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True
69
+ )
70
+ model.load_state_dict(state_dict)
71
+
72
+ return model
73
+
74
+ def MiDaS_small(pretrained=True, **kwargs):
75
+ """ # This docstring shows up in hub.help()
76
+ MiDaS small model for monocular depth estimation on resource-constrained devices
77
+ pretrained (bool): load pretrained weights into model
78
+ """
79
+
80
+ model = MidasNet_small(None, features=64, backbone="efficientnet_lite3", exportable=True, non_negative=True, blocks={'expand': True})
81
+
82
+ if pretrained:
83
+ checkpoint = (
84
+ "https://github.com/intel-isl/MiDaS/releases/download/v2_1/model-small-70d6b9c8.pt"
85
+ )
86
+ state_dict = torch.hub.load_state_dict_from_url(
87
+ checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True
88
+ )
89
+ model.load_state_dict(state_dict)
90
+
91
+ return model
92
+
93
+
94
+ def transforms():
95
+ import cv2
96
+ from torchvision.transforms import Compose
97
+ from midas.transforms import Resize, NormalizeImage, PrepareForNet
98
+ from midas import transforms
99
+
100
+ transforms.default_transform = Compose(
101
+ [
102
+ lambda img: {"image": img / 255.0},
103
+ Resize(
104
+ 384,
105
+ 384,
106
+ resize_target=None,
107
+ keep_aspect_ratio=True,
108
+ ensure_multiple_of=32,
109
+ resize_method="upper_bound",
110
+ image_interpolation_method=cv2.INTER_CUBIC,
111
+ ),
112
+ NormalizeImage(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
113
+ PrepareForNet(),
114
+ lambda sample: torch.from_numpy(sample["image"]).unsqueeze(0),
115
+ ]
116
+ )
117
+
118
+ transforms.small_transform = Compose(
119
+ [
120
+ lambda img: {"image": img / 255.0},
121
+ Resize(
122
+ 256,
123
+ 256,
124
+ resize_target=None,
125
+ keep_aspect_ratio=True,
126
+ ensure_multiple_of=32,
127
+ resize_method="upper_bound",
128
+ image_interpolation_method=cv2.INTER_CUBIC,
129
+ ),
130
+ NormalizeImage(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
131
+ PrepareForNet(),
132
+ lambda sample: torch.from_numpy(sample["image"]).unsqueeze(0),
133
+ ]
134
+ )
135
+
136
+ transforms.dpt_transform = Compose(
137
+ [
138
+ lambda img: {"image": img / 255.0},
139
+ Resize(
140
+ 384,
141
+ 384,
142
+ resize_target=None,
143
+ keep_aspect_ratio=True,
144
+ ensure_multiple_of=32,
145
+ resize_method="minimal",
146
+ image_interpolation_method=cv2.INTER_CUBIC,
147
+ ),
148
+ NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
149
+ PrepareForNet(),
150
+ lambda sample: torch.from_numpy(sample["image"]).unsqueeze(0),
151
+ ]
152
+ )
153
+
154
+ return transforms
live2diff/MiDaS/input/.placeholder ADDED
File without changes
live2diff/MiDaS/midas/base_model.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+
3
+
4
+ class BaseModel(torch.nn.Module):
5
+ def load(self, path):
6
+ """Load model from file.
7
+
8
+ Args:
9
+ path (str): file path
10
+ """
11
+ parameters = torch.load(path, map_location=torch.device('cpu'))
12
+
13
+ if "optimizer" in parameters:
14
+ parameters = parameters["model"]
15
+
16
+ self.load_state_dict(parameters)
live2diff/MiDaS/midas/blocks.py ADDED
@@ -0,0 +1,342 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+
4
+ from .vit import (
5
+ _make_pretrained_vitb_rn50_384,
6
+ _make_pretrained_vitl16_384,
7
+ _make_pretrained_vitb16_384,
8
+ forward_vit,
9
+ )
10
+
11
+ def _make_encoder(backbone, features, use_pretrained, groups=1, expand=False, exportable=True, hooks=None, use_vit_only=False, use_readout="ignore",):
12
+ if backbone == "vitl16_384":
13
+ pretrained = _make_pretrained_vitl16_384(
14
+ use_pretrained, hooks=hooks, use_readout=use_readout
15
+ )
16
+ scratch = _make_scratch(
17
+ [256, 512, 1024, 1024], features, groups=groups, expand=expand
18
+ ) # ViT-L/16 - 85.0% Top1 (backbone)
19
+ elif backbone == "vitb_rn50_384":
20
+ pretrained = _make_pretrained_vitb_rn50_384(
21
+ use_pretrained,
22
+ hooks=hooks,
23
+ use_vit_only=use_vit_only,
24
+ use_readout=use_readout,
25
+ )
26
+ scratch = _make_scratch(
27
+ [256, 512, 768, 768], features, groups=groups, expand=expand
28
+ ) # ViT-H/16 - 85.0% Top1 (backbone)
29
+ elif backbone == "vitb16_384":
30
+ pretrained = _make_pretrained_vitb16_384(
31
+ use_pretrained, hooks=hooks, use_readout=use_readout
32
+ )
33
+ scratch = _make_scratch(
34
+ [96, 192, 384, 768], features, groups=groups, expand=expand
35
+ ) # ViT-B/16 - 84.6% Top1 (backbone)
36
+ elif backbone == "resnext101_wsl":
37
+ pretrained = _make_pretrained_resnext101_wsl(use_pretrained)
38
+ scratch = _make_scratch([256, 512, 1024, 2048], features, groups=groups, expand=expand) # efficientnet_lite3
39
+ elif backbone == "efficientnet_lite3":
40
+ pretrained = _make_pretrained_efficientnet_lite3(use_pretrained, exportable=exportable)
41
+ scratch = _make_scratch([32, 48, 136, 384], features, groups=groups, expand=expand) # efficientnet_lite3
42
+ else:
43
+ print(f"Backbone '{backbone}' not implemented")
44
+ assert False
45
+
46
+ return pretrained, scratch
47
+
48
+
49
+ def _make_scratch(in_shape, out_shape, groups=1, expand=False):
50
+ scratch = nn.Module()
51
+
52
+ out_shape1 = out_shape
53
+ out_shape2 = out_shape
54
+ out_shape3 = out_shape
55
+ out_shape4 = out_shape
56
+ if expand==True:
57
+ out_shape1 = out_shape
58
+ out_shape2 = out_shape*2
59
+ out_shape3 = out_shape*4
60
+ out_shape4 = out_shape*8
61
+
62
+ scratch.layer1_rn = nn.Conv2d(
63
+ in_shape[0], out_shape1, kernel_size=3, stride=1, padding=1, bias=False, groups=groups
64
+ )
65
+ scratch.layer2_rn = nn.Conv2d(
66
+ in_shape[1], out_shape2, kernel_size=3, stride=1, padding=1, bias=False, groups=groups
67
+ )
68
+ scratch.layer3_rn = nn.Conv2d(
69
+ in_shape[2], out_shape3, kernel_size=3, stride=1, padding=1, bias=False, groups=groups
70
+ )
71
+ scratch.layer4_rn = nn.Conv2d(
72
+ in_shape[3], out_shape4, kernel_size=3, stride=1, padding=1, bias=False, groups=groups
73
+ )
74
+
75
+ return scratch
76
+
77
+
78
+ def _make_pretrained_efficientnet_lite3(use_pretrained, exportable=False):
79
+ efficientnet = torch.hub.load(
80
+ "rwightman/gen-efficientnet-pytorch",
81
+ "tf_efficientnet_lite3",
82
+ pretrained=use_pretrained,
83
+ exportable=exportable
84
+ )
85
+ return _make_efficientnet_backbone(efficientnet)
86
+
87
+
88
+ def _make_efficientnet_backbone(effnet):
89
+ pretrained = nn.Module()
90
+
91
+ pretrained.layer1 = nn.Sequential(
92
+ effnet.conv_stem, effnet.bn1, effnet.act1, *effnet.blocks[0:2]
93
+ )
94
+ pretrained.layer2 = nn.Sequential(*effnet.blocks[2:3])
95
+ pretrained.layer3 = nn.Sequential(*effnet.blocks[3:5])
96
+ pretrained.layer4 = nn.Sequential(*effnet.blocks[5:9])
97
+
98
+ return pretrained
99
+
100
+
101
+ def _make_resnet_backbone(resnet):
102
+ pretrained = nn.Module()
103
+ pretrained.layer1 = nn.Sequential(
104
+ resnet.conv1, resnet.bn1, resnet.relu, resnet.maxpool, resnet.layer1
105
+ )
106
+
107
+ pretrained.layer2 = resnet.layer2
108
+ pretrained.layer3 = resnet.layer3
109
+ pretrained.layer4 = resnet.layer4
110
+
111
+ return pretrained
112
+
113
+
114
+ def _make_pretrained_resnext101_wsl(use_pretrained):
115
+ resnet = torch.hub.load("facebookresearch/WSL-Images", "resnext101_32x8d_wsl")
116
+ return _make_resnet_backbone(resnet)
117
+
118
+
119
+
120
+ class Interpolate(nn.Module):
121
+ """Interpolation module.
122
+ """
123
+
124
+ def __init__(self, scale_factor, mode, align_corners=False):
125
+ """Init.
126
+
127
+ Args:
128
+ scale_factor (float): scaling
129
+ mode (str): interpolation mode
130
+ """
131
+ super(Interpolate, self).__init__()
132
+
133
+ self.interp = nn.functional.interpolate
134
+ self.scale_factor = scale_factor
135
+ self.mode = mode
136
+ self.align_corners = align_corners
137
+
138
+ def forward(self, x):
139
+ """Forward pass.
140
+
141
+ Args:
142
+ x (tensor): input
143
+
144
+ Returns:
145
+ tensor: interpolated data
146
+ """
147
+
148
+ x = self.interp(
149
+ x, scale_factor=self.scale_factor, mode=self.mode, align_corners=self.align_corners
150
+ )
151
+
152
+ return x
153
+
154
+
155
+ class ResidualConvUnit(nn.Module):
156
+ """Residual convolution module.
157
+ """
158
+
159
+ def __init__(self, features):
160
+ """Init.
161
+
162
+ Args:
163
+ features (int): number of features
164
+ """
165
+ super().__init__()
166
+
167
+ self.conv1 = nn.Conv2d(
168
+ features, features, kernel_size=3, stride=1, padding=1, bias=True
169
+ )
170
+
171
+ self.conv2 = nn.Conv2d(
172
+ features, features, kernel_size=3, stride=1, padding=1, bias=True
173
+ )
174
+
175
+ self.relu = nn.ReLU(inplace=True)
176
+
177
+ def forward(self, x):
178
+ """Forward pass.
179
+
180
+ Args:
181
+ x (tensor): input
182
+
183
+ Returns:
184
+ tensor: output
185
+ """
186
+ out = self.relu(x)
187
+ out = self.conv1(out)
188
+ out = self.relu(out)
189
+ out = self.conv2(out)
190
+
191
+ return out + x
192
+
193
+
194
+ class FeatureFusionBlock(nn.Module):
195
+ """Feature fusion block.
196
+ """
197
+
198
+ def __init__(self, features):
199
+ """Init.
200
+
201
+ Args:
202
+ features (int): number of features
203
+ """
204
+ super(FeatureFusionBlock, self).__init__()
205
+
206
+ self.resConfUnit1 = ResidualConvUnit(features)
207
+ self.resConfUnit2 = ResidualConvUnit(features)
208
+
209
+ def forward(self, *xs):
210
+ """Forward pass.
211
+
212
+ Returns:
213
+ tensor: output
214
+ """
215
+ output = xs[0]
216
+
217
+ if len(xs) == 2:
218
+ output += self.resConfUnit1(xs[1])
219
+
220
+ output = self.resConfUnit2(output)
221
+
222
+ output = nn.functional.interpolate(
223
+ output, scale_factor=2, mode="bilinear", align_corners=True
224
+ )
225
+
226
+ return output
227
+
228
+
229
+
230
+
231
+ class ResidualConvUnit_custom(nn.Module):
232
+ """Residual convolution module.
233
+ """
234
+
235
+ def __init__(self, features, activation, bn):
236
+ """Init.
237
+
238
+ Args:
239
+ features (int): number of features
240
+ """
241
+ super().__init__()
242
+
243
+ self.bn = bn
244
+
245
+ self.groups=1
246
+
247
+ self.conv1 = nn.Conv2d(
248
+ features, features, kernel_size=3, stride=1, padding=1, bias=True, groups=self.groups
249
+ )
250
+
251
+ self.conv2 = nn.Conv2d(
252
+ features, features, kernel_size=3, stride=1, padding=1, bias=True, groups=self.groups
253
+ )
254
+
255
+ if self.bn==True:
256
+ self.bn1 = nn.BatchNorm2d(features)
257
+ self.bn2 = nn.BatchNorm2d(features)
258
+
259
+ self.activation = activation
260
+
261
+ self.skip_add = nn.quantized.FloatFunctional()
262
+
263
+ def forward(self, x):
264
+ """Forward pass.
265
+
266
+ Args:
267
+ x (tensor): input
268
+
269
+ Returns:
270
+ tensor: output
271
+ """
272
+
273
+ out = self.activation(x)
274
+ out = self.conv1(out)
275
+ if self.bn==True:
276
+ out = self.bn1(out)
277
+
278
+ out = self.activation(out)
279
+ out = self.conv2(out)
280
+ if self.bn==True:
281
+ out = self.bn2(out)
282
+
283
+ if self.groups > 1:
284
+ out = self.conv_merge(out)
285
+
286
+ return self.skip_add.add(out, x)
287
+
288
+ # return out + x
289
+
290
+
291
+ class FeatureFusionBlock_custom(nn.Module):
292
+ """Feature fusion block.
293
+ """
294
+
295
+ def __init__(self, features, activation, deconv=False, bn=False, expand=False, align_corners=True):
296
+ """Init.
297
+
298
+ Args:
299
+ features (int): number of features
300
+ """
301
+ super(FeatureFusionBlock_custom, self).__init__()
302
+
303
+ self.deconv = deconv
304
+ self.align_corners = align_corners
305
+
306
+ self.groups=1
307
+
308
+ self.expand = expand
309
+ out_features = features
310
+ if self.expand==True:
311
+ out_features = features//2
312
+
313
+ self.out_conv = nn.Conv2d(features, out_features, kernel_size=1, stride=1, padding=0, bias=True, groups=1)
314
+
315
+ self.resConfUnit1 = ResidualConvUnit_custom(features, activation, bn)
316
+ self.resConfUnit2 = ResidualConvUnit_custom(features, activation, bn)
317
+
318
+ self.skip_add = nn.quantized.FloatFunctional()
319
+
320
+ def forward(self, *xs):
321
+ """Forward pass.
322
+
323
+ Returns:
324
+ tensor: output
325
+ """
326
+ output = xs[0]
327
+
328
+ if len(xs) == 2:
329
+ res = self.resConfUnit1(xs[1])
330
+ output = self.skip_add.add(output, res)
331
+ # output += res
332
+
333
+ output = self.resConfUnit2(output)
334
+
335
+ output = nn.functional.interpolate(
336
+ output, scale_factor=2, mode="bilinear", align_corners=self.align_corners
337
+ )
338
+
339
+ output = self.out_conv(output)
340
+
341
+ return output
342
+
live2diff/MiDaS/midas/dpt_depth.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+
5
+ from .base_model import BaseModel
6
+ from .blocks import (
7
+ FeatureFusionBlock,
8
+ FeatureFusionBlock_custom,
9
+ Interpolate,
10
+ _make_encoder,
11
+ forward_vit,
12
+ )
13
+
14
+
15
+ def _make_fusion_block(features, use_bn):
16
+ return FeatureFusionBlock_custom(
17
+ features,
18
+ nn.ReLU(False),
19
+ deconv=False,
20
+ bn=use_bn,
21
+ expand=False,
22
+ align_corners=True,
23
+ )
24
+
25
+
26
+ class DPT(BaseModel):
27
+ def __init__(
28
+ self,
29
+ head,
30
+ features=256,
31
+ backbone="vitb_rn50_384",
32
+ readout="project",
33
+ channels_last=False,
34
+ use_bn=False,
35
+ ):
36
+
37
+ super(DPT, self).__init__()
38
+
39
+ self.channels_last = channels_last
40
+
41
+ hooks = {
42
+ "vitb_rn50_384": [0, 1, 8, 11],
43
+ "vitb16_384": [2, 5, 8, 11],
44
+ "vitl16_384": [5, 11, 17, 23],
45
+ }
46
+
47
+ # Instantiate backbone and reassemble blocks
48
+ self.pretrained, self.scratch = _make_encoder(
49
+ backbone,
50
+ features,
51
+ False, # Set to true of you want to train from scratch, uses ImageNet weights
52
+ groups=1,
53
+ expand=False,
54
+ exportable=False,
55
+ hooks=hooks[backbone],
56
+ use_readout=readout,
57
+ )
58
+
59
+ self.scratch.refinenet1 = _make_fusion_block(features, use_bn)
60
+ self.scratch.refinenet2 = _make_fusion_block(features, use_bn)
61
+ self.scratch.refinenet3 = _make_fusion_block(features, use_bn)
62
+ self.scratch.refinenet4 = _make_fusion_block(features, use_bn)
63
+
64
+ self.scratch.output_conv = head
65
+
66
+
67
+ def forward(self, x):
68
+ if self.channels_last == True:
69
+ x.contiguous(memory_format=torch.channels_last)
70
+
71
+ layer_1, layer_2, layer_3, layer_4 = forward_vit(self.pretrained, x)
72
+
73
+ layer_1_rn = self.scratch.layer1_rn(layer_1)
74
+ layer_2_rn = self.scratch.layer2_rn(layer_2)
75
+ layer_3_rn = self.scratch.layer3_rn(layer_3)
76
+ layer_4_rn = self.scratch.layer4_rn(layer_4)
77
+
78
+ path_4 = self.scratch.refinenet4(layer_4_rn)
79
+ path_3 = self.scratch.refinenet3(path_4, layer_3_rn)
80
+ path_2 = self.scratch.refinenet2(path_3, layer_2_rn)
81
+ path_1 = self.scratch.refinenet1(path_2, layer_1_rn)
82
+
83
+ out = self.scratch.output_conv(path_1)
84
+
85
+ return out
86
+
87
+
88
+ class DPTDepthModel(DPT):
89
+ def __init__(self, path=None, non_negative=True, **kwargs):
90
+ features = kwargs["features"] if "features" in kwargs else 256
91
+
92
+ head = nn.Sequential(
93
+ nn.Conv2d(features, features // 2, kernel_size=3, stride=1, padding=1),
94
+ Interpolate(scale_factor=2, mode="bilinear", align_corners=True),
95
+ nn.Conv2d(features // 2, 32, kernel_size=3, stride=1, padding=1),
96
+ nn.ReLU(True),
97
+ nn.Conv2d(32, 1, kernel_size=1, stride=1, padding=0),
98
+ nn.ReLU(True) if non_negative else nn.Identity(),
99
+ nn.Identity(),
100
+ )
101
+
102
+ super().__init__(head, **kwargs)
103
+
104
+ if path is not None:
105
+ self.load(path)
106
+
107
+ def forward(self, x):
108
+ return super().forward(x).squeeze(dim=1)
109
+
live2diff/MiDaS/midas/midas_net.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """MidashNet: Network for monocular depth estimation trained by mixing several datasets.
2
+ This file contains code that is adapted from
3
+ https://github.com/thomasjpfan/pytorch_refinenet/blob/master/pytorch_refinenet/refinenet/refinenet_4cascade.py
4
+ """
5
+ import torch
6
+ import torch.nn as nn
7
+
8
+ from .base_model import BaseModel
9
+ from .blocks import FeatureFusionBlock, Interpolate, _make_encoder
10
+
11
+
12
+ class MidasNet(BaseModel):
13
+ """Network for monocular depth estimation.
14
+ """
15
+
16
+ def __init__(self, path=None, features=256, non_negative=True):
17
+ """Init.
18
+
19
+ Args:
20
+ path (str, optional): Path to saved model. Defaults to None.
21
+ features (int, optional): Number of features. Defaults to 256.
22
+ backbone (str, optional): Backbone network for encoder. Defaults to resnet50
23
+ """
24
+ print("Loading weights: ", path)
25
+
26
+ super(MidasNet, self).__init__()
27
+
28
+ use_pretrained = False if path is None else True
29
+
30
+ self.pretrained, self.scratch = _make_encoder(backbone="resnext101_wsl", features=features, use_pretrained=use_pretrained)
31
+
32
+ self.scratch.refinenet4 = FeatureFusionBlock(features)
33
+ self.scratch.refinenet3 = FeatureFusionBlock(features)
34
+ self.scratch.refinenet2 = FeatureFusionBlock(features)
35
+ self.scratch.refinenet1 = FeatureFusionBlock(features)
36
+
37
+ self.scratch.output_conv = nn.Sequential(
38
+ nn.Conv2d(features, 128, kernel_size=3, stride=1, padding=1),
39
+ Interpolate(scale_factor=2, mode="bilinear"),
40
+ nn.Conv2d(128, 32, kernel_size=3, stride=1, padding=1),
41
+ nn.ReLU(True),
42
+ nn.Conv2d(32, 1, kernel_size=1, stride=1, padding=0),
43
+ nn.ReLU(True) if non_negative else nn.Identity(),
44
+ )
45
+
46
+ if path:
47
+ self.load(path)
48
+
49
+ def forward(self, x):
50
+ """Forward pass.
51
+
52
+ Args:
53
+ x (tensor): input data (image)
54
+
55
+ Returns:
56
+ tensor: depth
57
+ """
58
+
59
+ layer_1 = self.pretrained.layer1(x)
60
+ layer_2 = self.pretrained.layer2(layer_1)
61
+ layer_3 = self.pretrained.layer3(layer_2)
62
+ layer_4 = self.pretrained.layer4(layer_3)
63
+
64
+ layer_1_rn = self.scratch.layer1_rn(layer_1)
65
+ layer_2_rn = self.scratch.layer2_rn(layer_2)
66
+ layer_3_rn = self.scratch.layer3_rn(layer_3)
67
+ layer_4_rn = self.scratch.layer4_rn(layer_4)
68
+
69
+ path_4 = self.scratch.refinenet4(layer_4_rn)
70
+ path_3 = self.scratch.refinenet3(path_4, layer_3_rn)
71
+ path_2 = self.scratch.refinenet2(path_3, layer_2_rn)
72
+ path_1 = self.scratch.refinenet1(path_2, layer_1_rn)
73
+
74
+ out = self.scratch.output_conv(path_1)
75
+
76
+ return torch.squeeze(out, dim=1)
live2diff/MiDaS/midas/midas_net_custom.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """MidashNet: Network for monocular depth estimation trained by mixing several datasets.
2
+ This file contains code that is adapted from
3
+ https://github.com/thomasjpfan/pytorch_refinenet/blob/master/pytorch_refinenet/refinenet/refinenet_4cascade.py
4
+ """
5
+ import torch
6
+ import torch.nn as nn
7
+
8
+ from .base_model import BaseModel
9
+ from .blocks import FeatureFusionBlock, FeatureFusionBlock_custom, Interpolate, _make_encoder
10
+
11
+
12
+ class MidasNet_small(BaseModel):
13
+ """Network for monocular depth estimation.
14
+ """
15
+
16
+ def __init__(self, path=None, features=64, backbone="efficientnet_lite3", non_negative=True, exportable=True, channels_last=False, align_corners=True,
17
+ blocks={'expand': True}):
18
+ """Init.
19
+
20
+ Args:
21
+ path (str, optional): Path to saved model. Defaults to None.
22
+ features (int, optional): Number of features. Defaults to 256.
23
+ backbone (str, optional): Backbone network for encoder. Defaults to resnet50
24
+ """
25
+ print("Loading weights: ", path)
26
+
27
+ super(MidasNet_small, self).__init__()
28
+
29
+ use_pretrained = False if path else True
30
+
31
+ self.channels_last = channels_last
32
+ self.blocks = blocks
33
+ self.backbone = backbone
34
+
35
+ self.groups = 1
36
+
37
+ features1=features
38
+ features2=features
39
+ features3=features
40
+ features4=features
41
+ self.expand = False
42
+ if "expand" in self.blocks and self.blocks['expand'] == True:
43
+ self.expand = True
44
+ features1=features
45
+ features2=features*2
46
+ features3=features*4
47
+ features4=features*8
48
+
49
+ self.pretrained, self.scratch = _make_encoder(self.backbone, features, use_pretrained, groups=self.groups, expand=self.expand, exportable=exportable)
50
+
51
+ self.scratch.activation = nn.ReLU(False)
52
+
53
+ self.scratch.refinenet4 = FeatureFusionBlock_custom(features4, self.scratch.activation, deconv=False, bn=False, expand=self.expand, align_corners=align_corners)
54
+ self.scratch.refinenet3 = FeatureFusionBlock_custom(features3, self.scratch.activation, deconv=False, bn=False, expand=self.expand, align_corners=align_corners)
55
+ self.scratch.refinenet2 = FeatureFusionBlock_custom(features2, self.scratch.activation, deconv=False, bn=False, expand=self.expand, align_corners=align_corners)
56
+ self.scratch.refinenet1 = FeatureFusionBlock_custom(features1, self.scratch.activation, deconv=False, bn=False, align_corners=align_corners)
57
+
58
+
59
+ self.scratch.output_conv = nn.Sequential(
60
+ nn.Conv2d(features, features//2, kernel_size=3, stride=1, padding=1, groups=self.groups),
61
+ Interpolate(scale_factor=2, mode="bilinear"),
62
+ nn.Conv2d(features//2, 32, kernel_size=3, stride=1, padding=1),
63
+ self.scratch.activation,
64
+ nn.Conv2d(32, 1, kernel_size=1, stride=1, padding=0),
65
+ nn.ReLU(True) if non_negative else nn.Identity(),
66
+ nn.Identity(),
67
+ )
68
+
69
+ if path:
70
+ self.load(path)
71
+
72
+
73
+ def forward(self, x):
74
+ """Forward pass.
75
+
76
+ Args:
77
+ x (tensor): input data (image)
78
+
79
+ Returns:
80
+ tensor: depth
81
+ """
82
+ if self.channels_last==True:
83
+ print("self.channels_last = ", self.channels_last)
84
+ x.contiguous(memory_format=torch.channels_last)
85
+
86
+
87
+ layer_1 = self.pretrained.layer1(x)
88
+ layer_2 = self.pretrained.layer2(layer_1)
89
+ layer_3 = self.pretrained.layer3(layer_2)
90
+ layer_4 = self.pretrained.layer4(layer_3)
91
+
92
+ layer_1_rn = self.scratch.layer1_rn(layer_1)
93
+ layer_2_rn = self.scratch.layer2_rn(layer_2)
94
+ layer_3_rn = self.scratch.layer3_rn(layer_3)
95
+ layer_4_rn = self.scratch.layer4_rn(layer_4)
96
+
97
+
98
+ path_4 = self.scratch.refinenet4(layer_4_rn)
99
+ path_3 = self.scratch.refinenet3(path_4, layer_3_rn)
100
+ path_2 = self.scratch.refinenet2(path_3, layer_2_rn)
101
+ path_1 = self.scratch.refinenet1(path_2, layer_1_rn)
102
+
103
+ out = self.scratch.output_conv(path_1)
104
+
105
+ return torch.squeeze(out, dim=1)
106
+
107
+
108
+
109
+ def fuse_model(m):
110
+ prev_previous_type = nn.Identity()
111
+ prev_previous_name = ''
112
+ previous_type = nn.Identity()
113
+ previous_name = ''
114
+ for name, module in m.named_modules():
115
+ if prev_previous_type == nn.Conv2d and previous_type == nn.BatchNorm2d and type(module) == nn.ReLU:
116
+ # print("FUSED ", prev_previous_name, previous_name, name)
117
+ torch.quantization.fuse_modules(m, [prev_previous_name, previous_name, name], inplace=True)
118
+ elif prev_previous_type == nn.Conv2d and previous_type == nn.BatchNorm2d:
119
+ # print("FUSED ", prev_previous_name, previous_name)
120
+ torch.quantization.fuse_modules(m, [prev_previous_name, previous_name], inplace=True)
121
+ # elif previous_type == nn.Conv2d and type(module) == nn.ReLU:
122
+ # print("FUSED ", previous_name, name)
123
+ # torch.quantization.fuse_modules(m, [previous_name, name], inplace=True)
124
+
125
+ prev_previous_type = previous_type
126
+ prev_previous_name = previous_name
127
+ previous_type = type(module)
128
+ previous_name = name
live2diff/MiDaS/midas/transforms.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import cv2
3
+ import math
4
+
5
+
6
+ def apply_min_size(sample, size, image_interpolation_method=cv2.INTER_AREA):
7
+ """Rezise the sample to ensure the given size. Keeps aspect ratio.
8
+
9
+ Args:
10
+ sample (dict): sample
11
+ size (tuple): image size
12
+
13
+ Returns:
14
+ tuple: new size
15
+ """
16
+ shape = list(sample["disparity"].shape)
17
+
18
+ if shape[0] >= size[0] and shape[1] >= size[1]:
19
+ return sample
20
+
21
+ scale = [0, 0]
22
+ scale[0] = size[0] / shape[0]
23
+ scale[1] = size[1] / shape[1]
24
+
25
+ scale = max(scale)
26
+
27
+ shape[0] = math.ceil(scale * shape[0])
28
+ shape[1] = math.ceil(scale * shape[1])
29
+
30
+ # resize
31
+ sample["image"] = cv2.resize(
32
+ sample["image"], tuple(shape[::-1]), interpolation=image_interpolation_method
33
+ )
34
+
35
+ sample["disparity"] = cv2.resize(
36
+ sample["disparity"], tuple(shape[::-1]), interpolation=cv2.INTER_NEAREST
37
+ )
38
+ sample["mask"] = cv2.resize(
39
+ sample["mask"].astype(np.float32),
40
+ tuple(shape[::-1]),
41
+ interpolation=cv2.INTER_NEAREST,
42
+ )
43
+ sample["mask"] = sample["mask"].astype(bool)
44
+
45
+ return tuple(shape)
46
+
47
+
48
+ class Resize(object):
49
+ """Resize sample to given size (width, height).
50
+ """
51
+
52
+ def __init__(
53
+ self,
54
+ width,
55
+ height,
56
+ resize_target=True,
57
+ keep_aspect_ratio=False,
58
+ ensure_multiple_of=1,
59
+ resize_method="lower_bound",
60
+ image_interpolation_method=cv2.INTER_AREA,
61
+ ):
62
+ """Init.
63
+
64
+ Args:
65
+ width (int): desired output width
66
+ height (int): desired output height
67
+ resize_target (bool, optional):
68
+ True: Resize the full sample (image, mask, target).
69
+ False: Resize image only.
70
+ Defaults to True.
71
+ keep_aspect_ratio (bool, optional):
72
+ True: Keep the aspect ratio of the input sample.
73
+ Output sample might not have the given width and height, and
74
+ resize behaviour depends on the parameter 'resize_method'.
75
+ Defaults to False.
76
+ ensure_multiple_of (int, optional):
77
+ Output width and height is constrained to be multiple of this parameter.
78
+ Defaults to 1.
79
+ resize_method (str, optional):
80
+ "lower_bound": Output will be at least as large as the given size.
81
+ "upper_bound": Output will be at max as large as the given size. (Output size might be smaller than given size.)
82
+ "minimal": Scale as least as possible. (Output size might be smaller than given size.)
83
+ Defaults to "lower_bound".
84
+ """
85
+ self.__width = width
86
+ self.__height = height
87
+
88
+ self.__resize_target = resize_target
89
+ self.__keep_aspect_ratio = keep_aspect_ratio
90
+ self.__multiple_of = ensure_multiple_of
91
+ self.__resize_method = resize_method
92
+ self.__image_interpolation_method = image_interpolation_method
93
+
94
+ def constrain_to_multiple_of(self, x, min_val=0, max_val=None):
95
+ y = (np.round(x / self.__multiple_of) * self.__multiple_of).astype(int)
96
+
97
+ if max_val is not None and y > max_val:
98
+ y = (np.floor(x / self.__multiple_of) * self.__multiple_of).astype(int)
99
+
100
+ if y < min_val:
101
+ y = (np.ceil(x / self.__multiple_of) * self.__multiple_of).astype(int)
102
+
103
+ return y
104
+
105
+ def get_size(self, width, height):
106
+ # determine new height and width
107
+ scale_height = self.__height / height
108
+ scale_width = self.__width / width
109
+
110
+ if self.__keep_aspect_ratio:
111
+ if self.__resize_method == "lower_bound":
112
+ # scale such that output size is lower bound
113
+ if scale_width > scale_height:
114
+ # fit width
115
+ scale_height = scale_width
116
+ else:
117
+ # fit height
118
+ scale_width = scale_height
119
+ elif self.__resize_method == "upper_bound":
120
+ # scale such that output size is upper bound
121
+ if scale_width < scale_height:
122
+ # fit width
123
+ scale_height = scale_width
124
+ else:
125
+ # fit height
126
+ scale_width = scale_height
127
+ elif self.__resize_method == "minimal":
128
+ # scale as least as possbile
129
+ if abs(1 - scale_width) < abs(1 - scale_height):
130
+ # fit width
131
+ scale_height = scale_width
132
+ else:
133
+ # fit height
134
+ scale_width = scale_height
135
+ else:
136
+ raise ValueError(
137
+ f"resize_method {self.__resize_method} not implemented"
138
+ )
139
+
140
+ if self.__resize_method == "lower_bound":
141
+ new_height = self.constrain_to_multiple_of(
142
+ scale_height * height, min_val=self.__height
143
+ )
144
+ new_width = self.constrain_to_multiple_of(
145
+ scale_width * width, min_val=self.__width
146
+ )
147
+ elif self.__resize_method == "upper_bound":
148
+ new_height = self.constrain_to_multiple_of(
149
+ scale_height * height, max_val=self.__height
150
+ )
151
+ new_width = self.constrain_to_multiple_of(
152
+ scale_width * width, max_val=self.__width
153
+ )
154
+ elif self.__resize_method == "minimal":
155
+ new_height = self.constrain_to_multiple_of(scale_height * height)
156
+ new_width = self.constrain_to_multiple_of(scale_width * width)
157
+ else:
158
+ raise ValueError(f"resize_method {self.__resize_method} not implemented")
159
+
160
+ return (new_width, new_height)
161
+
162
+ def __call__(self, sample):
163
+ width, height = self.get_size(
164
+ sample["image"].shape[1], sample["image"].shape[0]
165
+ )
166
+
167
+ # resize sample
168
+ sample["image"] = cv2.resize(
169
+ sample["image"],
170
+ (width, height),
171
+ interpolation=self.__image_interpolation_method,
172
+ )
173
+
174
+ if self.__resize_target:
175
+ if "disparity" in sample:
176
+ sample["disparity"] = cv2.resize(
177
+ sample["disparity"],
178
+ (width, height),
179
+ interpolation=cv2.INTER_NEAREST,
180
+ )
181
+
182
+ if "depth" in sample:
183
+ sample["depth"] = cv2.resize(
184
+ sample["depth"], (width, height), interpolation=cv2.INTER_NEAREST
185
+ )
186
+
187
+ sample["mask"] = cv2.resize(
188
+ sample["mask"].astype(np.float32),
189
+ (width, height),
190
+ interpolation=cv2.INTER_NEAREST,
191
+ )
192
+ sample["mask"] = sample["mask"].astype(bool)
193
+
194
+ return sample
195
+
196
+
197
+ class NormalizeImage(object):
198
+ """Normlize image by given mean and std.
199
+ """
200
+
201
+ def __init__(self, mean, std):
202
+ self.__mean = mean
203
+ self.__std = std
204
+
205
+ def __call__(self, sample):
206
+ sample["image"] = (sample["image"] - self.__mean) / self.__std
207
+
208
+ return sample
209
+
210
+
211
+ class PrepareForNet(object):
212
+ """Prepare sample for usage as network input.
213
+ """
214
+
215
+ def __init__(self):
216
+ pass
217
+
218
+ def __call__(self, sample):
219
+ image = np.transpose(sample["image"], (2, 0, 1))
220
+ sample["image"] = np.ascontiguousarray(image).astype(np.float32)
221
+
222
+ if "mask" in sample:
223
+ sample["mask"] = sample["mask"].astype(np.float32)
224
+ sample["mask"] = np.ascontiguousarray(sample["mask"])
225
+
226
+ if "disparity" in sample:
227
+ disparity = sample["disparity"].astype(np.float32)
228
+ sample["disparity"] = np.ascontiguousarray(disparity)
229
+
230
+ if "depth" in sample:
231
+ depth = sample["depth"].astype(np.float32)
232
+ sample["depth"] = np.ascontiguousarray(depth)
233
+
234
+ return sample
live2diff/MiDaS/midas/vit.py ADDED
@@ -0,0 +1,503 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import timm
4
+ import types
5
+ import math
6
+ import torch.nn.functional as F
7
+
8
+
9
+ class Slice(nn.Module):
10
+ def __init__(self, start_index=1):
11
+ super(Slice, self).__init__()
12
+ self.start_index = start_index
13
+
14
+ def forward(self, x):
15
+ return x[:, self.start_index :]
16
+
17
+
18
+ class AddReadout(nn.Module):
19
+ def __init__(self, start_index=1):
20
+ super(AddReadout, self).__init__()
21
+ self.start_index = start_index
22
+
23
+ def forward(self, x):
24
+ if self.start_index == 2:
25
+ readout = (x[:, 0] + x[:, 1]) / 2
26
+ else:
27
+ readout = x[:, 0]
28
+ return x[:, self.start_index :] + readout.unsqueeze(1)
29
+
30
+
31
+ class ProjectReadout(nn.Module):
32
+ def __init__(self, in_features, start_index=1):
33
+ super(ProjectReadout, self).__init__()
34
+ self.start_index = start_index
35
+
36
+ self.project = nn.Sequential(nn.Linear(2 * in_features, in_features), nn.GELU())
37
+
38
+ def forward(self, x):
39
+ readout = x[:, 0].unsqueeze(1).expand_as(x[:, self.start_index :])
40
+ features = torch.cat((x[:, self.start_index :], readout), -1)
41
+
42
+ return self.project(features)
43
+
44
+
45
+ class Transpose(nn.Module):
46
+ def __init__(self, dim0, dim1):
47
+ super(Transpose, self).__init__()
48
+ self.dim0 = dim0
49
+ self.dim1 = dim1
50
+
51
+ def forward(self, x):
52
+ x = x.transpose(self.dim0, self.dim1)
53
+ return x
54
+
55
+ class View(nn.Module):
56
+ def __init__(self, dim, shape):
57
+ super(View, self).__init__()
58
+ self.dim = dim
59
+ self.shape = shape
60
+
61
+ def forward(self, input):
62
+ new_shape = list(input.shape)[:self.dim] + list(self.shape) + list(input.shape)[self.dim+1:]
63
+ return input.view(*new_shape)
64
+
65
+
66
+ nn.Unflatten = View
67
+
68
+ def forward_vit(pretrained, x):
69
+ b, c, h, w = x.shape
70
+
71
+ glob = pretrained.model.forward_flex(x)
72
+
73
+ layer_1 = pretrained.activations["1"]
74
+ layer_2 = pretrained.activations["2"]
75
+ layer_3 = pretrained.activations["3"]
76
+ layer_4 = pretrained.activations["4"]
77
+
78
+ layer_1 = pretrained.act_postprocess1[0:2](layer_1)
79
+ layer_2 = pretrained.act_postprocess2[0:2](layer_2)
80
+ layer_3 = pretrained.act_postprocess3[0:2](layer_3)
81
+ layer_4 = pretrained.act_postprocess4[0:2](layer_4)
82
+
83
+ unflatten = nn.Sequential(
84
+ nn.Unflatten(
85
+ 2,
86
+ torch.Size(
87
+ [
88
+ h // pretrained.model.patch_size[1],
89
+ w // pretrained.model.patch_size[0],
90
+ ]
91
+ ),
92
+ )
93
+ )
94
+
95
+ if layer_1.ndim == 3:
96
+ layer_1 = unflatten(layer_1)
97
+ if layer_2.ndim == 3:
98
+ layer_2 = unflatten(layer_2)
99
+ if layer_3.ndim == 3:
100
+ layer_3 = unflatten(layer_3)
101
+ if layer_4.ndim == 3:
102
+ layer_4 = unflatten(layer_4)
103
+
104
+ layer_1 = pretrained.act_postprocess1[3 : len(pretrained.act_postprocess1)](layer_1)
105
+ layer_2 = pretrained.act_postprocess2[3 : len(pretrained.act_postprocess2)](layer_2)
106
+ layer_3 = pretrained.act_postprocess3[3 : len(pretrained.act_postprocess3)](layer_3)
107
+ layer_4 = pretrained.act_postprocess4[3 : len(pretrained.act_postprocess4)](layer_4)
108
+
109
+ return layer_1, layer_2, layer_3, layer_4
110
+
111
+
112
+ def _resize_pos_embed(self, posemb, gs_h, gs_w):
113
+ posemb_tok, posemb_grid = (
114
+ posemb[:, : self.start_index],
115
+ posemb[0, self.start_index :],
116
+ )
117
+
118
+ gs_old = int(math.sqrt(len(posemb_grid)))
119
+
120
+ posemb_grid = posemb_grid.reshape(1, gs_old, gs_old, -1).permute(0, 3, 1, 2)
121
+ posemb_grid = F.interpolate(posemb_grid, size=(gs_h, gs_w), mode="bilinear")
122
+ posemb_grid = posemb_grid.permute(0, 2, 3, 1).reshape(1, gs_h * gs_w, -1)
123
+
124
+ posemb = torch.cat([posemb_tok, posemb_grid], dim=1)
125
+
126
+ return posemb
127
+
128
+
129
+ def forward_flex(self, x):
130
+ b, c, h, w = x.shape
131
+
132
+ pos_embed = self._resize_pos_embed(
133
+ self.pos_embed, h // self.patch_size[1], w // self.patch_size[0]
134
+ )
135
+
136
+ B = x.shape[0]
137
+
138
+ if hasattr(self.patch_embed, "backbone"):
139
+ x = self.patch_embed.backbone(x)
140
+ if isinstance(x, (list, tuple)):
141
+ x = x[-1] # last feature if backbone outputs list/tuple of features
142
+
143
+ x = self.patch_embed.proj(x).flatten(2).transpose(1, 2)
144
+
145
+ if getattr(self, "dist_token", None) is not None:
146
+ cls_tokens = self.cls_token.expand(
147
+ B, -1, -1
148
+ ) # stole cls_tokens impl from Phil Wang, thanks
149
+ dist_token = self.dist_token.expand(B, -1, -1)
150
+ x = torch.cat((cls_tokens, dist_token, x), dim=1)
151
+ else:
152
+ cls_tokens = self.cls_token.expand(
153
+ B, -1, -1
154
+ ) # stole cls_tokens impl from Phil Wang, thanks
155
+ x = torch.cat((cls_tokens, x), dim=1)
156
+
157
+ x = x + pos_embed
158
+ x = self.pos_drop(x)
159
+
160
+ for blk in self.blocks:
161
+ x = blk(x)
162
+
163
+ x = self.norm(x)
164
+
165
+ return x
166
+
167
+
168
+ activations = {}
169
+
170
+
171
+ def get_activation(name):
172
+ def hook(model, input, output):
173
+ activations[name] = output
174
+
175
+ return hook
176
+
177
+
178
+ def get_readout_oper(vit_features, features, use_readout, start_index=1):
179
+ if use_readout == "ignore":
180
+ readout_oper = [Slice(start_index)] * len(features)
181
+ elif use_readout == "add":
182
+ readout_oper = [AddReadout(start_index)] * len(features)
183
+ elif use_readout == "project":
184
+ readout_oper = [
185
+ ProjectReadout(vit_features, start_index) for out_feat in features
186
+ ]
187
+ else:
188
+ assert (
189
+ False
190
+ ), "wrong operation for readout token, use_readout can be 'ignore', 'add', or 'project'"
191
+
192
+ return readout_oper
193
+
194
+
195
+ def _make_vit_b16_backbone(
196
+ model,
197
+ features=[96, 192, 384, 768],
198
+ size=[384, 384],
199
+ hooks=[2, 5, 8, 11],
200
+ vit_features=768,
201
+ use_readout="ignore",
202
+ start_index=1,
203
+ ):
204
+ pretrained = nn.Module()
205
+
206
+ pretrained.model = model
207
+ pretrained.model.blocks[hooks[0]].register_forward_hook(get_activation("1"))
208
+ pretrained.model.blocks[hooks[1]].register_forward_hook(get_activation("2"))
209
+ pretrained.model.blocks[hooks[2]].register_forward_hook(get_activation("3"))
210
+ pretrained.model.blocks[hooks[3]].register_forward_hook(get_activation("4"))
211
+
212
+ pretrained.activations = activations
213
+
214
+ readout_oper = get_readout_oper(vit_features, features, use_readout, start_index)
215
+
216
+ # 32, 48, 136, 384
217
+ pretrained.act_postprocess1 = nn.Sequential(
218
+ readout_oper[0],
219
+ Transpose(1, 2),
220
+ nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])),
221
+ nn.Conv2d(
222
+ in_channels=vit_features,
223
+ out_channels=features[0],
224
+ kernel_size=1,
225
+ stride=1,
226
+ padding=0,
227
+ ),
228
+ nn.ConvTranspose2d(
229
+ in_channels=features[0],
230
+ out_channels=features[0],
231
+ kernel_size=4,
232
+ stride=4,
233
+ padding=0,
234
+ bias=True,
235
+ dilation=1,
236
+ groups=1,
237
+ ),
238
+ )
239
+
240
+ pretrained.act_postprocess2 = nn.Sequential(
241
+ readout_oper[1],
242
+ Transpose(1, 2),
243
+ nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])),
244
+ nn.Conv2d(
245
+ in_channels=vit_features,
246
+ out_channels=features[1],
247
+ kernel_size=1,
248
+ stride=1,
249
+ padding=0,
250
+ ),
251
+ nn.ConvTranspose2d(
252
+ in_channels=features[1],
253
+ out_channels=features[1],
254
+ kernel_size=2,
255
+ stride=2,
256
+ padding=0,
257
+ bias=True,
258
+ dilation=1,
259
+ groups=1,
260
+ ),
261
+ )
262
+
263
+ pretrained.act_postprocess3 = nn.Sequential(
264
+ readout_oper[2],
265
+ Transpose(1, 2),
266
+ nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])),
267
+ nn.Conv2d(
268
+ in_channels=vit_features,
269
+ out_channels=features[2],
270
+ kernel_size=1,
271
+ stride=1,
272
+ padding=0,
273
+ ),
274
+ )
275
+
276
+ pretrained.act_postprocess4 = nn.Sequential(
277
+ readout_oper[3],
278
+ Transpose(1, 2),
279
+ nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])),
280
+ nn.Conv2d(
281
+ in_channels=vit_features,
282
+ out_channels=features[3],
283
+ kernel_size=1,
284
+ stride=1,
285
+ padding=0,
286
+ ),
287
+ nn.Conv2d(
288
+ in_channels=features[3],
289
+ out_channels=features[3],
290
+ kernel_size=3,
291
+ stride=2,
292
+ padding=1,
293
+ ),
294
+ )
295
+
296
+ pretrained.model.start_index = start_index
297
+ pretrained.model.patch_size = [16, 16]
298
+
299
+ # We inject this function into the VisionTransformer instances so that
300
+ # we can use it with interpolated position embeddings without modifying the library source.
301
+ pretrained.model.forward_flex = types.MethodType(forward_flex, pretrained.model)
302
+ pretrained.model._resize_pos_embed = types.MethodType(
303
+ _resize_pos_embed, pretrained.model
304
+ )
305
+
306
+ return pretrained
307
+
308
+
309
+ def _make_pretrained_vitl16_384(pretrained, use_readout="ignore", hooks=None):
310
+ model = timm.create_model("vit_large_patch16_384", pretrained=pretrained)
311
+
312
+ hooks = [5, 11, 17, 23] if hooks == None else hooks
313
+ return _make_vit_b16_backbone(
314
+ model,
315
+ features=[256, 512, 1024, 1024],
316
+ hooks=hooks,
317
+ vit_features=1024,
318
+ use_readout=use_readout,
319
+ )
320
+
321
+
322
+ def _make_pretrained_vitb16_384(pretrained, use_readout="ignore", hooks=None):
323
+ model = timm.create_model("vit_base_patch16_384", pretrained=pretrained)
324
+
325
+ hooks = [2, 5, 8, 11] if hooks == None else hooks
326
+ return _make_vit_b16_backbone(
327
+ model, features=[96, 192, 384, 768], hooks=hooks, use_readout=use_readout
328
+ )
329
+
330
+
331
+ def _make_pretrained_deitb16_384(pretrained, use_readout="ignore", hooks=None):
332
+ model = timm.create_model("vit_deit_base_patch16_384", pretrained=pretrained)
333
+
334
+ hooks = [2, 5, 8, 11] if hooks == None else hooks
335
+ return _make_vit_b16_backbone(
336
+ model, features=[96, 192, 384, 768], hooks=hooks, use_readout=use_readout
337
+ )
338
+
339
+
340
+ def _make_pretrained_deitb16_distil_384(pretrained, use_readout="ignore", hooks=None):
341
+ model = timm.create_model(
342
+ "vit_deit_base_distilled_patch16_384", pretrained=pretrained
343
+ )
344
+
345
+ hooks = [2, 5, 8, 11] if hooks == None else hooks
346
+ return _make_vit_b16_backbone(
347
+ model,
348
+ features=[96, 192, 384, 768],
349
+ hooks=hooks,
350
+ use_readout=use_readout,
351
+ start_index=2,
352
+ )
353
+
354
+
355
+ def _make_vit_b_rn50_backbone(
356
+ model,
357
+ features=[256, 512, 768, 768],
358
+ size=[384, 384],
359
+ hooks=[0, 1, 8, 11],
360
+ vit_features=768,
361
+ use_vit_only=False,
362
+ use_readout="ignore",
363
+ start_index=1,
364
+ ):
365
+ pretrained = nn.Module()
366
+
367
+ pretrained.model = model
368
+
369
+ if use_vit_only == True:
370
+ pretrained.model.blocks[hooks[0]].register_forward_hook(get_activation("1"))
371
+ pretrained.model.blocks[hooks[1]].register_forward_hook(get_activation("2"))
372
+ else:
373
+ pretrained.model.patch_embed.backbone.stages[0].register_forward_hook(
374
+ get_activation("1")
375
+ )
376
+ pretrained.model.patch_embed.backbone.stages[1].register_forward_hook(
377
+ get_activation("2")
378
+ )
379
+
380
+ pretrained.model.blocks[hooks[2]].register_forward_hook(get_activation("3"))
381
+ pretrained.model.blocks[hooks[3]].register_forward_hook(get_activation("4"))
382
+
383
+ pretrained.activations = activations
384
+
385
+ readout_oper = get_readout_oper(vit_features, features, use_readout, start_index)
386
+
387
+ if use_vit_only == True:
388
+ pretrained.act_postprocess1 = nn.Sequential(
389
+ readout_oper[0],
390
+ Transpose(1, 2),
391
+ nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])),
392
+ nn.Conv2d(
393
+ in_channels=vit_features,
394
+ out_channels=features[0],
395
+ kernel_size=1,
396
+ stride=1,
397
+ padding=0,
398
+ ),
399
+ nn.ConvTranspose2d(
400
+ in_channels=features[0],
401
+ out_channels=features[0],
402
+ kernel_size=4,
403
+ stride=4,
404
+ padding=0,
405
+ bias=True,
406
+ dilation=1,
407
+ groups=1,
408
+ ),
409
+ )
410
+
411
+ pretrained.act_postprocess2 = nn.Sequential(
412
+ readout_oper[1],
413
+ Transpose(1, 2),
414
+ nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])),
415
+ nn.Conv2d(
416
+ in_channels=vit_features,
417
+ out_channels=features[1],
418
+ kernel_size=1,
419
+ stride=1,
420
+ padding=0,
421
+ ),
422
+ nn.ConvTranspose2d(
423
+ in_channels=features[1],
424
+ out_channels=features[1],
425
+ kernel_size=2,
426
+ stride=2,
427
+ padding=0,
428
+ bias=True,
429
+ dilation=1,
430
+ groups=1,
431
+ ),
432
+ )
433
+ else:
434
+ pretrained.act_postprocess1 = nn.Sequential(
435
+ nn.Identity(), nn.Identity(), nn.Identity()
436
+ )
437
+ pretrained.act_postprocess2 = nn.Sequential(
438
+ nn.Identity(), nn.Identity(), nn.Identity()
439
+ )
440
+
441
+ pretrained.act_postprocess3 = nn.Sequential(
442
+ readout_oper[2],
443
+ Transpose(1, 2),
444
+ nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])),
445
+ nn.Conv2d(
446
+ in_channels=vit_features,
447
+ out_channels=features[2],
448
+ kernel_size=1,
449
+ stride=1,
450
+ padding=0,
451
+ ),
452
+ )
453
+
454
+ pretrained.act_postprocess4 = nn.Sequential(
455
+ readout_oper[3],
456
+ Transpose(1, 2),
457
+ nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])),
458
+ nn.Conv2d(
459
+ in_channels=vit_features,
460
+ out_channels=features[3],
461
+ kernel_size=1,
462
+ stride=1,
463
+ padding=0,
464
+ ),
465
+ nn.Conv2d(
466
+ in_channels=features[3],
467
+ out_channels=features[3],
468
+ kernel_size=3,
469
+ stride=2,
470
+ padding=1,
471
+ ),
472
+ )
473
+
474
+ pretrained.model.start_index = start_index
475
+ pretrained.model.patch_size = [16, 16]
476
+
477
+ # We inject this function into the VisionTransformer instances so that
478
+ # we can use it with interpolated position embeddings without modifying the library source.
479
+ pretrained.model.forward_flex = types.MethodType(forward_flex, pretrained.model)
480
+
481
+ # We inject this function into the VisionTransformer instances so that
482
+ # we can use it with interpolated position embeddings without modifying the library source.
483
+ pretrained.model._resize_pos_embed = types.MethodType(
484
+ _resize_pos_embed, pretrained.model
485
+ )
486
+
487
+ return pretrained
488
+
489
+
490
+ def _make_pretrained_vitb_rn50_384(
491
+ pretrained, use_readout="ignore", hooks=None, use_vit_only=False
492
+ ):
493
+ model = timm.create_model("vit_base_resnet50_384", pretrained=pretrained)
494
+
495
+ hooks = [0, 1, 8, 11] if hooks == None else hooks
496
+ return _make_vit_b_rn50_backbone(
497
+ model,
498
+ features=[256, 512, 768, 768],
499
+ size=[384, 384],
500
+ hooks=hooks,
501
+ use_vit_only=use_vit_only,
502
+ use_readout=use_readout,
503
+ )
live2diff/MiDaS/mobile/README.md ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Mobile version of MiDaS for iOS / Android - Monocular Depth Estimation
2
+
3
+ ### Accuracy
4
+
5
+ * Old small model - ResNet50 default-decoder 384x384
6
+ * New small model - EfficientNet-Lite3 small-decoder 256x256
7
+
8
+ **Zero-shot error** (the lower - the better):
9
+
10
+ | Model | DIW WHDR | Eth3d AbsRel | Sintel AbsRel | Kitti δ>1.25 | NyuDepthV2 δ>1.25 | TUM δ>1.25 |
11
+ |---|---|---|---|---|---|---|
12
+ | Old small model 384x384 | **0.1248** | 0.1550 | **0.3300** | **21.81** | 15.73 | 17.00 |
13
+ | New small model 256x256 | 0.1344 | **0.1344** | 0.3370 | 29.27 | **13.43** | **14.53** |
14
+ | Relative improvement, % | -8 % | **+13 %** | -2 % | -34 % | **+15 %** | **+15 %** |
15
+
16
+ None of Train/Valid/Test subsets of datasets (DIW, Eth3d, Sintel, Kitti, NyuDepthV2, TUM) were not involved in Training or Fine Tuning.
17
+
18
+ ### Inference speed (FPS) on iOS / Android
19
+
20
+ **Frames Per Second** (the higher - the better):
21
+
22
+ | Model | iPhone CPU | iPhone GPU | iPhone NPU | OnePlus8 CPU | OnePlus8 GPU | OnePlus8 NNAPI |
23
+ |---|---|---|---|---|---|---|
24
+ | Old small model 384x384 | 0.6 | N/A | N/A | 0.45 | 0.50 | 0.50 |
25
+ | New small model 256x256 | 8 | 22 | **30** | 6 | **22** | 4 |
26
+ | SpeedUp, X times | **12.8x** | - | - | **13.2x** | **44x** | **8x** |
27
+
28
+ N/A - run-time error (no data available)
29
+
30
+
31
+ #### Models:
32
+
33
+ * Old small model - ResNet50 default-decoder 1x384x384x3, batch=1 FP32 (converters: Pytorch -> ONNX - [onnx_tf](https://github.com/onnx/onnx-tensorflow) -> (saved model) PB -> TFlite)
34
+
35
+ (Trained on datasets: RedWeb, MegaDepth, WSVD, 3D Movies, DIML indoor)
36
+
37
+ * New small model - EfficientNet-Lite3 small-decoder 1x256x256x3, batch=1 FP32 (custom converter: Pytorch -> TFlite)
38
+
39
+ (Trained on datasets: RedWeb, MegaDepth, WSVD, 3D Movies, DIML indoor, HRWSI, IRS, TartanAir, BlendedMVS, ApolloScape)
40
+
41
+ #### Frameworks for training and conversions:
42
+ ```
43
+ pip install torch==1.6.0 torchvision==0.7.0
44
+ pip install tf-nightly-gpu==2.5.0.dev20201031 tensorflow-addons==0.11.2 numpy==1.18.0
45
+ git clone --depth 1 --branch v1.6.0 https://github.com/onnx/onnx-tensorflow
46
+ ```
47
+
48
+ #### SoC - OS - Library:
49
+
50
+ * iPhone 11 (A13 Bionic) - iOS 13.7 - TensorFlowLiteSwift 0.0.1-nightly
51
+ * OnePlus 8 (Snapdragon 865) - Andoird 10 - org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly
52
+
53
+
54
+ ### Citation
55
+
56
+ This repository contains code to compute depth from a single image. It accompanies our [paper](https://arxiv.org/abs/1907.01341v3):
57
+
58
+ >Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer
59
+ René Ranftl, Katrin Lasinger, David Hafner, Konrad Schindler, Vladlen Koltun
60
+
61
+ Please cite our paper if you use this code or any of the models:
62
+ ```
63
+ @article{Ranftl2020,
64
+ author = {Ren\'{e} Ranftl and Katrin Lasinger and David Hafner and Konrad Schindler and Vladlen Koltun},
65
+ title = {Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer},
66
+ journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence (TPAMI)},
67
+ year = {2020},
68
+ }
69
+ ```
70
+
live2diff/MiDaS/mobile/android/.gitignore ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.iml
2
+ .gradle
3
+ /local.properties
4
+ /.idea/libraries
5
+ /.idea/modules.xml
6
+ /.idea/workspace.xml
7
+ .DS_Store
8
+ /build
9
+ /captures
10
+ .externalNativeBuild
11
+
12
+ /.gradle/
13
+ /.idea/
live2diff/MiDaS/mobile/android/EXPLORE_THE_CODE.md ADDED
@@ -0,0 +1,414 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # TensorFlow Lite Android image classification example
2
+
3
+ This document walks through the code of a simple Android mobile application that
4
+ demonstrates
5
+ [image classification](https://www.tensorflow.org/lite/models/image_classification/overview)
6
+ using the device camera.
7
+
8
+ ## Explore the code
9
+
10
+ We're now going to walk through the most important parts of the sample code.
11
+
12
+ ### Get camera input
13
+
14
+ This mobile application gets the camera input using the functions defined in the
15
+ file
16
+ [`CameraActivity.java`](https://github.com/tensorflow/examples/tree/master/lite/examples/image_classification/android/app/src/main/java/org/tensorflow/lite/examples/classification/CameraActivity.java).
17
+ This file depends on
18
+ [`AndroidManifest.xml`](https://github.com/tensorflow/examples/tree/master/lite/examples/image_classification/android/app/src/main/AndroidManifest.xml)
19
+ to set the camera orientation.
20
+
21
+ `CameraActivity` also contains code to capture user preferences from the UI and
22
+ make them available to other classes via convenience methods.
23
+
24
+ ```java
25
+ model = Model.valueOf(modelSpinner.getSelectedItem().toString().toUpperCase());
26
+ device = Device.valueOf(deviceSpinner.getSelectedItem().toString());
27
+ numThreads = Integer.parseInt(threadsTextView.getText().toString().trim());
28
+ ```
29
+
30
+ ### Classifier
31
+
32
+ This Image Classification Android reference app demonstrates two implementation
33
+ solutions,
34
+ [`lib_task_api`](https://github.com/tensorflow/examples/tree/master/lite/examples/image_classification/android/lib_task_api)
35
+ that leverages the out-of-box API from the
36
+ [TensorFlow Lite Task Library](https://www.tensorflow.org/lite/inference_with_metadata/task_library/image_classifier),
37
+ and
38
+ [`lib_support`](https://github.com/tensorflow/examples/tree/master/lite/examples/image_classification/android/lib_support)
39
+ that creates the custom inference pipleline using the
40
+ [TensorFlow Lite Support Library](https://www.tensorflow.org/lite/inference_with_metadata/lite_support).
41
+
42
+ Both solutions implement the file `Classifier.java` (see
43
+ [the one in lib_task_api](https://github.com/tensorflow/examples/tree/master/lite/examples/image_classification/android/lib_task_api/src/main/java/org/tensorflow/lite/examples/classification/tflite/Classifier.java)
44
+ and
45
+ [the one in lib_support](https://github.com/tensorflow/examples/tree/master/lite/examples/image_classification/android/lib_support/src/main/java/org/tensorflow/lite/examples/classification/tflite/Classifier.java))
46
+ that contains most of the complex logic for processing the camera input and
47
+ running inference.
48
+
49
+ Two subclasses of the `Classifier` exist, as in `ClassifierFloatMobileNet.java`
50
+ and `ClassifierQuantizedMobileNet.java`, which contain settings for both
51
+ floating point and
52
+ [quantized](https://www.tensorflow.org/lite/performance/post_training_quantization)
53
+ models.
54
+
55
+ The `Classifier` class implements a static method, `create`, which is used to
56
+ instantiate the appropriate subclass based on the supplied model type (quantized
57
+ vs floating point).
58
+
59
+ #### Using the TensorFlow Lite Task Library
60
+
61
+ Inference can be done using just a few lines of code with the
62
+ [`ImageClassifier`](https://www.tensorflow.org/lite/inference_with_metadata/task_library/image_classifier)
63
+ in the TensorFlow Lite Task Library.
64
+
65
+ ##### Load model and create ImageClassifier
66
+
67
+ `ImageClassifier` expects a model populated with the
68
+ [model metadata](https://www.tensorflow.org/lite/convert/metadata) and the label
69
+ file. See the
70
+ [model compatibility requirements](https://www.tensorflow.org/lite/inference_with_metadata/task_library/image_classifier#model_compatibility_requirements)
71
+ for more details.
72
+
73
+ `ImageClassifierOptions` allows manipulation on various inference options, such
74
+ as setting the maximum number of top scored results to return using
75
+ `setMaxResults(MAX_RESULTS)`, and setting the score threshold using
76
+ `setScoreThreshold(scoreThreshold)`.
77
+
78
+ ```java
79
+ // Create the ImageClassifier instance.
80
+ ImageClassifierOptions options =
81
+ ImageClassifierOptions.builder().setMaxResults(MAX_RESULTS).build();
82
+ imageClassifier = ImageClassifier.createFromFileAndOptions(activity,
83
+ getModelPath(), options);
84
+ ```
85
+
86
+ `ImageClassifier` currently does not support configuring delegates and
87
+ multithread, but those are on our roadmap. Please stay tuned!
88
+
89
+ ##### Run inference
90
+
91
+ `ImageClassifier` contains builtin logic to preprocess the input image, such as
92
+ rotating and resizing an image. Processing options can be configured through
93
+ `ImageProcessingOptions`. In the following example, input images are rotated to
94
+ the up-right angle and cropped to the center as the model expects a square input
95
+ (`224x224`). See the
96
+ [Java doc of `ImageClassifier`](https://github.com/tensorflow/tflite-support/blob/195b574f0aa9856c618b3f1ad87bd185cddeb657/tensorflow_lite_support/java/src/java/org/tensorflow/lite/task/core/vision/ImageProcessingOptions.java#L22)
97
+ for more details about how the underlying image processing is performed.
98
+
99
+ ```java
100
+ TensorImage inputImage = TensorImage.fromBitmap(bitmap);
101
+ int width = bitmap.getWidth();
102
+ int height = bitmap.getHeight();
103
+ int cropSize = min(width, height);
104
+ ImageProcessingOptions imageOptions =
105
+ ImageProcessingOptions.builder()
106
+ .setOrientation(getOrientation(sensorOrientation))
107
+ // Set the ROI to the center of the image.
108
+ .setRoi(
109
+ new Rect(
110
+ /*left=*/ (width - cropSize) / 2,
111
+ /*top=*/ (height - cropSize) / 2,
112
+ /*right=*/ (width + cropSize) / 2,
113
+ /*bottom=*/ (height + cropSize) / 2))
114
+ .build();
115
+
116
+ List<Classifications> results = imageClassifier.classify(inputImage,
117
+ imageOptions);
118
+ ```
119
+
120
+ The output of `ImageClassifier` is a list of `Classifications` instance, where
121
+ each `Classifications` element is a single head classification result. All the
122
+ demo models are single head models, therefore, `results` only contains one
123
+ `Classifications` object. Use `Classifications.getCategories()` to get a list of
124
+ top-k categories as specified with `MAX_RESULTS`. Each `Category` object
125
+ contains the srting label and the score of that category.
126
+
127
+ To match the implementation of
128
+ [`lib_support`](https://github.com/tensorflow/examples/tree/master/lite/examples/image_classification/android/lib_support),
129
+ `results` is converted into `List<Recognition>` in the method,
130
+ `getRecognitions`.
131
+
132
+ #### Using the TensorFlow Lite Support Library
133
+
134
+ ##### Load model and create interpreter
135
+
136
+ To perform inference, we need to load a model file and instantiate an
137
+ `Interpreter`. This happens in the constructor of the `Classifier` class, along
138
+ with loading the list of class labels. Information about the device type and
139
+ number of threads is used to configure the `Interpreter` via the
140
+ `Interpreter.Options` instance passed into its constructor. Note that if a GPU,
141
+ DSP (Digital Signal Processor) or NPU (Neural Processing Unit) is available, a
142
+ [`Delegate`](https://www.tensorflow.org/lite/performance/delegates) can be used
143
+ to take full advantage of these hardware.
144
+
145
+ Please note that there are performance edge cases and developers are adviced to
146
+ test with a representative set of devices prior to production.
147
+
148
+ ```java
149
+ protected Classifier(Activity activity, Device device, int numThreads) throws
150
+ IOException {
151
+ tfliteModel = FileUtil.loadMappedFile(activity, getModelPath());
152
+ switch (device) {
153
+ case NNAPI:
154
+ nnApiDelegate = new NnApiDelegate();
155
+ tfliteOptions.addDelegate(nnApiDelegate);
156
+ break;
157
+ case GPU:
158
+ gpuDelegate = new GpuDelegate();
159
+ tfliteOptions.addDelegate(gpuDelegate);
160
+ break;
161
+ case CPU:
162
+ break;
163
+ }
164
+ tfliteOptions.setNumThreads(numThreads);
165
+ tflite = new Interpreter(tfliteModel, tfliteOptions);
166
+ labels = FileUtil.loadLabels(activity, getLabelPath());
167
+ ...
168
+ ```
169
+
170
+ For Android devices, we recommend pre-loading and memory mapping the model file
171
+ to offer faster load times and reduce the dirty pages in memory. The method
172
+ `FileUtil.loadMappedFile` does this, returning a `MappedByteBuffer` containing
173
+ the model.
174
+
175
+ The `MappedByteBuffer` is passed into the `Interpreter` constructor, along with
176
+ an `Interpreter.Options` object. This object can be used to configure the
177
+ interpreter, for example by setting the number of threads (`.setNumThreads(1)`)
178
+ or enabling [NNAPI](https://developer.android.com/ndk/guides/neuralnetworks)
179
+ (`.addDelegate(nnApiDelegate)`).
180
+
181
+ ##### Pre-process bitmap image
182
+
183
+ Next in the `Classifier` constructor, we take the input camera bitmap image,
184
+ convert it to a `TensorImage` format for efficient processing and pre-process
185
+ it. The steps are shown in the private 'loadImage' method:
186
+
187
+ ```java
188
+ /** Loads input image, and applys preprocessing. */
189
+ private TensorImage loadImage(final Bitmap bitmap, int sensorOrientation) {
190
+ // Loads bitmap into a TensorImage.
191
+ image.load(bitmap);
192
+
193
+ // Creates processor for the TensorImage.
194
+ int cropSize = Math.min(bitmap.getWidth(), bitmap.getHeight());
195
+ int numRoration = sensorOrientation / 90;
196
+ ImageProcessor imageProcessor =
197
+ new ImageProcessor.Builder()
198
+ .add(new ResizeWithCropOrPadOp(cropSize, cropSize))
199
+ .add(new ResizeOp(imageSizeX, imageSizeY, ResizeMethod.BILINEAR))
200
+ .add(new Rot90Op(numRoration))
201
+ .add(getPreprocessNormalizeOp())
202
+ .build();
203
+ return imageProcessor.process(inputImageBuffer);
204
+ }
205
+ ```
206
+
207
+ The pre-processing is largely the same for quantized and float models with one
208
+ exception: Normalization.
209
+
210
+ In `ClassifierFloatMobileNet`, the normalization parameters are defined as:
211
+
212
+ ```java
213
+ private static final float IMAGE_MEAN = 127.5f;
214
+ private static final float IMAGE_STD = 127.5f;
215
+ ```
216
+
217
+ In `ClassifierQuantizedMobileNet`, normalization is not required. Thus the
218
+ nomalization parameters are defined as:
219
+
220
+ ```java
221
+ private static final float IMAGE_MEAN = 0.0f;
222
+ private static final float IMAGE_STD = 1.0f;
223
+ ```
224
+
225
+ ##### Allocate output object
226
+
227
+ Initiate the output `TensorBuffer` for the output of the model.
228
+
229
+ ```java
230
+ /** Output probability TensorBuffer. */
231
+ private final TensorBuffer outputProbabilityBuffer;
232
+
233
+ //...
234
+ // Get the array size for the output buffer from the TensorFlow Lite model file
235
+ int probabilityTensorIndex = 0;
236
+ int[] probabilityShape =
237
+ tflite.getOutputTensor(probabilityTensorIndex).shape(); // {1, 1001}
238
+ DataType probabilityDataType =
239
+ tflite.getOutputTensor(probabilityTensorIndex).dataType();
240
+
241
+ // Creates the output tensor and its processor.
242
+ outputProbabilityBuffer =
243
+ TensorBuffer.createFixedSize(probabilityShape, probabilityDataType);
244
+
245
+ // Creates the post processor for the output probability.
246
+ probabilityProcessor =
247
+ new TensorProcessor.Builder().add(getPostprocessNormalizeOp()).build();
248
+ ```
249
+
250
+ For quantized models, we need to de-quantize the prediction with the NormalizeOp
251
+ (as they are all essentially linear transformation). For float model,
252
+ de-quantize is not required. But to uniform the API, de-quantize is added to
253
+ float model too. Mean and std are set to 0.0f and 1.0f, respectively. To be more
254
+ specific,
255
+
256
+ In `ClassifierQuantizedMobileNet`, the normalized parameters are defined as:
257
+
258
+ ```java
259
+ private static final float PROBABILITY_MEAN = 0.0f;
260
+ private static final float PROBABILITY_STD = 255.0f;
261
+ ```
262
+
263
+ In `ClassifierFloatMobileNet`, the normalized parameters are defined as:
264
+
265
+ ```java
266
+ private static final float PROBABILITY_MEAN = 0.0f;
267
+ private static final float PROBABILITY_STD = 1.0f;
268
+ ```
269
+
270
+ ##### Run inference
271
+
272
+ Inference is performed using the following in `Classifier` class:
273
+
274
+ ```java
275
+ tflite.run(inputImageBuffer.getBuffer(),
276
+ outputProbabilityBuffer.getBuffer().rewind());
277
+ ```
278
+
279
+ ##### Recognize image
280
+
281
+ Rather than call `run` directly, the method `recognizeImage` is used. It accepts
282
+ a bitmap and sensor orientation, runs inference, and returns a sorted `List` of
283
+ `Recognition` instances, each corresponding to a label. The method will return a
284
+ number of results bounded by `MAX_RESULTS`, which is 3 by default.
285
+
286
+ `Recognition` is a simple class that contains information about a specific
287
+ recognition result, including its `title` and `confidence`. Using the
288
+ post-processing normalization method specified, the confidence is converted to
289
+ between 0 and 1 of a given class being represented by the image.
290
+
291
+ ```java
292
+ /** Gets the label to probability map. */
293
+ Map<String, Float> labeledProbability =
294
+ new TensorLabel(labels,
295
+ probabilityProcessor.process(outputProbabilityBuffer))
296
+ .getMapWithFloatValue();
297
+ ```
298
+
299
+ A `PriorityQueue` is used for sorting.
300
+
301
+ ```java
302
+ /** Gets the top-k results. */
303
+ private static List<Recognition> getTopKProbability(
304
+ Map<String, Float> labelProb) {
305
+ // Find the best classifications.
306
+ PriorityQueue<Recognition> pq =
307
+ new PriorityQueue<>(
308
+ MAX_RESULTS,
309
+ new Comparator<Recognition>() {
310
+ @Override
311
+ public int compare(Recognition lhs, Recognition rhs) {
312
+ // Intentionally reversed to put high confidence at the head of
313
+ // the queue.
314
+ return Float.compare(rhs.getConfidence(), lhs.getConfidence());
315
+ }
316
+ });
317
+
318
+ for (Map.Entry<String, Float> entry : labelProb.entrySet()) {
319
+ pq.add(new Recognition("" + entry.getKey(), entry.getKey(),
320
+ entry.getValue(), null));
321
+ }
322
+
323
+ final ArrayList<Recognition> recognitions = new ArrayList<>();
324
+ int recognitionsSize = Math.min(pq.size(), MAX_RESULTS);
325
+ for (int i = 0; i < recognitionsSize; ++i) {
326
+ recognitions.add(pq.poll());
327
+ }
328
+ return recognitions;
329
+ }
330
+ ```
331
+
332
+ ### Display results
333
+
334
+ The classifier is invoked and inference results are displayed by the
335
+ `processImage()` function in
336
+ [`ClassifierActivity.java`](https://github.com/tensorflow/examples/tree/master/lite/examples/image_classification/android/app/src/main/java/org/tensorflow/lite/examples/classification/ClassifierActivity.java).
337
+
338
+ `ClassifierActivity` is a subclass of `CameraActivity` that contains method
339
+ implementations that render the camera image, run classification, and display
340
+ the results. The method `processImage()` runs classification on a background
341
+ thread as fast as possible, rendering information on the UI thread to avoid
342
+ blocking inference and creating latency.
343
+
344
+ ```java
345
+ @Override
346
+ protected void processImage() {
347
+ rgbFrameBitmap.setPixels(getRgbBytes(), 0, previewWidth, 0, 0, previewWidth,
348
+ previewHeight);
349
+ final int imageSizeX = classifier.getImageSizeX();
350
+ final int imageSizeY = classifier.getImageSizeY();
351
+
352
+ runInBackground(
353
+ new Runnable() {
354
+ @Override
355
+ public void run() {
356
+ if (classifier != null) {
357
+ final long startTime = SystemClock.uptimeMillis();
358
+ final List<Classifier.Recognition> results =
359
+ classifier.recognizeImage(rgbFrameBitmap, sensorOrientation);
360
+ lastProcessingTimeMs = SystemClock.uptimeMillis() - startTime;
361
+ LOGGER.v("Detect: %s", results);
362
+
363
+ runOnUiThread(
364
+ new Runnable() {
365
+ @Override
366
+ public void run() {
367
+ showResultsInBottomSheet(results);
368
+ showFrameInfo(previewWidth + "x" + previewHeight);
369
+ showCropInfo(imageSizeX + "x" + imageSizeY);
370
+ showCameraResolution(imageSizeX + "x" + imageSizeY);
371
+ showRotationInfo(String.valueOf(sensorOrientation));
372
+ showInference(lastProcessingTimeMs + "ms");
373
+ }
374
+ });
375
+ }
376
+ readyForNextImage();
377
+ }
378
+ });
379
+ }
380
+ ```
381
+
382
+ Another important role of `ClassifierActivity` is to determine user preferences
383
+ (by interrogating `CameraActivity`), and instantiate the appropriately
384
+ configured `Classifier` subclass. This happens when the video feed begins (via
385
+ `onPreviewSizeChosen()`) and when options are changed in the UI (via
386
+ `onInferenceConfigurationChanged()`).
387
+
388
+ ```java
389
+ private void recreateClassifier(Model model, Device device, int numThreads) {
390
+ if (classifier != null) {
391
+ LOGGER.d("Closing classifier.");
392
+ classifier.close();
393
+ classifier = null;
394
+ }
395
+ if (device == Device.GPU && model == Model.QUANTIZED) {
396
+ LOGGER.d("Not creating classifier: GPU doesn't support quantized models.");
397
+ runOnUiThread(
398
+ () -> {
399
+ Toast.makeText(this, "GPU does not yet supported quantized models.",
400
+ Toast.LENGTH_LONG)
401
+ .show();
402
+ });
403
+ return;
404
+ }
405
+ try {
406
+ LOGGER.d(
407
+ "Creating classifier (model=%s, device=%s, numThreads=%d)", model,
408
+ device, numThreads);
409
+ classifier = Classifier.create(this, model, device, numThreads);
410
+ } catch (IOException e) {
411
+ LOGGER.e(e, "Failed to create classifier.");
412
+ }
413
+ }
414
+ ```
live2diff/MiDaS/mobile/android/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Alexey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
live2diff/MiDaS/mobile/android/README.md ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MiDaS on Android smartphone by using TensorFlow-lite (TFLite)
2
+
3
+
4
+ * Either use Android Studio for compilation.
5
+
6
+ * Or use ready to install apk-file:
7
+ * Or use URL: https://i.diawi.com/CVb8a9
8
+ * Or use QR-code:
9
+
10
+ Scan QR-code or open URL -> Press `Install application` -> Press `Download` and wait for download -> Open -> Install -> Open -> Press: Allow MiDaS to take photo and video from the camera While using the APP
11
+
12
+ ![CVb8a9](https://user-images.githubusercontent.com/4096485/97727213-38552500-1ae1-11eb-8b76-4ea11216f76d.png)
13
+
14
+ ----
15
+
16
+ To use another model, you should convert it to `model_opt.tflite` and place it to the directory: `models\src\main\assets`
17
+
18
+
19
+ ----
20
+
21
+ Original repository: https://github.com/intel-isl/MiDaS
live2diff/MiDaS/mobile/android/app/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ /build
2
+
3
+ /build/
live2diff/MiDaS/mobile/android/app/build.gradle ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ apply plugin: 'com.android.application'
2
+
3
+ android {
4
+ compileSdkVersion 28
5
+ defaultConfig {
6
+ applicationId "org.tensorflow.lite.examples.classification"
7
+ minSdkVersion 21
8
+ targetSdkVersion 28
9
+ versionCode 1
10
+ versionName "1.0"
11
+
12
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13
+ }
14
+ buildTypes {
15
+ release {
16
+ minifyEnabled false
17
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18
+ }
19
+ }
20
+ aaptOptions {
21
+ noCompress "tflite"
22
+ }
23
+ compileOptions {
24
+ sourceCompatibility = '1.8'
25
+ targetCompatibility = '1.8'
26
+ }
27
+ lintOptions {
28
+ abortOnError false
29
+ }
30
+ flavorDimensions "tfliteInference"
31
+ productFlavors {
32
+ // The TFLite inference is built using the TFLite Support library.
33
+ support {
34
+ dimension "tfliteInference"
35
+ }
36
+ // The TFLite inference is built using the TFLite Task library.
37
+ taskApi {
38
+ dimension "tfliteInference"
39
+ }
40
+ }
41
+
42
+ }
43
+
44
+ dependencies {
45
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
46
+ supportImplementation project(":lib_support")
47
+ taskApiImplementation project(":lib_task_api")
48
+ implementation 'androidx.appcompat:appcompat:1.0.0'
49
+ implementation 'androidx.coordinatorlayout:coordinatorlayout:1.0.0'
50
+ implementation 'com.google.android.material:material:1.0.0'
51
+
52
+ androidTestImplementation 'androidx.test.ext:junit:1.1.1'
53
+ androidTestImplementation 'com.google.truth:truth:1.0.1'
54
+ androidTestImplementation 'androidx.test:runner:1.2.0'
55
+ androidTestImplementation 'androidx.test:rules:1.1.0'
56
+ }
live2diff/MiDaS/mobile/android/app/proguard-rules.pro ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Add project specific ProGuard rules here.
2
+ # You can control the set of applied configuration files using the
3
+ # proguardFiles setting in build.gradle.
4
+ #
5
+ # For more details, see
6
+ # http://developer.android.com/guide/developing/tools/proguard.html
7
+
8
+ # If your project uses WebView with JS, uncomment the following
9
+ # and specify the fully qualified class name to the JavaScript interface
10
+ # class:
11
+ #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12
+ # public *;
13
+ #}
14
+
15
+ # Uncomment this to preserve the line number information for
16
+ # debugging stack traces.
17
+ #-keepattributes SourceFile,LineNumberTable
18
+
19
+ # If you keep the line number information, uncomment this to
20
+ # hide the original source file name.
21
+ #-renamesourcefileattribute SourceFile
live2diff/MiDaS/mobile/android/app/src/androidTest/assets/fox-mobilenet_v1_1.0_224_support.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ red_fox 0.79403335
2
+ kit_fox 0.16753247
3
+ grey_fox 0.03619214
live2diff/MiDaS/mobile/android/app/src/androidTest/assets/fox-mobilenet_v1_1.0_224_task_api.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ red_fox 0.85
2
+ kit_fox 0.13
3
+ grey_fox 0.02
live2diff/MiDaS/mobile/android/app/src/androidTest/java/AndroidManifest.xml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ package="org.tensorflow.lite.examples.classification">
4
+ <uses-sdk />
5
+ </manifest>
live2diff/MiDaS/mobile/android/app/src/androidTest/java/org/tensorflow/lite/examples/classification/ClassifierTest.java ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2019 The TensorFlow Authors. All Rights Reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ package org.tensorflow.lite.examples.classification;
18
+
19
+ import static com.google.common.truth.Truth.assertThat;
20
+
21
+ import android.content.res.AssetManager;
22
+ import android.graphics.Bitmap;
23
+ import android.graphics.BitmapFactory;
24
+ import android.util.Log;
25
+ import androidx.test.ext.junit.runners.AndroidJUnit4;
26
+ import androidx.test.platform.app.InstrumentationRegistry;
27
+ import androidx.test.rule.ActivityTestRule;
28
+ import java.io.IOException;
29
+ import java.io.InputStream;
30
+ import java.util.ArrayList;
31
+ import java.util.Iterator;
32
+ import java.util.List;
33
+ import java.util.Scanner;
34
+ import org.junit.Assert;
35
+ import org.junit.Rule;
36
+ import org.junit.Test;
37
+ import org.junit.runner.RunWith;
38
+ import org.tensorflow.lite.examples.classification.tflite.Classifier;
39
+ import org.tensorflow.lite.examples.classification.tflite.Classifier.Device;
40
+ import org.tensorflow.lite.examples.classification.tflite.Classifier.Model;
41
+ import org.tensorflow.lite.examples.classification.tflite.Classifier.Recognition;
42
+
43
+ /** Golden test for Image Classification Reference app. */
44
+ @RunWith(AndroidJUnit4.class)
45
+ public class ClassifierTest {
46
+
47
+ @Rule
48
+ public ActivityTestRule<ClassifierActivity> rule =
49
+ new ActivityTestRule<>(ClassifierActivity.class);
50
+
51
+ private static final String[] INPUTS = {"fox.jpg"};
52
+ private static final String[] GOLDEN_OUTPUTS_SUPPORT = {"fox-mobilenet_v1_1.0_224_support.txt"};
53
+ private static final String[] GOLDEN_OUTPUTS_TASK = {"fox-mobilenet_v1_1.0_224_task_api.txt"};
54
+
55
+ @Test
56
+ public void classificationResultsShouldNotChange() throws IOException {
57
+ ClassifierActivity activity = rule.getActivity();
58
+ Classifier classifier = Classifier.create(activity, Model.FLOAT_MOBILENET, Device.CPU, 1);
59
+ for (int i = 0; i < INPUTS.length; i++) {
60
+ String imageFileName = INPUTS[i];
61
+ String goldenOutputFileName;
62
+ // TODO(b/169379396): investigate the impact of the resize algorithm on accuracy.
63
+ // This is a temporary workaround to set different golden rest results as the preprocessing
64
+ // of lib_support and lib_task_api are different. Will merge them once the above TODO is
65
+ // resolved.
66
+ if (Classifier.TAG.equals("ClassifierWithSupport")) {
67
+ goldenOutputFileName = GOLDEN_OUTPUTS_SUPPORT[i];
68
+ } else {
69
+ goldenOutputFileName = GOLDEN_OUTPUTS_TASK[i];
70
+ }
71
+ Bitmap input = loadImage(imageFileName);
72
+ List<Recognition> goldenOutput = loadRecognitions(goldenOutputFileName);
73
+
74
+ List<Recognition> result = classifier.recognizeImage(input, 0);
75
+ Iterator<Recognition> goldenOutputIterator = goldenOutput.iterator();
76
+
77
+ for (Recognition actual : result) {
78
+ Assert.assertTrue(goldenOutputIterator.hasNext());
79
+ Recognition expected = goldenOutputIterator.next();
80
+ assertThat(actual.getTitle()).isEqualTo(expected.getTitle());
81
+ assertThat(actual.getConfidence()).isWithin(0.01f).of(expected.getConfidence());
82
+ }
83
+ }
84
+ }
85
+
86
+ private static Bitmap loadImage(String fileName) {
87
+ AssetManager assetManager =
88
+ InstrumentationRegistry.getInstrumentation().getContext().getAssets();
89
+ InputStream inputStream = null;
90
+ try {
91
+ inputStream = assetManager.open(fileName);
92
+ } catch (IOException e) {
93
+ Log.e("Test", "Cannot load image from assets");
94
+ }
95
+ return BitmapFactory.decodeStream(inputStream);
96
+ }
97
+
98
+ private static List<Recognition> loadRecognitions(String fileName) {
99
+ AssetManager assetManager =
100
+ InstrumentationRegistry.getInstrumentation().getContext().getAssets();
101
+ InputStream inputStream = null;
102
+ try {
103
+ inputStream = assetManager.open(fileName);
104
+ } catch (IOException e) {
105
+ Log.e("Test", "Cannot load probability results from assets");
106
+ }
107
+ Scanner scanner = new Scanner(inputStream);
108
+ List<Recognition> result = new ArrayList<>();
109
+ while (scanner.hasNext()) {
110
+ String category = scanner.next();
111
+ category = category.replace('_', ' ');
112
+ if (!scanner.hasNextFloat()) {
113
+ break;
114
+ }
115
+ float probability = scanner.nextFloat();
116
+ Recognition recognition = new Recognition(null, category, probability, null);
117
+ result.add(recognition);
118
+ }
119
+ return result;
120
+ }
121
+ }
live2diff/MiDaS/mobile/android/app/src/main/AndroidManifest.xml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
+ package="org.tensorflow.lite.examples.classification">
3
+
4
+ <uses-sdk />
5
+
6
+ <uses-permission android:name="android.permission.CAMERA" />
7
+
8
+ <uses-feature android:name="android.hardware.camera" />
9
+ <uses-feature android:name="android.hardware.camera.autofocus" />
10
+
11
+ <application
12
+ android:allowBackup="true"
13
+ android:icon="@mipmap/ic_launcher"
14
+ android:label="@string/tfe_ic_app_name"
15
+ android:roundIcon="@mipmap/ic_launcher_round"
16
+ android:supportsRtl="true"
17
+ android:theme="@style/AppTheme.ImageClassification">
18
+ <activity
19
+ android:name=".ClassifierActivity"
20
+ android:label="@string/tfe_ic_app_name"
21
+ android:screenOrientation="portrait">
22
+ <intent-filter>
23
+ <action android:name="android.intent.action.MAIN" />
24
+ <category android:name="android.intent.category.LAUNCHER" />
25
+ </intent-filter>
26
+ </activity>
27
+ </application>
28
+ </manifest>
live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/CameraActivity.java ADDED
@@ -0,0 +1,717 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2019 The TensorFlow Authors. All Rights Reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ package org.tensorflow.lite.examples.classification;
18
+
19
+ import android.Manifest;
20
+ import android.app.Fragment;
21
+ import android.content.Context;
22
+ import android.content.pm.PackageManager;
23
+ import android.graphics.Bitmap;
24
+ import android.graphics.Canvas;
25
+ import android.graphics.Color;
26
+ import android.graphics.Paint;
27
+ import android.graphics.RectF;
28
+ import android.hardware.Camera;
29
+ import android.hardware.camera2.CameraAccessException;
30
+ import android.hardware.camera2.CameraCharacteristics;
31
+ import android.hardware.camera2.CameraManager;
32
+ import android.hardware.camera2.params.StreamConfigurationMap;
33
+ import android.media.Image;
34
+ import android.media.Image.Plane;
35
+ import android.media.ImageReader;
36
+ import android.media.ImageReader.OnImageAvailableListener;
37
+ import android.os.Build;
38
+ import android.os.Bundle;
39
+ import android.os.Handler;
40
+ import android.os.HandlerThread;
41
+ import android.os.Trace;
42
+ import androidx.annotation.NonNull;
43
+ import androidx.annotation.UiThread;
44
+ import androidx.appcompat.app.AppCompatActivity;
45
+ import android.util.Size;
46
+ import android.view.Surface;
47
+ import android.view.TextureView;
48
+ import android.view.View;
49
+ import android.view.ViewTreeObserver;
50
+ import android.view.WindowManager;
51
+ import android.widget.AdapterView;
52
+ import android.widget.ImageView;
53
+ import android.widget.LinearLayout;
54
+ import android.widget.Spinner;
55
+ import android.widget.TextView;
56
+ import android.widget.Toast;
57
+ import com.google.android.material.bottomsheet.BottomSheetBehavior;
58
+ import java.nio.ByteBuffer;
59
+ import java.util.List;
60
+ import org.tensorflow.lite.examples.classification.env.ImageUtils;
61
+ import org.tensorflow.lite.examples.classification.env.Logger;
62
+ import org.tensorflow.lite.examples.classification.tflite.Classifier.Device;
63
+ import org.tensorflow.lite.examples.classification.tflite.Classifier.Model;
64
+ import org.tensorflow.lite.examples.classification.tflite.Classifier.Recognition;
65
+
66
+ public abstract class CameraActivity extends AppCompatActivity
67
+ implements OnImageAvailableListener,
68
+ Camera.PreviewCallback,
69
+ View.OnClickListener,
70
+ AdapterView.OnItemSelectedListener {
71
+ private static final Logger LOGGER = new Logger();
72
+
73
+ private static final int PERMISSIONS_REQUEST = 1;
74
+
75
+ private static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;
76
+ protected int previewWidth = 0;
77
+ protected int previewHeight = 0;
78
+ private Handler handler;
79
+ private HandlerThread handlerThread;
80
+ private boolean useCamera2API;
81
+ private boolean isProcessingFrame = false;
82
+ private byte[][] yuvBytes = new byte[3][];
83
+ private int[] rgbBytes = null;
84
+ private int yRowStride;
85
+ private Runnable postInferenceCallback;
86
+ private Runnable imageConverter;
87
+ private LinearLayout bottomSheetLayout;
88
+ private LinearLayout gestureLayout;
89
+ private BottomSheetBehavior<LinearLayout> sheetBehavior;
90
+ protected TextView recognitionTextView,
91
+ recognition1TextView,
92
+ recognition2TextView,
93
+ recognitionValueTextView,
94
+ recognition1ValueTextView,
95
+ recognition2ValueTextView;
96
+ protected TextView frameValueTextView,
97
+ cropValueTextView,
98
+ cameraResolutionTextView,
99
+ rotationTextView,
100
+ inferenceTimeTextView;
101
+ protected ImageView bottomSheetArrowImageView;
102
+ private ImageView plusImageView, minusImageView;
103
+ private Spinner modelSpinner;
104
+ private Spinner deviceSpinner;
105
+ private TextView threadsTextView;
106
+
107
+ //private Model model = Model.QUANTIZED_EFFICIENTNET;
108
+ //private Device device = Device.CPU;
109
+ private Model model = Model.FLOAT_EFFICIENTNET;
110
+ private Device device = Device.GPU;
111
+ private int numThreads = -1;
112
+
113
+ @Override
114
+ protected void onCreate(final Bundle savedInstanceState) {
115
+ LOGGER.d("onCreate " + this);
116
+ super.onCreate(null);
117
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
118
+
119
+ setContentView(R.layout.tfe_ic_activity_camera);
120
+
121
+ if (hasPermission()) {
122
+ setFragment();
123
+ } else {
124
+ requestPermission();
125
+ }
126
+
127
+ threadsTextView = findViewById(R.id.threads);
128
+ plusImageView = findViewById(R.id.plus);
129
+ minusImageView = findViewById(R.id.minus);
130
+ modelSpinner = findViewById(R.id.model_spinner);
131
+ deviceSpinner = findViewById(R.id.device_spinner);
132
+ bottomSheetLayout = findViewById(R.id.bottom_sheet_layout);
133
+ gestureLayout = findViewById(R.id.gesture_layout);
134
+ sheetBehavior = BottomSheetBehavior.from(bottomSheetLayout);
135
+ bottomSheetArrowImageView = findViewById(R.id.bottom_sheet_arrow);
136
+
137
+ ViewTreeObserver vto = gestureLayout.getViewTreeObserver();
138
+ vto.addOnGlobalLayoutListener(
139
+ new ViewTreeObserver.OnGlobalLayoutListener() {
140
+ @Override
141
+ public void onGlobalLayout() {
142
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
143
+ gestureLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
144
+ } else {
145
+ gestureLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
146
+ }
147
+ // int width = bottomSheetLayout.getMeasuredWidth();
148
+ int height = gestureLayout.getMeasuredHeight();
149
+
150
+ sheetBehavior.setPeekHeight(height);
151
+ }
152
+ });
153
+ sheetBehavior.setHideable(false);
154
+
155
+ sheetBehavior.setBottomSheetCallback(
156
+ new BottomSheetBehavior.BottomSheetCallback() {
157
+ @Override
158
+ public void onStateChanged(@NonNull View bottomSheet, int newState) {
159
+ switch (newState) {
160
+ case BottomSheetBehavior.STATE_HIDDEN:
161
+ break;
162
+ case BottomSheetBehavior.STATE_EXPANDED:
163
+ {
164
+ bottomSheetArrowImageView.setImageResource(R.drawable.icn_chevron_down);
165
+ }
166
+ break;
167
+ case BottomSheetBehavior.STATE_COLLAPSED:
168
+ {
169
+ bottomSheetArrowImageView.setImageResource(R.drawable.icn_chevron_up);
170
+ }
171
+ break;
172
+ case BottomSheetBehavior.STATE_DRAGGING:
173
+ break;
174
+ case BottomSheetBehavior.STATE_SETTLING:
175
+ bottomSheetArrowImageView.setImageResource(R.drawable.icn_chevron_up);
176
+ break;
177
+ }
178
+ }
179
+
180
+ @Override
181
+ public void onSlide(@NonNull View bottomSheet, float slideOffset) {}
182
+ });
183
+
184
+ recognitionTextView = findViewById(R.id.detected_item);
185
+ recognitionValueTextView = findViewById(R.id.detected_item_value);
186
+ recognition1TextView = findViewById(R.id.detected_item1);
187
+ recognition1ValueTextView = findViewById(R.id.detected_item1_value);
188
+ recognition2TextView = findViewById(R.id.detected_item2);
189
+ recognition2ValueTextView = findViewById(R.id.detected_item2_value);
190
+
191
+ frameValueTextView = findViewById(R.id.frame_info);
192
+ cropValueTextView = findViewById(R.id.crop_info);
193
+ cameraResolutionTextView = findViewById(R.id.view_info);
194
+ rotationTextView = findViewById(R.id.rotation_info);
195
+ inferenceTimeTextView = findViewById(R.id.inference_info);
196
+
197
+ modelSpinner.setOnItemSelectedListener(this);
198
+ deviceSpinner.setOnItemSelectedListener(this);
199
+
200
+ plusImageView.setOnClickListener(this);
201
+ minusImageView.setOnClickListener(this);
202
+
203
+ model = Model.valueOf(modelSpinner.getSelectedItem().toString().toUpperCase());
204
+ device = Device.valueOf(deviceSpinner.getSelectedItem().toString());
205
+ numThreads = Integer.parseInt(threadsTextView.getText().toString().trim());
206
+ }
207
+
208
+ protected int[] getRgbBytes() {
209
+ imageConverter.run();
210
+ return rgbBytes;
211
+ }
212
+
213
+ protected int getLuminanceStride() {
214
+ return yRowStride;
215
+ }
216
+
217
+ protected byte[] getLuminance() {
218
+ return yuvBytes[0];
219
+ }
220
+
221
+ /** Callback for android.hardware.Camera API */
222
+ @Override
223
+ public void onPreviewFrame(final byte[] bytes, final Camera camera) {
224
+ if (isProcessingFrame) {
225
+ LOGGER.w("Dropping frame!");
226
+ return;
227
+ }
228
+
229
+ try {
230
+ // Initialize the storage bitmaps once when the resolution is known.
231
+ if (rgbBytes == null) {
232
+ Camera.Size previewSize = camera.getParameters().getPreviewSize();
233
+ previewHeight = previewSize.height;
234
+ previewWidth = previewSize.width;
235
+ rgbBytes = new int[previewWidth * previewHeight];
236
+ onPreviewSizeChosen(new Size(previewSize.width, previewSize.height), 90);
237
+ }
238
+ } catch (final Exception e) {
239
+ LOGGER.e(e, "Exception!");
240
+ return;
241
+ }
242
+
243
+ isProcessingFrame = true;
244
+ yuvBytes[0] = bytes;
245
+ yRowStride = previewWidth;
246
+
247
+ imageConverter =
248
+ new Runnable() {
249
+ @Override
250
+ public void run() {
251
+ ImageUtils.convertYUV420SPToARGB8888(bytes, previewWidth, previewHeight, rgbBytes);
252
+ }
253
+ };
254
+
255
+ postInferenceCallback =
256
+ new Runnable() {
257
+ @Override
258
+ public void run() {
259
+ camera.addCallbackBuffer(bytes);
260
+ isProcessingFrame = false;
261
+ }
262
+ };
263
+ processImage();
264
+ }
265
+
266
+ /** Callback for Camera2 API */
267
+ @Override
268
+ public void onImageAvailable(final ImageReader reader) {
269
+ // We need wait until we have some size from onPreviewSizeChosen
270
+ if (previewWidth == 0 || previewHeight == 0) {
271
+ return;
272
+ }
273
+ if (rgbBytes == null) {
274
+ rgbBytes = new int[previewWidth * previewHeight];
275
+ }
276
+ try {
277
+ final Image image = reader.acquireLatestImage();
278
+
279
+ if (image == null) {
280
+ return;
281
+ }
282
+
283
+ if (isProcessingFrame) {
284
+ image.close();
285
+ return;
286
+ }
287
+ isProcessingFrame = true;
288
+ Trace.beginSection("imageAvailable");
289
+ final Plane[] planes = image.getPlanes();
290
+ fillBytes(planes, yuvBytes);
291
+ yRowStride = planes[0].getRowStride();
292
+ final int uvRowStride = planes[1].getRowStride();
293
+ final int uvPixelStride = planes[1].getPixelStride();
294
+
295
+ imageConverter =
296
+ new Runnable() {
297
+ @Override
298
+ public void run() {
299
+ ImageUtils.convertYUV420ToARGB8888(
300
+ yuvBytes[0],
301
+ yuvBytes[1],
302
+ yuvBytes[2],
303
+ previewWidth,
304
+ previewHeight,
305
+ yRowStride,
306
+ uvRowStride,
307
+ uvPixelStride,
308
+ rgbBytes);
309
+ }
310
+ };
311
+
312
+ postInferenceCallback =
313
+ new Runnable() {
314
+ @Override
315
+ public void run() {
316
+ image.close();
317
+ isProcessingFrame = false;
318
+ }
319
+ };
320
+
321
+ processImage();
322
+ } catch (final Exception e) {
323
+ LOGGER.e(e, "Exception!");
324
+ Trace.endSection();
325
+ return;
326
+ }
327
+ Trace.endSection();
328
+ }
329
+
330
+ @Override
331
+ public synchronized void onStart() {
332
+ LOGGER.d("onStart " + this);
333
+ super.onStart();
334
+ }
335
+
336
+ @Override
337
+ public synchronized void onResume() {
338
+ LOGGER.d("onResume " + this);
339
+ super.onResume();
340
+
341
+ handlerThread = new HandlerThread("inference");
342
+ handlerThread.start();
343
+ handler = new Handler(handlerThread.getLooper());
344
+ }
345
+
346
+ @Override
347
+ public synchronized void onPause() {
348
+ LOGGER.d("onPause " + this);
349
+
350
+ handlerThread.quitSafely();
351
+ try {
352
+ handlerThread.join();
353
+ handlerThread = null;
354
+ handler = null;
355
+ } catch (final InterruptedException e) {
356
+ LOGGER.e(e, "Exception!");
357
+ }
358
+
359
+ super.onPause();
360
+ }
361
+
362
+ @Override
363
+ public synchronized void onStop() {
364
+ LOGGER.d("onStop " + this);
365
+ super.onStop();
366
+ }
367
+
368
+ @Override
369
+ public synchronized void onDestroy() {
370
+ LOGGER.d("onDestroy " + this);
371
+ super.onDestroy();
372
+ }
373
+
374
+ protected synchronized void runInBackground(final Runnable r) {
375
+ if (handler != null) {
376
+ handler.post(r);
377
+ }
378
+ }
379
+
380
+ @Override
381
+ public void onRequestPermissionsResult(
382
+ final int requestCode, final String[] permissions, final int[] grantResults) {
383
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
384
+ if (requestCode == PERMISSIONS_REQUEST) {
385
+ if (allPermissionsGranted(grantResults)) {
386
+ setFragment();
387
+ } else {
388
+ requestPermission();
389
+ }
390
+ }
391
+ }
392
+
393
+ private static boolean allPermissionsGranted(final int[] grantResults) {
394
+ for (int result : grantResults) {
395
+ if (result != PackageManager.PERMISSION_GRANTED) {
396
+ return false;
397
+ }
398
+ }
399
+ return true;
400
+ }
401
+
402
+ private boolean hasPermission() {
403
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
404
+ return checkSelfPermission(PERMISSION_CAMERA) == PackageManager.PERMISSION_GRANTED;
405
+ } else {
406
+ return true;
407
+ }
408
+ }
409
+
410
+ private void requestPermission() {
411
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
412
+ if (shouldShowRequestPermissionRationale(PERMISSION_CAMERA)) {
413
+ Toast.makeText(
414
+ CameraActivity.this,
415
+ "Camera permission is required for this demo",
416
+ Toast.LENGTH_LONG)
417
+ .show();
418
+ }
419
+ requestPermissions(new String[] {PERMISSION_CAMERA}, PERMISSIONS_REQUEST);
420
+ }
421
+ }
422
+
423
+ // Returns true if the device supports the required hardware level, or better.
424
+ private boolean isHardwareLevelSupported(
425
+ CameraCharacteristics characteristics, int requiredLevel) {
426
+ int deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
427
+ if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
428
+ return requiredLevel == deviceLevel;
429
+ }
430
+ // deviceLevel is not LEGACY, can use numerical sort
431
+ return requiredLevel <= deviceLevel;
432
+ }
433
+
434
+ private String chooseCamera() {
435
+ final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
436
+ try {
437
+ for (final String cameraId : manager.getCameraIdList()) {
438
+ final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
439
+
440
+ // We don't use a front facing camera in this sample.
441
+ final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
442
+ if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
443
+ continue;
444
+ }
445
+
446
+ final StreamConfigurationMap map =
447
+ characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
448
+
449
+ if (map == null) {
450
+ continue;
451
+ }
452
+
453
+ // Fallback to camera1 API for internal cameras that don't have full support.
454
+ // This should help with legacy situations where using the camera2 API causes
455
+ // distorted or otherwise broken previews.
456
+ useCamera2API =
457
+ (facing == CameraCharacteristics.LENS_FACING_EXTERNAL)
458
+ || isHardwareLevelSupported(
459
+ characteristics, CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);
460
+ LOGGER.i("Camera API lv2?: %s", useCamera2API);
461
+ return cameraId;
462
+ }
463
+ } catch (CameraAccessException e) {
464
+ LOGGER.e(e, "Not allowed to access camera");
465
+ }
466
+
467
+ return null;
468
+ }
469
+
470
+ protected void setFragment() {
471
+ String cameraId = chooseCamera();
472
+
473
+ Fragment fragment;
474
+ if (useCamera2API) {
475
+ CameraConnectionFragment camera2Fragment =
476
+ CameraConnectionFragment.newInstance(
477
+ new CameraConnectionFragment.ConnectionCallback() {
478
+ @Override
479
+ public void onPreviewSizeChosen(final Size size, final int rotation) {
480
+ previewHeight = size.getHeight();
481
+ previewWidth = size.getWidth();
482
+ CameraActivity.this.onPreviewSizeChosen(size, rotation);
483
+ }
484
+ },
485
+ this,
486
+ getLayoutId(),
487
+ getDesiredPreviewFrameSize());
488
+
489
+ camera2Fragment.setCamera(cameraId);
490
+ fragment = camera2Fragment;
491
+ } else {
492
+ fragment =
493
+ new LegacyCameraConnectionFragment(this, getLayoutId(), getDesiredPreviewFrameSize());
494
+ }
495
+
496
+ getFragmentManager().beginTransaction().replace(R.id.container, fragment).commit();
497
+ }
498
+
499
+ protected void fillBytes(final Plane[] planes, final byte[][] yuvBytes) {
500
+ // Because of the variable row stride it's not possible to know in
501
+ // advance the actual necessary dimensions of the yuv planes.
502
+ for (int i = 0; i < planes.length; ++i) {
503
+ final ByteBuffer buffer = planes[i].getBuffer();
504
+ if (yuvBytes[i] == null) {
505
+ LOGGER.d("Initializing buffer %d at size %d", i, buffer.capacity());
506
+ yuvBytes[i] = new byte[buffer.capacity()];
507
+ }
508
+ buffer.get(yuvBytes[i]);
509
+ }
510
+ }
511
+
512
+ protected void readyForNextImage() {
513
+ if (postInferenceCallback != null) {
514
+ postInferenceCallback.run();
515
+ }
516
+ }
517
+
518
+ protected int getScreenOrientation() {
519
+ switch (getWindowManager().getDefaultDisplay().getRotation()) {
520
+ case Surface.ROTATION_270:
521
+ return 270;
522
+ case Surface.ROTATION_180:
523
+ return 180;
524
+ case Surface.ROTATION_90:
525
+ return 90;
526
+ default:
527
+ return 0;
528
+ }
529
+ }
530
+
531
+ @UiThread
532
+ protected void showResultsInTexture(float[] img_array, int imageSizeX, int imageSizeY) {
533
+ float maxval = Float.NEGATIVE_INFINITY;
534
+ float minval = Float.POSITIVE_INFINITY;
535
+ for (float cur : img_array) {
536
+ maxval = Math.max(maxval, cur);
537
+ minval = Math.min(minval, cur);
538
+ }
539
+ float multiplier = 0;
540
+ if ((maxval - minval) > 0) multiplier = 255 / (maxval - minval);
541
+
542
+ int[] img_normalized = new int[img_array.length];
543
+ for (int i = 0; i < img_array.length; ++i) {
544
+ float val = (float) (multiplier * (img_array[i] - minval));
545
+ img_normalized[i] = (int) val;
546
+ }
547
+
548
+
549
+
550
+ TextureView textureView = findViewById(R.id.textureView3);
551
+ //AutoFitTextureView textureView = (AutoFitTextureView) findViewById(R.id.texture);
552
+
553
+ if(textureView.isAvailable()) {
554
+ int width = imageSizeX;
555
+ int height = imageSizeY;
556
+
557
+ Canvas canvas = textureView.lockCanvas();
558
+ canvas.drawColor(Color.BLUE);
559
+ Paint paint = new Paint();
560
+ paint.setStyle(Paint.Style.FILL);
561
+ paint.setARGB(255, 150, 150, 150);
562
+
563
+ int canvas_size = Math.min(canvas.getWidth(), canvas.getHeight());
564
+
565
+ Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
566
+
567
+ for (int ii = 0; ii < width; ii++) //pass the screen pixels in 2 directions
568
+ {
569
+ for (int jj = 0; jj < height; jj++) {
570
+ //int val = img_normalized[ii + jj * width];
571
+ int index = (width - ii - 1) + (height - jj - 1) * width;
572
+ if(index < img_array.length) {
573
+ int val = img_normalized[index];
574
+ bitmap.setPixel(ii, jj, Color.rgb(val, val, val));
575
+ }
576
+ }
577
+ }
578
+
579
+ canvas.drawBitmap(bitmap, null, new RectF(0, 0, canvas_size, canvas_size), null);
580
+
581
+ textureView.unlockCanvasAndPost(canvas);
582
+
583
+ }
584
+
585
+ }
586
+
587
+ protected void showResultsInBottomSheet(List<Recognition> results) {
588
+ if (results != null && results.size() >= 3) {
589
+ Recognition recognition = results.get(0);
590
+ if (recognition != null) {
591
+ if (recognition.getTitle() != null) recognitionTextView.setText(recognition.getTitle());
592
+ if (recognition.getConfidence() != null)
593
+ recognitionValueTextView.setText(
594
+ String.format("%.2f", (100 * recognition.getConfidence())) + "%");
595
+ }
596
+
597
+ Recognition recognition1 = results.get(1);
598
+ if (recognition1 != null) {
599
+ if (recognition1.getTitle() != null) recognition1TextView.setText(recognition1.getTitle());
600
+ if (recognition1.getConfidence() != null)
601
+ recognition1ValueTextView.setText(
602
+ String.format("%.2f", (100 * recognition1.getConfidence())) + "%");
603
+ }
604
+
605
+ Recognition recognition2 = results.get(2);
606
+ if (recognition2 != null) {
607
+ if (recognition2.getTitle() != null) recognition2TextView.setText(recognition2.getTitle());
608
+ if (recognition2.getConfidence() != null)
609
+ recognition2ValueTextView.setText(
610
+ String.format("%.2f", (100 * recognition2.getConfidence())) + "%");
611
+ }
612
+ }
613
+ }
614
+
615
+ protected void showFrameInfo(String frameInfo) {
616
+ frameValueTextView.setText(frameInfo);
617
+ }
618
+
619
+ protected void showCropInfo(String cropInfo) {
620
+ cropValueTextView.setText(cropInfo);
621
+ }
622
+
623
+ protected void showCameraResolution(String cameraInfo) {
624
+ cameraResolutionTextView.setText(cameraInfo);
625
+ }
626
+
627
+ protected void showRotationInfo(String rotation) {
628
+ rotationTextView.setText(rotation);
629
+ }
630
+
631
+ protected void showInference(String inferenceTime) {
632
+ inferenceTimeTextView.setText(inferenceTime);
633
+ }
634
+
635
+ protected Model getModel() {
636
+ return model;
637
+ }
638
+
639
+ private void setModel(Model model) {
640
+ if (this.model != model) {
641
+ LOGGER.d("Updating model: " + model);
642
+ this.model = model;
643
+ onInferenceConfigurationChanged();
644
+ }
645
+ }
646
+
647
+ protected Device getDevice() {
648
+ return device;
649
+ }
650
+
651
+ private void setDevice(Device device) {
652
+ if (this.device != device) {
653
+ LOGGER.d("Updating device: " + device);
654
+ this.device = device;
655
+ final boolean threadsEnabled = device == Device.CPU;
656
+ plusImageView.setEnabled(threadsEnabled);
657
+ minusImageView.setEnabled(threadsEnabled);
658
+ threadsTextView.setText(threadsEnabled ? String.valueOf(numThreads) : "N/A");
659
+ onInferenceConfigurationChanged();
660
+ }
661
+ }
662
+
663
+ protected int getNumThreads() {
664
+ return numThreads;
665
+ }
666
+
667
+ private void setNumThreads(int numThreads) {
668
+ if (this.numThreads != numThreads) {
669
+ LOGGER.d("Updating numThreads: " + numThreads);
670
+ this.numThreads = numThreads;
671
+ onInferenceConfigurationChanged();
672
+ }
673
+ }
674
+
675
+ protected abstract void processImage();
676
+
677
+ protected abstract void onPreviewSizeChosen(final Size size, final int rotation);
678
+
679
+ protected abstract int getLayoutId();
680
+
681
+ protected abstract Size getDesiredPreviewFrameSize();
682
+
683
+ protected abstract void onInferenceConfigurationChanged();
684
+
685
+ @Override
686
+ public void onClick(View v) {
687
+ if (v.getId() == R.id.plus) {
688
+ String threads = threadsTextView.getText().toString().trim();
689
+ int numThreads = Integer.parseInt(threads);
690
+ if (numThreads >= 9) return;
691
+ setNumThreads(++numThreads);
692
+ threadsTextView.setText(String.valueOf(numThreads));
693
+ } else if (v.getId() == R.id.minus) {
694
+ String threads = threadsTextView.getText().toString().trim();
695
+ int numThreads = Integer.parseInt(threads);
696
+ if (numThreads == 1) {
697
+ return;
698
+ }
699
+ setNumThreads(--numThreads);
700
+ threadsTextView.setText(String.valueOf(numThreads));
701
+ }
702
+ }
703
+
704
+ @Override
705
+ public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
706
+ if (parent == modelSpinner) {
707
+ setModel(Model.valueOf(parent.getItemAtPosition(pos).toString().toUpperCase()));
708
+ } else if (parent == deviceSpinner) {
709
+ setDevice(Device.valueOf(parent.getItemAtPosition(pos).toString()));
710
+ }
711
+ }
712
+
713
+ @Override
714
+ public void onNothingSelected(AdapterView<?> parent) {
715
+ // Do nothing.
716
+ }
717
+ }
live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/CameraConnectionFragment.java ADDED
@@ -0,0 +1,575 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2019 The TensorFlow Authors. All Rights Reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ package org.tensorflow.lite.examples.classification;
18
+
19
+ import android.annotation.SuppressLint;
20
+ import android.app.Activity;
21
+ import android.app.AlertDialog;
22
+ import android.app.Dialog;
23
+ import android.app.DialogFragment;
24
+ import android.app.Fragment;
25
+ import android.content.Context;
26
+ import android.content.DialogInterface;
27
+ import android.content.res.Configuration;
28
+ import android.graphics.ImageFormat;
29
+ import android.graphics.Matrix;
30
+ import android.graphics.RectF;
31
+ import android.graphics.SurfaceTexture;
32
+ import android.hardware.camera2.CameraAccessException;
33
+ import android.hardware.camera2.CameraCaptureSession;
34
+ import android.hardware.camera2.CameraCharacteristics;
35
+ import android.hardware.camera2.CameraDevice;
36
+ import android.hardware.camera2.CameraManager;
37
+ import android.hardware.camera2.CaptureRequest;
38
+ import android.hardware.camera2.CaptureResult;
39
+ import android.hardware.camera2.TotalCaptureResult;
40
+ import android.hardware.camera2.params.StreamConfigurationMap;
41
+ import android.media.ImageReader;
42
+ import android.media.ImageReader.OnImageAvailableListener;
43
+ import android.os.Bundle;
44
+ import android.os.Handler;
45
+ import android.os.HandlerThread;
46
+ import android.text.TextUtils;
47
+ import android.util.Size;
48
+ import android.util.SparseIntArray;
49
+ import android.view.LayoutInflater;
50
+ import android.view.Surface;
51
+ import android.view.TextureView;
52
+ import android.view.View;
53
+ import android.view.ViewGroup;
54
+ import android.widget.Toast;
55
+ import java.util.ArrayList;
56
+ import java.util.Arrays;
57
+ import java.util.Collections;
58
+ import java.util.Comparator;
59
+ import java.util.List;
60
+ import java.util.concurrent.Semaphore;
61
+ import java.util.concurrent.TimeUnit;
62
+ import org.tensorflow.lite.examples.classification.customview.AutoFitTextureView;
63
+ import org.tensorflow.lite.examples.classification.env.Logger;
64
+
65
+ /**
66
+ * Camera Connection Fragment that captures images from camera.
67
+ *
68
+ * <p>Instantiated by newInstance.</p>
69
+ */
70
+ @SuppressWarnings("FragmentNotInstantiable")
71
+ public class CameraConnectionFragment extends Fragment {
72
+ private static final Logger LOGGER = new Logger();
73
+
74
+ /**
75
+ * The camera preview size will be chosen to be the smallest frame by pixel size capable of
76
+ * containing a DESIRED_SIZE x DESIRED_SIZE square.
77
+ */
78
+ private static final int MINIMUM_PREVIEW_SIZE = 320;
79
+
80
+ /** Conversion from screen rotation to JPEG orientation. */
81
+ private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
82
+
83
+ private static final String FRAGMENT_DIALOG = "dialog";
84
+
85
+ static {
86
+ ORIENTATIONS.append(Surface.ROTATION_0, 90);
87
+ ORIENTATIONS.append(Surface.ROTATION_90, 0);
88
+ ORIENTATIONS.append(Surface.ROTATION_180, 270);
89
+ ORIENTATIONS.append(Surface.ROTATION_270, 180);
90
+ }
91
+
92
+ /** A {@link Semaphore} to prevent the app from exiting before closing the camera. */
93
+ private final Semaphore cameraOpenCloseLock = new Semaphore(1);
94
+ /** A {@link OnImageAvailableListener} to receive frames as they are available. */
95
+ private final OnImageAvailableListener imageListener;
96
+ /** The input size in pixels desired by TensorFlow (width and height of a square bitmap). */
97
+ private final Size inputSize;
98
+ /** The layout identifier to inflate for this Fragment. */
99
+ private final int layout;
100
+
101
+ private final ConnectionCallback cameraConnectionCallback;
102
+ private final CameraCaptureSession.CaptureCallback captureCallback =
103
+ new CameraCaptureSession.CaptureCallback() {
104
+ @Override
105
+ public void onCaptureProgressed(
106
+ final CameraCaptureSession session,
107
+ final CaptureRequest request,
108
+ final CaptureResult partialResult) {}
109
+
110
+ @Override
111
+ public void onCaptureCompleted(
112
+ final CameraCaptureSession session,
113
+ final CaptureRequest request,
114
+ final TotalCaptureResult result) {}
115
+ };
116
+ /** ID of the current {@link CameraDevice}. */
117
+ private String cameraId;
118
+ /** An {@link AutoFitTextureView} for camera preview. */
119
+ private AutoFitTextureView textureView;
120
+ /** A {@link CameraCaptureSession } for camera preview. */
121
+ private CameraCaptureSession captureSession;
122
+ /** A reference to the opened {@link CameraDevice}. */
123
+ private CameraDevice cameraDevice;
124
+ /** The rotation in degrees of the camera sensor from the display. */
125
+ private Integer sensorOrientation;
126
+ /** The {@link Size} of camera preview. */
127
+ private Size previewSize;
128
+ /** An additional thread for running tasks that shouldn't block the UI. */
129
+ private HandlerThread backgroundThread;
130
+ /** A {@link Handler} for running tasks in the background. */
131
+ private Handler backgroundHandler;
132
+ /**
133
+ * {@link TextureView.SurfaceTextureListener} handles several lifecycle events on a {@link
134
+ * TextureView}.
135
+ */
136
+ private final TextureView.SurfaceTextureListener surfaceTextureListener =
137
+ new TextureView.SurfaceTextureListener() {
138
+ @Override
139
+ public void onSurfaceTextureAvailable(
140
+ final SurfaceTexture texture, final int width, final int height) {
141
+ openCamera(width, height);
142
+ }
143
+
144
+ @Override
145
+ public void onSurfaceTextureSizeChanged(
146
+ final SurfaceTexture texture, final int width, final int height) {
147
+ configureTransform(width, height);
148
+ }
149
+
150
+ @Override
151
+ public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {
152
+ return true;
153
+ }
154
+
155
+ @Override
156
+ public void onSurfaceTextureUpdated(final SurfaceTexture texture) {}
157
+ };
158
+ /** An {@link ImageReader} that handles preview frame capture. */
159
+ private ImageReader previewReader;
160
+ /** {@link CaptureRequest.Builder} for the camera preview */
161
+ private CaptureRequest.Builder previewRequestBuilder;
162
+ /** {@link CaptureRequest} generated by {@link #previewRequestBuilder} */
163
+ private CaptureRequest previewRequest;
164
+ /** {@link CameraDevice.StateCallback} is called when {@link CameraDevice} changes its state. */
165
+ private final CameraDevice.StateCallback stateCallback =
166
+ new CameraDevice.StateCallback() {
167
+ @Override
168
+ public void onOpened(final CameraDevice cd) {
169
+ // This method is called when the camera is opened. We start camera preview here.
170
+ cameraOpenCloseLock.release();
171
+ cameraDevice = cd;
172
+ createCameraPreviewSession();
173
+ }
174
+
175
+ @Override
176
+ public void onDisconnected(final CameraDevice cd) {
177
+ cameraOpenCloseLock.release();
178
+ cd.close();
179
+ cameraDevice = null;
180
+ }
181
+
182
+ @Override
183
+ public void onError(final CameraDevice cd, final int error) {
184
+ cameraOpenCloseLock.release();
185
+ cd.close();
186
+ cameraDevice = null;
187
+ final Activity activity = getActivity();
188
+ if (null != activity) {
189
+ activity.finish();
190
+ }
191
+ }
192
+ };
193
+
194
+ @SuppressLint("ValidFragment")
195
+ private CameraConnectionFragment(
196
+ final ConnectionCallback connectionCallback,
197
+ final OnImageAvailableListener imageListener,
198
+ final int layout,
199
+ final Size inputSize) {
200
+ this.cameraConnectionCallback = connectionCallback;
201
+ this.imageListener = imageListener;
202
+ this.layout = layout;
203
+ this.inputSize = inputSize;
204
+ }
205
+
206
+ /**
207
+ * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose
208
+ * width and height are at least as large as the minimum of both, or an exact match if possible.
209
+ *
210
+ * @param choices The list of sizes that the camera supports for the intended output class
211
+ * @param width The minimum desired width
212
+ * @param height The minimum desired height
213
+ * @return The optimal {@code Size}, or an arbitrary one if none were big enough
214
+ */
215
+ protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {
216
+ final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);
217
+ final Size desiredSize = new Size(width, height);
218
+
219
+ // Collect the supported resolutions that are at least as big as the preview Surface
220
+ boolean exactSizeFound = false;
221
+ final List<Size> bigEnough = new ArrayList<Size>();
222
+ final List<Size> tooSmall = new ArrayList<Size>();
223
+ for (final Size option : choices) {
224
+ if (option.equals(desiredSize)) {
225
+ // Set the size but don't return yet so that remaining sizes will still be logged.
226
+ exactSizeFound = true;
227
+ }
228
+
229
+ if (option.getHeight() >= minSize && option.getWidth() >= minSize) {
230
+ bigEnough.add(option);
231
+ } else {
232
+ tooSmall.add(option);
233
+ }
234
+ }
235
+
236
+ LOGGER.i("Desired size: " + desiredSize + ", min size: " + minSize + "x" + minSize);
237
+ LOGGER.i("Valid preview sizes: [" + TextUtils.join(", ", bigEnough) + "]");
238
+ LOGGER.i("Rejected preview sizes: [" + TextUtils.join(", ", tooSmall) + "]");
239
+
240
+ if (exactSizeFound) {
241
+ LOGGER.i("Exact size match found.");
242
+ return desiredSize;
243
+ }
244
+
245
+ // Pick the smallest of those, assuming we found any
246
+ if (bigEnough.size() > 0) {
247
+ final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());
248
+ LOGGER.i("Chosen size: " + chosenSize.getWidth() + "x" + chosenSize.getHeight());
249
+ return chosenSize;
250
+ } else {
251
+ LOGGER.e("Couldn't find any suitable preview size");
252
+ return choices[0];
253
+ }
254
+ }
255
+
256
+ public static CameraConnectionFragment newInstance(
257
+ final ConnectionCallback callback,
258
+ final OnImageAvailableListener imageListener,
259
+ final int layout,
260
+ final Size inputSize) {
261
+ return new CameraConnectionFragment(callback, imageListener, layout, inputSize);
262
+ }
263
+
264
+ /**
265
+ * Shows a {@link Toast} on the UI thread.
266
+ *
267
+ * @param text The message to show
268
+ */
269
+ private void showToast(final String text) {
270
+ final Activity activity = getActivity();
271
+ if (activity != null) {
272
+ activity.runOnUiThread(
273
+ new Runnable() {
274
+ @Override
275
+ public void run() {
276
+ Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();
277
+ }
278
+ });
279
+ }
280
+ }
281
+
282
+ @Override
283
+ public View onCreateView(
284
+ final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
285
+ return inflater.inflate(layout, container, false);
286
+ }
287
+
288
+ @Override
289
+ public void onViewCreated(final View view, final Bundle savedInstanceState) {
290
+ textureView = (AutoFitTextureView) view.findViewById(R.id.texture);
291
+ }
292
+
293
+ @Override
294
+ public void onActivityCreated(final Bundle savedInstanceState) {
295
+ super.onActivityCreated(savedInstanceState);
296
+ }
297
+
298
+ @Override
299
+ public void onResume() {
300
+ super.onResume();
301
+ startBackgroundThread();
302
+
303
+ // When the screen is turned off and turned back on, the SurfaceTexture is already
304
+ // available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open
305
+ // a camera and start preview from here (otherwise, we wait until the surface is ready in
306
+ // the SurfaceTextureListener).
307
+ if (textureView.isAvailable()) {
308
+ openCamera(textureView.getWidth(), textureView.getHeight());
309
+ } else {
310
+ textureView.setSurfaceTextureListener(surfaceTextureListener);
311
+ }
312
+ }
313
+
314
+ @Override
315
+ public void onPause() {
316
+ closeCamera();
317
+ stopBackgroundThread();
318
+ super.onPause();
319
+ }
320
+
321
+ public void setCamera(String cameraId) {
322
+ this.cameraId = cameraId;
323
+ }
324
+
325
+ /** Sets up member variables related to camera. */
326
+ private void setUpCameraOutputs() {
327
+ final Activity activity = getActivity();
328
+ final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
329
+ try {
330
+ final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
331
+
332
+ final StreamConfigurationMap map =
333
+ characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
334
+
335
+ sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
336
+
337
+ // Danger, W.R.! Attempting to use too large a preview size could exceed the camera
338
+ // bus' bandwidth limitation, resulting in gorgeous previews but the storage of
339
+ // garbage capture data.
340
+ previewSize =
341
+ chooseOptimalSize(
342
+ map.getOutputSizes(SurfaceTexture.class),
343
+ inputSize.getWidth(),
344
+ inputSize.getHeight());
345
+
346
+ // We fit the aspect ratio of TextureView to the size of preview we picked.
347
+ final int orientation = getResources().getConfiguration().orientation;
348
+ if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
349
+ textureView.setAspectRatio(previewSize.getWidth(), previewSize.getHeight());
350
+ } else {
351
+ textureView.setAspectRatio(previewSize.getHeight(), previewSize.getWidth());
352
+ }
353
+ } catch (final CameraAccessException e) {
354
+ LOGGER.e(e, "Exception!");
355
+ } catch (final NullPointerException e) {
356
+ // Currently an NPE is thrown when the Camera2API is used but not supported on the
357
+ // device this code runs.
358
+ ErrorDialog.newInstance(getString(R.string.tfe_ic_camera_error))
359
+ .show(getChildFragmentManager(), FRAGMENT_DIALOG);
360
+ throw new IllegalStateException(getString(R.string.tfe_ic_camera_error));
361
+ }
362
+
363
+ cameraConnectionCallback.onPreviewSizeChosen(previewSize, sensorOrientation);
364
+ }
365
+
366
+ /** Opens the camera specified by {@link CameraConnectionFragment#cameraId}. */
367
+ private void openCamera(final int width, final int height) {
368
+ setUpCameraOutputs();
369
+ configureTransform(width, height);
370
+ final Activity activity = getActivity();
371
+ final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
372
+ try {
373
+ if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
374
+ throw new RuntimeException("Time out waiting to lock camera opening.");
375
+ }
376
+ manager.openCamera(cameraId, stateCallback, backgroundHandler);
377
+ } catch (final CameraAccessException e) {
378
+ LOGGER.e(e, "Exception!");
379
+ } catch (final InterruptedException e) {
380
+ throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
381
+ }
382
+ }
383
+
384
+ /** Closes the current {@link CameraDevice}. */
385
+ private void closeCamera() {
386
+ try {
387
+ cameraOpenCloseLock.acquire();
388
+ if (null != captureSession) {
389
+ captureSession.close();
390
+ captureSession = null;
391
+ }
392
+ if (null != cameraDevice) {
393
+ cameraDevice.close();
394
+ cameraDevice = null;
395
+ }
396
+ if (null != previewReader) {
397
+ previewReader.close();
398
+ previewReader = null;
399
+ }
400
+ } catch (final InterruptedException e) {
401
+ throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
402
+ } finally {
403
+ cameraOpenCloseLock.release();
404
+ }
405
+ }
406
+
407
+ /** Starts a background thread and its {@link Handler}. */
408
+ private void startBackgroundThread() {
409
+ backgroundThread = new HandlerThread("ImageListener");
410
+ backgroundThread.start();
411
+ backgroundHandler = new Handler(backgroundThread.getLooper());
412
+ }
413
+
414
+ /** Stops the background thread and its {@link Handler}. */
415
+ private void stopBackgroundThread() {
416
+ backgroundThread.quitSafely();
417
+ try {
418
+ backgroundThread.join();
419
+ backgroundThread = null;
420
+ backgroundHandler = null;
421
+ } catch (final InterruptedException e) {
422
+ LOGGER.e(e, "Exception!");
423
+ }
424
+ }
425
+
426
+ /** Creates a new {@link CameraCaptureSession} for camera preview. */
427
+ private void createCameraPreviewSession() {
428
+ try {
429
+ final SurfaceTexture texture = textureView.getSurfaceTexture();
430
+ assert texture != null;
431
+
432
+ // We configure the size of default buffer to be the size of camera preview we want.
433
+ texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
434
+
435
+ // This is the output Surface we need to start preview.
436
+ final Surface surface = new Surface(texture);
437
+
438
+ // We set up a CaptureRequest.Builder with the output Surface.
439
+ previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
440
+ previewRequestBuilder.addTarget(surface);
441
+
442
+ LOGGER.i("Opening camera preview: " + previewSize.getWidth() + "x" + previewSize.getHeight());
443
+
444
+ // Create the reader for the preview frames.
445
+ previewReader =
446
+ ImageReader.newInstance(
447
+ previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);
448
+
449
+ previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);
450
+ previewRequestBuilder.addTarget(previewReader.getSurface());
451
+
452
+ // Here, we create a CameraCaptureSession for camera preview.
453
+ cameraDevice.createCaptureSession(
454
+ Arrays.asList(surface, previewReader.getSurface()),
455
+ new CameraCaptureSession.StateCallback() {
456
+
457
+ @Override
458
+ public void onConfigured(final CameraCaptureSession cameraCaptureSession) {
459
+ // The camera is already closed
460
+ if (null == cameraDevice) {
461
+ return;
462
+ }
463
+
464
+ // When the session is ready, we start displaying the preview.
465
+ captureSession = cameraCaptureSession;
466
+ try {
467
+ // Auto focus should be continuous for camera preview.
468
+ previewRequestBuilder.set(
469
+ CaptureRequest.CONTROL_AF_MODE,
470
+ CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
471
+ // Flash is automatically enabled when necessary.
472
+ previewRequestBuilder.set(
473
+ CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
474
+
475
+ // Finally, we start displaying the camera preview.
476
+ previewRequest = previewRequestBuilder.build();
477
+ captureSession.setRepeatingRequest(
478
+ previewRequest, captureCallback, backgroundHandler);
479
+ } catch (final CameraAccessException e) {
480
+ LOGGER.e(e, "Exception!");
481
+ }
482
+ }
483
+
484
+ @Override
485
+ public void onConfigureFailed(final CameraCaptureSession cameraCaptureSession) {
486
+ showToast("Failed");
487
+ }
488
+ },
489
+ null);
490
+ } catch (final CameraAccessException e) {
491
+ LOGGER.e(e, "Exception!");
492
+ }
493
+ }
494
+
495
+ /**
496
+ * Configures the necessary {@link Matrix} transformation to `mTextureView`. This method should be
497
+ * called after the camera preview size is determined in setUpCameraOutputs and also the size of
498
+ * `mTextureView` is fixed.
499
+ *
500
+ * @param viewWidth The width of `mTextureView`
501
+ * @param viewHeight The height of `mTextureView`
502
+ */
503
+ private void configureTransform(final int viewWidth, final int viewHeight) {
504
+ final Activity activity = getActivity();
505
+ if (null == textureView || null == previewSize || null == activity) {
506
+ return;
507
+ }
508
+ final int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
509
+ final Matrix matrix = new Matrix();
510
+ final RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
511
+ final RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());
512
+ final float centerX = viewRect.centerX();
513
+ final float centerY = viewRect.centerY();
514
+ if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
515
+ bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
516
+ matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
517
+ final float scale =
518
+ Math.max(
519
+ (float) viewHeight / previewSize.getHeight(),
520
+ (float) viewWidth / previewSize.getWidth());
521
+ matrix.postScale(scale, scale, centerX, centerY);
522
+ matrix.postRotate(90 * (rotation - 2), centerX, centerY);
523
+ } else if (Surface.ROTATION_180 == rotation) {
524
+ matrix.postRotate(180, centerX, centerY);
525
+ }
526
+ textureView.setTransform(matrix);
527
+ }
528
+
529
+ /**
530
+ * Callback for Activities to use to initialize their data once the selected preview size is
531
+ * known.
532
+ */
533
+ public interface ConnectionCallback {
534
+ void onPreviewSizeChosen(Size size, int cameraRotation);
535
+ }
536
+
537
+ /** Compares two {@code Size}s based on their areas. */
538
+ static class CompareSizesByArea implements Comparator<Size> {
539
+ @Override
540
+ public int compare(final Size lhs, final Size rhs) {
541
+ // We cast here to ensure the multiplications won't overflow
542
+ return Long.signum(
543
+ (long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());
544
+ }
545
+ }
546
+
547
+ /** Shows an error message dialog. */
548
+ public static class ErrorDialog extends DialogFragment {
549
+ private static final String ARG_MESSAGE = "message";
550
+
551
+ public static ErrorDialog newInstance(final String message) {
552
+ final ErrorDialog dialog = new ErrorDialog();
553
+ final Bundle args = new Bundle();
554
+ args.putString(ARG_MESSAGE, message);
555
+ dialog.setArguments(args);
556
+ return dialog;
557
+ }
558
+
559
+ @Override
560
+ public Dialog onCreateDialog(final Bundle savedInstanceState) {
561
+ final Activity activity = getActivity();
562
+ return new AlertDialog.Builder(activity)
563
+ .setMessage(getArguments().getString(ARG_MESSAGE))
564
+ .setPositiveButton(
565
+ android.R.string.ok,
566
+ new DialogInterface.OnClickListener() {
567
+ @Override
568
+ public void onClick(final DialogInterface dialogInterface, final int i) {
569
+ activity.finish();
570
+ }
571
+ })
572
+ .create();
573
+ }
574
+ }
575
+ }
live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/ClassifierActivity.java ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2019 The TensorFlow Authors. All Rights Reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ package org.tensorflow.lite.examples.classification;
18
+
19
+ import android.graphics.Bitmap;
20
+ import android.graphics.Bitmap.Config;
21
+ import android.graphics.Typeface;
22
+ import android.media.ImageReader.OnImageAvailableListener;
23
+ import android.os.SystemClock;
24
+ import android.util.Size;
25
+ import android.util.TypedValue;
26
+ import android.view.TextureView;
27
+ import android.view.ViewStub;
28
+ import android.widget.TextView;
29
+ import android.widget.Toast;
30
+ import java.io.IOException;
31
+ import java.util.List;
32
+ import java.util.ArrayList;
33
+
34
+ import org.tensorflow.lite.examples.classification.customview.AutoFitTextureView;
35
+ import org.tensorflow.lite.examples.classification.env.BorderedText;
36
+ import org.tensorflow.lite.examples.classification.env.Logger;
37
+ import org.tensorflow.lite.examples.classification.tflite.Classifier;
38
+ import org.tensorflow.lite.examples.classification.tflite.Classifier.Device;
39
+ import org.tensorflow.lite.examples.classification.tflite.Classifier.Model;
40
+
41
+ import android.widget.ImageView;
42
+ import android.graphics.Bitmap;
43
+ import android.graphics.BitmapFactory;
44
+ import android.graphics.Canvas;
45
+ import android.graphics.Color;
46
+ import android.graphics.Paint;
47
+ import android.graphics.Rect;
48
+ import android.graphics.RectF;
49
+ import android.graphics.PixelFormat;
50
+ import java.nio.ByteBuffer;
51
+
52
+ public class ClassifierActivity extends CameraActivity implements OnImageAvailableListener {
53
+ private static final Logger LOGGER = new Logger();
54
+ private static final Size DESIRED_PREVIEW_SIZE = new Size(640, 480);
55
+ private static final float TEXT_SIZE_DIP = 10;
56
+ private Bitmap rgbFrameBitmap = null;
57
+ private long lastProcessingTimeMs;
58
+ private Integer sensorOrientation;
59
+ private Classifier classifier;
60
+ private BorderedText borderedText;
61
+ /** Input image size of the model along x axis. */
62
+ private int imageSizeX;
63
+ /** Input image size of the model along y axis. */
64
+ private int imageSizeY;
65
+
66
+ @Override
67
+ protected int getLayoutId() {
68
+ return R.layout.tfe_ic_camera_connection_fragment;
69
+ }
70
+
71
+ @Override
72
+ protected Size getDesiredPreviewFrameSize() {
73
+ return DESIRED_PREVIEW_SIZE;
74
+ }
75
+
76
+ @Override
77
+ public void onPreviewSizeChosen(final Size size, final int rotation) {
78
+ final float textSizePx =
79
+ TypedValue.applyDimension(
80
+ TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DIP, getResources().getDisplayMetrics());
81
+ borderedText = new BorderedText(textSizePx);
82
+ borderedText.setTypeface(Typeface.MONOSPACE);
83
+
84
+ recreateClassifier(getModel(), getDevice(), getNumThreads());
85
+ if (classifier == null) {
86
+ LOGGER.e("No classifier on preview!");
87
+ return;
88
+ }
89
+
90
+ previewWidth = size.getWidth();
91
+ previewHeight = size.getHeight();
92
+
93
+ sensorOrientation = rotation - getScreenOrientation();
94
+ LOGGER.i("Camera orientation relative to screen canvas: %d", sensorOrientation);
95
+
96
+ LOGGER.i("Initializing at size %dx%d", previewWidth, previewHeight);
97
+ rgbFrameBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
98
+ }
99
+
100
+ @Override
101
+ protected void processImage() {
102
+ rgbFrameBitmap.setPixels(getRgbBytes(), 0, previewWidth, 0, 0, previewWidth, previewHeight);
103
+ final int cropSize = Math.min(previewWidth, previewHeight);
104
+
105
+ runInBackground(
106
+ new Runnable() {
107
+ @Override
108
+ public void run() {
109
+ if (classifier != null) {
110
+ final long startTime = SystemClock.uptimeMillis();
111
+ //final List<Classifier.Recognition> results =
112
+ // classifier.recognizeImage(rgbFrameBitmap, sensorOrientation);
113
+ final List<Classifier.Recognition> results = new ArrayList<>();
114
+
115
+ float[] img_array = classifier.recognizeImage(rgbFrameBitmap, sensorOrientation);
116
+
117
+
118
+ /*
119
+ float maxval = Float.NEGATIVE_INFINITY;
120
+ float minval = Float.POSITIVE_INFINITY;
121
+ for (float cur : img_array) {
122
+ maxval = Math.max(maxval, cur);
123
+ minval = Math.min(minval, cur);
124
+ }
125
+ float multiplier = 0;
126
+ if ((maxval - minval) > 0) multiplier = 255 / (maxval - minval);
127
+
128
+ int[] img_normalized = new int[img_array.length];
129
+ for (int i = 0; i < img_array.length; ++i) {
130
+ float val = (float) (multiplier * (img_array[i] - minval));
131
+ img_normalized[i] = (int) val;
132
+ }
133
+
134
+
135
+
136
+ TextureView textureView = findViewById(R.id.textureView3);
137
+ //AutoFitTextureView textureView = (AutoFitTextureView) findViewById(R.id.texture);
138
+
139
+ if(textureView.isAvailable()) {
140
+ int width = imageSizeX;
141
+ int height = imageSizeY;
142
+
143
+ Canvas canvas = textureView.lockCanvas();
144
+ canvas.drawColor(Color.BLUE);
145
+ Paint paint = new Paint();
146
+ paint.setStyle(Paint.Style.FILL);
147
+ paint.setARGB(255, 150, 150, 150);
148
+
149
+ int canvas_size = Math.min(canvas.getWidth(), canvas.getHeight());
150
+
151
+ Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
152
+
153
+ for (int ii = 0; ii < width; ii++) //pass the screen pixels in 2 directions
154
+ {
155
+ for (int jj = 0; jj < height; jj++) {
156
+ //int val = img_normalized[ii + jj * width];
157
+ int index = (width - ii - 1) + (height - jj - 1) * width;
158
+ if(index < img_array.length) {
159
+ int val = img_normalized[index];
160
+ bitmap.setPixel(ii, jj, Color.rgb(val, val, val));
161
+ }
162
+ }
163
+ }
164
+
165
+ canvas.drawBitmap(bitmap, null, new RectF(0, 0, canvas_size, canvas_size), null);
166
+
167
+ textureView.unlockCanvasAndPost(canvas);
168
+
169
+ }
170
+ */
171
+
172
+ lastProcessingTimeMs = SystemClock.uptimeMillis() - startTime;
173
+ LOGGER.v("Detect: %s", results);
174
+
175
+ runOnUiThread(
176
+ new Runnable() {
177
+ @Override
178
+ public void run() {
179
+ //showResultsInBottomSheet(results);
180
+ showResultsInTexture(img_array, imageSizeX, imageSizeY);
181
+ showFrameInfo(previewWidth + "x" + previewHeight);
182
+ showCropInfo(imageSizeX + "x" + imageSizeY);
183
+ showCameraResolution(cropSize + "x" + cropSize);
184
+ showRotationInfo(String.valueOf(sensorOrientation));
185
+ showInference(lastProcessingTimeMs + "ms");
186
+ }
187
+ });
188
+ }
189
+ readyForNextImage();
190
+ }
191
+ });
192
+ }
193
+
194
+ @Override
195
+ protected void onInferenceConfigurationChanged() {
196
+ if (rgbFrameBitmap == null) {
197
+ // Defer creation until we're getting camera frames.
198
+ return;
199
+ }
200
+ final Device device = getDevice();
201
+ final Model model = getModel();
202
+ final int numThreads = getNumThreads();
203
+ runInBackground(() -> recreateClassifier(model, device, numThreads));
204
+ }
205
+
206
+ private void recreateClassifier(Model model, Device device, int numThreads) {
207
+ if (classifier != null) {
208
+ LOGGER.d("Closing classifier.");
209
+ classifier.close();
210
+ classifier = null;
211
+ }
212
+ if (device == Device.GPU
213
+ && (model == Model.QUANTIZED_MOBILENET || model == Model.QUANTIZED_EFFICIENTNET)) {
214
+ LOGGER.d("Not creating classifier: GPU doesn't support quantized models.");
215
+ runOnUiThread(
216
+ () -> {
217
+ Toast.makeText(this, R.string.tfe_ic_gpu_quant_error, Toast.LENGTH_LONG).show();
218
+ });
219
+ return;
220
+ }
221
+ try {
222
+ LOGGER.d(
223
+ "Creating classifier (model=%s, device=%s, numThreads=%d)", model, device, numThreads);
224
+ classifier = Classifier.create(this, model, device, numThreads);
225
+ } catch (IOException | IllegalArgumentException e) {
226
+ LOGGER.e(e, "Failed to create classifier.");
227
+ runOnUiThread(
228
+ () -> {
229
+ Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
230
+ });
231
+ return;
232
+ }
233
+
234
+ // Updates the input image size.
235
+ imageSizeX = classifier.getImageSizeX();
236
+ imageSizeY = classifier.getImageSizeY();
237
+ }
238
+ }
live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/LegacyCameraConnectionFragment.java ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package org.tensorflow.lite.examples.classification;
2
+
3
+ /*
4
+ * Copyright 2019 The TensorFlow Authors. All Rights Reserved.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import android.annotation.SuppressLint;
20
+ import android.app.Fragment;
21
+ import android.graphics.SurfaceTexture;
22
+ import android.hardware.Camera;
23
+ import android.hardware.Camera.CameraInfo;
24
+ import android.os.Bundle;
25
+ import android.os.Handler;
26
+ import android.os.HandlerThread;
27
+ import android.util.Size;
28
+ import android.util.SparseIntArray;
29
+ import android.view.LayoutInflater;
30
+ import android.view.Surface;
31
+ import android.view.TextureView;
32
+ import android.view.View;
33
+ import android.view.ViewGroup;
34
+ import java.io.IOException;
35
+ import java.util.List;
36
+ import org.tensorflow.lite.examples.classification.customview.AutoFitTextureView;
37
+ import org.tensorflow.lite.examples.classification.env.ImageUtils;
38
+ import org.tensorflow.lite.examples.classification.env.Logger;
39
+
40
+ public class LegacyCameraConnectionFragment extends Fragment {
41
+ private static final Logger LOGGER = new Logger();
42
+ /** Conversion from screen rotation to JPEG orientation. */
43
+ private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
44
+
45
+ static {
46
+ ORIENTATIONS.append(Surface.ROTATION_0, 90);
47
+ ORIENTATIONS.append(Surface.ROTATION_90, 0);
48
+ ORIENTATIONS.append(Surface.ROTATION_180, 270);
49
+ ORIENTATIONS.append(Surface.ROTATION_270, 180);
50
+ }
51
+
52
+ private Camera camera;
53
+ private Camera.PreviewCallback imageListener;
54
+ private Size desiredSize;
55
+ /** The layout identifier to inflate for this Fragment. */
56
+ private int layout;
57
+ /** An {@link AutoFitTextureView} for camera preview. */
58
+ private AutoFitTextureView textureView;
59
+ /**
60
+ * {@link TextureView.SurfaceTextureListener} handles several lifecycle events on a {@link
61
+ * TextureView}.
62
+ */
63
+ private final TextureView.SurfaceTextureListener surfaceTextureListener =
64
+ new TextureView.SurfaceTextureListener() {
65
+ @Override
66
+ public void onSurfaceTextureAvailable(
67
+ final SurfaceTexture texture, final int width, final int height) {
68
+
69
+ int index = getCameraId();
70
+ camera = Camera.open(index);
71
+
72
+ try {
73
+ Camera.Parameters parameters = camera.getParameters();
74
+ List<String> focusModes = parameters.getSupportedFocusModes();
75
+ if (focusModes != null
76
+ && focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
77
+ parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
78
+ }
79
+ List<Camera.Size> cameraSizes = parameters.getSupportedPreviewSizes();
80
+ Size[] sizes = new Size[cameraSizes.size()];
81
+ int i = 0;
82
+ for (Camera.Size size : cameraSizes) {
83
+ sizes[i++] = new Size(size.width, size.height);
84
+ }
85
+ Size previewSize =
86
+ CameraConnectionFragment.chooseOptimalSize(
87
+ sizes, desiredSize.getWidth(), desiredSize.getHeight());
88
+ parameters.setPreviewSize(previewSize.getWidth(), previewSize.getHeight());
89
+ camera.setDisplayOrientation(90);
90
+ camera.setParameters(parameters);
91
+ camera.setPreviewTexture(texture);
92
+ } catch (IOException exception) {
93
+ camera.release();
94
+ }
95
+
96
+ camera.setPreviewCallbackWithBuffer(imageListener);
97
+ Camera.Size s = camera.getParameters().getPreviewSize();
98
+ camera.addCallbackBuffer(new byte[ImageUtils.getYUVByteSize(s.height, s.width)]);
99
+
100
+ textureView.setAspectRatio(s.height, s.width);
101
+
102
+ camera.startPreview();
103
+ }
104
+
105
+ @Override
106
+ public void onSurfaceTextureSizeChanged(
107
+ final SurfaceTexture texture, final int width, final int height) {}
108
+
109
+ @Override
110
+ public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {
111
+ return true;
112
+ }
113
+
114
+ @Override
115
+ public void onSurfaceTextureUpdated(final SurfaceTexture texture) {}
116
+ };
117
+ /** An additional thread for running tasks that shouldn't block the UI. */
118
+ private HandlerThread backgroundThread;
119
+
120
+ @SuppressLint("ValidFragment")
121
+ public LegacyCameraConnectionFragment(
122
+ final Camera.PreviewCallback imageListener, final int layout, final Size desiredSize) {
123
+ this.imageListener = imageListener;
124
+ this.layout = layout;
125
+ this.desiredSize = desiredSize;
126
+ }
127
+
128
+ @Override
129
+ public View onCreateView(
130
+ final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
131
+ return inflater.inflate(layout, container, false);
132
+ }
133
+
134
+ @Override
135
+ public void onViewCreated(final View view, final Bundle savedInstanceState) {
136
+ textureView = (AutoFitTextureView) view.findViewById(R.id.texture);
137
+ }
138
+
139
+ @Override
140
+ public void onActivityCreated(final Bundle savedInstanceState) {
141
+ super.onActivityCreated(savedInstanceState);
142
+ }
143
+
144
+ @Override
145
+ public void onResume() {
146
+ super.onResume();
147
+ startBackgroundThread();
148
+ // When the screen is turned off and turned back on, the SurfaceTexture is already
149
+ // available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open
150
+ // a camera and start preview from here (otherwise, we wait until the surface is ready in
151
+ // the SurfaceTextureListener).
152
+
153
+ if (textureView.isAvailable()) {
154
+ if (camera != null) {
155
+ camera.startPreview();
156
+ }
157
+ } else {
158
+ textureView.setSurfaceTextureListener(surfaceTextureListener);
159
+ }
160
+ }
161
+
162
+ @Override
163
+ public void onPause() {
164
+ stopCamera();
165
+ stopBackgroundThread();
166
+ super.onPause();
167
+ }
168
+
169
+ /** Starts a background thread and its {@link Handler}. */
170
+ private void startBackgroundThread() {
171
+ backgroundThread = new HandlerThread("CameraBackground");
172
+ backgroundThread.start();
173
+ }
174
+
175
+ /** Stops the background thread and its {@link Handler}. */
176
+ private void stopBackgroundThread() {
177
+ backgroundThread.quitSafely();
178
+ try {
179
+ backgroundThread.join();
180
+ backgroundThread = null;
181
+ } catch (final InterruptedException e) {
182
+ LOGGER.e(e, "Exception!");
183
+ }
184
+ }
185
+
186
+ protected void stopCamera() {
187
+ if (camera != null) {
188
+ camera.stopPreview();
189
+ camera.setPreviewCallback(null);
190
+ camera.release();
191
+ camera = null;
192
+ }
193
+ }
194
+
195
+ private int getCameraId() {
196
+ CameraInfo ci = new CameraInfo();
197
+ for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
198
+ Camera.getCameraInfo(i, ci);
199
+ if (ci.facing == CameraInfo.CAMERA_FACING_BACK) return i;
200
+ }
201
+ return -1; // No camera found
202
+ }
203
+ }
live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/customview/AutoFitTextureView.java ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2019 The TensorFlow Authors. All Rights Reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ package org.tensorflow.lite.examples.classification.customview;
18
+
19
+ import android.content.Context;
20
+ import android.util.AttributeSet;
21
+ import android.view.TextureView;
22
+
23
+ /** A {@link TextureView} that can be adjusted to a specified aspect ratio. */
24
+ public class AutoFitTextureView extends TextureView {
25
+ private int ratioWidth = 0;
26
+ private int ratioHeight = 0;
27
+
28
+ public AutoFitTextureView(final Context context) {
29
+ this(context, null);
30
+ }
31
+
32
+ public AutoFitTextureView(final Context context, final AttributeSet attrs) {
33
+ this(context, attrs, 0);
34
+ }
35
+
36
+ public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {
37
+ super(context, attrs, defStyle);
38
+ }
39
+
40
+ /**
41
+ * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
42
+ * calculated from the parameters. Note that the actual sizes of parameters don't matter, that is,
43
+ * calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
44
+ *
45
+ * @param width Relative horizontal size
46
+ * @param height Relative vertical size
47
+ */
48
+ public void setAspectRatio(final int width, final int height) {
49
+ if (width < 0 || height < 0) {
50
+ throw new IllegalArgumentException("Size cannot be negative.");
51
+ }
52
+ ratioWidth = width;
53
+ ratioHeight = height;
54
+ requestLayout();
55
+ }
56
+
57
+ @Override
58
+ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
59
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
60
+ final int width = MeasureSpec.getSize(widthMeasureSpec);
61
+ final int height = MeasureSpec.getSize(heightMeasureSpec);
62
+ if (0 == ratioWidth || 0 == ratioHeight) {
63
+ setMeasuredDimension(width, height);
64
+ } else {
65
+ if (width < height * ratioWidth / ratioHeight) {
66
+ setMeasuredDimension(width, width * ratioHeight / ratioWidth);
67
+ } else {
68
+ setMeasuredDimension(height * ratioWidth / ratioHeight, height);
69
+ }
70
+ }
71
+ }
72
+ }
live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/customview/OverlayView.java ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
14
+ ==============================================================================*/
15
+
16
+ package org.tensorflow.lite.examples.classification.customview;
17
+
18
+ import android.content.Context;
19
+ import android.graphics.Canvas;
20
+ import android.util.AttributeSet;
21
+ import android.view.View;
22
+ import java.util.LinkedList;
23
+ import java.util.List;
24
+
25
+ /** A simple View providing a render callback to other classes. */
26
+ public class OverlayView extends View {
27
+ private final List<DrawCallback> callbacks = new LinkedList<DrawCallback>();
28
+
29
+ public OverlayView(final Context context, final AttributeSet attrs) {
30
+ super(context, attrs);
31
+ }
32
+
33
+ public void addCallback(final DrawCallback callback) {
34
+ callbacks.add(callback);
35
+ }
36
+
37
+ @Override
38
+ public synchronized void draw(final Canvas canvas) {
39
+ for (final DrawCallback callback : callbacks) {
40
+ callback.drawCallback(canvas);
41
+ }
42
+ }
43
+
44
+ /** Interface defining the callback for client classes. */
45
+ public interface DrawCallback {
46
+ public void drawCallback(final Canvas canvas);
47
+ }
48
+ }
live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/customview/RecognitionScoreView.java ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
14
+ ==============================================================================*/
15
+
16
+ package org.tensorflow.lite.examples.classification.customview;
17
+
18
+ import android.content.Context;
19
+ import android.graphics.Canvas;
20
+ import android.graphics.Paint;
21
+ import android.util.AttributeSet;
22
+ import android.util.TypedValue;
23
+ import android.view.View;
24
+ import java.util.List;
25
+ import org.tensorflow.lite.examples.classification.tflite.Classifier.Recognition;
26
+
27
+ public class RecognitionScoreView extends View implements ResultsView {
28
+ private static final float TEXT_SIZE_DIP = 16;
29
+ private final float textSizePx;
30
+ private final Paint fgPaint;
31
+ private final Paint bgPaint;
32
+ private List<Recognition> results;
33
+
34
+ public RecognitionScoreView(final Context context, final AttributeSet set) {
35
+ super(context, set);
36
+
37
+ textSizePx =
38
+ TypedValue.applyDimension(
39
+ TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DIP, getResources().getDisplayMetrics());
40
+ fgPaint = new Paint();
41
+ fgPaint.setTextSize(textSizePx);
42
+
43
+ bgPaint = new Paint();
44
+ bgPaint.setColor(0xcc4285f4);
45
+ }
46
+
47
+ @Override
48
+ public void setResults(final List<Recognition> results) {
49
+ this.results = results;
50
+ postInvalidate();
51
+ }
52
+
53
+ @Override
54
+ public void onDraw(final Canvas canvas) {
55
+ final int x = 10;
56
+ int y = (int) (fgPaint.getTextSize() * 1.5f);
57
+
58
+ canvas.drawPaint(bgPaint);
59
+
60
+ if (results != null) {
61
+ for (final Recognition recog : results) {
62
+ canvas.drawText(recog.getTitle() + ": " + recog.getConfidence(), x, y, fgPaint);
63
+ y += (int) (fgPaint.getTextSize() * 1.5f);
64
+ }
65
+ }
66
+ }
67
+ }
live2diff/MiDaS/mobile/android/app/src/main/java/org/tensorflow/lite/examples/classification/customview/ResultsView.java ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
14
+ ==============================================================================*/
15
+
16
+ package org.tensorflow.lite.examples.classification.customview;
17
+
18
+ import java.util.List;
19
+ import org.tensorflow.lite.examples.classification.tflite.Classifier.Recognition;
20
+
21
+ public interface ResultsView {
22
+ public void setResults(final List<Recognition> results);
23
+ }
live2diff/MiDaS/mobile/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ xmlns:aapt="http://schemas.android.com/aapt"
3
+ android:width="108dp"
4
+ android:height="108dp"
5
+ android:viewportHeight="108"
6
+ android:viewportWidth="108">
7
+ <path
8
+ android:fillType="evenOdd"
9
+ android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
10
+ android:strokeColor="#00000000"
11
+ android:strokeWidth="1">
12
+ <aapt:attr name="android:fillColor">
13
+ <gradient
14
+ android:endX="78.5885"
15
+ android:endY="90.9159"
16
+ android:startX="48.7653"
17
+ android:startY="61.0927"
18
+ android:type="linear">
19
+ <item
20
+ android:color="#44000000"
21
+ android:offset="0.0"/>
22
+ <item
23
+ android:color="#00000000"
24
+ android:offset="1.0"/>
25
+ </gradient>
26
+ </aapt:attr>
27
+ </path>
28
+ <path
29
+ android:fillColor="#FFFFFF"
30
+ android:fillType="nonZero"
31
+ android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
32
+ android:strokeColor="#00000000"
33
+ android:strokeWidth="1"/>
34
+ </vector>
live2diff/MiDaS/mobile/android/app/src/main/res/drawable/bottom_sheet_bg.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <shape xmlns:android="http://schemas.android.com/apk/res/android"
3
+ android:shape="rectangle">
4
+ <corners
5
+ android:topLeftRadius="@dimen/tfe_bottom_sheet_corner_radius"
6
+ android:topRightRadius="@dimen/tfe_bottom_sheet_corner_radius" />
7
+ <padding android:top="@dimen/tfe_bottom_sheet_top_padding" />
8
+ <solid android:color="@android:color/white" />
9
+ </shape>
live2diff/MiDaS/mobile/android/app/src/main/res/drawable/ic_baseline_add.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:width="24dp"
3
+ android:height="24dp"
4
+ android:viewportWidth="24"
5
+ android:viewportHeight="24">
6
+ <path
7
+ android:fillColor="#FF000000"
8
+ android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
9
+ </vector>
live2diff/MiDaS/mobile/android/app/src/main/res/drawable/ic_baseline_remove.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:width="24dp"
3
+ android:height="24dp"
4
+ android:viewportWidth="24"
5
+ android:viewportHeight="24">
6
+ <path
7
+ android:fillColor="#FF000000"
8
+ android:pathData="M19,13H5v-2h14v2z"/>
9
+ </vector>
live2diff/MiDaS/mobile/android/app/src/main/res/drawable/ic_launcher_background.xml ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
3
+ android:width="108dp"
4
+ android:height="108dp"
5
+ android:viewportHeight="108"
6
+ android:viewportWidth="108">
7
+ <path
8
+ android:fillColor="#26A69A"
9
+ android:pathData="M0,0h108v108h-108z" />
10
+ <path
11
+ android:fillColor="#00000000"
12
+ android:pathData="M9,0L9,108"
13
+ android:strokeColor="#33FFFFFF"
14
+ android:strokeWidth="0.8" />
15
+ <path
16
+ android:fillColor="#00000000"
17
+ android:pathData="M19,0L19,108"
18
+ android:strokeColor="#33FFFFFF"
19
+ android:strokeWidth="0.8" />
20
+ <path
21
+ android:fillColor="#00000000"
22
+ android:pathData="M29,0L29,108"
23
+ android:strokeColor="#33FFFFFF"
24
+ android:strokeWidth="0.8" />
25
+ <path
26
+ android:fillColor="#00000000"
27
+ android:pathData="M39,0L39,108"
28
+ android:strokeColor="#33FFFFFF"
29
+ android:strokeWidth="0.8" />
30
+ <path
31
+ android:fillColor="#00000000"
32
+ android:pathData="M49,0L49,108"
33
+ android:strokeColor="#33FFFFFF"
34
+ android:strokeWidth="0.8" />
35
+ <path
36
+ android:fillColor="#00000000"
37
+ android:pathData="M59,0L59,108"
38
+ android:strokeColor="#33FFFFFF"
39
+ android:strokeWidth="0.8" />
40
+ <path
41
+ android:fillColor="#00000000"
42
+ android:pathData="M69,0L69,108"
43
+ android:strokeColor="#33FFFFFF"
44
+ android:strokeWidth="0.8" />
45
+ <path
46
+ android:fillColor="#00000000"
47
+ android:pathData="M79,0L79,108"
48
+ android:strokeColor="#33FFFFFF"
49
+ android:strokeWidth="0.8" />
50
+ <path
51
+ android:fillColor="#00000000"
52
+ android:pathData="M89,0L89,108"
53
+ android:strokeColor="#33FFFFFF"
54
+ android:strokeWidth="0.8" />
55
+ <path
56
+ android:fillColor="#00000000"
57
+ android:pathData="M99,0L99,108"
58
+ android:strokeColor="#33FFFFFF"
59
+ android:strokeWidth="0.8" />
60
+ <path
61
+ android:fillColor="#00000000"
62
+ android:pathData="M0,9L108,9"
63
+ android:strokeColor="#33FFFFFF"
64
+ android:strokeWidth="0.8" />
65
+ <path
66
+ android:fillColor="#00000000"
67
+ android:pathData="M0,19L108,19"
68
+ android:strokeColor="#33FFFFFF"
69
+ android:strokeWidth="0.8" />
70
+ <path
71
+ android:fillColor="#00000000"
72
+ android:pathData="M0,29L108,29"
73
+ android:strokeColor="#33FFFFFF"
74
+ android:strokeWidth="0.8" />
75
+ <path
76
+ android:fillColor="#00000000"
77
+ android:pathData="M0,39L108,39"
78
+ android:strokeColor="#33FFFFFF"
79
+ android:strokeWidth="0.8" />
80
+ <path
81
+ android:fillColor="#00000000"
82
+ android:pathData="M0,49L108,49"
83
+ android:strokeColor="#33FFFFFF"
84
+ android:strokeWidth="0.8" />
85
+ <path
86
+ android:fillColor="#00000000"
87
+ android:pathData="M0,59L108,59"
88
+ android:strokeColor="#33FFFFFF"
89
+ android:strokeWidth="0.8" />
90
+ <path
91
+ android:fillColor="#00000000"
92
+ android:pathData="M0,69L108,69"
93
+ android:strokeColor="#33FFFFFF"
94
+ android:strokeWidth="0.8" />
95
+ <path
96
+ android:fillColor="#00000000"
97
+ android:pathData="M0,79L108,79"
98
+ android:strokeColor="#33FFFFFF"
99
+ android:strokeWidth="0.8" />
100
+ <path
101
+ android:fillColor="#00000000"
102
+ android:pathData="M0,89L108,89"
103
+ android:strokeColor="#33FFFFFF"
104
+ android:strokeWidth="0.8" />
105
+ <path
106
+ android:fillColor="#00000000"
107
+ android:pathData="M0,99L108,99"
108
+ android:strokeColor="#33FFFFFF"
109
+ android:strokeWidth="0.8" />
110
+ <path
111
+ android:fillColor="#00000000"
112
+ android:pathData="M19,29L89,29"
113
+ android:strokeColor="#33FFFFFF"
114
+ android:strokeWidth="0.8" />
115
+ <path
116
+ android:fillColor="#00000000"
117
+ android:pathData="M19,39L89,39"
118
+ android:strokeColor="#33FFFFFF"
119
+ android:strokeWidth="0.8" />
120
+ <path
121
+ android:fillColor="#00000000"
122
+ android:pathData="M19,49L89,49"
123
+ android:strokeColor="#33FFFFFF"
124
+ android:strokeWidth="0.8" />
125
+ <path
126
+ android:fillColor="#00000000"
127
+ android:pathData="M19,59L89,59"
128
+ android:strokeColor="#33FFFFFF"
129
+ android:strokeWidth="0.8" />
130
+ <path
131
+ android:fillColor="#00000000"
132
+ android:pathData="M19,69L89,69"
133
+ android:strokeColor="#33FFFFFF"
134
+ android:strokeWidth="0.8" />
135
+ <path
136
+ android:fillColor="#00000000"
137
+ android:pathData="M19,79L89,79"
138
+ android:strokeColor="#33FFFFFF"
139
+ android:strokeWidth="0.8" />
140
+ <path
141
+ android:fillColor="#00000000"
142
+ android:pathData="M29,19L29,89"
143
+ android:strokeColor="#33FFFFFF"
144
+ android:strokeWidth="0.8" />
145
+ <path
146
+ android:fillColor="#00000000"
147
+ android:pathData="M39,19L39,89"
148
+ android:strokeColor="#33FFFFFF"
149
+ android:strokeWidth="0.8" />
150
+ <path
151
+ android:fillColor="#00000000"
152
+ android:pathData="M49,19L49,89"
153
+ android:strokeColor="#33FFFFFF"
154
+ android:strokeWidth="0.8" />
155
+ <path
156
+ android:fillColor="#00000000"
157
+ android:pathData="M59,19L59,89"
158
+ android:strokeColor="#33FFFFFF"
159
+ android:strokeWidth="0.8" />
160
+ <path
161
+ android:fillColor="#00000000"
162
+ android:pathData="M69,19L69,89"
163
+ android:strokeColor="#33FFFFFF"
164
+ android:strokeWidth="0.8" />
165
+ <path
166
+ android:fillColor="#00000000"
167
+ android:pathData="M79,19L79,89"
168
+ android:strokeColor="#33FFFFFF"
169
+ android:strokeWidth="0.8" />
170
+ </vector>
live2diff/MiDaS/mobile/android/app/src/main/res/drawable/rectangle.xml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <shape xmlns:android="http://schemas.android.com/apk/res/android"
3
+ android:id="@+id/listview_background_shape">
4
+ <stroke
5
+ android:width="1dp"
6
+ android:color="@android:color/darker_gray" />
7
+ <padding
8
+ android:bottom="2dp"
9
+ android:left="2dp"
10
+ android:right="2dp"
11
+ android:top="2dp" />
12
+ <solid android:color="#ffffffff" />
13
+ </shape>
live2diff/MiDaS/mobile/android/app/src/main/res/layout/tfe_ic_activity_camera.xml ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?><!--
2
+ Copyright 2019 The TensorFlow Authors. All Rights Reserved.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ -->
16
+ <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
17
+ xmlns:tools="http://schemas.android.com/tools"
18
+ android:layout_width="match_parent"
19
+ android:layout_height="match_parent"
20
+ android:background="#00000000">
21
+
22
+ <RelativeLayout
23
+ android:layout_width="match_parent"
24
+ android:layout_height="match_parent"
25
+ android:background="#00000000"
26
+ android:orientation="vertical">
27
+
28
+
29
+ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
30
+ xmlns:tools="http://schemas.android.com/tools"
31
+ android:id="@+id/container"
32
+ android:layout_width="match_parent"
33
+ android:layout_height="match_parent"
34
+ android:background="@android:color/black"
35
+ tools:context="org.tensorflow.lite.examples.classification.CameraActivity" />
36
+
37
+
38
+ <androidx.appcompat.widget.Toolbar
39
+ android:id="@+id/toolbar"
40
+ android:layout_width="match_parent"
41
+ android:layout_height="?attr/actionBarSize"
42
+ android:layout_alignParentTop="true"
43
+ android:background="@color/tfe_semi_transparent">
44
+
45
+ <ImageView
46
+ android:layout_width="wrap_content"
47
+ android:layout_height="wrap_content"
48
+ android:src="@drawable/tfl2_logo" />
49
+ </androidx.appcompat.widget.Toolbar>
50
+
51
+ </RelativeLayout>
52
+
53
+ <include
54
+ android:id="@+id/bottom_sheet_layout"
55
+ layout="@layout/tfe_ic_layout_bottom_sheet" />
56
+ </androidx.coordinatorlayout.widget.CoordinatorLayout>
live2diff/MiDaS/mobile/android/app/src/main/res/layout/tfe_ic_camera_connection_fragment.xml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?><!--
2
+ Copyright 2019 The TensorFlow Authors. All Rights Reserved.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ -->
16
+ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
17
+ android:layout_width="match_parent"
18
+ android:layout_height="match_parent">
19
+
20
+ <org.tensorflow.lite.examples.classification.customview.AutoFitTextureView
21
+ android:id="@+id/texture"
22
+ android:layout_width="wrap_content"
23
+ android:layout_height="wrap_content"
24
+ android:layout_alignParentTop="true" />
25
+
26
+ <TextureView
27
+ android:id="@+id/textureView3"
28
+ android:layout_width="wrap_content"
29
+ android:layout_height="wrap_content" />
30
+
31
+
32
+ </RelativeLayout>
live2diff/MiDaS/mobile/android/app/src/main/res/layout/tfe_ic_layout_bottom_sheet.xml ADDED
@@ -0,0 +1,321 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
+ xmlns:app="http://schemas.android.com/apk/res-auto"
4
+ android:id="@+id/bottom_sheet_layout"
5
+ android:layout_width="match_parent"
6
+ android:layout_height="wrap_content"
7
+ android:layout_gravity="center_horizontal"
8
+ android:background="@drawable/bottom_sheet_bg"
9
+ android:gravity="center_horizontal"
10
+ android:orientation="vertical"
11
+ android:padding="8dp"
12
+ app:behavior_hideable="true"
13
+ app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
14
+
15
+ <LinearLayout
16
+ android:id="@+id/gesture_layout"
17
+ android:layout_width="match_parent"
18
+ android:layout_height="wrap_content"
19
+ android:orientation="vertical"
20
+ android:paddingTop="10dp"
21
+ android:paddingBottom="10dp">
22
+
23
+ <ImageView
24
+ android:id="@+id/bottom_sheet_arrow"
25
+ android:layout_width="wrap_content"
26
+ android:layout_height="wrap_content"
27
+ android:layout_gravity="center"
28
+ android:src="@drawable/icn_chevron_up" />
29
+
30
+ <LinearLayout
31
+ android:layout_width="match_parent"
32
+ android:layout_height="wrap_content"
33
+ android:layout_marginTop="10dp"
34
+ android:orientation="horizontal">
35
+
36
+ <TextView
37
+ android:id="@+id/detected_item"
38
+ android:layout_width="wrap_content"
39
+ android:layout_height="wrap_content"
40
+ android:textColor="@android:color/black"
41
+ android:textSize="16sp" />
42
+
43
+ <TextView
44
+ android:id="@+id/detected_item_value"
45
+ android:layout_width="match_parent"
46
+ android:layout_height="wrap_content"
47
+ android:gravity="right"
48
+ android:textColor="@android:color/black"
49
+ android:textSize="16sp" />
50
+
51
+ </LinearLayout>
52
+
53
+ <LinearLayout
54
+ android:layout_width="match_parent"
55
+ android:layout_height="wrap_content"
56
+ android:layout_marginTop="10dp"
57
+ android:orientation="horizontal">
58
+
59
+ <TextView
60
+ android:id="@+id/detected_item1"
61
+ android:layout_width="wrap_content"
62
+ android:layout_height="wrap_content"
63
+ android:textColor="@android:color/darker_gray"
64
+ android:textSize="12sp" />
65
+
66
+ <TextView
67
+ android:id="@+id/detected_item1_value"
68
+ android:layout_width="match_parent"
69
+ android:layout_height="wrap_content"
70
+ android:gravity="right"
71
+ android:textColor="@android:color/darker_gray"
72
+ android:textSize="12sp" />
73
+
74
+ </LinearLayout>
75
+
76
+ <LinearLayout
77
+ android:layout_width="match_parent"
78
+ android:layout_height="wrap_content"
79
+ android:layout_marginTop="10dp"
80
+ android:orientation="horizontal">
81
+
82
+ <TextView
83
+ android:id="@+id/detected_item2"
84
+ android:layout_width="wrap_content"
85
+ android:layout_height="wrap_content"
86
+ android:textColor="@android:color/darker_gray"
87
+ android:textSize="12sp" />
88
+
89
+ <TextView
90
+ android:id="@+id/detected_item2_value"
91
+ android:layout_width="match_parent"
92
+ android:layout_height="wrap_content"
93
+ android:gravity="right"
94
+ android:textColor="@android:color/darker_gray"
95
+ android:textSize="12sp" />
96
+
97
+ </LinearLayout>
98
+
99
+ <View
100
+ android:layout_width="match_parent"
101
+ android:layout_height="1px"
102
+ android:layout_marginTop="8dp"
103
+ android:background="@android:color/darker_gray" />
104
+ </LinearLayout>
105
+
106
+ <LinearLayout
107
+ android:layout_width="match_parent"
108
+ android:layout_height="wrap_content"
109
+ android:orientation="horizontal">
110
+
111
+ <TextView
112
+ android:id="@+id/frame"
113
+ android:layout_width="wrap_content"
114
+ android:layout_height="wrap_content"
115
+ android:layout_marginTop="10dp"
116
+ android:text="Frame"
117
+ android:textColor="@android:color/black" />
118
+
119
+ <TextView
120
+ android:id="@+id/frame_info"
121
+ android:layout_width="match_parent"
122
+ android:layout_height="wrap_content"
123
+ android:layout_marginTop="10dp"
124
+ android:gravity="right"
125
+ android:text="640*480"
126
+ android:textColor="@android:color/black" />
127
+ </LinearLayout>
128
+
129
+ <LinearLayout
130
+ android:layout_width="match_parent"
131
+ android:layout_height="wrap_content"
132
+ android:orientation="horizontal">
133
+
134
+ <TextView
135
+ android:id="@+id/crop"
136
+ android:layout_width="wrap_content"
137
+ android:layout_height="wrap_content"
138
+ android:layout_marginTop="10dp"
139
+ android:text="Crop"
140
+ android:textColor="@android:color/black" />
141
+
142
+ <TextView
143
+ android:id="@+id/crop_info"
144
+ android:layout_width="match_parent"
145
+ android:layout_height="wrap_content"
146
+ android:layout_marginTop="10dp"
147
+ android:gravity="right"
148
+ android:text="640*480"
149
+ android:textColor="@android:color/black" />
150
+ </LinearLayout>
151
+
152
+ <LinearLayout
153
+ android:layout_width="match_parent"
154
+ android:layout_height="wrap_content"
155
+ android:orientation="horizontal">
156
+
157
+ <TextView
158
+ android:id="@+id/view"
159
+ android:layout_width="wrap_content"
160
+ android:layout_height="wrap_content"
161
+ android:layout_marginTop="10dp"
162
+ android:text="View"
163
+ android:textColor="@android:color/black" />
164
+
165
+ <TextView
166
+ android:id="@+id/view_info"
167
+ android:layout_width="match_parent"
168
+ android:layout_height="wrap_content"
169
+ android:layout_marginTop="10dp"
170
+ android:gravity="right"
171
+ android:text="640*480"
172
+ android:textColor="@android:color/black" />
173
+ </LinearLayout>
174
+
175
+ <LinearLayout
176
+ android:layout_width="match_parent"
177
+ android:layout_height="wrap_content"
178
+ android:orientation="horizontal">
179
+
180
+ <TextView
181
+ android:id="@+id/rotation"
182
+ android:layout_width="wrap_content"
183
+ android:layout_height="wrap_content"
184
+ android:layout_marginTop="10dp"
185
+ android:text="Rotation"
186
+ android:textColor="@android:color/black" />
187
+
188
+ <TextView
189
+ android:id="@+id/rotation_info"
190
+ android:layout_width="match_parent"
191
+ android:layout_height="wrap_content"
192
+ android:layout_marginTop="10dp"
193
+ android:gravity="right"
194
+ android:text="640*480"
195
+ android:textColor="@android:color/black" />
196
+ </LinearLayout>
197
+
198
+ <LinearLayout
199
+ android:layout_width="match_parent"
200
+ android:layout_height="wrap_content"
201
+ android:orientation="horizontal">
202
+
203
+ <TextView
204
+ android:id="@+id/inference"
205
+ android:layout_width="wrap_content"
206
+ android:layout_height="wrap_content"
207
+ android:layout_marginTop="10dp"
208
+ android:text="Inference Time"
209
+ android:textColor="@android:color/black" />
210
+
211
+ <TextView
212
+ android:id="@+id/inference_info"
213
+ android:layout_width="match_parent"
214
+ android:layout_height="wrap_content"
215
+ android:layout_marginTop="10dp"
216
+ android:gravity="right"
217
+ android:text="640*480"
218
+ android:textColor="@android:color/black" />
219
+ </LinearLayout>
220
+
221
+ <View
222
+ android:layout_width="match_parent"
223
+ android:layout_height="1px"
224
+ android:layout_marginTop="10dp"
225
+ android:background="@android:color/darker_gray" />
226
+
227
+ <RelativeLayout
228
+ android:layout_width="match_parent"
229
+ android:layout_height="wrap_content"
230
+ android:layout_marginTop="10dp"
231
+ android:orientation="horizontal">
232
+
233
+ <TextView
234
+ android:layout_width="wrap_content"
235
+ android:layout_height="wrap_content"
236
+ android:layout_marginTop="10dp"
237
+ android:text="Threads"
238
+ android:textColor="@android:color/black" />
239
+
240
+ <LinearLayout
241
+ android:layout_width="wrap_content"
242
+ android:layout_height="wrap_content"
243
+ android:layout_alignParentRight="true"
244
+ android:background="@drawable/rectangle"
245
+ android:gravity="center"
246
+ android:orientation="horizontal"
247
+ android:padding="4dp">
248
+
249
+ <ImageView
250
+ android:id="@+id/minus"
251
+ android:layout_width="wrap_content"
252
+ android:layout_height="wrap_content"
253
+ android:src="@drawable/ic_baseline_remove" />
254
+
255
+ <TextView
256
+ android:id="@+id/threads"
257
+ android:layout_width="wrap_content"
258
+ android:layout_height="wrap_content"
259
+ android:layout_marginLeft="10dp"
260
+ android:layout_marginRight="10dp"
261
+ android:text="1"
262
+ android:textColor="@android:color/black"
263
+ android:textSize="14sp" />
264
+ <ImageView
265
+ android:id="@+id/plus"
266
+ android:layout_width="wrap_content"
267
+ android:layout_height="wrap_content"
268
+ android:src="@drawable/ic_baseline_add" />
269
+
270
+ </LinearLayout>
271
+ </RelativeLayout>
272
+
273
+ <View
274
+ android:layout_width="match_parent"
275
+ android:layout_height="1px"
276
+ android:layout_marginTop="10dp"
277
+ android:background="@android:color/darker_gray" />
278
+
279
+ <RelativeLayout
280
+ android:layout_width="match_parent"
281
+ android:layout_height="wrap_content"
282
+ android:orientation="horizontal">
283
+
284
+ <TextView
285
+ android:layout_width="wrap_content"
286
+ android:layout_height="wrap_content"
287
+ android:layout_marginTop="10dp"
288
+ android:text="@string/tfe_ic_model"
289
+ android:textColor="@android:color/black" />
290
+
291
+ <Spinner
292
+ android:id="@+id/model_spinner"
293
+ android:layout_width="wrap_content"
294
+ android:layout_height="wrap_content"
295
+ android:layout_alignParentRight="true"
296
+ android:layout_marginTop="10dp"
297
+ android:entries="@array/tfe_ic_models"
298
+ android:prompt="@string/tfe_ic_model" />
299
+ </RelativeLayout>
300
+
301
+ <RelativeLayout
302
+ android:layout_width="match_parent"
303
+ android:layout_height="wrap_content"
304
+ android:orientation="horizontal">
305
+ <TextView
306
+ android:layout_width="wrap_content"
307
+ android:layout_height="wrap_content"
308
+ android:layout_marginTop="10dp"
309
+ android:text="@string/tfe_ic_device"
310
+ android:textColor="@android:color/black" />
311
+
312
+ <Spinner
313
+ android:id="@+id/device_spinner"
314
+ android:layout_width="wrap_content"
315
+ android:layout_height="wrap_content"
316
+ android:layout_marginTop="10dp"
317
+ android:layout_alignParentRight="true"
318
+ android:entries="@array/tfe_ic_devices"
319
+ android:prompt="@string/tfe_ic_device" />
320
+ </RelativeLayout>
321
+ </LinearLayout>
live2diff/MiDaS/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <background android:drawable="@android:color/white"/>
4
+ <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
5
+ </adaptive-icon>
live2diff/MiDaS/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <background android:drawable="@android:color/white"/>
4
+ <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
5
+ </adaptive-icon>
live2diff/MiDaS/mobile/android/app/src/main/res/values/colors.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <resources>
3
+ <color name="tfe_color_primary">#ffa800</color>
4
+ <color name="tfe_color_primary_dark">#ff6f00</color>
5
+ <color name="tfe_color_accent">#425066</color>
6
+
7
+ <color name="tfe_semi_transparent">#66000000</color>
8
+ </resources>
live2diff/MiDaS/mobile/android/app/src/main/res/values/dimens.xml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <resources>
3
+ <dimen name="tfe_bottom_sheet_corner_radius">15dp</dimen>
4
+ <dimen name="tfe_bottom_sheet_top_padding">8dp</dimen>
5
+ </resources>
live2diff/MiDaS/mobile/android/app/src/main/res/values/strings.xml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <resources>
2
+ <string name="tfe_ic_app_name" translation_description="Image Classification demo app [CHAR_LIMIT=40]">Midas</string>
3
+ <string name="tfe_ic_camera_error" translation_description="Error regarding camera support[CHAR_LIMIT=40]">This device doesn\'t support Camera2 API.</string>
4
+ <string name="tfe_ic_gpu_quant_error" translation_description="Error regarding GPU support for Quant models[CHAR_LIMIT=60]">GPU does not yet supported quantized models.</string>
5
+ <string name="tfe_ic_model" translatable="false">Model:</string>
6
+ <string-array name="tfe_ic_models" translatable="false">
7
+ <item>Float_EfficientNet</item>
8
+ <!--
9
+ <item>Quantized_EfficientNet</item>
10
+ <item>Quantized_MobileNet</item>
11
+ <item>Float_MobileNet</item>
12
+ -->
13
+ </string-array>
14
+
15
+ <string name="tfe_ic_device" translatable="false">Device:</string>
16
+ <string-array name="tfe_ic_devices" translatable="false">
17
+ <item>GPU</item>
18
+ <item>CPU</item>
19
+ <item>NNAPI</item>
20
+ </string-array>
21
+ </resources>
live2diff/MiDaS/mobile/android/app/src/main/res/values/styles.xml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <resources>
2
+
3
+ <!-- Base application theme. -->
4
+ <style name="AppTheme.ImageClassification" parent="Theme.AppCompat.Light.NoActionBar">
5
+ <!-- Customize your theme here. -->
6
+ <item name="colorPrimary">@color/tfe_color_primary</item>
7
+ <item name="colorPrimaryDark">@color/tfe_color_primary_dark</item>
8
+ <item name="colorAccent">@color/tfe_color_accent</item>
9
+ </style>
10
+
11
+ </resources>
live2diff/MiDaS/mobile/android/build.gradle ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Top-level build file where you can add configuration options common to all sub-projects/modules.
2
+
3
+ buildscript {
4
+
5
+ repositories {
6
+ google()
7
+ jcenter()
8
+ }
9
+ dependencies {
10
+ classpath 'com.android.tools.build:gradle:4.0.0'
11
+ classpath 'de.undercouch:gradle-download-task:4.0.2'
12
+ // NOTE: Do not place your application dependencies here; they belong
13
+ // in the individual module build.gradle files
14
+ }
15
+ }
16
+
17
+ allprojects {
18
+ repositories {
19
+ google()
20
+ jcenter()
21
+ }
22
+ }
23
+
24
+ task clean(type: Delete) {
25
+ delete rootProject.buildDir
26
+ }
27
+