├── .gitignore ├── Convert ├── convert.py ├── download.sh └── flowers.txt ├── Flowers.xcodeproj └── project.pbxproj ├── Flowers.xcworkspace └── contents.xcworkspacedata ├── Flowers ├── AppDelegate.swift ├── ClassificationService.swift ├── Resources │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-40.png │ │ │ ├── Icon-40@2x.png │ │ │ ├── Icon-40@3x.png │ │ │ ├── Icon-60@2x.png │ │ │ ├── Icon-60@3x.png │ │ │ ├── Icon-72.png │ │ │ ├── Icon-72@2x.png │ │ │ ├── Icon-76.png │ │ │ ├── Icon-76@2x.png │ │ │ ├── Icon-83.5@2x.png │ │ │ ├── Icon-Small-50.png │ │ │ ├── Icon-Small-50@2x.png │ │ │ ├── Icon-Small.png │ │ │ ├── Icon-Small@2x.png │ │ │ ├── Icon-Small@3x.png │ │ │ ├── Icon.png │ │ │ ├── Icon@2x.png │ │ │ ├── NotificationIcon@2x.png │ │ │ ├── NotificationIcon@3x.png │ │ │ ├── NotificationIcon~ipad.png │ │ │ └── NotificationIcon~ipad@2x.png │ │ └── Contents.json │ ├── Info.plist │ └── LaunchScreen.storyboard └── ViewController.swift ├── LICENSE ├── Podfile ├── Podfile.lock ├── README.md └── Screenshot.png /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | Icon 6 | ._* 7 | .Spotlight-V100 8 | .Trashes 9 | 10 | # Xcode 11 | # 12 | build/ 13 | *.pbxuser 14 | !default.pbxuser 15 | *.mode1v3 16 | !default.mode1v3 17 | *.mode2v3 18 | !default.mode2v3 19 | *.perspectivev3 20 | !default.perspectivev3 21 | xcuserdata 22 | *.xccheckout 23 | *.moved-aside 24 | DerivedData 25 | *.hmap 26 | *.ipa 27 | *.xcuserstate 28 | .idea/ 29 | *.xcworkspace/xcshareddata/*.xcscmblueprint 30 | 31 | # CocoaPods 32 | Pods 33 | 34 | # Carthage 35 | Carthage 36 | 37 | # SPM 38 | .build/ 39 | 40 | ## CoreML models 41 | *.mlmodel 42 | -------------------------------------------------------------------------------- /Convert/convert.py: -------------------------------------------------------------------------------- 1 | import coremltools 2 | 3 | coreml_model = coremltools.converters.caffe.convert(('oxford102.caffemodel', 'deploy.prototxt'), image_input_names = 'data', class_labels = 'flowers.txt') 4 | coreml_model.author = 'Jimmie Goode' 5 | coreml_model.license = 'Unknown' 6 | coreml_model.short_description = 'Classifying images in the Oxford 102 flower dataset with CNNs' 7 | coreml_model.input_description['data'] = 'An image of a flower.' 8 | coreml_model.output_description['prob'] = 'The probabilities for each flower type, for the given input.' 9 | coreml_model.output_description['classLabel'] = 'The most likely type of flower, for the given input.' 10 | coreml_model.save('Oxford102.mlmodel') 11 | -------------------------------------------------------------------------------- /Convert/download.sh: -------------------------------------------------------------------------------- 1 | wget https://s3.amazonaws.com/jgoode/oxford102.caffemodel 2 | wget https://github.com/jimgoo/caffe-oxford102/raw/master/AlexNet/deploy.prototxt 3 | -------------------------------------------------------------------------------- /Convert/flowers.txt: -------------------------------------------------------------------------------- 1 | pink primrose 2 | hard-leaved pocket orchid 3 | canterbury bells 4 | sweet pea 5 | english marigold 6 | tiger lily 7 | moon orchid 8 | bird of paradise 9 | monkshood 10 | globe thistle 11 | snapdragon 12 | colt's foot 13 | king protea 14 | spear thistle 15 | yellow iris 16 | globe-flower 17 | purple coneflower 18 | peruvian lily 19 | balloon flower 20 | giant white arum lily 21 | fire lily 22 | pincushion flower 23 | fritillary 24 | red ginger 25 | grape hyacinth 26 | corn poppy 27 | prince of wales feathers 28 | stemless gentian 29 | artichoke 30 | sweet william 31 | carnation 32 | garden phlox 33 | love in the mist 34 | mexican aster 35 | alpine sea holly 36 | ruby-lipped cattleya 37 | cape flower 38 | great masterwort 39 | siam tulip 40 | lenten rose 41 | barbeton daisy 42 | daffodil 43 | sword lily 44 | poinsettia 45 | bolero deep blue 46 | wallflower 47 | marigold 48 | buttercup 49 | oxeye daisy 50 | common dandelion 51 | petunia 52 | wild pansy 53 | primula 54 | sunflower 55 | pelargonium 56 | bishop of llandaff 57 | gaura 58 | geranium 59 | orange dahlia 60 | pink-yellow dahlia? 61 | cautleya spicata 62 | japanese anemone 63 | black-eyed susan 64 | silverbush 65 | californian poppy 66 | osteospermum 67 | spring crocus 68 | bearded iris 69 | windflower 70 | tree poppy 71 | gazania 72 | azalea 73 | water lily 74 | rose 75 | thorn apple 76 | morning glory 77 | passion flower 78 | lotus 79 | toad lily 80 | anthurium 81 | frangipani 82 | clematis 83 | hibiscus 84 | columbine 85 | desert-rose 86 | tree mallow 87 | magnolia 88 | cyclamen 89 | watercress 90 | canna lily 91 | hippeastrum 92 | bee balm 93 | ball moss 94 | foxglove 95 | bougainvillea 96 | camellia 97 | mallow 98 | mexican petunia 99 | bromelia 100 | blanket flower 101 | trumpet creeper 102 | blackberry lily 103 | -------------------------------------------------------------------------------- /Flowers.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 811EABD860D14F03420BE967 /* Pods_Flowers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 48589CB4E830E4FF5B0F5EE8 /* Pods_Flowers.framework */; }; 11 | D5174FCC1EFB24F0000D98EB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5174FCB1EFB24F0000D98EB /* AppDelegate.swift */; }; 12 | D5174FCE1EFB24F0000D98EB /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5174FCD1EFB24F0000D98EB /* ViewController.swift */; }; 13 | D5174FD31EFB24F0000D98EB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D5174FD21EFB24F0000D98EB /* Assets.xcassets */; }; 14 | D517504B1EFB3845000D98EB /* Oxford102.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = D517504A1EFB3842000D98EB /* Oxford102.mlmodel */; }; 15 | D5D4DFCB1EFB400D005EBAA6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D5D4DFCA1EFB3FEE005EBAA6 /* LaunchScreen.storyboard */; }; 16 | D5D4DFCF1EFB409E005EBAA6 /* ClassificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5D4DFCE1EFB409E005EBAA6 /* ClassificationService.swift */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 48589CB4E830E4FF5B0F5EE8 /* Pods_Flowers.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Flowers.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 21 | 8AEED58946656734D6DA0FDF /* Pods-Flowers.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Flowers.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Flowers/Pods-Flowers.debug.xcconfig"; sourceTree = ""; }; 22 | ADA3D861A5F908B4B1B253DD /* Pods-Flowers.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Flowers.release.xcconfig"; path = "Pods/Target Support Files/Pods-Flowers/Pods-Flowers.release.xcconfig"; sourceTree = ""; }; 23 | D5174FC81EFB24F0000D98EB /* Flowers.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Flowers.app; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | D5174FCB1EFB24F0000D98EB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 25 | D5174FCD1EFB24F0000D98EB /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 26 | D5174FD21EFB24F0000D98EB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 27 | D5174FD71EFB24F0000D98EB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 28 | D517504A1EFB3842000D98EB /* Oxford102.mlmodel */ = {isa = PBXFileReference; lastKnownFileType = file.mlmodel; path = Oxford102.mlmodel; sourceTree = ""; }; 29 | D5D4DFCA1EFB3FEE005EBAA6 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; 30 | D5D4DFCE1EFB409E005EBAA6 /* ClassificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClassificationService.swift; sourceTree = ""; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | D5174FC51EFB24F0000D98EB /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | 811EABD860D14F03420BE967 /* Pods_Flowers.framework in Frameworks */, 39 | ); 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXFrameworksBuildPhase section */ 43 | 44 | /* Begin PBXGroup section */ 45 | 3F2B96718A5D2EABFFF3D31D /* Frameworks */ = { 46 | isa = PBXGroup; 47 | children = ( 48 | 48589CB4E830E4FF5B0F5EE8 /* Pods_Flowers.framework */, 49 | ); 50 | name = Frameworks; 51 | sourceTree = ""; 52 | }; 53 | 4F572AD98C45A3B6743FB8B7 /* Pods */ = { 54 | isa = PBXGroup; 55 | children = ( 56 | 8AEED58946656734D6DA0FDF /* Pods-Flowers.debug.xcconfig */, 57 | ADA3D861A5F908B4B1B253DD /* Pods-Flowers.release.xcconfig */, 58 | ); 59 | name = Pods; 60 | sourceTree = ""; 61 | }; 62 | D5174FBF1EFB24F0000D98EB = { 63 | isa = PBXGroup; 64 | children = ( 65 | D5174FCA1EFB24F0000D98EB /* Flowers */, 66 | D5174FC91EFB24F0000D98EB /* Products */, 67 | 4F572AD98C45A3B6743FB8B7 /* Pods */, 68 | 3F2B96718A5D2EABFFF3D31D /* Frameworks */, 69 | ); 70 | sourceTree = ""; 71 | }; 72 | D5174FC91EFB24F0000D98EB /* Products */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | D5174FC81EFB24F0000D98EB /* Flowers.app */, 76 | ); 77 | name = Products; 78 | sourceTree = ""; 79 | }; 80 | D5174FCA1EFB24F0000D98EB /* Flowers */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | D5174FDD1EFB250A000D98EB /* Resources */, 84 | D5174FCB1EFB24F0000D98EB /* AppDelegate.swift */, 85 | D5174FCD1EFB24F0000D98EB /* ViewController.swift */, 86 | D5D4DFCE1EFB409E005EBAA6 /* ClassificationService.swift */, 87 | ); 88 | path = Flowers; 89 | sourceTree = ""; 90 | }; 91 | D5174FDD1EFB250A000D98EB /* Resources */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | D5D4DFCA1EFB3FEE005EBAA6 /* LaunchScreen.storyboard */, 95 | D517504A1EFB3842000D98EB /* Oxford102.mlmodel */, 96 | D5174FD21EFB24F0000D98EB /* Assets.xcassets */, 97 | D5174FD71EFB24F0000D98EB /* Info.plist */, 98 | ); 99 | path = Resources; 100 | sourceTree = ""; 101 | }; 102 | /* End PBXGroup section */ 103 | 104 | /* Begin PBXNativeTarget section */ 105 | D5174FC71EFB24F0000D98EB /* Flowers */ = { 106 | isa = PBXNativeTarget; 107 | buildConfigurationList = D5174FDA1EFB24F0000D98EB /* Build configuration list for PBXNativeTarget "Flowers" */; 108 | buildPhases = ( 109 | 317D5E2D997126AFC85E2332 /* [CP] Check Pods Manifest.lock */, 110 | D5174FC41EFB24F0000D98EB /* Sources */, 111 | D5174FC51EFB24F0000D98EB /* Frameworks */, 112 | D5174FC61EFB24F0000D98EB /* Resources */, 113 | DC101EEA19207432F4CAB8B7 /* [CP] Embed Pods Frameworks */, 114 | 2ED72FEEB5A1AF22930AA8A7 /* [CP] Copy Pods Resources */, 115 | ); 116 | buildRules = ( 117 | ); 118 | dependencies = ( 119 | ); 120 | name = Flowers; 121 | productName = Flowers; 122 | productReference = D5174FC81EFB24F0000D98EB /* Flowers.app */; 123 | productType = "com.apple.product-type.application"; 124 | }; 125 | /* End PBXNativeTarget section */ 126 | 127 | /* Begin PBXProject section */ 128 | D5174FC01EFB24F0000D98EB /* Project object */ = { 129 | isa = PBXProject; 130 | attributes = { 131 | LastSwiftUpdateCheck = 0900; 132 | LastUpgradeCheck = 0900; 133 | ORGANIZATIONNAME = "Vadym Markov"; 134 | TargetAttributes = { 135 | D5174FC71EFB24F0000D98EB = { 136 | CreatedOnToolsVersion = 9.0; 137 | ProvisioningStyle = Manual; 138 | }; 139 | }; 140 | }; 141 | buildConfigurationList = D5174FC31EFB24F0000D98EB /* Build configuration list for PBXProject "Flowers" */; 142 | compatibilityVersion = "Xcode 8.0"; 143 | developmentRegion = en; 144 | hasScannedForEncodings = 0; 145 | knownRegions = ( 146 | en, 147 | Base, 148 | ); 149 | mainGroup = D5174FBF1EFB24F0000D98EB; 150 | productRefGroup = D5174FC91EFB24F0000D98EB /* Products */; 151 | projectDirPath = ""; 152 | projectRoot = ""; 153 | targets = ( 154 | D5174FC71EFB24F0000D98EB /* Flowers */, 155 | ); 156 | }; 157 | /* End PBXProject section */ 158 | 159 | /* Begin PBXResourcesBuildPhase section */ 160 | D5174FC61EFB24F0000D98EB /* Resources */ = { 161 | isa = PBXResourcesBuildPhase; 162 | buildActionMask = 2147483647; 163 | files = ( 164 | D5174FD31EFB24F0000D98EB /* Assets.xcassets in Resources */, 165 | D5D4DFCB1EFB400D005EBAA6 /* LaunchScreen.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 2ED72FEEB5A1AF22930AA8A7 /* [CP] Copy Pods Resources */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "[CP] Copy Pods Resources"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Flowers/Pods-Flowers-resources.sh\"\n"; 185 | showEnvVarsInLog = 0; 186 | }; 187 | 317D5E2D997126AFC85E2332 /* [CP] Check Pods Manifest.lock */ = { 188 | isa = PBXShellScriptBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | ); 192 | inputPaths = ( 193 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 194 | "${PODS_ROOT}/Manifest.lock", 195 | ); 196 | name = "[CP] Check Pods Manifest.lock"; 197 | outputPaths = ( 198 | "$(DERIVED_FILE_DIR)/Pods-Flowers-checkManifestLockResult.txt", 199 | ); 200 | runOnlyForDeploymentPostprocessing = 0; 201 | shellPath = /bin/sh; 202 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 203 | showEnvVarsInLog = 0; 204 | }; 205 | DC101EEA19207432F4CAB8B7 /* [CP] Embed Pods Frameworks */ = { 206 | isa = PBXShellScriptBuildPhase; 207 | buildActionMask = 2147483647; 208 | files = ( 209 | ); 210 | inputPaths = ( 211 | "${SRCROOT}/Pods/Target Support Files/Pods-Flowers/Pods-Flowers-frameworks.sh", 212 | "${BUILT_PRODUCTS_DIR}/VisionLab/VisionLab.framework", 213 | ); 214 | name = "[CP] Embed Pods Frameworks"; 215 | outputPaths = ( 216 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/VisionLab.framework", 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | shellPath = /bin/sh; 220 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Flowers/Pods-Flowers-frameworks.sh\"\n"; 221 | showEnvVarsInLog = 0; 222 | }; 223 | /* End PBXShellScriptBuildPhase section */ 224 | 225 | /* Begin PBXSourcesBuildPhase section */ 226 | D5174FC41EFB24F0000D98EB /* Sources */ = { 227 | isa = PBXSourcesBuildPhase; 228 | buildActionMask = 2147483647; 229 | files = ( 230 | D517504B1EFB3845000D98EB /* Oxford102.mlmodel in Sources */, 231 | D5174FCE1EFB24F0000D98EB /* ViewController.swift in Sources */, 232 | D5174FCC1EFB24F0000D98EB /* AppDelegate.swift in Sources */, 233 | D5D4DFCF1EFB409E005EBAA6 /* ClassificationService.swift in Sources */, 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | }; 237 | /* End PBXSourcesBuildPhase section */ 238 | 239 | /* Begin XCBuildConfiguration section */ 240 | D5174FD81EFB24F0000D98EB /* Debug */ = { 241 | isa = XCBuildConfiguration; 242 | buildSettings = { 243 | ALWAYS_SEARCH_USER_PATHS = NO; 244 | CLANG_ANALYZER_NONNULL = YES; 245 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 246 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 247 | CLANG_CXX_LIBRARY = "libc++"; 248 | CLANG_ENABLE_MODULES = YES; 249 | CLANG_ENABLE_OBJC_ARC = YES; 250 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 251 | CLANG_WARN_BOOL_CONVERSION = YES; 252 | CLANG_WARN_COMMA = YES; 253 | CLANG_WARN_CONSTANT_CONVERSION = YES; 254 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 255 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 256 | CLANG_WARN_EMPTY_BODY = YES; 257 | CLANG_WARN_ENUM_CONVERSION = YES; 258 | CLANG_WARN_INFINITE_RECURSION = YES; 259 | CLANG_WARN_INT_CONVERSION = YES; 260 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 261 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 262 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 263 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 264 | CLANG_WARN_STRICT_PROTOTYPES = YES; 265 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 266 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 267 | CLANG_WARN_UNREACHABLE_CODE = YES; 268 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 269 | CODE_SIGN_IDENTITY = "iPhone Developer"; 270 | COPY_PHASE_STRIP = NO; 271 | DEBUG_INFORMATION_FORMAT = dwarf; 272 | ENABLE_STRICT_OBJC_MSGSEND = YES; 273 | ENABLE_TESTABILITY = YES; 274 | GCC_C_LANGUAGE_STANDARD = gnu11; 275 | GCC_DYNAMIC_NO_PIC = NO; 276 | GCC_NO_COMMON_BLOCKS = YES; 277 | GCC_OPTIMIZATION_LEVEL = 0; 278 | GCC_PREPROCESSOR_DEFINITIONS = ( 279 | "DEBUG=1", 280 | "$(inherited)", 281 | ); 282 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 283 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 284 | GCC_WARN_UNDECLARED_SELECTOR = YES; 285 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 286 | GCC_WARN_UNUSED_FUNCTION = YES; 287 | GCC_WARN_UNUSED_VARIABLE = YES; 288 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 289 | MTL_ENABLE_DEBUG_INFO = YES; 290 | ONLY_ACTIVE_ARCH = YES; 291 | SDKROOT = iphoneos; 292 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 293 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 294 | }; 295 | name = Debug; 296 | }; 297 | D5174FD91EFB24F0000D98EB /* Release */ = { 298 | isa = XCBuildConfiguration; 299 | buildSettings = { 300 | ALWAYS_SEARCH_USER_PATHS = NO; 301 | CLANG_ANALYZER_NONNULL = YES; 302 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 303 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 304 | CLANG_CXX_LIBRARY = "libc++"; 305 | CLANG_ENABLE_MODULES = YES; 306 | CLANG_ENABLE_OBJC_ARC = YES; 307 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 308 | CLANG_WARN_BOOL_CONVERSION = YES; 309 | CLANG_WARN_COMMA = YES; 310 | CLANG_WARN_CONSTANT_CONVERSION = YES; 311 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 312 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 313 | CLANG_WARN_EMPTY_BODY = YES; 314 | CLANG_WARN_ENUM_CONVERSION = YES; 315 | CLANG_WARN_INFINITE_RECURSION = YES; 316 | CLANG_WARN_INT_CONVERSION = YES; 317 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 318 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 319 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 320 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 321 | CLANG_WARN_STRICT_PROTOTYPES = YES; 322 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 323 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 324 | CLANG_WARN_UNREACHABLE_CODE = YES; 325 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 326 | CODE_SIGN_IDENTITY = "iPhone Developer"; 327 | COPY_PHASE_STRIP = NO; 328 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 329 | ENABLE_NS_ASSERTIONS = NO; 330 | ENABLE_STRICT_OBJC_MSGSEND = YES; 331 | GCC_C_LANGUAGE_STANDARD = gnu11; 332 | GCC_NO_COMMON_BLOCKS = YES; 333 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 334 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 335 | GCC_WARN_UNDECLARED_SELECTOR = YES; 336 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 337 | GCC_WARN_UNUSED_FUNCTION = YES; 338 | GCC_WARN_UNUSED_VARIABLE = YES; 339 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 340 | MTL_ENABLE_DEBUG_INFO = NO; 341 | SDKROOT = iphoneos; 342 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 343 | VALIDATE_PRODUCT = YES; 344 | }; 345 | name = Release; 346 | }; 347 | D5174FDB1EFB24F0000D98EB /* Debug */ = { 348 | isa = XCBuildConfiguration; 349 | baseConfigurationReference = 8AEED58946656734D6DA0FDF /* Pods-Flowers.debug.xcconfig */; 350 | buildSettings = { 351 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 352 | CODE_SIGN_STYLE = Manual; 353 | DEVELOPMENT_TEAM = LG4DBY4QF9; 354 | INFOPLIST_FILE = Flowers/Resources/Info.plist; 355 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 356 | PRODUCT_BUNDLE_IDENTIFIER = no.hyper.Flowers; 357 | PRODUCT_NAME = "$(TARGET_NAME)"; 358 | PROVISIONING_PROFILE = "4a41613b-fcd3-4f3f-8ee3-512782bcf82c"; 359 | PROVISIONING_PROFILE_SPECIFIER = "Wildcard Development Provisioning Profile"; 360 | SWIFT_VERSION = 4.0; 361 | TARGETED_DEVICE_FAMILY = 1; 362 | }; 363 | name = Debug; 364 | }; 365 | D5174FDC1EFB24F0000D98EB /* Release */ = { 366 | isa = XCBuildConfiguration; 367 | baseConfigurationReference = ADA3D861A5F908B4B1B253DD /* Pods-Flowers.release.xcconfig */; 368 | buildSettings = { 369 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 370 | CODE_SIGN_STYLE = Manual; 371 | DEVELOPMENT_TEAM = LG4DBY4QF9; 372 | INFOPLIST_FILE = Flowers/Resources/Info.plist; 373 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 374 | PRODUCT_BUNDLE_IDENTIFIER = no.hyper.Flowers; 375 | PRODUCT_NAME = "$(TARGET_NAME)"; 376 | PROVISIONING_PROFILE = "4a41613b-fcd3-4f3f-8ee3-512782bcf82c"; 377 | PROVISIONING_PROFILE_SPECIFIER = "Wildcard Development Provisioning Profile"; 378 | SWIFT_VERSION = 4.0; 379 | TARGETED_DEVICE_FAMILY = 1; 380 | }; 381 | name = Release; 382 | }; 383 | /* End XCBuildConfiguration section */ 384 | 385 | /* Begin XCConfigurationList section */ 386 | D5174FC31EFB24F0000D98EB /* Build configuration list for PBXProject "Flowers" */ = { 387 | isa = XCConfigurationList; 388 | buildConfigurations = ( 389 | D5174FD81EFB24F0000D98EB /* Debug */, 390 | D5174FD91EFB24F0000D98EB /* Release */, 391 | ); 392 | defaultConfigurationIsVisible = 0; 393 | defaultConfigurationName = Release; 394 | }; 395 | D5174FDA1EFB24F0000D98EB /* Build configuration list for PBXNativeTarget "Flowers" */ = { 396 | isa = XCConfigurationList; 397 | buildConfigurations = ( 398 | D5174FDB1EFB24F0000D98EB /* Debug */, 399 | D5174FDC1EFB24F0000D98EB /* Release */, 400 | ); 401 | defaultConfigurationIsVisible = 0; 402 | defaultConfigurationName = Release; 403 | }; 404 | /* End XCConfigurationList section */ 405 | }; 406 | rootObject = D5174FC01EFB24F0000D98EB /* Project object */; 407 | } 408 | -------------------------------------------------------------------------------- /Flowers.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Flowers/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | @UIApplicationMain 4 | final class AppDelegate: UIResponder, UIApplicationDelegate { 5 | var window: UIWindow? 6 | private lazy var controller: UIViewController = ViewController() 7 | 8 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 9 | window = UIWindow() 10 | window?.rootViewController = controller 11 | window?.makeKeyAndVisible() 12 | 13 | return true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Flowers/ClassificationService.swift: -------------------------------------------------------------------------------- 1 | import CoreML 2 | import Vision 3 | import VisionLab 4 | 5 | protocol ClassificationServiceDelegate: class { 6 | func classificationService(_ service: ClassificationService, didDetectFlower flower: String) 7 | } 8 | 9 | /// Service used to perform gender, age and emotion classification 10 | final class ClassificationService: ClassificationServiceProtocol { 11 | /// The service's delegate 12 | weak var delegate: ClassificationServiceDelegate? 13 | /// Array of vision requests 14 | private var requests = [VNRequest]() 15 | 16 | /// Create CoreML model and classification requests 17 | func setup() { 18 | do { 19 | // Flower request 20 | requests.append(VNCoreMLRequest( 21 | model: try VNCoreMLModel(for: Oxford102().model), 22 | completionHandler: handleClassification 23 | )) 24 | } catch { 25 | assertionFailure("Can't load Vision ML model: \(error)") 26 | } 27 | } 28 | 29 | /// Run individual requests one by one. 30 | func classify(image: CIImage) { 31 | do { 32 | for request in self.requests { 33 | let handler = VNImageRequestHandler(ciImage: image) 34 | try handler.perform([request]) 35 | } 36 | } catch { 37 | print(error) 38 | } 39 | } 40 | 41 | // MARK: - Handling 42 | 43 | @objc private func handleClassification(request: VNRequest, error: Error?) { 44 | let result = extractClassificationResult(from: request, count: 3) 45 | delegate?.classificationService(self, didDetectFlower: result) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "NotificationIcon@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "NotificationIcon@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-Small.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-Small@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-Small@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "57x57", 47 | "idiom" : "iphone", 48 | "filename" : "Icon.png", 49 | "scale" : "1x" 50 | }, 51 | { 52 | "size" : "57x57", 53 | "idiom" : "iphone", 54 | "filename" : "Icon@2x.png", 55 | "scale" : "2x" 56 | }, 57 | { 58 | "size" : "60x60", 59 | "idiom" : "iphone", 60 | "filename" : "Icon-60@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "60x60", 65 | "idiom" : "iphone", 66 | "filename" : "Icon-60@3x.png", 67 | "scale" : "3x" 68 | }, 69 | { 70 | "size" : "20x20", 71 | "idiom" : "ipad", 72 | "filename" : "NotificationIcon~ipad.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "20x20", 77 | "idiom" : "ipad", 78 | "filename" : "NotificationIcon~ipad@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "29x29", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-Small.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "29x29", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-Small@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "40x40", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-40.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "40x40", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-40@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "50x50", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-Small-50.png", 109 | "scale" : "1x" 110 | }, 111 | { 112 | "size" : "50x50", 113 | "idiom" : "ipad", 114 | "filename" : "Icon-Small-50@2x.png", 115 | "scale" : "2x" 116 | }, 117 | { 118 | "size" : "72x72", 119 | "idiom" : "ipad", 120 | "filename" : "Icon-72.png", 121 | "scale" : "1x" 122 | }, 123 | { 124 | "size" : "72x72", 125 | "idiom" : "ipad", 126 | "filename" : "Icon-72@2x.png", 127 | "scale" : "2x" 128 | }, 129 | { 130 | "size" : "76x76", 131 | "idiom" : "ipad", 132 | "filename" : "Icon-76.png", 133 | "scale" : "1x" 134 | }, 135 | { 136 | "size" : "76x76", 137 | "idiom" : "ipad", 138 | "filename" : "Icon-76@2x.png", 139 | "scale" : "2x" 140 | }, 141 | { 142 | "size" : "83.5x83.5", 143 | "idiom" : "ipad", 144 | "filename" : "Icon-83.5@2x.png", 145 | "scale" : "2x" 146 | }, 147 | { 148 | "idiom" : "ios-marketing", 149 | "size" : "1024x1024", 150 | "scale" : "1x" 151 | } 152 | ], 153 | "info" : { 154 | "version" : 1, 155 | "author" : "xcode" 156 | } 157 | } -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-40.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-72.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/NotificationIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/NotificationIcon@2x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/NotificationIcon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/NotificationIcon@3x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Flowers/Resources/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad@2x.png -------------------------------------------------------------------------------- /Flowers/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } -------------------------------------------------------------------------------- /Flowers/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | NSCameraUsageDescription 24 | To demonstrate image recognition. 25 | NSPhotoLibraryUsageDescription 26 | To demonstrate image recognition. 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIStatusBarStyle 34 | UIStatusBarStyleLightContent 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Flowers/Resources/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Flowers/ViewController.swift: -------------------------------------------------------------------------------- 1 | import VisionLab 2 | 3 | final class ViewController: ImageClassificationController { 4 | override func viewDidLoad() { 5 | super.viewDidLoad() 6 | mainView.button.setTitle("Choose an image of a flower", for: .normal) 7 | classificationService.delegate = self 8 | } 9 | } 10 | 11 | // MARK: - ClassificationServiceDelegate 12 | 13 | extension ViewController: ClassificationServiceDelegate { 14 | func classificationService(_ service: ClassificationService, didDetectFlower flower: String) { 15 | DispatchQueue.main.async { [weak mainView] in 16 | mainView?.label.text = flower.capitalized 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Vadym Markov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | platform :ios, '11.0' 3 | pod 'VisionLab', git: 'https://github.com/cocoa-ai/VisionLab' 4 | target 'Flowers' 5 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - VisionLab (0.2.0) 3 | 4 | DEPENDENCIES: 5 | - VisionLab (from `https://github.com/cocoa-ai/VisionLab`) 6 | 7 | EXTERNAL SOURCES: 8 | VisionLab: 9 | :git: https://github.com/cocoa-ai/VisionLab 10 | 11 | CHECKOUT OPTIONS: 12 | VisionLab: 13 | :commit: aea33bfae9755aa9f175f2783f97593775f664e5 14 | :git: https://github.com/cocoa-ai/VisionLab 15 | 16 | SPEC CHECKSUMS: 17 | VisionLab: 6fc2dcc1f731dd21891c7bd9878a93c0526bfc91 18 | 19 | PODFILE CHECKSUM: 8e6ebda03575aaa9c904fce0dd8e70528c42d143 20 | 21 | COCOAPODS: 1.3.1 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flowers Vision Demo 2 | 3 | iOS11 demo application for flower classification using `Vision` and `CoreML` 4 | frameworks. 5 | 6 |
7 | FlowersVisionDemo 8 |
9 | 10 | ## Model 11 | 12 | This demo is based on [Caffe CNNs for the Oxford 102 flower dataset](https://github.com/jimgoo/caffe-oxford102), 13 | which was converted to [CoreML model](https://drive.google.com/file/d/1mg0V6xsQJ18yYfKORtZA506cZgdiqfGS/view?usp=sharing) 14 | using [coremltools](https://pypi.python.org/pypi/coremltools) python package. 15 | 16 | ## Requirements 17 | 18 | - Xcode 9 19 | - iOS 11 20 | 21 | ## Installation 22 | 23 | ```sh 24 | git clone https://github.com/cocoa-ai/FlowersVisionDemo.git 25 | cd FlowersVisionDemo 26 | pod install 27 | open Flowers.xcworkspace/ 28 | ``` 29 | 30 | Download the [CoreMl model](https://drive.google.com/file/d/0B1ghKa_MYL6meDBHT2NaZGxkNzQ/view?usp=sharing) 31 | and add the file to "Resources" folder in the project's directory. 32 | 33 | Build the project and run it on a simulator or a device with iOS 11. 34 | 35 | ## Conversion 36 | 37 | ```sh 38 | cd Convert 39 | ./download.sh 40 | python convert.py 41 | ``` 42 | 43 | ## Author 44 | 45 | Vadym Markov, markov.vadym@gmail.com 46 | 47 | ## Credits 48 | 49 | - [Classifying images in the Oxford 102 flower dataset with CNNs](http://jimgoo.com/flower-power/) 50 | - Photo in the demo is taken from [Flickr](https://flic.kr/p/2zjdHr) and is 51 | distributed under [Attribution 2.0 Generic (CC BY 2.0) license](https://creativecommons.org/licenses/by/2.0/legalcode) 52 | 53 | ## References 54 | - [Caffe Model Zoo](https://github.com/caffe2/caffe2/wiki/Model-Zoo) 55 | - [Apple Machine Learning](https://developer.apple.com/machine-learning/) 56 | - [Vision Framework](https://developer.apple.com/documentation/vision) 57 | - [CoreML Framework](https://developer.apple.com/documentation/coreml) 58 | - [coremltools](https://pypi.python.org/pypi/coremltools) 59 | -------------------------------------------------------------------------------- /Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoa-ai/FlowersVisionDemo/01b7b3eef8806bbe1a658f7a966843a5fbed1562/Screenshot.png --------------------------------------------------------------------------------