├── .gitignore
├── AndroidManifest.xml
├── LICENSE
├── README.md
├── assets
├── OpenSans-Regular.ttf
├── affenpinscher.jpg
├── afghan_hound.jpg
├── african_hunting_dog.jpg
├── airedale_terrier.jpg
├── american_staffordshire_terrier.jpg
├── appenzeller_sennenhund.jpg
├── australian_terrier.jpg
├── basenji.jpg
├── basset_hound.jpg
├── beagle.jpg
├── bedlington_terrier.jpg
├── bernese_mountain_dog.jpg
├── blenheim_spaniel.jpg
├── bloodhound.jpg
├── bluetick_coonhound.jpg
├── border_collie.jpg
├── border_terrier.jpg
├── borzoi.jpg
├── boston_terrier.jpg
├── bouvier_des_flandres.jpg
├── boxer_dog.jpg
├── brabancon_griffon.jpg
├── briard.jpg
├── brittany_spaniel.jpg
├── bull_mastiff.jpg
├── cairn_terrier.jpg
├── cardigan_welsh_corgi.jpg
├── chesapeake_bay_retriever.jpg
├── chihuahua_dog.jpg
├── chow_chow.jpg
├── clumber_spaniel.jpg
├── coated_retriever.jpg
├── coated_wheaten_terrier.jpg
├── cocker_spaniel.jpg
├── collie.jpg
├── curly_coated_retriever.jpg
├── dachshund.jpg
├── dandie_dinmont_terrier.jpg
├── dhole.jpg
├── dingo.jpg
├── doberman.jpg
├── english_foxhound.jpg
├── english_setter.jpg
├── english_springer_spaniel.jpg
├── entlebucher_mountain_dog.jpg
├── eskimo_dog.jpg
├── french_bulldog.jpg
├── german_shepherd.jpg
├── giant_schnauzer.jpg
├── golden_retriever.jpg
├── gordon_setter.jpg
├── great_dane.jpg
├── great_pyrenees.jpg
├── greater_swiss_mountain_dog.jpg
├── groenendael_dog.jpg
├── haired_fox_terrier.jpg
├── haired_pointer.jpg
├── ibizan_hound.jpg
├── irish_setter.jpg
├── irish_terrier.jpg
├── irish_water_spaniel.jpg
├── irish_wolfhound.jpg
├── italian_greyhound.jpg
├── japanese_spaniel.jpg
├── keeshond.jpg
├── kelpie.jpg
├── kerry_blue_terrier.jpg
├── komondor.jpg
├── kuvasz.jpg
├── labrador_retriever.jpg
├── lakeland_terrier.jpg
├── leonberger.jpg
├── lhasa_apso.jpg
├── malamute.jpg
├── malinois_dog.jpg
├── maltese_dog.jpg
├── mexican_hairless_dog.jpg
├── miniature_pinscher.jpg
├── miniature_poodle.jpg
├── miniature_schnauzer.jpg
├── newfoundland_dog.jpg
├── nodata.jpg
├── norfolk_terrier.jpg
├── norwegian_elkhound.jpg
├── norwich_terrier.jpg
├── old_english_sheepdog.jpg
├── otterhound.jpg
├── papillon_dog.jpg
├── pekingese.jpg
├── pembroke_welsh_corgi.jpg
├── pomeranian.jpg
├── pug.jpg
├── redbone_coonhound.jpg
├── rhodesian_ridgeback.jpg
├── rottweiler.jpg
├── saint_bernard.jpg
├── saluki.jpg
├── samoyed_dog.jpg
├── schipperke.jpg
├── scotch_terrier.jpg
├── scottish_deerhound.jpg
├── sealyham_terrier.jpg
├── shetland_sheepdog.jpg
├── shih_tzu.jpg
├── siberian_husky.jpg
├── silky_terrier.jpg
├── staffordshire_bull_terrier.jpg
├── standard_poodle.jpg
├── standard_schnauzer.jpg
├── stripped.pb
├── sussex_spaniel.jpg
├── tan_coonhound.jpg
├── tibetan_mastiff.jpg
├── tibetan_terrier.jpg
├── toy_poodle.jpg
├── toy_terrier.jpg
├── vizsla.jpg
├── walker_hound.jpg
├── weimaraner.jpg
├── welsh_springer_spaniel.jpg
├── west_highland_white_terrier.jpg
├── whippet.jpg
└── yorkshire_terrier.jpg
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── metadata
├── ar
│ └── summary.txt
├── de
│ └── summary.txt
├── en-US
│ ├── full_description.txt
│ ├── images
│ │ ├── featureGraphic.png
│ │ ├── icon.png
│ │ └── phoneScreenshots
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ ├── 4.png
│ │ │ ├── 5.png
│ │ │ ├── 6.png
│ │ │ ├── 7.png
│ │ │ └── 8.png
│ ├── short_description.txt
│ ├── summary.txt
│ └── title.txt
├── es
│ └── summary.txt
├── fr
│ └── summary.txt
├── he
│ └── summary.txt
├── it
│ └── summary.txt
├── nb
│ └── summary.txt
├── pl
│ └── summary.txt
├── pt-BR
│ └── summary.txt
├── pt-PT
│ └── summary.txt
├── pt
│ └── summary.txt
├── ro
│ └── summary.txt
├── ru
│ └── summary.txt
├── tr
│ └── summary.txt
├── uk
│ └── summary.txt
└── zh-CN
│ └── summary.txt
├── res
├── drawable-hdpi
│ ├── camera_icon.png
│ ├── ic_action_save.png
│ └── ic_launcher.png
├── drawable-mdpi
│ ├── camera_icon.png
│ ├── ic_action_save.png
│ └── ic_launcher.png
├── drawable-v21
│ └── button_background_selector.xml
├── drawable-xhdpi
│ ├── camera_icon.png
│ ├── ic_action_save.png
│ └── ic_launcher.png
├── drawable-xxhdpi
│ ├── camera_icon.png
│ ├── ic_action_save.png
│ └── ic_launcher.png
├── drawable-xxxhdpi
│ └── ic_action_save.png
├── drawable
│ ├── blackout_transition.xml
│ ├── button_background_selector.xml
│ ├── ic_change_language.xml
│ └── roundedbutton.xml
├── layout
│ ├── activity_camera.xml
│ ├── activity_list.xml
│ ├── camera_connection_fragment.xml
│ ├── lang_dialog.xml
│ ├── list_group.xml
│ └── list_item.xml
├── menu
│ └── mainmenu.xml
├── values-de
│ └── strings.xml
├── values-fr
│ └── strings.xml
├── values-ka
│ └── strings.xml
├── values
│ ├── colors.xml
│ ├── filenames.xml
│ └── strings.xml
└── xml
│ └── filepaths.xml
└── src
└── com
└── jstappdev
└── dbclf
├── AutoFitTextureView.java
├── CameraActivity.java
├── CameraConnectionFragment.java
├── Classifier.java
├── ClassifierActivity.java
├── LegacyCameraConnectionFragment.java
├── ListAdapter.java
├── RecognitionScoreView.java
├── SimpleListActivity.java
├── TensorFlowImageClassifier.java
└── env
└── ImageUtils.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the ART/Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 | out/
15 | release/
16 | debug/
17 | gradleBuild/
18 | dbclf.iml
19 | .idea/
20 |
21 | # Gradle files
22 | .gradle/
23 | build/
24 |
25 | # Local configuration file (sdk path, etc)
26 | local.properties
27 |
28 | # Proguard folder generated by Eclipse
29 | proguard/
30 |
31 | # Log Files
32 | *.log
33 |
34 | # Android Studio Navigation editor temp files
35 | .navigation/
36 |
37 | # Android Studio captures folder
38 | captures/
39 |
40 | # IntelliJ
41 | *.iml
42 | .idea/workspace.xml
43 | .idea/tasks.xml
44 | .idea/gradle.xml
45 | .idea/assetWizardSettings.xml
46 | .idea/dictionaries
47 | .idea/libraries
48 | .idea/caches
49 |
50 | # Keystore files
51 | # Uncomment the following line if you do not want to check your keystore files in.
52 | #*.jks
53 |
54 | # External native build folder generated in Android Studio 2.2 and later
55 | .externalNativeBuild
56 |
57 | # Google Services (e.g. APIs or Firebase)
58 | google-services.json
59 |
60 | # Freeline
61 | freeline.py
62 | freeline/
63 | freeline_project_description.json
64 |
65 | # fastlane
66 | fastlane/report.xml
67 | fastlane/Preview.html
68 | fastlane/screenshots
69 | fastlane/test_output
70 | fastlane/readme.md
71 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
22 |
27 |
30 |
31 |
32 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Identify Dog Breeds Android App
2 |
3 | This is the source code for the Identify Dog Breeds and Identify Dog Breeds Pro Android applications. The uploaded TensorFlow model (assets/stripped.pb) is the same as used in the free mobile app and was trained on an extended version of the
4 | Stanford Dogs Dataset. Based on the TensorFlow Android Camera Demo application, licensed under Apache License 2.0. French translation by Clément Thonon. Georgian translation by Giorgi Abulashvili.
5 |
6 | Project abandoned in favor of https://github.com/j05t/identify-dog-breeds-pro. The Pro version is available for free from the F-Droid store at https://f-droid.org/packages/com.jstappdev.identify_dog_breeds_pro/ so there is no reason to maintain a separate free version of the app.
7 |
8 |
9 |
10 |
11 | ## Downloads
12 |
13 |
14 |
--------------------------------------------------------------------------------
/assets/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/assets/affenpinscher.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/affenpinscher.jpg
--------------------------------------------------------------------------------
/assets/afghan_hound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/afghan_hound.jpg
--------------------------------------------------------------------------------
/assets/african_hunting_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/african_hunting_dog.jpg
--------------------------------------------------------------------------------
/assets/airedale_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/airedale_terrier.jpg
--------------------------------------------------------------------------------
/assets/american_staffordshire_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/american_staffordshire_terrier.jpg
--------------------------------------------------------------------------------
/assets/appenzeller_sennenhund.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/appenzeller_sennenhund.jpg
--------------------------------------------------------------------------------
/assets/australian_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/australian_terrier.jpg
--------------------------------------------------------------------------------
/assets/basenji.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/basenji.jpg
--------------------------------------------------------------------------------
/assets/basset_hound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/basset_hound.jpg
--------------------------------------------------------------------------------
/assets/beagle.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/beagle.jpg
--------------------------------------------------------------------------------
/assets/bedlington_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/bedlington_terrier.jpg
--------------------------------------------------------------------------------
/assets/bernese_mountain_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/bernese_mountain_dog.jpg
--------------------------------------------------------------------------------
/assets/blenheim_spaniel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/blenheim_spaniel.jpg
--------------------------------------------------------------------------------
/assets/bloodhound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/bloodhound.jpg
--------------------------------------------------------------------------------
/assets/bluetick_coonhound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/bluetick_coonhound.jpg
--------------------------------------------------------------------------------
/assets/border_collie.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/border_collie.jpg
--------------------------------------------------------------------------------
/assets/border_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/border_terrier.jpg
--------------------------------------------------------------------------------
/assets/borzoi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/borzoi.jpg
--------------------------------------------------------------------------------
/assets/boston_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/boston_terrier.jpg
--------------------------------------------------------------------------------
/assets/bouvier_des_flandres.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/bouvier_des_flandres.jpg
--------------------------------------------------------------------------------
/assets/boxer_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/boxer_dog.jpg
--------------------------------------------------------------------------------
/assets/brabancon_griffon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/brabancon_griffon.jpg
--------------------------------------------------------------------------------
/assets/briard.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/briard.jpg
--------------------------------------------------------------------------------
/assets/brittany_spaniel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/brittany_spaniel.jpg
--------------------------------------------------------------------------------
/assets/bull_mastiff.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/bull_mastiff.jpg
--------------------------------------------------------------------------------
/assets/cairn_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/cairn_terrier.jpg
--------------------------------------------------------------------------------
/assets/cardigan_welsh_corgi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/cardigan_welsh_corgi.jpg
--------------------------------------------------------------------------------
/assets/chesapeake_bay_retriever.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/chesapeake_bay_retriever.jpg
--------------------------------------------------------------------------------
/assets/chihuahua_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/chihuahua_dog.jpg
--------------------------------------------------------------------------------
/assets/chow_chow.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/chow_chow.jpg
--------------------------------------------------------------------------------
/assets/clumber_spaniel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/clumber_spaniel.jpg
--------------------------------------------------------------------------------
/assets/coated_retriever.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/coated_retriever.jpg
--------------------------------------------------------------------------------
/assets/coated_wheaten_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/coated_wheaten_terrier.jpg
--------------------------------------------------------------------------------
/assets/cocker_spaniel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/cocker_spaniel.jpg
--------------------------------------------------------------------------------
/assets/collie.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/collie.jpg
--------------------------------------------------------------------------------
/assets/curly_coated_retriever.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/curly_coated_retriever.jpg
--------------------------------------------------------------------------------
/assets/dachshund.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/dachshund.jpg
--------------------------------------------------------------------------------
/assets/dandie_dinmont_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/dandie_dinmont_terrier.jpg
--------------------------------------------------------------------------------
/assets/dhole.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/dhole.jpg
--------------------------------------------------------------------------------
/assets/dingo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/dingo.jpg
--------------------------------------------------------------------------------
/assets/doberman.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/doberman.jpg
--------------------------------------------------------------------------------
/assets/english_foxhound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/english_foxhound.jpg
--------------------------------------------------------------------------------
/assets/english_setter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/english_setter.jpg
--------------------------------------------------------------------------------
/assets/english_springer_spaniel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/english_springer_spaniel.jpg
--------------------------------------------------------------------------------
/assets/entlebucher_mountain_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/entlebucher_mountain_dog.jpg
--------------------------------------------------------------------------------
/assets/eskimo_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/eskimo_dog.jpg
--------------------------------------------------------------------------------
/assets/french_bulldog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/french_bulldog.jpg
--------------------------------------------------------------------------------
/assets/german_shepherd.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/german_shepherd.jpg
--------------------------------------------------------------------------------
/assets/giant_schnauzer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/giant_schnauzer.jpg
--------------------------------------------------------------------------------
/assets/golden_retriever.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/golden_retriever.jpg
--------------------------------------------------------------------------------
/assets/gordon_setter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/gordon_setter.jpg
--------------------------------------------------------------------------------
/assets/great_dane.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/great_dane.jpg
--------------------------------------------------------------------------------
/assets/great_pyrenees.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/great_pyrenees.jpg
--------------------------------------------------------------------------------
/assets/greater_swiss_mountain_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/greater_swiss_mountain_dog.jpg
--------------------------------------------------------------------------------
/assets/groenendael_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/groenendael_dog.jpg
--------------------------------------------------------------------------------
/assets/haired_fox_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/haired_fox_terrier.jpg
--------------------------------------------------------------------------------
/assets/haired_pointer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/haired_pointer.jpg
--------------------------------------------------------------------------------
/assets/ibizan_hound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/ibizan_hound.jpg
--------------------------------------------------------------------------------
/assets/irish_setter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/irish_setter.jpg
--------------------------------------------------------------------------------
/assets/irish_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/irish_terrier.jpg
--------------------------------------------------------------------------------
/assets/irish_water_spaniel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/irish_water_spaniel.jpg
--------------------------------------------------------------------------------
/assets/irish_wolfhound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/irish_wolfhound.jpg
--------------------------------------------------------------------------------
/assets/italian_greyhound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/italian_greyhound.jpg
--------------------------------------------------------------------------------
/assets/japanese_spaniel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/japanese_spaniel.jpg
--------------------------------------------------------------------------------
/assets/keeshond.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/keeshond.jpg
--------------------------------------------------------------------------------
/assets/kelpie.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/kelpie.jpg
--------------------------------------------------------------------------------
/assets/kerry_blue_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/kerry_blue_terrier.jpg
--------------------------------------------------------------------------------
/assets/komondor.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/komondor.jpg
--------------------------------------------------------------------------------
/assets/kuvasz.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/kuvasz.jpg
--------------------------------------------------------------------------------
/assets/labrador_retriever.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/labrador_retriever.jpg
--------------------------------------------------------------------------------
/assets/lakeland_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/lakeland_terrier.jpg
--------------------------------------------------------------------------------
/assets/leonberger.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/leonberger.jpg
--------------------------------------------------------------------------------
/assets/lhasa_apso.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/lhasa_apso.jpg
--------------------------------------------------------------------------------
/assets/malamute.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/malamute.jpg
--------------------------------------------------------------------------------
/assets/malinois_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/malinois_dog.jpg
--------------------------------------------------------------------------------
/assets/maltese_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/maltese_dog.jpg
--------------------------------------------------------------------------------
/assets/mexican_hairless_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/mexican_hairless_dog.jpg
--------------------------------------------------------------------------------
/assets/miniature_pinscher.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/miniature_pinscher.jpg
--------------------------------------------------------------------------------
/assets/miniature_poodle.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/miniature_poodle.jpg
--------------------------------------------------------------------------------
/assets/miniature_schnauzer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/miniature_schnauzer.jpg
--------------------------------------------------------------------------------
/assets/newfoundland_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/newfoundland_dog.jpg
--------------------------------------------------------------------------------
/assets/nodata.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/nodata.jpg
--------------------------------------------------------------------------------
/assets/norfolk_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/norfolk_terrier.jpg
--------------------------------------------------------------------------------
/assets/norwegian_elkhound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/norwegian_elkhound.jpg
--------------------------------------------------------------------------------
/assets/norwich_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/norwich_terrier.jpg
--------------------------------------------------------------------------------
/assets/old_english_sheepdog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/old_english_sheepdog.jpg
--------------------------------------------------------------------------------
/assets/otterhound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/otterhound.jpg
--------------------------------------------------------------------------------
/assets/papillon_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/papillon_dog.jpg
--------------------------------------------------------------------------------
/assets/pekingese.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/pekingese.jpg
--------------------------------------------------------------------------------
/assets/pembroke_welsh_corgi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/pembroke_welsh_corgi.jpg
--------------------------------------------------------------------------------
/assets/pomeranian.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/pomeranian.jpg
--------------------------------------------------------------------------------
/assets/pug.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/pug.jpg
--------------------------------------------------------------------------------
/assets/redbone_coonhound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/redbone_coonhound.jpg
--------------------------------------------------------------------------------
/assets/rhodesian_ridgeback.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/rhodesian_ridgeback.jpg
--------------------------------------------------------------------------------
/assets/rottweiler.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/rottweiler.jpg
--------------------------------------------------------------------------------
/assets/saint_bernard.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/saint_bernard.jpg
--------------------------------------------------------------------------------
/assets/saluki.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/saluki.jpg
--------------------------------------------------------------------------------
/assets/samoyed_dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/samoyed_dog.jpg
--------------------------------------------------------------------------------
/assets/schipperke.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/schipperke.jpg
--------------------------------------------------------------------------------
/assets/scotch_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/scotch_terrier.jpg
--------------------------------------------------------------------------------
/assets/scottish_deerhound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/scottish_deerhound.jpg
--------------------------------------------------------------------------------
/assets/sealyham_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/sealyham_terrier.jpg
--------------------------------------------------------------------------------
/assets/shetland_sheepdog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/shetland_sheepdog.jpg
--------------------------------------------------------------------------------
/assets/shih_tzu.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/shih_tzu.jpg
--------------------------------------------------------------------------------
/assets/siberian_husky.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/siberian_husky.jpg
--------------------------------------------------------------------------------
/assets/silky_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/silky_terrier.jpg
--------------------------------------------------------------------------------
/assets/staffordshire_bull_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/staffordshire_bull_terrier.jpg
--------------------------------------------------------------------------------
/assets/standard_poodle.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/standard_poodle.jpg
--------------------------------------------------------------------------------
/assets/standard_schnauzer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/standard_schnauzer.jpg
--------------------------------------------------------------------------------
/assets/stripped.pb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/stripped.pb
--------------------------------------------------------------------------------
/assets/sussex_spaniel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/sussex_spaniel.jpg
--------------------------------------------------------------------------------
/assets/tan_coonhound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/tan_coonhound.jpg
--------------------------------------------------------------------------------
/assets/tibetan_mastiff.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/tibetan_mastiff.jpg
--------------------------------------------------------------------------------
/assets/tibetan_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/tibetan_terrier.jpg
--------------------------------------------------------------------------------
/assets/toy_poodle.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/toy_poodle.jpg
--------------------------------------------------------------------------------
/assets/toy_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/toy_terrier.jpg
--------------------------------------------------------------------------------
/assets/vizsla.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/vizsla.jpg
--------------------------------------------------------------------------------
/assets/walker_hound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/walker_hound.jpg
--------------------------------------------------------------------------------
/assets/weimaraner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/weimaraner.jpg
--------------------------------------------------------------------------------
/assets/welsh_springer_spaniel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/welsh_springer_spaniel.jpg
--------------------------------------------------------------------------------
/assets/west_highland_white_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/west_highland_white_terrier.jpg
--------------------------------------------------------------------------------
/assets/whippet.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/whippet.jpg
--------------------------------------------------------------------------------
/assets/yorkshire_terrier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/assets/yorkshire_terrier.jpg
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // set to 'armabi-v7a', 'all', 'arm64-v8a'
2 | // armabi-v7a will only build for armabi-v7a (most smartphones)
3 | // all will build for arm64-v8a, armabi-v7a, x86, x86_64
4 | def buildFor = 'armabi-v7a'
5 |
6 |
7 | project.buildDir = 'gradleBuild'
8 | getProject().setBuildDir('gradleBuild')
9 |
10 | buildscript {
11 | repositories {
12 | google()
13 | jcenter()
14 | }
15 |
16 | dependencies {
17 | classpath 'com.android.tools.build:gradle:4.1.3'
18 | classpath 'org.apache.httpcomponents:httpclient:4.5.6'
19 | }
20 | }
21 |
22 | allprojects {
23 | repositories {
24 | google()
25 | jcenter()
26 | maven { url "https://jitpack.io" }
27 | }
28 | }
29 |
30 |
31 | project.ext.ASSET_DIR = projectDir.toString() + '/assets'
32 |
33 | apply plugin: 'com.android.application'
34 |
35 | android {
36 | compileSdkVersion 30
37 | buildToolsVersion '30.0.3'
38 |
39 | defaultConfig {
40 | applicationId = 'com.jstappdev.dbclf'
41 | minSdkVersion 21
42 | targetSdkVersion 30
43 |
44 | versionCode 103
45 | versionName "45"
46 | }
47 |
48 | if (buildFor == 'armabi-v7a') {
49 | defaultConfig {
50 | ndk {
51 | abiFilters 'armeabi-v7a'
52 | }
53 | }
54 | } else if (buildFor == 'arm64-v8a') {
55 | defaultConfig {
56 | ndk {
57 | abiFilters 'arm64-v8a'
58 | }
59 | }
60 | }
61 |
62 | sourceSets {
63 | main {
64 | java {
65 | srcDir 'src'
66 | }
67 |
68 | manifest.srcFile 'AndroidManifest.xml'
69 | resources.srcDirs = ['src']
70 | aidl.srcDirs = ['src']
71 | renderscript.srcDirs = ['src']
72 | res.srcDirs = ['res']
73 | assets.srcDirs = [project.ext.ASSET_DIR]
74 | jniLibs.srcDirs = ['libs']
75 | }
76 |
77 | debug.setRoot('build-types/debug')
78 | release.setRoot('build-types/release')
79 | }
80 | compileOptions {
81 | targetCompatibility 1.8
82 | sourceCompatibility 1.8
83 | }
84 | }
85 |
86 |
87 | dependencies {
88 | implementation 'org.tensorflow:tensorflow-android:1.8.0'
89 | implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
90 | implementation 'androidx.legacy:legacy-support-v4:1.0.0'
91 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
92 | }
93 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | ## For more details on how to configure your build environment visit
2 | # http://www.gradle.org/docs/current/userguide/build_environment.html
3 | #
4 | # Specifies the JVM arguments used for the daemon process.
5 | # The setting is particularly useful for tweaking memory settings.
6 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
7 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
8 | #
9 | # When configured, Gradle will run in incubating parallel mode.
10 | # This option should only be used with decoupled projects. More details, visit
11 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
12 | # org.gradle.parallel=true
13 | #Thu Sep 26 10:56:51 CEST 2019
14 | android.enableJetifier=true
15 | org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx1024M"
16 | android.useAndroidX=true
17 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Aug 07 13:37:03 CEST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/metadata/ar/summary.txt:
--------------------------------------------------------------------------------
1 | حدد أكثر من مائة سلالة مختلفة من الكلاب باستخدام هاتفك الذكي
2 |
--------------------------------------------------------------------------------
/metadata/de/summary.txt:
--------------------------------------------------------------------------------
1 | Über 100 verschiedene Hundebabys mit dem Smartphone bestimmen
2 |
--------------------------------------------------------------------------------
/metadata/en-US/full_description.txt:
--------------------------------------------------------------------------------
1 | Identify over one hundred different dog breeds with your smartphone.
2 |
3 | This application will not run on devices with less than 1 GB of RAM.
4 |
5 | If you like this app consider buying the premium version which supports the identification of more than two hundred different dog breeds with much higher accuracy.
6 |
7 | Click the camera button or load an image from the gallery to identify a dog in a single picture. Activate continuous predictions and keep the dog in the circle to get predictions directly from the video stream. The app works best for high quality images loaded from the gallery.
8 |
9 | The application reports up to three predictions with highest confidence. Please treat the output only as a suggestion.
10 |
11 | Based on an extended version of the Stanford Dogs Dataset.
12 | Icons made by Pause08, Smashicons, Freepik from www.flaticon.com.
13 |
--------------------------------------------------------------------------------
/metadata/en-US/images/featureGraphic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/metadata/en-US/images/featureGraphic.png
--------------------------------------------------------------------------------
/metadata/en-US/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/metadata/en-US/images/icon.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/metadata/en-US/images/phoneScreenshots/1.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/metadata/en-US/images/phoneScreenshots/2.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/metadata/en-US/images/phoneScreenshots/3.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/metadata/en-US/images/phoneScreenshots/4.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/metadata/en-US/images/phoneScreenshots/5.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/metadata/en-US/images/phoneScreenshots/6.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/metadata/en-US/images/phoneScreenshots/7.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/metadata/en-US/images/phoneScreenshots/8.png
--------------------------------------------------------------------------------
/metadata/en-US/short_description.txt:
--------------------------------------------------------------------------------
1 | Identify dog breeds with your smartphone.
2 |
--------------------------------------------------------------------------------
/metadata/en-US/summary.txt:
--------------------------------------------------------------------------------
1 | Identify over one hundred different dog breeds with your smartphone
2 |
--------------------------------------------------------------------------------
/metadata/en-US/title.txt:
--------------------------------------------------------------------------------
1 | Identify Dog Breeds
2 |
--------------------------------------------------------------------------------
/metadata/es/summary.txt:
--------------------------------------------------------------------------------
1 | Identificar más de 100 razas de perros diferentes con su teléfono inteligente
2 |
--------------------------------------------------------------------------------
/metadata/fr/summary.txt:
--------------------------------------------------------------------------------
1 | Identifiez plus de cent races de chien avec votre téléphone
2 |
--------------------------------------------------------------------------------
/metadata/he/summary.txt:
--------------------------------------------------------------------------------
1 | זיהוי מבין מאות זני כלבים בעזרת הטלפון החכם שלך
2 |
--------------------------------------------------------------------------------
/metadata/it/summary.txt:
--------------------------------------------------------------------------------
1 | Identifica oltre cento diverse razze di cani con il tuo smartphone
2 |
--------------------------------------------------------------------------------
/metadata/nb/summary.txt:
--------------------------------------------------------------------------------
1 | Identifiser over hundre hunderaser med din enhet
2 |
--------------------------------------------------------------------------------
/metadata/pl/summary.txt:
--------------------------------------------------------------------------------
1 | Zidentyfikuj ponad sto różnych ras psów za pomocą smartfona
2 |
--------------------------------------------------------------------------------
/metadata/pt-BR/summary.txt:
--------------------------------------------------------------------------------
1 | Identifique mais de 100 diferentes raças de cães com seu smartphone
2 |
--------------------------------------------------------------------------------
/metadata/pt-PT/summary.txt:
--------------------------------------------------------------------------------
1 | Identifique mais de 100 raças de cães diferentes com seu smartphone
2 |
--------------------------------------------------------------------------------
/metadata/pt/summary.txt:
--------------------------------------------------------------------------------
1 | Identifique mais de 100 raças de cães diferentes com seu smartphone
2 |
--------------------------------------------------------------------------------
/metadata/ro/summary.txt:
--------------------------------------------------------------------------------
1 | Identificați peste o sută de rase diferite de câini cu ajutorul smartphone-ului
2 |
--------------------------------------------------------------------------------
/metadata/ru/summary.txt:
--------------------------------------------------------------------------------
1 | Определите более сотни разных пород собак с помощью своего смартфона
2 |
--------------------------------------------------------------------------------
/metadata/tr/summary.txt:
--------------------------------------------------------------------------------
1 | Akıllı telefonunuzla yüzden fazla farklı köpek türünü tanımlayın
2 |
--------------------------------------------------------------------------------
/metadata/uk/summary.txt:
--------------------------------------------------------------------------------
1 | Визначте понад сто різних порід псів за допомогою смартфона
2 |
--------------------------------------------------------------------------------
/metadata/zh-CN/summary.txt:
--------------------------------------------------------------------------------
1 | 使用智能手机识别超过一百种不同的狗品种
2 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/camera_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/res/drawable-hdpi/camera_icon.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_action_save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/res/drawable-hdpi/ic_action_save.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/camera_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/res/drawable-mdpi/camera_icon.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_action_save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/res/drawable-mdpi/ic_action_save.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-v21/button_background_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/res/drawable-xhdpi/camera_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/res/drawable-xhdpi/camera_icon.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_action_save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/res/drawable-xhdpi/ic_action_save.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xxhdpi/camera_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/res/drawable-xxhdpi/camera_icon.png
--------------------------------------------------------------------------------
/res/drawable-xxhdpi/ic_action_save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/res/drawable-xxhdpi/ic_action_save.png
--------------------------------------------------------------------------------
/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xxxhdpi/ic_action_save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j05t/dbclf/d6cf06d60a58367b4baefa8732947abe97581b10/res/drawable-xxxhdpi/ic_action_save.png
--------------------------------------------------------------------------------
/res/drawable/blackout_transition.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/res/drawable/button_background_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/res/drawable/ic_change_language.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/res/drawable/roundedbutton.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 | -
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/res/layout/activity_camera.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
22 |
23 |
32 |
33 |
43 |
44 |
55 |
56 |
67 |
68 |
81 |
82 |
89 |
90 |
97 |
98 |
108 |
109 |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/res/layout/activity_list.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/res/layout/camera_connection_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
13 |
14 |
--------------------------------------------------------------------------------
/res/layout/lang_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
--------------------------------------------------------------------------------
/res/layout/list_group.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
--------------------------------------------------------------------------------
/res/layout/list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/res/menu/mainmenu.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/res/values-de/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Erkenne Hunderassen
4 | Erkenne Hunderassen
5 | Dieses Gerät unterstützt die Camera2 API nicht.
6 | Lade Foto..
7 | Erkenne Hunderassen
9 | Erkenne über einhundert verschiedene Hunderassen mit deinem Smartphone.
10 | Klicken Sie auf den Kamera-Button oder laden Sie ein Bild aus der Bildergalerie, um ein einzelnes Bild zu analysieren. Tippen Sie auf die Anzeige, um das angezeigte Ergebnis zu schließen, oder verwenden Sie die Teilen-Schaltfläche, um einen Screenshot zu teilen.
11 | Aktivieren Sie kontinuierliche Vorhersagen und halten Sie den Hund im Kreis, um Vorhersagen direkt aus dem Videostrom zu erhalten. Die Anwendung meldet die drei Vorhersagen mit der höchsten Wahrscheinlichkeit. Bitte behandeln Sie die Ausgabe nur als Vorschlag.
12 | Wenn Ihnen diese App gefällt, sollten Sie die Premium Version kaufen, die die Identifizierung von mehr als zweihundert verschiedenen Hunderassen mit viel höherer Genauigkeit erlaubt: https://play.google.com/store/apps/details?id=com.jstappdev.identify_dog_breeds_pro
13 | Anerkennungen
14 | Basierend auf einer erweiterten Version des Stanford Dogs Datensatzes. Icons von Pause08, Smashicons, Becris, Freepik von www.flaticon.com.
15 | Apache License 2.0. Source code verfügbar auf github.com/j05t/dbclf. Bilder von Wikipedia.
16 | ]]>
17 | Über diese App
18 | Beenden
19 | Zu wenig freier Speicher. Versuchen Sie, einige Hintergrundanwendungen zu schließen.
20 | Teile mit..
21 | Unterstützte Rassen
22 | Suche auf Wikipedia?
23 | Nein
24 | Ja
25 | Keine Erkennung
26 | Sprache ändern
27 |
28 |
29 | - Affenpinscher
30 | - Afghanischer Windhund
31 | - Afrikanischer Wildhund
32 | - Airedale Terrier
33 | - American Staffordshire Terrier
34 | - Appenzeller Sennenhund
35 | - Australian Terrier
36 | - Basenji
37 | - Basset Hound
38 | - Beagle
39 | - Bedlington Terrier
40 | - Berner Sennenhund
41 | - Cavalier King Charles Spaniel
42 | - Bloodhound
43 | - Bluetick Coonhound
44 | - Border Collie
45 | - Border Terrier
46 | - Barsoi
47 | - Bouvier des Flandres
48 | - Deutscher Boxer
49 | - Belgischer Zwerggriffon
50 | - Briard
51 | - Brittany Spaniel
52 | - Bullmastiff
53 | - Cairn Terrier
54 | - Welsh Corgi Cardigan
55 | - Chesapeake Bay Retriever
56 | - Chihuahua (Hunderasse)
57 | - Chow Chow
58 | - Clumber Spaniel
59 | - Flat Coated Retriever
60 | - Irish Soft Coated Wheaten Terrier
61 | - Cocker Spaniel
62 | - Langhaarcollie
63 | - Curly Coated Retriever
64 | - Dandie Dinmont Terrier
65 | - Dingo
66 | - Dobermann
67 | - English Foxhound
68 | - English Setter
69 | - English Springer Spaniel
70 | - Entlebucher Sennenhund
71 | - American Eskimo Dog
72 | - Französische Bulldogge
73 | - Deutscher Schäferhund
74 | - Riesenschnauzer
75 | - Golden Retriever
76 | - Gordon Setter
77 | - Grosser Schweizer Sennenhund
78 | - Deutsche Dogge
79 | - Chien de Montagne des Pyrénées
80 | - Groenendael
81 | - Foxterrier
82 | - Deutsch Kurzhaar
83 | - Irish Setter
84 | - Irish Terrier
85 | - Irish Water Spaniel
86 | - Irish Wolfhound
87 | - Italienisches Windspiel
88 | - Japan Chin
89 | - Keeshond
90 | - Kelpie
91 | - Kerry Blue Terrier
92 | - Komondor
93 | - Kuvasz
94 | - Labrador Retriever
95 | - Lakeland Terrier
96 | - Leonberger
97 | - Lhasa Apso
98 | - Dackel
99 | - Alaskan Malamute
100 | - Malinois
101 | - Xoloitzcuintle
102 | - Zwergpinscher
103 | - Zwergpudel
104 | - Zwergschnauzer
105 | - Neufundländer
106 | - Norfolk Terrier
107 | - Norwegischer Elchhund grau
108 | - Norwich Terrier
109 | - Bobtail
110 | - Otterhund
111 | - Kontinentaler Zwergspaniel
112 | - Pekingese
113 | - Welsh Corgi Pembroke
114 | - Deutsche Spitze
115 | - Mops
116 | - Redbone Coonhound
117 | - Rhodesian Ridgeback
118 | - Rottweiler
119 | - Boston Terrier
120 | - Rothund
121 | - Podenco Ibicenco
122 | - Malteser (Hunderasse)
123 | - Saint Bernard
124 | - Saluki
125 | - Samojede
126 | - Schipperke
127 | - Scotch Terrier
128 | - Deerhound
129 | - Sealyham Terrier
130 | - Shetland Sheepdog
131 | - Siberian Husky
132 | - Australian Silky Terrier
133 | - Staffordshire Bull Terrier
134 | - Pudel
135 | - Schnauzer
136 | - Sussex Spaniel
137 | - Black and Tan Coonhound
138 | - Do Khyi
139 | - Tibet-Terrier
140 | - Kleinpudel
141 | - English Toy Terrier
142 | - Shih Tzu
143 | - Vizsla
144 | - Treeing Walker Coonhound
145 | - Weimaraner
146 | - Welsh Springer Spaniel
147 | - West Highland White Terrier
148 | - Whippet
149 | - Yorkshire Terrier
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/res/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Identify Dog Breeds
4 | Identifiez les races de chiens
5 | Cet appareil ne prend pas en charge l\'API Camera2.
6 | Depuis la Galerie..
7 | Identify Dog Breeds
9 | Identifiez plus d\'une centaine de races de chiens différentes avec votre smartphone.
10 | Cliquez sur le bouton de l\'appareil photo ou chargez une image à partir de la galerie d\'images pour analyser une image. Appuyez sur l\'écran pour fermer le résultat affiché ou utilisez le bouton Partager pour partager une capture d\'écran.
11 | Activer les prédictions continues et garder le chien dans le cercle pour obtenir le résultat en direct. L\'application indique jusqu\'à trois prédictions jugées les plus correctes. Ce résultat n\'a aucune valeur scientifique.
12 | Si vous aimez cette application, passez à la version premium qui permet l\'identification de plus de deux cents races de chiens différentes avec une précision plus accrue : https://play.google.com/store/apps/details?id=com.jstappdev.identify_dog_breeds_pro
13 | Remerciements
14 | Basé sur une version étendue de la base de données Stanford Dogs. Icônes créées par Pause08, Smashicons, Becris, Freepik de www.flaticon.com.
15 |
Apache License 2.0. Code source disponible à github.com/j05t/dbclf. Images issues de Wikipedia. Traduction française par Clément Thonon.
16 | ]]>
17 | A propos
18 | Quitter
19 | Erreur de mémoire insuffisante. Essayez de fermer quelques applications en arrière-plan.
20 | Partager avec..
21 | Races identifiables
22 | Regarder sur Wikipedia ?
23 | Non
24 | Oui
25 | Pas de détection
26 | Langue
27 |
28 |
29 | - Affenpinscher
30 | - Lévrier afghan
31 | - Lycaon
32 | - Airedale Terrier
33 | - American Staffordshire Terrier
34 | - Bouvier de l’Appenzell
35 | - Terrier australien
36 | - Basenji
37 | - Basset Hound
38 | - Beagle
39 | - Bedlington terrier
40 | - Bouvier bernois
41 | - Cavalier King Charles Spaniel
42 | - Chien de Saint-Hubert
43 | - Bluetick coonhound
44 | - Border Collie
45 | - Border Terrier
46 | - Barzoï
47 | - Bouvier des Flandres
48 | - Boxer
49 | - Petit brabançon
50 | - Berger de Brie
51 | - Épagneul breton
52 | - Bullmastiff
53 | - Cairn terrier
54 | - Welsh Corgi Cardigan
55 | - Retriever de la baie de Chesapeake
56 | - Chihuahua
57 | - Chow-chow
58 | - Clumber Spaniel
59 | - Retriever à poil plat
60 | - Terrier irlandais à poil doux
61 | - Cocker Spaniel
62 | - Colley à poil long
63 | - Retriever à poil bouclé
64 | - Dandie Dinmont Terrier
65 | - Dingo
66 | - Dobermann
67 | - Foxhound anglais
68 | - Setter anglais
69 | - Springer anglais
70 | - Bouvier de l\'Entlebuch
71 | - Esquimau américain
72 | - Bouledogue
73 | - Berger allemand
74 | - Schnauzer géant
75 | - Golden retriever
76 | - Setter Gordon
77 | - Grand bouvier suisse
78 | - Dogue allemand
79 | - Chien de montagne des Pyrénées
80 | - Berger belge Groenendael
81 | - Fox-terrier à poil dur
82 | - Braque allemand à poil court
83 | - Setter irlandais rouge
84 | - Terrier irlandais
85 | - Épagneul d\'eau irlandais
86 | - Irish wolfhound
87 | - Petit lévrier italien
88 | - Épagneul japonais
89 | - Spitz Loup
90 | - Australian Kelpie
91 | - Terrier Kerry Blue
92 | - Komondor
93 | - Kuvasz
94 | - Labrador retriever
95 | - Lakeland Terrier
96 | - Leonberg (chien)
97 | - Lhassa Apso
98 | - Teckel
99 | - Malamute de l\'Alaska
100 | - Malinois
101 | - Xoloitzcuintle
102 | - Pinscher nain
103 | - Caniche
104 | - Schnauzer nain
105 | - Terre-neuve
106 | - Norfolk Terrier
107 | - Chien d\'élan norvégien gris
108 | - Norwich Terrier
109 | - Bobtail
110 | - Chien à loutre
111 | - Épagneul nain continental papillon
112 | - Pékinois
113 | - Welsh Corgi Pembroke
114 | - Spitz nain
115 | - Carlin
116 | - Redbone Coonhound
117 | - Rhodesian Ridgeback
118 | - Rottweiler
119 | - Terrier de Boston
120 | - Dhole
121 | - Podenco d\'Ibiza
122 | - Bichon maltais
123 | - Saint-bernard
124 | - Lévrier persan
125 | - Samoyède
126 | - Schipperke
127 | - Terrier écossais
128 | - Deerhound
129 | - Sealyham Terrier
130 | - Shetland
131 | - Husky de Sibérie
132 | - Terrier australien à poil soyeux
133 | - Staffordshire Bull Terrier
134 | - Caniche
135 | - Schnauzer moyen
136 | - Sussex Spaniel
137 | - Chien noir et feu pour la chasse au raton laveur
138 | - Dogue du Tibet
139 | - Terrier tibétain
140 | - Caniche
141 | - Terrier d\'agrément anglais noir et feu
142 | - Shih tzu
143 | - Braque hongrois à poil court
144 | - Treeing Walker Coonhound
145 | - Braque de Weimar
146 | - Welsh Springer Spaniel
147 | - West Highland white terrier
148 | - Lévrier whippet
149 | - Yorkshire Terrier
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/res/values-ka/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ძაღლების ჯიშის ამომცნობი
4 | ძაღლების ჯიშის ამომცნობი
5 | ამ მოწყობილობაში Camera2 API მხარდაჭერილი არაა.
6 | გალერეიდან..
7 | ძაღლების ჯიშის ამომცნობი
9 | ამოიცანი ასზე მეტი განსხვავებული ძაღლის ჯიში თქვენი სმარტფონით.
10 | დააჭირე კამერის ღილაკს ან სურათის ჩატვირთვას სურათების გალერეიდან სურათის ანალიზისთვის. დააჭირეთ დახურვას ან გაზიარების ღილაკს სკრინშოტის გასაზიარებლად.
11 | განგრძობითი ამოცნობის გააქტიურება. გთხოვთ მოათავსოთ ძაღლი წრეში(ეკრანზე) პირდაპირ ვიდეო ნაკადიდან ამოცნობის მისაღებად. პროგრამა შეგატყობინებთ 3-მდე ამოცნობის ვარიანტს, რომელსაც იგი მიიჩნევს ყველა ზუსტად. გთხოვთ მიღებული შედეგი მიიღოთ მხოლოდ შესაძლო დაშვებად.
12 | თუ თქვენ მოგეწონათ ეს აპლიკაცია, გთხოვთ შეიძინოთ პრემიუმ ვერსია, სტანდარტულისგან განსხვავებით მასში მხარდაჭერილია 200-ზე მეტი განსხვავებული ძაღლის ჯიში მაღალი სიზუსტით: https://play.google.com/store/apps/details?id=com.jstappdev.identify_dog_breeds_pro
13 | მადლიერებები
14 | ეფუძნება Stanford Dogs dataset გაფართოებულ ვერსიას. ხატულების ავტორები: Pause08, Smashicons, Freepik > www.flaticon.com.
15 | Apache License 2.0. საწყისი კოდი ხელმისაწვდომია github.com/j05t/dbclf. სურათები აღებულია ვიკიპედიიდან.
16 | ]]>
17 | პროგრამის შესახებ
18 | გამოსვლა
19 | მეხსიერება არაა საკმარისი. გთხოვთ დახურეთ რამდენიმე ფონური აპლიკაცია.
20 | გაზიარება შერჩეულთან..
21 | მხარდაჭერილი ჯიშები
22 | ვიკიპედიაზე ვნახო?
23 | არა
24 | კი
25 | ვერ მოიძებნა
26 | ენის შეცვლა
27 |
28 |
29 | - აფენ პინჩერი
30 | - ავღანური მწევარი
31 | - აფრიკული აფთრისებრი ძაღლი
32 | - ერდელტერიერი
33 | - ამერიკული სტაფორდშირის ტერიერი
34 | - აპენცელერ ზენენჰუნდი
35 | - ავსტრალიური ტერიერი
36 | - ბასენჯი
37 | - ბასეტ ჰაუნდი
38 | - ბიგლი
39 | - ბედლინგტონ ტერიერი
40 | - ბერნული ზენენჰუნდი
41 | - ბლენჰეიმ სპანიელი(კავალერი მეფე ჩარლზის სპანიელი)
42 | - ბლადჰოუნდი
43 | - Bluetick Coonhound
44 | - ბორდერ-კოლი
45 | - ბორდერ-ტერიერი
46 | - ბორზოი
47 | - ფლანდრიული ბუვიე
48 | - ბოქსიორი
49 | - ბრიუსელური გრიფონი
50 | - ბრიარი
51 | - ბრეტონული სპანიელი
52 | - ბულმასტიფი
53 | - კერნ-ტერიერი
54 | - უელშ კორგი კარდიგანი
55 | - ჩესაპიკ ბეი რეტრივერი
56 | - ჩიუაუა
57 | - ჩაუ-ჩაუ
58 | - კლამბერ-სპანიელი
59 | - სწორ ბალნიანი რეტრივერი
60 | - რბილბალნიანი ხორბლისფერი ტერიერი
61 | - კოკერ-სპანიელი
62 | - კოლი
63 | - ხუჭუჭ ბალნიანი რეტრივერი
64 | - დენდი დინმონტ ტერიერი
65 | - დინგო
66 | - დობერმანი
67 | - ინგლისური ფოქსჰაუნდი
68 | - ინგლისური სეტერი
69 | - ინგლისური სპრინგერ სპანიელი
70 | - ენტლებუხერ-ზენენჰუნდი
71 | - ესკიმოსური ძაღლი
72 | - ფრანგული ბულდოგი
73 | - გერმანული ნაგაზი
74 | - რიზენშნაუცერი
75 | - ოქროსფერი რეტრივერი
76 | - შოტლანდიური სეტტერი(გორდონი)
77 | - დიდი შვეიცარიული მთის ძაღლი
78 | - გერმანული დოგი
79 | - პირენეული მთის ძაღლი
80 | - გრიუნენდალი
81 | - ფოქს-ტერიერი
82 | - კურცჰაარი
83 | - ირლანდიური სეტერი
84 | - ირლანდიური ტერიერი
85 | - ირლანდიური წყლის სპანიელი
86 | - ირლანდიური მგლის მახრჩობელა
87 | - იტალიური გრეიჰაუნდი(ლევრეტკა)
88 | - იაპონური ჩინი
89 | - კეესჰონდი
90 | - კელპი
91 | - კერი-ბლუ ტერიერი
92 | - კომონდორი
93 | - კუვასი
94 | - ლაბრადორ-რეტრივერი
95 | - ლეიკლენდ-ტერიერი
96 | - ლეონბერგერი
97 | - ლჰასური აპსო
98 | - ტაქსა
99 | - ალასკური მალამუტი
100 | - მოლინუა
101 | - მექსიკური შიშველი ძაღლი
102 | - მინიატურული პინჩერი
103 | - მინიატურული პუდელი
104 | - ცვერგშნაუცერი
105 | - ნიუფაუნდლენდი
106 | - ნორფოლკ-ტერიერი
107 | - ნორვეგიული ელკჰაუნდი
108 | - ნორვიჩ-ტერიერი
109 | - ძველინგლისური ნაგაზი
110 | - ოტერჰაუნდი
111 | - პაპილიონი
112 | - პეკინესი
113 | - უელშ კორგი პემბროკი
114 | - პომერანიული შპიცი
115 | - მოპსი
116 | - რედბონ-კუნჰაუნდი (
117 | - როდეზიული რიჯბეკი
118 | - როტვეილერი
119 | - ბოსტონ ტერიერი
120 | - წითელი მგელი(Dhole)
121 | - პოდენკო იბისენკო
122 | - მალტეზე
123 | - სენბერნარი
124 | - სალუკი
125 | - სამოედური შპიცი
126 | - შიპერკე
127 | - შოტლანდიური ტერიერი
128 | - დირჰაუნდი
129 | - სილიჰემ-ტერიერი
130 | - შეტლანდიური ნაგაზი
131 | - ციმბირული ჰასკი
132 | - ავსტრალიური აბრეშუმისებრი ტერიერი
133 | - სტაფორდშირული ბულტერიერი
134 | - სტანდარტ პუდელი
135 | - მიტელშნაუცერი
136 | - სუსექსური სპანიელი
137 | - კუნჰაუნდი
138 | - ტიბეტური მასტიფი
139 | - ტიბეტური ტერიერი
140 | - სათამაშო პუდელი
141 | - ინგლისური სათამაშო პუდელი (Black & Tan)
142 | - ში ცუ
143 | - უნგრული ვიზლა
144 | - Treeing Walker Coonhound
145 | - ვეიმარანერი
146 | - უელსური სპირნგერ სპანიელი
147 | - უესტ-ჰაილენდ-უაიტ-ტერიერი
148 | - უიპეტი
149 | - იორკშირ-ტერიერი
150 |
151 |
152 |
--------------------------------------------------------------------------------
/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #1A000000
4 | #000
5 |
6 |
--------------------------------------------------------------------------------
/res/values/filenames.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - affenpinscher.jpg
5 | - afghan_hound.jpg
6 | - african_hunting_dog.jpg
7 | - airedale_terrier.jpg
8 | - american_staffordshire_terrier.jpg
9 | - appenzeller_sennenhund.jpg
10 | - australian_terrier.jpg
11 | - basenji.jpg
12 | - basset_hound.jpg
13 | - beagle.jpg
14 | - bedlington_terrier.jpg
15 | - bernese_mountain_dog.jpg
16 | - blenheim_spaniel.jpg
17 | - bloodhound.jpg
18 | - bluetick_coonhound.jpg
19 | - border_collie.jpg
20 | - border_terrier.jpg
21 | - borzoi.jpg
22 | - bouvier_des_flandres.jpg
23 | - boxer_dog.jpg
24 | - brabancon_griffon.jpg
25 | - briard.jpg
26 | - brittany_spaniel.jpg
27 | - bull_mastiff.jpg
28 | - cairn_terrier.jpg
29 | - cardigan_welsh_corgi.jpg
30 | - chesapeake_bay_retriever.jpg
31 | - chihuahua_dog.jpg
32 | - chow_chow.jpg
33 | - clumber_spaniel.jpg
34 | - coated_retriever.jpg
35 | - coated_wheaten_terrier.jpg
36 | - cocker_spaniel.jpg
37 | - collie.jpg
38 | - curly_coated_retriever.jpg
39 | - dandie_dinmont_terrier.jpg
40 | - dingo.jpg
41 | - doberman.jpg
42 | - english_foxhound.jpg
43 | - english_setter.jpg
44 | - english_springer_spaniel.jpg
45 | - entlebucher_mountain_dog.jpg
46 | - eskimo_dog.jpg
47 | - french_bulldog.jpg
48 | - german_shepherd.jpg
49 | - giant_schnauzer.jpg
50 | - golden_retriever.jpg
51 | - gordon_setter.jpg
52 | - greater_swiss_mountain_dog.jpg
53 | - great_dane.jpg
54 | - great_pyrenees.jpg
55 | - groenendael_dog.jpg
56 | - haired_fox_terrier.jpg
57 | - haired_pointer.jpg
58 | - irish_setter.jpg
59 | - irish_terrier.jpg
60 | - irish_water_spaniel.jpg
61 | - irish_wolfhound.jpg
62 | - italian_greyhound.jpg
63 | - japanese_spaniel.jpg
64 | - keeshond.jpg
65 | - kelpie.jpg
66 | - kerry_blue_terrier.jpg
67 | - komondor.jpg
68 | - kuvasz.jpg
69 | - labrador_retriever.jpg
70 | - lakeland_terrier.jpg
71 | - leonberger.jpg
72 | - lhasa_apso.jpg
73 | - dachshund.jpg
74 | - malamute.jpg
75 | - malinois_dog.jpg
76 | - mexican_hairless_dog.jpg
77 | - miniature_pinscher.jpg
78 | - miniature_poodle.jpg
79 | - miniature_schnauzer.jpg
80 | - newfoundland_dog.jpg
81 | - norfolk_terrier.jpg
82 | - norwegian_elkhound.jpg
83 | - norwich_terrier.jpg
84 | - old_english_sheepdog.jpg
85 | - otterhound.jpg
86 | - papillon_dog.jpg
87 | - pekingese.jpg
88 | - pembroke_welsh_corgi.jpg
89 | - pomeranian.jpg
90 | - pug.jpg
91 | - redbone_coonhound.jpg
92 | - rhodesian_ridgeback.jpg
93 | - rottweiler.jpg
94 | - boston_terrier.jpg
95 | - dhole.jpg
96 | - ibizan_hound.jpg
97 | - maltese_dog.jpg
98 | - saint_bernard.jpg
99 | - saluki.jpg
100 | - samoyed_dog.jpg
101 | - schipperke.jpg
102 | - scotch_terrier.jpg
103 | - scottish_deerhound.jpg
104 | - sealyham_terrier.jpg
105 | - shetland_sheepdog.jpg
106 | - siberian_husky.jpg
107 | - silky_terrier.jpg
108 | - staffordshire_bull_terrier.jpg
109 | - standard_poodle.jpg
110 | - standard_schnauzer.jpg
111 | - sussex_spaniel.jpg
112 | - tan_coonhound.jpg
113 | - tibetan_mastiff.jpg
114 | - tibetan_terrier.jpg
115 | - toy_poodle.jpg
116 | - toy_terrier.jpg
117 | - shih_tzu.jpg
118 | - vizsla.jpg
119 | - walker_hound.jpg
120 | - weimaraner.jpg
121 | - welsh_springer_spaniel.jpg
122 | - west_highland_white_terrier.jpg
123 | - whippet.jpg
124 | - yorkshire_terrier.jpg
125 |
126 |
127 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Identify Dog Breeds
4 | Identify Dog Breeds
5 | This device doesn\'t support Camera2 API.
6 | From Gallery..
7 | Identify Dog Breeds
9 | Identify over one hundred different dog breeds with your smartphone.
10 | Click the camera button or load an image from the image gallery to analyze a single picture. Tap the display to close the displayed result, or use the share button to share a screenshot.
11 | Activate continuous predictions and keep the dog in the circle to get predictions directly from the video stream. The application reports up to three predictions it believes to be the most correct. Please treat the output only as a suggestion.
12 | If you like this app consider buying the premium version which supports the identification of more than two hundred different dog breeds with much higher accuracy: https://play.google.com/store/apps/details?id=com.jstappdev.identify_dog_breeds_pro
13 | Acknowledgements
14 | Based on an extended version of the Stanford Dogs dataset. Icons made by Pause08, Smashicons, Becris, Freepik from www.flaticon.com.
15 |
Apache License 2.0. Source code available at github.com/j05t/dbclf. Pictures from Wikipedia.
16 | ]]>
17 | About
18 | Exit
19 | Out of Memory Error. Try closing a few background applications.
20 | Share with..
21 | Supported Breeds
22 | Look up on Wikipedia?
23 | No
24 | Yes
25 | No detection
26 | Change Language
27 |
28 |
29 | - Affenpinscher
30 | - Afghan Hound
31 | - African Hunting Dog
32 | - Airedale Terrier
33 | - American Staffordshire Terrier
34 | - Appenzeller Sennenhund
35 | - Australian Terrier
36 | - Basenji
37 | - Basset Hound
38 | - Beagle
39 | - Bedlington Terrier
40 | - Bernese Mountain Dog
41 | - Blenheim Spaniel
42 | - Bloodhound
43 | - Bluetick Coonhound
44 | - Border Collie
45 | - Border Terrier
46 | - Borzoi
47 | - Bouvier Des Flandres
48 | - Boxer (dog)
49 | - Griffon Bruxellois
50 | - Briard
51 | - Brittany Spaniel
52 | - Bullmastiff
53 | - Cairn Terrier
54 | - Cardigan Welsh Corgi
55 | - Chesapeake Bay Retriever
56 | - Chihuahua (dog)
57 | - Chow Chow
58 | - Clumber Spaniel
59 | - Flat-coated Retriever
60 | - Soft-coated Wheaten Terrier
61 | - Cocker Spaniel
62 | - Collie
63 | - Curly Coated Retriever
64 | - Dandie Dinmont Terrier
65 | - Dingo
66 | - Doberman
67 | - English Foxhound
68 | - English Setter
69 | - English Springer Spaniel
70 | - Entlebucher Mountain Dog
71 | - Eskimo Dog
72 | - French Bulldog
73 | - German Shepherd
74 | - Giant Schnauzer
75 | - Golden Retriever
76 | - Gordon Setter
77 | - Greater Swiss Mountain Dog
78 | - Great Dane
79 | - Great Pyrenees
80 | - Groenendael dog
81 | - Fox Terrier
82 | - German Shorthaired Pointer
83 | - Irish Setter
84 | - Irish Terrier
85 | - Irish Water Spaniel
86 | - Irish Wolfhound
87 | - Italian Greyhound
88 | - Japanese Chin
89 | - Keeshond
90 | - Kelpie
91 | - Kerry Blue Terrier
92 | - Komondor
93 | - Kuvasz
94 | - Labrador Retriever
95 | - Lakeland Terrier
96 | - Leonberger
97 | - Lhasa Apso
98 | - Dachshund
99 | - Alaskan Malamute
100 | - Malinois dog
101 | - Mexican Hairless Dog
102 | - Miniature Pinscher
103 | - Miniature Poodle
104 | - Miniature Schnauzer
105 | - Newfoundland dog
106 | - Norfolk Terrier
107 | - Norwegian Elkhound
108 | - Norwich Terrier
109 | - Old English Sheepdog
110 | - Otterhound
111 | - Papillon dog
112 | - Pekingese
113 | - Pembroke Welsh Corgi
114 | - Pomeranian
115 | - Pug
116 | - Redbone Coonhound
117 | - Rhodesian Ridgeback
118 | - Rottweiler
119 | - Boston Terrier
120 | - Dhole
121 | - Ibizan Hound
122 | - Maltese dog
123 | - Saint Bernard
124 | - Saluki
125 | - Samoyed dog
126 | - Schipperke
127 | - Scotch Terrier
128 | - Scottish Deerhound
129 | - Sealyham Terrier
130 | - Shetland Sheepdog
131 | - Siberian Husky
132 | - Silky Terrier
133 | - Staffordshire Bull Terrier
134 | - Standard Poodle
135 | - Standard Schnauzer
136 | - Sussex Spaniel
137 | - Black and Tan Coonhound
138 | - Tibetan Mastiff
139 | - Tibetan Terrier
140 | - Toy Poodle
141 | - English Toy Terrier (Black & Tan)
142 | - Shih Tzu
143 | - Vizsla
144 | - Treeing Walker Coonhound
145 | - Weimaraner
146 | - Welsh Springer Spaniel
147 | - West Highland White Terrier
148 | - Whippet
149 | - Yorkshire Terrier
150 |
151 |
152 |
153 | - English
154 | - Deutsch
155 | - Français
156 | - ქართული
157 |
158 |
159 |
160 | - en
161 | - de
162 | - fr
163 | - ka
164 |
165 |
166 |
167 |
--------------------------------------------------------------------------------
/res/xml/filepaths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
--------------------------------------------------------------------------------
/src/com/jstappdev/dbclf/AutoFitTextureView.java:
--------------------------------------------------------------------------------
1 | package com.jstappdev.dbclf;
2 |
3 | /*
4 | * Copyright 2016 The TensorFlow Authors. All Rights Reserved.
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | import android.content.Context;
19 | import android.util.AttributeSet;
20 | import android.view.TextureView;
21 |
22 | /**
23 | * A {@link TextureView} that can be adjusted to a specified aspect ratio.
24 | */
25 | public class AutoFitTextureView extends TextureView {
26 | private int ratioWidth = 0;
27 | private int ratioHeight = 0;
28 |
29 | public AutoFitTextureView(final Context context) {
30 | this(context, null);
31 | }
32 |
33 | public AutoFitTextureView(final Context context, final AttributeSet attrs) {
34 | this(context, attrs, 0);
35 | }
36 |
37 | public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {
38 | super(context, attrs, defStyle);
39 | }
40 |
41 | /**
42 | * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
43 | * calculated from the parameters. Note that the actual sizes of parameters don't matter, that
44 | * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
45 | *
46 | * @param width Relative horizontal size
47 | * @param height Relative vertical size
48 | */
49 | public void setAspectRatio(final int width, final int height) {
50 | if (width < 0 || height < 0) {
51 | throw new IllegalArgumentException("Size cannot be negative.");
52 | }
53 | ratioWidth = width;
54 | ratioHeight = height;
55 | requestLayout();
56 | }
57 |
58 | @Override
59 | protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
60 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
61 | final int width = MeasureSpec.getSize(widthMeasureSpec);
62 | final int height = MeasureSpec.getSize(heightMeasureSpec);
63 | if (0 == ratioWidth || 0 == ratioHeight) {
64 | setMeasuredDimension(width, height);
65 | } else {
66 | if (width < height * ratioWidth / ratioHeight) {
67 | setMeasuredDimension(width, width * ratioHeight / ratioWidth);
68 | } else {
69 | setMeasuredDimension(height * ratioWidth / ratioHeight, height);
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/com/jstappdev/dbclf/CameraConnectionFragment.java:
--------------------------------------------------------------------------------
1 | package com.jstappdev.dbclf;
2 |
3 | /*
4 | * Copyright 2016 The TensorFlow Authors. All Rights Reserved.
5 | * Modifications copyright (C) 2018 Josef Steppan
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import android.Manifest;
21 | import android.app.Activity;
22 | import android.content.Context;
23 | import android.content.pm.PackageManager;
24 | import android.content.res.Configuration;
25 | import android.graphics.ImageFormat;
26 | import android.graphics.Matrix;
27 | import android.graphics.RectF;
28 | import android.graphics.SurfaceTexture;
29 | import android.hardware.camera2.CameraAccessException;
30 | import android.hardware.camera2.CameraCaptureSession;
31 | import android.hardware.camera2.CameraCharacteristics;
32 | import android.hardware.camera2.CameraDevice;
33 | import android.hardware.camera2.CameraManager;
34 | import android.hardware.camera2.CaptureRequest;
35 | import android.hardware.camera2.CaptureResult;
36 | import android.hardware.camera2.TotalCaptureResult;
37 | import android.hardware.camera2.params.StreamConfigurationMap;
38 | import android.media.ImageReader;
39 | import android.media.ImageReader.OnImageAvailableListener;
40 | import android.os.Bundle;
41 | import android.os.Handler;
42 | import android.os.HandlerThread;
43 | import android.util.Size;
44 | import android.util.SparseIntArray;
45 | import android.view.LayoutInflater;
46 | import android.view.Surface;
47 | import android.view.TextureView;
48 | import android.view.View;
49 | import android.view.ViewGroup;
50 | import android.widget.Toast;
51 |
52 | import androidx.annotation.NonNull;
53 | import androidx.core.app.ActivityCompat;
54 | import androidx.fragment.app.Fragment;
55 |
56 | import java.util.ArrayList;
57 | import java.util.Arrays;
58 | import java.util.Collections;
59 | import java.util.Comparator;
60 | import java.util.List;
61 | import java.util.concurrent.Semaphore;
62 | import java.util.concurrent.TimeUnit;
63 |
64 | public class CameraConnectionFragment extends Fragment {
65 |
66 | /**
67 | * The camera preview size will be chosen to be the smallest frame by pixel size capable of
68 | * containing a DESIRED_SIZE x DESIRED_SIZE square.
69 | */
70 | private static final int MINIMUM_PREVIEW_SIZE = 299;
71 |
72 | /**
73 | * Conversion from screen rotation to JPEG orientation.
74 | */
75 | private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
76 |
77 | static {
78 | ORIENTATIONS.append(Surface.ROTATION_0, 90);
79 | ORIENTATIONS.append(Surface.ROTATION_90, 0);
80 | ORIENTATIONS.append(Surface.ROTATION_180, 270);
81 | ORIENTATIONS.append(Surface.ROTATION_270, 180);
82 | }
83 |
84 | /**
85 | * A {@link Semaphore} to prevent the app from exiting before closing the camera.
86 | */
87 | private final Semaphore cameraOpenCloseLock = new Semaphore(1);
88 | /**
89 | * The input size in pixels desired by TensorFlow (width and height of a square bitmap).
90 | */
91 | private final Size inputSize;
92 | /**
93 | * The layout identifier to inflate for this Fragment.
94 | */
95 | private final int layout;
96 | private final CameraCaptureSession.CaptureCallback captureCallback =
97 | new CameraCaptureSession.CaptureCallback() {
98 | @Override
99 | public void onCaptureProgressed(
100 | final CameraCaptureSession session,
101 | final CaptureRequest request,
102 | final CaptureResult partialResult) {
103 | }
104 |
105 | @Override
106 | public void onCaptureCompleted(
107 | final CameraCaptureSession session,
108 | final CaptureRequest request,
109 | final TotalCaptureResult result) {
110 | }
111 | };
112 | /**
113 | * ID of the current {@link CameraDevice}.
114 | */
115 | private String cameraId;
116 | /**
117 | * An {@link AutoFitTextureView} for camera preview.
118 | */
119 | private AutoFitTextureView textureView;
120 | /**
121 | * A {@link CameraCaptureSession } for camera preview.
122 | */
123 | private CameraCaptureSession captureSession;
124 | /**
125 | * A reference to the opened {@link CameraDevice}.
126 | */
127 | private CameraDevice cameraDevice;
128 | /**
129 | * The rotation in degrees of the camera sensor from the display.
130 | */
131 | private Integer sensorOrientation;
132 | /**
133 | * The {@link android.util.Size} of camera preview.
134 | */
135 | private Size previewSize;
136 | /**
137 | * An additional thread for running tasks that shouldn't block the UI.
138 | */
139 | private HandlerThread backgroundThread;
140 | /**
141 | * A {@link Handler} for running tasks in the background.
142 | */
143 | private Handler backgroundHandler;
144 | /**
145 | * An {@link ImageReader} that handles preview frame capture.
146 | */
147 | private ImageReader previewReader;
148 | /**
149 | * {@link android.hardware.camera2.CaptureRequest.Builder} for the camera preview
150 | */
151 | private CaptureRequest.Builder previewRequestBuilder;
152 | /**
153 | * {@link CaptureRequest} generated by {@link #previewRequestBuilder}
154 | */
155 | private CaptureRequest previewRequest;
156 | /**
157 | * A {@link OnImageAvailableListener} to receive frames as they are available.
158 | */
159 | private OnImageAvailableListener imageListener;
160 | /**
161 | * {@link android.hardware.camera2.CameraDevice.StateCallback}
162 | * is called when {@link CameraDevice} changes its state.
163 | */
164 | private final CameraDevice.StateCallback stateCallback =
165 | new CameraDevice.StateCallback() {
166 | @Override
167 | public void onOpened(final CameraDevice cd) {
168 | // This method is called when the camera is opened. We start camera preview here.
169 | cameraDevice = cd;
170 | createCameraPreviewSession();
171 | cameraOpenCloseLock.release();
172 | }
173 |
174 | @Override
175 | public void onDisconnected(final CameraDevice cd) {
176 | cameraOpenCloseLock.release();
177 | cd.close();
178 | cameraDevice = null;
179 | }
180 |
181 | @Override
182 | public void onError(final CameraDevice cd, final int error) {
183 | cameraOpenCloseLock.release();
184 | cd.close();
185 | cameraDevice = null;
186 | final Activity activity = getActivity();
187 | if (null != activity) {
188 | activity.finish();
189 | }
190 | }
191 | };
192 | private ConnectionCallback cameraConnectionCallback;
193 | /**
194 | * {@link android.view.TextureView.SurfaceTextureListener} handles several lifecycle events on a
195 | * {@link TextureView}.
196 | */
197 | private final TextureView.SurfaceTextureListener surfaceTextureListener =
198 | new TextureView.SurfaceTextureListener() {
199 | @Override
200 | public void onSurfaceTextureAvailable(
201 | final SurfaceTexture texture, final int width, final int height) {
202 | openCamera(width, height);
203 | }
204 |
205 | @Override
206 | public void onSurfaceTextureSizeChanged(
207 | final SurfaceTexture texture, final int width, final int height) {
208 | configureTransform(width, height);
209 | }
210 |
211 | @Override
212 | public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {
213 | return true;
214 | }
215 |
216 | @Override
217 | public void onSurfaceTextureUpdated(final SurfaceTexture texture) {
218 | }
219 | };
220 |
221 | public CameraConnectionFragment() {
222 | this.layout = R.layout.camera_connection_fragment;
223 | this.inputSize = new Size(299, 299);
224 | this.cameraId = CameraActivity.cameraId;
225 | }
226 |
227 | /**
228 | * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose
229 | * width and height are at least as large as the minimum of both, or an exact match if possible.
230 | *
231 | * @param choices The list of sizes that the camera supports for the intended output class
232 | * @param width The minimum desired width
233 | * @param height The minimum desired height
234 | * @return The optimal {@code Size}, or an arbitrary one if none were big enough
235 | */
236 | protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {
237 | final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);
238 | final Size desiredSize = new Size(width, height);
239 |
240 | // Collect the supported resolutions that are at least as big as the preview Surface
241 | boolean exactSizeFound = false;
242 | final List bigEnough = new ArrayList();
243 |
244 | for (final Size option : choices) {
245 | if (option.equals(desiredSize)) {
246 | // Set the size but don't return yet so that remaining sizes will still be logged.
247 | exactSizeFound = true;
248 | }
249 |
250 | if (option.getHeight() >= minSize && option.getWidth() >= minSize) {
251 | bigEnough.add(option);
252 | }
253 | }
254 |
255 |
256 | if (exactSizeFound) {
257 | return desiredSize;
258 | }
259 |
260 | // Pick the smallest of those, assuming we found any
261 | if (bigEnough.size() > 0) {
262 | final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());
263 | return chosenSize;
264 | } else {
265 | return choices[0];
266 | }
267 | }
268 |
269 | @Override
270 | public void onCreate(Bundle savedInstanceState) {
271 | super.onCreate(savedInstanceState);
272 |
273 | this.cameraConnectionCallback = new ConnectionCallback() {
274 | @Override
275 | public void onPreviewSizeChosen(Size size, int rotation) {
276 | ((CameraActivity) requireContext()).onPreviewSizeChosen(size, rotation);
277 | }
278 | };
279 |
280 | this.imageListener = (CameraActivity) requireContext();
281 | }
282 |
283 | /**
284 | * Shows a {@link Toast} on the UI thread.
285 | *
286 | * @param text The message to show
287 | */
288 | private void showToast(final String text) {
289 | final Activity activity = getActivity();
290 | if (activity != null) {
291 | activity.runOnUiThread(
292 | () -> Toast.makeText(requireContext().getApplicationContext(), text, Toast.LENGTH_SHORT).show());
293 | }
294 | }
295 |
296 | @Override
297 | public View onCreateView(
298 | final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
299 | return inflater.inflate(layout, container, false);
300 | }
301 |
302 | @Override
303 | public void onViewCreated(final View view, final Bundle savedInstanceState) {
304 | textureView = view.findViewById(R.id.texture);
305 | }
306 |
307 | @Override
308 | public void onActivityCreated(final Bundle savedInstanceState) {
309 | super.onActivityCreated(savedInstanceState);
310 | }
311 |
312 | @Override
313 | public void onResume() {
314 | super.onResume();
315 | startBackgroundThread();
316 |
317 | // When the screen is turned off and turned back on, the SurfaceTexture is already
318 | // available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open
319 | // a camera and start preview from here (otherwise, we wait until the surface is ready in
320 | // the SurfaceTextureListener).
321 | if (textureView.isAvailable()) {
322 | openCamera(textureView.getWidth(), textureView.getHeight());
323 | } else {
324 | textureView.setSurfaceTextureListener(surfaceTextureListener);
325 | }
326 | }
327 |
328 | @Override
329 | public void onPause() {
330 | closeCamera();
331 | stopBackgroundThread();
332 | super.onPause();
333 | }
334 |
335 |
336 | /**
337 | * Sets up member variables related to camera.
338 | */
339 | private void setUpCameraOutputs() {
340 | final Activity activity = getActivity();
341 | final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
342 | try {
343 | final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
344 |
345 | final StreamConfigurationMap map =
346 | characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
347 |
348 | sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
349 |
350 | // Danger, W.R.! Attempting to use too large a preview size could exceed the camera
351 | // bus' bandwidth limitation, resulting in gorgeous previews but the storage of
352 | // garbage capture data.
353 | previewSize =
354 | chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
355 | inputSize.getWidth(),
356 | inputSize.getHeight());
357 |
358 | // We fit the aspect ratio of TextureView to the size of preview we picked.
359 | final int orientation = getResources().getConfiguration().orientation;
360 | if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
361 | textureView.setAspectRatio(previewSize.getWidth(), previewSize.getHeight());
362 | } else {
363 | textureView.setAspectRatio(previewSize.getHeight(), previewSize.getWidth());
364 | }
365 | } catch (final CameraAccessException ignored) {
366 | } catch (final NullPointerException e) {
367 | // Currently an NPE is thrown when the Camera2API is used but not supported on the
368 | // device this code runs.
369 | throw new RuntimeException(getString(R.string.camera_error));
370 | }
371 |
372 | cameraConnectionCallback.onPreviewSizeChosen(previewSize, sensorOrientation);
373 | }
374 |
375 | /**
376 | * Opens the camera specified by {@link CameraConnectionFragment#cameraId}.
377 | */
378 | private void openCamera(final int width, final int height) {
379 | setUpCameraOutputs();
380 | configureTransform(width, height);
381 | final Activity activity = getActivity();
382 | final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
383 | try {
384 | if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
385 | throw new RuntimeException("Time out waiting to lock camera opening.");
386 | }
387 | if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
388 | return;
389 | }
390 | manager.openCamera(cameraId, stateCallback, backgroundHandler);
391 | } catch (final CameraAccessException e) {
392 | } catch (final InterruptedException e) {
393 | throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
394 | }
395 | }
396 |
397 | /**
398 | * Closes the current {@link CameraDevice}.
399 | */
400 | private void closeCamera() {
401 | try {
402 | cameraOpenCloseLock.acquire();
403 | if (null != captureSession) {
404 | captureSession.close();
405 | captureSession = null;
406 | }
407 | if (null != cameraDevice) {
408 | cameraDevice.close();
409 | cameraDevice = null;
410 | }
411 | if (null != previewReader) {
412 | previewReader.close();
413 | previewReader = null;
414 | }
415 | } catch (final InterruptedException e) {
416 | throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
417 | } finally {
418 | cameraOpenCloseLock.release();
419 | }
420 | }
421 |
422 | /**
423 | * Starts a background thread and its {@link Handler}.
424 | */
425 | private void startBackgroundThread() {
426 | backgroundThread = new HandlerThread("ImageListener");
427 | backgroundThread.start();
428 | backgroundHandler = new Handler(backgroundThread.getLooper());
429 | }
430 |
431 | /**
432 | * Stops the background thread and its {@link Handler}.
433 | */
434 | private void stopBackgroundThread() {
435 | backgroundThread.quitSafely();
436 | try {
437 | backgroundThread.join();
438 | backgroundThread.quit();
439 | backgroundThread = null;
440 | backgroundHandler = null;
441 | } catch (final InterruptedException e) {
442 | }
443 | }
444 |
445 | /**
446 | * Creates a new {@link CameraCaptureSession} for camera preview.
447 | */
448 | private void createCameraPreviewSession() {
449 | try {
450 | final SurfaceTexture texture = textureView.getSurfaceTexture();
451 | assert texture != null;
452 |
453 | // We configure the size of default buffer to be the size of camera preview we want.
454 | texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
455 |
456 | // This is the output Surface we need to start preview.
457 | final Surface surface = new Surface(texture);
458 |
459 | // We set up a CaptureRequest.Builder with the output Surface.
460 | previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
461 | previewRequestBuilder.addTarget(surface);
462 |
463 | // Create the reader for the preview frames.
464 | previewReader =
465 | ImageReader.newInstance(
466 | previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);
467 |
468 | previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);
469 | previewRequestBuilder.addTarget(previewReader.getSurface());
470 |
471 | // Here, we create a CameraCaptureSession for camera preview.
472 | cameraDevice.createCaptureSession(
473 | Arrays.asList(surface, previewReader.getSurface()),
474 | new CameraCaptureSession.StateCallback() {
475 |
476 | @Override
477 | public void onConfigured(@NonNull final CameraCaptureSession cameraCaptureSession) {
478 | // The camera is already closed
479 | if (null == cameraDevice) {
480 | return;
481 | }
482 |
483 | // When the session is ready, we start displaying the preview.
484 | captureSession = cameraCaptureSession;
485 | try {
486 | // Auto focus should be continuous for camera preview.
487 | previewRequestBuilder.set(
488 | CaptureRequest.CONTROL_AF_MODE,
489 | CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
490 | // Flash is automatically enabled when necessary.
491 | previewRequestBuilder.set(
492 | CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
493 |
494 | // Finally, we start displaying the camera preview.
495 | previewRequest = previewRequestBuilder.build();
496 | /*
497 | * @throws IllegalStateException if this session is no longer active, either because the session
498 | * was explicitly closed, a new session has been created
499 | * or the camera device has been closed.
500 | */
501 | // https://stackoverflow.com/questions/40146485/session-has-been-closed-further-changes-are-illegal
502 | new Handler().postDelayed(new Runnable() {
503 | @Override
504 | public void run() {
505 | try {
506 | if (captureSession != null)
507 | captureSession.setRepeatingRequest(previewRequest,
508 | captureCallback, null);
509 | } catch (CameraAccessException e) {
510 | showToast("Failed to start camera preview because it couldn't access camera");
511 | } catch (IllegalStateException e) {
512 | showToast("Failed to start camera preview.");
513 | }
514 | }
515 | }, 500);
516 |
517 | } catch (final Exception ignored) {
518 | }
519 | }
520 |
521 | @Override
522 | public void onConfigureFailed(@NonNull final CameraCaptureSession cameraCaptureSession) {
523 | showToast("Failed");
524 | }
525 | },
526 | null);
527 | } catch (final CameraAccessException ignored) {
528 | }
529 | }
530 |
531 | /**
532 | * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.
533 | * This method should be called after the camera preview size is determined in
534 | * setUpCameraOutputs and also the size of `mTextureView` is fixed.
535 | *
536 | * @param viewWidth The width of `mTextureView`
537 | * @param viewHeight The height of `mTextureView`
538 | */
539 | private void configureTransform(final int viewWidth, final int viewHeight) {
540 | final Activity activity = getActivity();
541 | if (null == textureView || null == previewSize || null == activity) {
542 | return;
543 | }
544 | final int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
545 | final Matrix matrix = new Matrix();
546 | final RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
547 | final RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());
548 | final float centerX = viewRect.centerX();
549 | final float centerY = viewRect.centerY();
550 | if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
551 | bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
552 | matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
553 | final float scale =
554 | Math.max(
555 | (float) viewHeight / previewSize.getHeight(),
556 | (float) viewWidth / previewSize.getWidth());
557 | matrix.postScale(scale, scale, centerX, centerY);
558 | matrix.postRotate(90 * (rotation - 2), centerX, centerY);
559 | } else if (Surface.ROTATION_180 == rotation) {
560 | matrix.postRotate(180, centerX, centerY);
561 | }
562 | textureView.setTransform(matrix);
563 | }
564 |
565 | /**
566 | * Callback for Activities to use to initialize their data once the
567 | * selected preview size is known.
568 | */
569 | public interface ConnectionCallback {
570 | void onPreviewSizeChosen(Size size, int cameraRotation);
571 | }
572 |
573 | /**
574 | * Compares two {@code Size}s based on their areas.
575 | */
576 | static class CompareSizesByArea implements Comparator {
577 | @Override
578 | public int compare(final Size lhs, final Size rhs) {
579 | // We cast here to ensure the multiplications won't overflow
580 | return Long.signum(
581 | (long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());
582 | }
583 | }
584 |
585 | }
586 |
--------------------------------------------------------------------------------
/src/com/jstappdev/dbclf/Classifier.java:
--------------------------------------------------------------------------------
1 | package com.jstappdev.dbclf;
2 |
3 | /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
4 | * Modifications copyright (C) 2018 Josef Steppan
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 | http://www.apache.org/licenses/LICENSE-2.0
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 | import android.graphics.Bitmap;
18 | import android.graphics.RectF;
19 |
20 | import java.util.List;
21 | import java.util.Locale;
22 |
23 | /**
24 | * Generic interface for interacting with different recognition engines.
25 | */
26 | public interface Classifier {
27 | List recognizeImage(Bitmap bitmap);
28 |
29 | /**
30 | * An immutable result returned by a Classifier describing what was recognized.
31 | */
32 | class Recognition {
33 | /**
34 | * A unique identifier for what has been recognized. Specific to the class, not the instance of
35 | * the object.
36 | */
37 | private final String id;
38 |
39 | /**
40 | * Display name for the recognition.
41 | */
42 | private final String title;
43 |
44 | /**
45 | * A sortable score for how good the recognition is relative to others. Higher should be better.
46 | */
47 | private final Float confidence;
48 |
49 | /**
50 | * Optional location within the source image for the location of the recognized object.
51 | */
52 | private RectF location;
53 |
54 | public Recognition(
55 | final String id, final String title, final Float confidence, final RectF location) {
56 | this.id = id;
57 | this.title = title;
58 | this.confidence = confidence;
59 | this.location = location;
60 | }
61 |
62 | public String getId() {
63 | return id;
64 | }
65 |
66 | public String getTitle() {
67 | return title;
68 | }
69 |
70 | public Float getConfidence() {
71 | return confidence;
72 | }
73 |
74 | @Override
75 | public String toString() {
76 | String resultString = "";
77 | if (id != null) {
78 | resultString += "[" + id + "] ";
79 | }
80 |
81 | if (title != null) {
82 | resultString += title + " ";
83 | }
84 |
85 | if (confidence != null) {
86 | resultString += String.format(Locale.getDefault(), "(%.1f%%) ", confidence * 100.0f);
87 | }
88 |
89 | if (location != null) {
90 | resultString += location + " ";
91 | }
92 |
93 | return resultString.trim();
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/com/jstappdev/dbclf/ClassifierActivity.java:
--------------------------------------------------------------------------------
1 | package com.jstappdev.dbclf;
2 |
3 | /*
4 | * Copyright 2016 The TensorFlow Authors. All Rights Reserved.
5 | * Modifications copyright (C) 2018 Josef Steppan
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import android.content.ContentResolver;
21 | import android.content.Context;
22 | import android.content.Intent;
23 | import android.database.Cursor;
24 | import android.graphics.Bitmap;
25 | import android.graphics.Bitmap.Config;
26 | import android.graphics.Canvas;
27 | import android.graphics.Matrix;
28 | import android.graphics.Paint;
29 | import android.media.ImageReader.OnImageAvailableListener;
30 | import android.net.Uri;
31 | import android.os.AsyncTask;
32 | import android.provider.MediaStore;
33 | import android.util.Size;
34 | import android.view.View;
35 | import android.widget.Toast;
36 |
37 | import com.jstappdev.dbclf.env.ImageUtils;
38 |
39 | import java.io.IOException;
40 | import java.util.List;
41 |
42 |
43 | public class ClassifierActivity extends CameraActivity implements OnImageAvailableListener {
44 | // mobilenet: 224, inception_v3: 299
45 | private static final int INPUT_SIZE = 299;
46 | private static final int IMAGE_MEAN = 128;
47 | private static final float IMAGE_STD = 128;
48 | // mobilenet: input, inception_v3: Mul, Keras: input_1
49 | private static final String INPUT_NAME = "Mul";
50 | // output, inception(tf): final_result, Keras: output/Softmax
51 | private static final String OUTPUT_NAME = "final_result";
52 | private static final String MODEL_FILE = "file:///android_asset/stripped.pb";
53 | private static final boolean MAINTAIN_ASPECT = true;
54 | private Bitmap rgbFrameBitmap = null;
55 | private Bitmap croppedBitmap = null;
56 | private Matrix frameToCropTransform;
57 |
58 | private Classifier classifier;
59 |
60 | @Override
61 | void handleSendImage(Intent data) {
62 | final Uri imageUri = data.getParcelableExtra(Intent.EXTRA_STREAM);
63 | classifyLoadedImage(imageUri);
64 | }
65 |
66 | /**
67 | * user has chosen a picture from the image gallery
68 | */
69 | @Override
70 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
71 | super.onActivityResult(requestCode, resultCode, data);
72 |
73 | if (resultCode == RESULT_OK && requestCode == PICK_IMAGE)
74 | classifyLoadedImage(data.getData());
75 | }
76 |
77 | private void classifyLoadedImage(Uri imageUri) {
78 | updateResults(null);
79 |
80 | final int orientation = getOrientation(getApplicationContext(), imageUri);
81 | final ContentResolver contentResolver = this.getContentResolver();
82 |
83 | try {
84 | final Bitmap croppedFromGallery;
85 | croppedFromGallery = resizeCropAndRotate(MediaStore.Images.Media.getBitmap(contentResolver, imageUri), orientation);
86 |
87 | runOnUiThread(() -> {
88 | setImage(croppedFromGallery);
89 | inferenceTask = new InferenceTask();
90 | inferenceTask.execute(croppedFromGallery);
91 | });
92 | } catch (IOException e) {
93 | Toast.makeText(getApplicationContext(), "Unable to load image", Toast.LENGTH_LONG).show();
94 | }
95 | }
96 |
97 | // get orientation of picture
98 | public int getOrientation(Context context, Uri photoUri) {
99 | /* it's on the external media. */
100 | try (final Cursor cursor = context.getContentResolver().query(photoUri,
101 | new String[]{MediaStore.Images.ImageColumns.ORIENTATION}, null, null, null)
102 | ) {
103 | if (cursor.getCount() != 1) {
104 | cursor.close();
105 | return -1;
106 | }
107 |
108 | if (cursor != null && cursor.moveToFirst()) {
109 | final int r = cursor.getInt(0);
110 | cursor.close();
111 | return r;
112 | }
113 |
114 | } catch (Exception e) {
115 | return -1;
116 | }
117 | return -1;
118 | }
119 |
120 | private Bitmap resizeCropAndRotate(Bitmap originalImage, int orientation) {
121 | Bitmap result = Bitmap.createBitmap(INPUT_SIZE, INPUT_SIZE, Config.ARGB_8888);
122 |
123 | final float originalWidth = originalImage.getWidth();
124 | final float originalHeight = originalImage.getHeight();
125 |
126 | final Canvas canvas = new Canvas(result);
127 |
128 | final float scale = INPUT_SIZE / originalWidth;
129 |
130 | final float xTranslation = 0.0f;
131 | final float yTranslation = (INPUT_SIZE - originalHeight * scale) / 2.0f;
132 |
133 | final Matrix transformation = new Matrix();
134 | transformation.postTranslate(xTranslation, yTranslation);
135 | transformation.preScale(scale, scale);
136 |
137 | final Paint paint = new Paint();
138 | paint.setFilterBitmap(true);
139 |
140 | canvas.drawBitmap(originalImage, transformation, paint);
141 |
142 | /*
143 | * if the orientation is not 0 (or -1, which means we don't know), we
144 | * have to do a rotation.
145 | */
146 | if (orientation > 0) {
147 | final Matrix matrix = new Matrix();
148 | matrix.postRotate(orientation);
149 |
150 | result = Bitmap.createBitmap(result, 0, 0, INPUT_SIZE,
151 | INPUT_SIZE, matrix, true);
152 | }
153 |
154 | return result;
155 | }
156 |
157 | @Override
158 | public void onPreviewSizeChosen(final Size size, final int rotation) {
159 | previewWidth = size.getWidth();
160 | previewHeight = size.getHeight();
161 |
162 | final int sensorOrientation = rotation - getScreenOrientation();
163 |
164 | rgbFrameBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
165 | croppedBitmap = Bitmap.createBitmap(INPUT_SIZE, INPUT_SIZE, Config.ARGB_8888);
166 |
167 | frameToCropTransform = ImageUtils.getTransformationMatrix(
168 | previewWidth, previewHeight,
169 | INPUT_SIZE, INPUT_SIZE,
170 | sensorOrientation, MAINTAIN_ASPECT);
171 |
172 | final Matrix cropToFrameTransform = new Matrix();
173 | frameToCropTransform.invert(cropToFrameTransform);
174 | }
175 |
176 | protected synchronized void initClassifier() {
177 | if (classifier == null)
178 | try {
179 | classifier =
180 | TensorFlowImageClassifier.create(
181 | getAssets(),
182 | MODEL_FILE,
183 | getResources().getStringArray(R.array.breeds_array),
184 | INPUT_SIZE,
185 | IMAGE_MEAN,
186 | IMAGE_STD,
187 | INPUT_NAME,
188 | OUTPUT_NAME);
189 | } catch (OutOfMemoryError e) {
190 | runOnUiThread(() -> {
191 | cameraButton.setEnabled(true);
192 | continuousInferenceButton.setChecked(false);
193 | Toast.makeText(getApplicationContext(), R.string.error_tf_init, Toast.LENGTH_LONG).show();
194 | });
195 | }
196 | }
197 |
198 | @Override
199 | protected void processImage() {
200 | if (!snapShot.get() && !continuousInference && !imageSet) {
201 | readyForNextImage();
202 | return;
203 | }
204 |
205 | rgbFrameBitmap.setPixels(getRgbBytes(), 0, previewWidth, 0, 0, previewWidth, previewHeight);
206 | final Canvas canvas = new Canvas(croppedBitmap);
207 | canvas.drawBitmap(rgbFrameBitmap, frameToCropTransform, null);
208 |
209 | if (snapShot.compareAndSet(true, false) || continuousInference) {
210 | final Bitmap finalCroppedBitmap = croppedBitmap.copy(croppedBitmap.getConfig(), false);
211 |
212 | runOnUiThread(() -> {
213 | if (!continuousInference && !imageSet)
214 | setImage(finalCroppedBitmap);
215 |
216 | inferenceTask = new InferenceTask();
217 | inferenceTask.execute(finalCroppedBitmap);
218 | });
219 | }
220 | }
221 |
222 | protected class InferenceTask extends AsyncTask> {
223 | @Override
224 | protected void onPreExecute() {
225 | if (!continuousInference)
226 | progressBar.setVisibility(View.VISIBLE);
227 | }
228 |
229 | @Override
230 | protected List doInBackground(Bitmap... bitmaps) {
231 | initClassifier();
232 |
233 | if (!isCancelled() && classifier != null) {
234 | return classifier.recognizeImage(bitmaps[0]);
235 | }
236 |
237 | return null;
238 | }
239 |
240 | @Override
241 | protected void onPostExecute(List recognitions) {
242 | progressBar.setVisibility(View.GONE);
243 |
244 | if (!isCancelled())
245 | updateResults(recognitions);
246 |
247 | readyForNextImage();
248 | }
249 | }
250 |
251 | }
252 |
--------------------------------------------------------------------------------
/src/com/jstappdev/dbclf/LegacyCameraConnectionFragment.java:
--------------------------------------------------------------------------------
1 | package com.jstappdev.dbclf;
2 |
3 | /*
4 | * Copyright 2017 The TensorFlow Authors. All Rights Reserved.
5 | * Modifications copyright (C) 2018 Josef Steppan
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import android.graphics.SurfaceTexture;
21 | import android.hardware.Camera;
22 | import android.hardware.Camera.CameraInfo;
23 | import android.os.Bundle;
24 | import android.os.Handler;
25 | import android.os.HandlerThread;
26 | import android.util.Size;
27 | import android.util.SparseIntArray;
28 | import android.view.LayoutInflater;
29 | import android.view.Surface;
30 | import android.view.TextureView;
31 | import android.view.View;
32 | import android.view.ViewGroup;
33 |
34 | import androidx.fragment.app.Fragment;
35 |
36 | import com.jstappdev.dbclf.env.ImageUtils;
37 |
38 | import java.io.IOException;
39 | import java.util.List;
40 |
41 | public class LegacyCameraConnectionFragment extends Fragment {
42 | /**
43 | * Conversion from screen rotation to JPEG orientation.
44 | */
45 | private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
46 |
47 | static {
48 | ORIENTATIONS.append(Surface.ROTATION_0, 90);
49 | ORIENTATIONS.append(Surface.ROTATION_90, 0);
50 | ORIENTATIONS.append(Surface.ROTATION_180, 270);
51 | ORIENTATIONS.append(Surface.ROTATION_270, 180);
52 | }
53 |
54 | private Camera camera;
55 | private Camera.PreviewCallback imageListener;
56 | private Size desiredSize;
57 | /**
58 | * The layout identifier to inflate for this Fragment.
59 | */
60 | private int layout;
61 | /**
62 | * An {@link AutoFitTextureView} for camera preview.
63 | */
64 | private AutoFitTextureView textureView;
65 | /**
66 | * {@link android.view.TextureView.SurfaceTextureListener} handles several lifecycle events on a
67 | * {@link TextureView}.
68 | */
69 | private final TextureView.SurfaceTextureListener surfaceTextureListener =
70 | new TextureView.SurfaceTextureListener() {
71 | @Override
72 | public void onSurfaceTextureAvailable(
73 | final SurfaceTexture texture, final int width, final int height) {
74 |
75 | int index = getCameraId();
76 | camera = Camera.open(index);
77 |
78 | try {
79 | Camera.Parameters parameters = camera.getParameters();
80 | List focusModes = parameters.getSupportedFocusModes();
81 | if (focusModes != null
82 | && focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
83 | parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
84 | }
85 | List cameraSizes = parameters.getSupportedPreviewSizes();
86 | Size[] sizes = new Size[cameraSizes.size()];
87 | int i = 0;
88 | for (Camera.Size size : cameraSizes) {
89 | sizes[i++] = new Size(size.width, size.height);
90 | }
91 | Size previewSize =
92 | CameraConnectionFragment.chooseOptimalSize(
93 | sizes, desiredSize.getWidth(), desiredSize.getHeight());
94 | parameters.setPreviewSize(previewSize.getWidth(), previewSize.getHeight());
95 | camera.setDisplayOrientation(90);
96 | camera.setParameters(parameters);
97 | camera.setPreviewTexture(texture);
98 | } catch (IOException exception) {
99 | camera.release();
100 | }
101 |
102 | camera.setPreviewCallbackWithBuffer(imageListener);
103 | Camera.Size s = camera.getParameters().getPreviewSize();
104 | camera.addCallbackBuffer(new byte[ImageUtils.getYUVByteSize(s.height, s.width)]);
105 |
106 | textureView.setAspectRatio(s.height, s.width);
107 |
108 | camera.startPreview();
109 | }
110 |
111 | @Override
112 | public void onSurfaceTextureSizeChanged(
113 | final SurfaceTexture texture, final int width, final int height) {
114 | }
115 |
116 | @Override
117 | public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {
118 | return true;
119 | }
120 |
121 | @Override
122 | public void onSurfaceTextureUpdated(final SurfaceTexture texture) {
123 | }
124 | };
125 | /**
126 | * An additional thread for running tasks that shouldn't block the UI.
127 | */
128 | private HandlerThread backgroundThread;
129 |
130 | public LegacyCameraConnectionFragment() {
131 | this.layout = R.layout.camera_connection_fragment;
132 | this.desiredSize = new Size(299, 299);
133 | }
134 |
135 | @Override
136 | public void onCreate(Bundle savedInstanceState) {
137 | super.onCreate(savedInstanceState);
138 | this.imageListener = (CameraActivity) requireContext();
139 | }
140 |
141 | @Override
142 | public View onCreateView(
143 | final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
144 | return inflater.inflate(layout, container, false);
145 | }
146 |
147 | @Override
148 | public void onViewCreated(final View view, final Bundle savedInstanceState) {
149 | textureView = view.findViewById(R.id.texture);
150 | }
151 |
152 | @Override
153 | public void onActivityCreated(final Bundle savedInstanceState) {
154 | super.onActivityCreated(savedInstanceState);
155 | }
156 |
157 | @Override
158 | public void onResume() {
159 | super.onResume();
160 | startBackgroundThread();
161 | // When the screen is turned off and turned back on, the SurfaceTexture is already
162 | // available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open
163 | // a camera and start preview from here (otherwise, we wait until the surface is ready in
164 | // the SurfaceTextureListener).
165 |
166 | if (textureView.isAvailable() && camera != null) {
167 | camera.startPreview();
168 | } else {
169 | textureView.setSurfaceTextureListener(surfaceTextureListener);
170 | }
171 | }
172 |
173 | @Override
174 | public void onPause() {
175 | stopCamera();
176 | stopBackgroundThread();
177 | super.onPause();
178 | }
179 |
180 | /**
181 | * Starts a background thread and its {@link Handler}.
182 | */
183 | private void startBackgroundThread() {
184 | backgroundThread = new HandlerThread("CameraBackground");
185 | backgroundThread.start();
186 | }
187 |
188 | /**
189 | * Stops the background thread and its {@link Handler}.
190 | */
191 | private void stopBackgroundThread() {
192 | backgroundThread.quitSafely();
193 | try {
194 | backgroundThread.join();
195 | backgroundThread = null;
196 | } catch (final InterruptedException ignored) {
197 | }
198 | }
199 |
200 | private void stopCamera() {
201 | if (camera != null) {
202 | camera.stopPreview();
203 | camera.setPreviewCallback(null);
204 | camera.release();
205 | camera = null;
206 | }
207 | }
208 |
209 | private int getCameraId() {
210 | CameraInfo ci = new CameraInfo();
211 | for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
212 | Camera.getCameraInfo(i, ci);
213 | if (ci.facing == CameraInfo.CAMERA_FACING_BACK)
214 | return i;
215 | }
216 | return -1; // No camera found
217 | }
218 | }
--------------------------------------------------------------------------------
/src/com/jstappdev/dbclf/ListAdapter.java:
--------------------------------------------------------------------------------
1 | package com.jstappdev.dbclf;
2 |
3 | import android.content.Context;
4 | import android.content.res.AssetManager;
5 | import android.graphics.Bitmap;
6 | import android.graphics.BitmapFactory;
7 | import android.graphics.Typeface;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.BaseExpandableListAdapter;
12 | import android.widget.ImageView;
13 | import android.widget.SectionIndexer;
14 | import android.widget.TextView;
15 |
16 | import java.io.IOException;
17 | import java.io.InputStream;
18 | import java.text.Collator;
19 | import java.util.ArrayList;
20 | import java.util.Collections;
21 | import java.util.HashMap;
22 | import java.util.LinkedHashMap;
23 | import java.util.List;
24 | import java.util.Locale;
25 |
26 | public class ListAdapter extends BaseExpandableListAdapter implements SectionIndexer {
27 |
28 | private Context context;
29 | private List listDataHeader; // header titles
30 | // child data in format of header title, child title
31 | private HashMap listDataChild;
32 | // index for side index list
33 | private HashMap mapIndex;
34 | private String[] sections;
35 |
36 | ListAdapter(Context context, List listDataHeader,
37 | HashMap listChildData) {
38 | this.context = context;
39 | this.listDataHeader = listDataHeader;
40 | this.listDataChild = listChildData;
41 |
42 | // HashMap will prevent duplicates
43 | mapIndex = new LinkedHashMap();
44 | for (int i = listDataHeader.size() - 1; i >= 0; i--) {
45 | mapIndex.put(listDataHeader.get(i).substring(0, 1).toUpperCase(Locale.getDefault()), i);
46 | }
47 |
48 | // create a list from the set to sort
49 | final ArrayList sectionList = new ArrayList(mapIndex.keySet());
50 |
51 | final Collator coll = Collator.getInstance(Locale.getDefault());
52 | coll.setStrength(Collator.PRIMARY);
53 | Collections.sort(sectionList, coll);
54 |
55 | sections = new String[sectionList.size()];
56 |
57 | sectionList.toArray(sections);
58 | }
59 |
60 | private static Bitmap getBitmapFromAsset(Context context, String filePath) {
61 | final AssetManager assetManager = context.getAssets();
62 |
63 | InputStream istr;
64 | Bitmap bitmap = null;
65 | try {
66 | istr = assetManager.open(filePath);
67 | bitmap = BitmapFactory.decodeStream(istr);
68 | } catch (IOException e) {
69 | try {
70 | istr = assetManager.open("nodata.jpg");
71 | bitmap = BitmapFactory.decodeStream(istr);
72 | } catch (IOException ignored) {
73 | }
74 | }
75 | return bitmap;
76 | }
77 |
78 | @Override
79 | public Object getChild(int groupPosition, int childPosititon) {
80 | return this.listDataChild.get(this.listDataHeader.get(groupPosition));
81 | }
82 |
83 | @Override
84 | public long getChildId(int groupPosition, int childPosition) {
85 | return childPosition;
86 | }
87 |
88 | @Override
89 | public View getChildView(int groupPosition, final int childPosition,
90 | boolean isLastChild, View convertView, ViewGroup parent) {
91 |
92 | final String childText = (String) getChild(groupPosition, childPosition);
93 |
94 | if (convertView == null) {
95 | LayoutInflater infalInflater = (LayoutInflater) this.context
96 | .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
97 | convertView = infalInflater.inflate(R.layout.list_item, parent, false);
98 | }
99 |
100 | final ImageView imageViewListChild = convertView.findViewById(R.id.breed_image);
101 |
102 | imageViewListChild.setImageBitmap(getBitmapFromAsset(context, childText));
103 | return convertView;
104 | }
105 |
106 | @Override
107 | public int getChildrenCount(int groupPosition) {
108 | if (this.listDataChild.get(this.listDataHeader.get(groupPosition)) != null)
109 | return 1;
110 | else return 0;
111 | }
112 |
113 | @Override
114 | public Object getGroup(int groupPosition) {
115 | return this.listDataHeader.get(groupPosition);
116 | }
117 |
118 | @Override
119 | public int getGroupCount() {
120 | return this.listDataHeader.size();
121 | }
122 |
123 | @Override
124 | public long getGroupId(int groupPosition) {
125 | return groupPosition;
126 | }
127 |
128 | @Override
129 | public View getGroupView(int groupPosition, boolean isExpanded,
130 | View convertView, ViewGroup parent) {
131 |
132 | final String headerTitle = (String) getGroup(groupPosition);
133 | if (convertView == null) {
134 | LayoutInflater infalInflater = (LayoutInflater) this.context
135 | .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
136 | convertView = infalInflater.inflate(R.layout.list_group, parent, false);
137 | }
138 |
139 | final TextView lblListHeader = convertView.findViewById(R.id.lblListHeader);
140 | lblListHeader.setTypeface(null, Typeface.BOLD);
141 | lblListHeader.setText(headerTitle);
142 |
143 | return convertView;
144 | }
145 |
146 | @Override
147 | public boolean hasStableIds() {
148 | return false;
149 | }
150 |
151 | @Override
152 | public boolean isChildSelectable(int groupPosition, int childPosition) {
153 | return true;
154 | }
155 |
156 | public int getPositionForSection(int section) {
157 | //noinspection ConstantConditions
158 | return mapIndex.get(sections[section]);
159 | }
160 |
161 | public int getSectionForPosition(int position) {
162 | return 0;
163 | }
164 |
165 | public Object[] getSections() {
166 | return sections;
167 | }
168 | }
--------------------------------------------------------------------------------
/src/com/jstappdev/dbclf/RecognitionScoreView.java:
--------------------------------------------------------------------------------
1 | package com.jstappdev.dbclf;
2 |
3 | import android.content.Context;
4 | import android.graphics.Typeface;
5 | import android.util.AttributeSet;
6 | import android.widget.TextView;
7 |
8 | // custom textview to show recognition results
9 | public class RecognitionScoreView extends TextView {
10 |
11 | public RecognitionScoreView(final Context context, final AttributeSet set) {
12 | super(context, set);
13 | this.setTypeface(Typeface.createFromAsset(context.getAssets(), "OpenSans-Regular.ttf"));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/com/jstappdev/dbclf/SimpleListActivity.java:
--------------------------------------------------------------------------------
1 | package com.jstappdev.dbclf;
2 |
3 | import android.app.Activity;
4 | import android.app.AlertDialog;
5 | import android.content.DialogInterface;
6 | import android.content.Intent;
7 | import android.net.Uri;
8 | import android.os.Bundle;
9 | import android.util.Log;
10 | import android.widget.ExpandableListAdapter;
11 | import android.widget.ExpandableListView;
12 |
13 | import java.text.Collator;
14 | import java.util.ArrayList;
15 | import java.util.Collections;
16 | import java.util.HashMap;
17 | import java.util.List;
18 | import java.util.Locale;
19 |
20 | public class SimpleListActivity extends Activity {
21 |
22 | private static String wikiLangSubDomain = "";
23 | private ExpandableListView expListView;
24 | private List listDataHeader;
25 | private HashMap listDataChild;
26 | private ArrayList recogs;
27 |
28 | @Override
29 | protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 |
32 | setContentView(R.layout.activity_list);
33 |
34 | final String lang = CameraActivity.preferredLanguageCode;
35 | if (CameraActivity.supportedLanguageCodes.contains(lang)) {
36 | wikiLangSubDomain = lang + ".";
37 | }
38 |
39 | recogs = getIntent().getStringArrayListExtra("recogs");
40 |
41 | expListView = findViewById(R.id.lvExp);
42 |
43 | prepareListData();
44 |
45 | final ExpandableListAdapter listAdapter = new ListAdapter(this, listDataHeader, listDataChild);
46 |
47 | expListView.setOnChildClickListener((parent, v, groupPosition, childPosition, id) -> {
48 | final String title = listDataHeader.get(groupPosition);
49 | final String searchText = title.replace(" ", "+");
50 |
51 | final DialogInterface.OnClickListener dialogClickListener = (dialog, which) -> {
52 | switch (which) {
53 | case DialogInterface.BUTTON_POSITIVE:
54 | final String url = String.format("https://%swikipedia.org/w/index.php?search=%s&title=Special:Search", wikiLangSubDomain, searchText);
55 |
56 | final Intent i = new Intent(Intent.ACTION_VIEW);
57 | i.setData(Uri.parse(url));
58 | startActivity(i);
59 | break;
60 |
61 | case DialogInterface.BUTTON_NEGATIVE:
62 | break;
63 | }
64 | };
65 |
66 | (new AlertDialog.Builder(this))
67 | .setMessage(R.string.searchFor).setTitle(title)
68 | .setNegativeButton(R.string.no, dialogClickListener)
69 | .setPositiveButton(R.string.yes, dialogClickListener).show();
70 |
71 | return false;
72 | });
73 |
74 | expListView.setFastScrollEnabled(true);
75 | expListView.setAdapter(listAdapter);
76 | }
77 |
78 | @Override
79 | public void onResume() {
80 | super.onResume();
81 |
82 | if (null != recogs)
83 | for (int i = 0; i < listDataHeader.size(); i++)
84 | expListView.expandGroup(i);
85 | }
86 |
87 | /*
88 | * Preparing the list data
89 | */
90 | private void prepareListData() {
91 | listDataHeader = new ArrayList<>();
92 | listDataChild = new HashMap<>();
93 |
94 | Collections.addAll(listDataHeader, getResources().getStringArray(R.array.breeds_array));
95 | final String[] fileNames = getResources().getStringArray(R.array.file_names);
96 |
97 | // load file names
98 | for (int i = 0; i < listDataHeader.size(); i++) {
99 | listDataChild.put(listDataHeader.get(i), fileNames[i]);
100 | }
101 |
102 | if (null != recogs) {
103 | listDataHeader = new ArrayList<>();
104 | listDataHeader.addAll(recogs);
105 | expListView.setFastScrollAlwaysVisible(false);
106 | } else {
107 | Locale locale;
108 |
109 | if (CameraActivity.supportedLanguageCodes.contains(CameraActivity.preferredLanguageCode)) {
110 | locale = new Locale(CameraActivity.preferredLanguageCode);
111 | } else {
112 | locale = Locale.getDefault();
113 | }
114 |
115 | final Collator coll = Collator.getInstance(locale);
116 | coll.setStrength(Collator.PRIMARY);
117 | Collections.sort(listDataHeader, coll);
118 | expListView.setFastScrollAlwaysVisible(true);
119 | }
120 | }
121 |
122 | }
123 |
--------------------------------------------------------------------------------
/src/com/jstappdev/dbclf/TensorFlowImageClassifier.java:
--------------------------------------------------------------------------------
1 | package com.jstappdev.dbclf;
2 |
3 | /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
4 | * Modifications copyright (C) 2018 Josef Steppan
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 | http://www.apache.org/licenses/LICENSE-2.0
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 | import android.content.res.AssetManager;
18 | import android.graphics.Bitmap;
19 |
20 | import org.tensorflow.Operation;
21 | import org.tensorflow.contrib.android.TensorFlowInferenceInterface;
22 |
23 | import java.io.IOException;
24 | import java.util.ArrayList;
25 | import java.util.Collections;
26 | import java.util.List;
27 | import java.util.PriorityQueue;
28 | import java.util.Vector;
29 |
30 | /**
31 | * A classifier specialized to label images using TensorFlow.
32 | */
33 | public class TensorFlowImageClassifier implements Classifier {
34 | // Only return this many results with at least this confidence.
35 | private static final int MAX_RESULTS = 3;
36 | private static final float THRESHOLD = 0.1f;
37 |
38 | // Config values.
39 | private String inputName;
40 | private String outputName;
41 | private int inputSize;
42 | private int imageMean;
43 | private float imageStd;
44 |
45 | // Pre-allocated buffers.
46 | private Vector labels = new Vector();
47 | private int[] intValues;
48 | private float[] floatValues;
49 | private float[] outputs;
50 | private String[] outputNames;
51 |
52 | private boolean logStats = false;
53 |
54 | private TensorFlowInferenceInterface inferenceInterface;
55 |
56 | private TensorFlowImageClassifier() {
57 | }
58 |
59 | /**
60 | * Initializes a native TensorFlow session for classifying images.
61 | *
62 | * @param assetManager The asset manager to be used to load assets.
63 | * @param modelFilename The filepath of the model GraphDef protocol buffer.
64 | * @param labels String array of labels.
65 | * @param inputSize The input size. A square image of inputSize x inputSize is assumed.
66 | * @param imageMean The assumed mean of the image values.
67 | * @param imageStd The assumed std of the image values.
68 | * @param inputName The label of the image input node.
69 | * @param outputName The label of the output node.
70 | * @throws IOException
71 | */
72 | public static Classifier create(
73 | AssetManager assetManager,
74 | String modelFilename,
75 | String[] labels,
76 | int inputSize,
77 | int imageMean,
78 | float imageStd,
79 | String inputName,
80 | String outputName) {
81 | final TensorFlowImageClassifier c = new TensorFlowImageClassifier();
82 | c.inputName = inputName;
83 | c.outputName = outputName;
84 |
85 | // Read the label names into memory.
86 | Collections.addAll(c.labels, labels);
87 |
88 | c.inferenceInterface = new TensorFlowInferenceInterface(assetManager, modelFilename);
89 |
90 | // The shape of the output is [N, NUM_CLASSES], where N is the batch size.
91 | final Operation operation = c.inferenceInterface.graphOperation(outputName);
92 | final int numClasses = (int) operation.output(0).shape().size(1);
93 |
94 | // Ideally, inputSize could have been retrieved from the shape of the input operation. Alas,
95 | // the placeholder node for input in the graphdef typically used does not specify a shape, so it
96 | // must be passed in as a parameter.
97 | c.inputSize = inputSize;
98 | c.imageMean = imageMean;
99 | c.imageStd = imageStd;
100 |
101 | // Pre-allocate buffers.
102 | c.outputNames = new String[]{outputName};
103 | c.intValues = new int[inputSize * inputSize];
104 | c.floatValues = new float[inputSize * inputSize * 3];
105 | c.outputs = new float[numClasses];
106 |
107 | return c;
108 | }
109 |
110 |
111 | @Override
112 | public List recognizeImage(final Bitmap bitmap) {
113 |
114 | // Preprocess the image data from 0-255 int to normalized float based
115 | // on the provided parameters.
116 | bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
117 | for (int i = 0; i < intValues.length; ++i) {
118 | final int val = intValues[i];
119 | floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - imageMean) / imageStd;
120 | floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - imageMean) / imageStd;
121 | floatValues[i * 3 + 2] = ((val & 0xFF) - imageMean) / imageStd;
122 | }
123 |
124 | // Copy the input data into TensorFlow.
125 | inferenceInterface.feed(inputName, floatValues, 1, inputSize, inputSize, 3);
126 |
127 | // Run the inference call.
128 | inferenceInterface.run(outputNames, logStats);
129 |
130 | // Copy the output Tensor back into the output array.
131 | inferenceInterface.fetch(outputName, outputs);
132 |
133 | // Find the best classifications.
134 | PriorityQueue pq =
135 | new PriorityQueue(
136 | 3,
137 | (lhs, rhs) -> {
138 | // Intentionally reversed to put high confidence at the head of the queue.
139 | return Float.compare(rhs.getConfidence(), lhs.getConfidence());
140 | });
141 |
142 | for (int i = 0; i < outputs.length; ++i) {
143 | if (outputs[i] > THRESHOLD) {
144 | pq.add(
145 | new Recognition(
146 | "" + i, labels.size() > i ? labels.get(i) : "unknown", outputs[i], null));
147 | }
148 | }
149 | final ArrayList recognitions = new ArrayList();
150 | final int recognitionsSize = Math.min(pq.size(), MAX_RESULTS);
151 | for (int i = 0; i < recognitionsSize; ++i) {
152 | recognitions.add(pq.poll());
153 | }
154 | return recognitions;
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/src/com/jstappdev/dbclf/env/ImageUtils.java:
--------------------------------------------------------------------------------
1 | package com.jstappdev.dbclf.env;
2 |
3 | /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
4 | * Modifications copyright (C) 2018 Josef Steppan
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 | http://www.apache.org/licenses/LICENSE-2.0
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 | import android.graphics.Matrix;
18 |
19 | /**
20 | * Utility class for manipulating images.
21 | **/
22 | public class ImageUtils {
23 |
24 | // This value is 2 ^ 18 - 1, and is used to clamp the RGB values before their ranges
25 | // are normalized to eight bits.
26 | static final int kMaxChannelValue = 262143;
27 |
28 | private static int YUV2RGB(int y, int u, int v) {
29 | // Adjust and check YUV values
30 | y = (y - 16) < 0 ? 0 : (y - 16);
31 | u -= 128;
32 | v -= 128;
33 |
34 | // This is the floating point equivalent. We do the conversion in integer
35 | // because some Android devices do not have floating point in hardware.
36 | // nR = (int)(1.164 * nY + 2.018 * nU);
37 | // nG = (int)(1.164 * nY - 0.813 * nV - 0.391 * nU);
38 | // nB = (int)(1.164 * nY + 1.596 * nV);
39 | int y1192 = 1192 * y;
40 | int r = (y1192 + 1634 * v);
41 | int g = (y1192 - 833 * v - 400 * u);
42 | int b = (y1192 + 2066 * u);
43 |
44 | // Clipping RGB values to be inside boundaries [ 0 , kMaxChannelValue ]
45 | r = r > kMaxChannelValue ? kMaxChannelValue : (r < 0 ? 0 : r);
46 | g = g > kMaxChannelValue ? kMaxChannelValue : (g < 0 ? 0 : g);
47 | b = b > kMaxChannelValue ? kMaxChannelValue : (b < 0 ? 0 : b);
48 |
49 | return 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
50 | }
51 |
52 | public static void convertYUV420SPToARGB8888(
53 | byte[] input,
54 | int width,
55 | int height,
56 | int[] output) {
57 |
58 | // Java implementation of YUV420SP to ARGB8888 converting
59 | final int frameSize = width * height;
60 | for (int j = 0, yp = 0; j < height; j++) {
61 | int uvp = frameSize + (j >> 1) * width;
62 | int u = 0;
63 | int v = 0;
64 |
65 | for (int i = 0; i < width; i++, yp++) {
66 | int y = 0xff & input[yp];
67 | if ((i & 1) == 0) {
68 | v = 0xff & input[uvp++];
69 | u = 0xff & input[uvp++];
70 | }
71 |
72 | output[yp] = YUV2RGB(y, u, v);
73 | }
74 | }
75 | }
76 |
77 | public static void convertYUV420ToARGB8888(
78 | byte[] yData,
79 | byte[] uData,
80 | byte[] vData,
81 | int width,
82 | int height,
83 | int yRowStride,
84 | int uvRowStride,
85 | int uvPixelStride,
86 | int[] out) {
87 |
88 | int yp = 0;
89 | for (int j = 0; j < height; j++) {
90 | int pY = yRowStride * j;
91 | int pUV = uvRowStride * (j >> 1);
92 |
93 | for (int i = 0; i < width; i++) {
94 | int uv_offset = pUV + (i >> 1) * uvPixelStride;
95 |
96 | out[yp++] = YUV2RGB(
97 | 0xff & yData[pY + i],
98 | 0xff & uData[uv_offset],
99 | 0xff & vData[uv_offset]);
100 | }
101 | }
102 | }
103 |
104 | /**
105 | * Utility method to compute the allocated size in bytes of a YUV420SP image
106 | * of the given dimensions.
107 | */
108 | public static int getYUVByteSize(final int width, final int height) {
109 | // The luminance plane requires 1 byte per pixel.
110 | final int ySize = width * height;
111 |
112 | // The UV plane works on 2x2 blocks, so dimensions with odd size must be rounded up.
113 | // Each 2x2 block takes 2 bytes to encode, one each for U and V.
114 | final int uvSize = ((width + 1) / 2) * ((height + 1) / 2) * 2;
115 |
116 | return ySize + uvSize;
117 | }
118 |
119 | /**
120 | * Returns a transformation matrix from one reference frame into another.
121 | * Handles cropping (if maintaining aspect ratio is desired) and rotation.
122 | *
123 | * @param srcWidth Width of source frame.
124 | * @param srcHeight Height of source frame.
125 | * @param dstWidth Width of destination frame.
126 | * @param dstHeight Height of destination frame.
127 | * @param applyRotation Amount of rotation to apply from one frame to another.
128 | * Must be a multiple of 90.
129 | * @param maintainAspectRatio If true, will ensure that scaling in x and y remains constant,
130 | * cropping the image if necessary.
131 | * @return The transformation fulfilling the desired requirements.
132 | */
133 | public static Matrix getTransformationMatrix(
134 | final int srcWidth,
135 | final int srcHeight,
136 | final int dstWidth,
137 | final int dstHeight,
138 | final int applyRotation,
139 | final boolean maintainAspectRatio) {
140 | final Matrix matrix = new Matrix();
141 |
142 | if (applyRotation != 0) {
143 | // Translate so center of image is at origin.
144 | matrix.postTranslate(-srcWidth / 2.0f, -srcHeight / 2.0f);
145 |
146 | // Rotate around origin.
147 | matrix.postRotate(applyRotation);
148 | }
149 |
150 | // Account for the already applied rotation, if any, and then determine how
151 | // much scaling is needed for each axis.
152 | final boolean transpose = (Math.abs(applyRotation) + 90) % 180 == 0;
153 |
154 | final int inWidth = transpose ? srcHeight : srcWidth;
155 | final int inHeight = transpose ? srcWidth : srcHeight;
156 |
157 | // Apply scaling if necessary.
158 | if (inWidth != dstWidth || inHeight != dstHeight) {
159 | final float scaleFactorX = dstWidth / (float) inWidth;
160 | final float scaleFactorY = dstHeight / (float) inHeight;
161 |
162 | if (maintainAspectRatio) {
163 | // Scale by minimum factor so that dst is filled completely while
164 | // maintaining the aspect ratio. Some image may fall off the edge.
165 | final float scaleFactor = Math.max(scaleFactorX, scaleFactorY);
166 | matrix.postScale(scaleFactor, scaleFactor);
167 | } else {
168 | // Scale exactly to fill dst from src.
169 | matrix.postScale(scaleFactorX, scaleFactorY);
170 | }
171 | }
172 |
173 | if (applyRotation != 0) {
174 | // Translate back from origin centered reference to destination frame.
175 | matrix.postTranslate(dstWidth / 2.0f, dstHeight / 2.0f);
176 | }
177 |
178 | return matrix;
179 | }
180 | }
181 |
--------------------------------------------------------------------------------