1. Прежде чем начать
В этой лабораторной работе вы узнаете, как создать приложение, которое обрабатывает основной вариант использования Computer Vision, определяя основное содержимое изображения. Обычно это называется классификацией изображений или маркировкой изображений .
Предпосылки
Эта лаборатория кода является частью пути " Начало работы с классификацией изображений ". Он был написан для опытных разработчиков, плохо знакомых с машинным обучением.
Что вы будете строить
- Android-приложение, способное классифицировать изображение цветка
- (Необязательно) Приложение для iOS, способное классифицировать изображение цветка.
Что вам понадобится
- Android Studio, доступная по адресу https://developer.android.com/studio для Android-части Codelab.
- Xcode, доступный в Apple App Store, для iOS-части Codelab.
2. Начать
Компьютерное зрение — это область более широкой дисциплины машинного обучения, которая работает над поиском новых способов обработки и извлечения машинами информации из содержимого изображения. Если раньше компьютер сохранял только фактические данные изображений, такие как значения пикселей, составляющих изображение, Computer Vision позволяет компьютеру анализировать содержимое изображения и получать информацию о том, что в нем содержится.
Например, в области компьютерного зрения изображение кошки может быть помечено как содержащее кошку в дополнение к пикселям, из которых состоит это изображение. Существуют и другие области компьютерного зрения, которые более подробно рассматриваются, например, обнаружение объектов, когда компьютер может находить несколько элементов на изображении и создавать для них ограничивающие рамки.
В этой лаборатории кода вы узнаете, как создать приложение, которое обрабатывает основной вариант использования, определяя основное содержимое изображения. Обычно это называется классификацией изображений или маркировкой изображений .
Чтобы сделать приложение как можно более простым, оно будет использовать изображения, связанные с ним, в качестве ресурсов и показывать вам их классификацию. Будущие расширения могут заключаться в использовании средства выбора изображений или извлечении изображений непосредственно из камеры.
Вы начнете с процесса создания приложения на Android с помощью Android Studio. (Перейдите к шагу 7, чтобы сделать то же самое на iOS.)
- Откройте Android Studio, перейдите в меню «Файл» и выберите «Создать новый проект».
- Вам будет предложено выбрать шаблон проекта. Выберите Пустое действие.
- Нажмите «Далее» . Вам будет предложено настроить свой проект . Дайте ему любое имя и имя пакета, которые вы хотите, но пример кода в этой лаборатории использует имя проекта ImageClassifierStep1 и имя пакета com.google.imageclassifierstep1.
- Выберите предпочитаемый язык: Kotlin или Java. В этой лаборатории используется Kotlin, поэтому, если вы хотите точно следовать ей, вы, вероятно, захотите выбрать Kotlin.
- Когда будете готовы, нажмите Готово. Android Studio создаст для вас приложение. Настройка всех параметров может занять несколько минут.
3. Импорт библиотеки маркировки изображений ML Kit
ML Kit (https://developers.google.com/ml-kit) предлагает ряд решений для разработчиков, отвечающих распространенным сценариям машинного обучения и упрощающих их реализацию и кросс-платформенную работу. ML Kit предоставляет готовую библиотеку, которую вы можете использовать в этом приложении под названием Image Labelling. Эта библиотека включает модель, предварительно обученную распознавать более 600 классов изображений. Таким образом, он идеально подходит для начала.
Обратите внимание, что ML Kit также позволяет вам использовать пользовательские модели с использованием того же API, поэтому, когда вы будете готовы, вы можете перейти от «начала работы» и приступить к созданию своего персонализированного приложения для маркировки изображений, которое использует модель, обученную для вашего сценария.
В этом сценарии вы создадите распознаватель цветов. Когда вы создадите свое первое приложение и покажете ему изображение цветка, оно распознает его как цветок. (Позже, когда вы создадите свою собственную модель детектора цветов, вы сможете поместить ее в свое приложение с минимальными изменениями благодаря ML Kit, и новая модель скажет вам, какой это тип цветка, например, тюльпан или тюльпан. Роза.)
- В Android Studio, используя проводник проекта, убедитесь, что Android выбран вверху.
- Откройте папку Gradle Scripts и выберите файл
build.gradle
для приложения. Их может быть 2 или больше, поэтому убедитесь, что вы используете первый уровень приложения , как показано здесь:
- В нижней части файла вы увидите раздел зависимостей , в котором хранится список настроек
implementation
,testImplementation
иandroidImplementation
. Добавьте новый в файл с этим кодом:
implementation 'com.google.mlkit:image-labeling:17.0.3'
(Убедитесь, что это внутри зависимостей {})
- В верхней части окна появится полоса, помечающая, что
build.gradle
изменился, и вам необходимо выполнить повторную синхронизацию. Иди и сделай это. Если вы его не видите, найдите маленький значок слона на панели инструментов в правом верхнем углу и щелкните его.
Вы импортировали ML Kit и готовы приступить к маркировке изображений.
Далее вы создадите простой пользовательский интерфейс для рендеринга изображения и предоставите вам кнопку, при нажатии которой ваш пользователь запускает модель маркировки изображений для анализа содержимого изображения.
4. Создайте пользовательский интерфейс
В Android Studio вы редактируете пользовательский интерфейс для каждого экрана (или действия) с помощью файла макета на основе xml. Базовое приложение, которое вы создали, имеет одно действие (код которого находится в MainActivity
, и вы скоро это увидите), а объявление пользовательского интерфейса — в activity_main.xml
.
Вы можете найти это в папке res > layout в проводнике проектов Android, например:
Откроется полноценный редактор, который позволит вам создать пользовательский интерфейс Activity. Там много всего, и цель этой лаборатории не в том, чтобы научить вас, как это использовать. Чтобы узнать больше о редакторе макетов, посетите: https://developer.android.com/studio/write/layout-editor.
Для целей этого практического занятия выберите инструмент «Код» в правом верхнем углу редактора.
Теперь вы увидите только XML-код в основной части окна. Измените код на этот:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/imageToLabel"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="@+id/btnTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Label Image"
android:layout_gravity="center"/>
<TextView
android:id="@+id/txtOutput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:gravity="start|top" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Это даст вам очень простой макет, содержащий ImageView
(для рендеринга изображения), Button
(для нажатия пользователем) и TextView
, где будут отображаться метки.
Теперь у вас есть определенный пользовательский интерфейс. Прежде чем приступить к кодированию, добавьте несколько изображений в качестве активов, и приложение сделает вывод на основе этих изображений.
5. Связывайте изображения с приложением
Один из способов связать дополнительные файлы с приложением Android — добавить их в качестве ресурсов, которые компилируются в приложение. Чтобы сделать это приложение простым, мы сделаем это, чтобы добавить изображение некоторых цветов. Позже вы можете расширить это приложение, чтобы использовать CameraX или другие библиотеки, чтобы делать фотографии и использовать их. Но для простоты мы пока просто объединим изображение.
- В проводнике проекта в приложении вверху щелкните правой кнопкой мыши и выберите «Новый каталог».
- В появившемся диалоговом окне со списком различных каталогов выберите src/main/assets .
Как только вы это сделаете, в проводнике проекта появится новая папка ресурсов :
- Щелкните правой кнопкой мыши эту папку, и вы увидите всплывающее окно со списком параметров. Одним из них будет открытие папки в вашей файловой системе. Найдите подходящий для вашей операционной системы и выберите его. (На Mac это будет « Показать в Finder », в Windows — « Открыть в проводнике », а в Ubuntu — « Показать в файлах» .)
- Скопируйте в него файл. Вы можете загружать изображения с таких сайтов, как Pixabay. Рекомендуется переименовать изображение во что-то простое. В данном случае изображение было переименовано в
flower1.jpg
.
Сделав это, вернитесь в Android Studio, и вы должны увидеть свой файл в папке с ресурсами.
Теперь вы готовы пометить это изображение!
6. Напишите код классификации для маркировки изображения
(А теперь то, чего мы все так долго ждали, — компьютерное зрение на Android!)
- Вы напишете свой код в файле
MainActivity
, поэтому найдите его в папке проекта в разделе com.google.devrel.imageclassifierstep1 (или любое другое эквивалентное пространство имен, если вы выбрали другое). Обратите внимание, что в проекте Android Studio обычно настраиваются 3 папки пространств имен: одна для приложения, одна для Android Test и одна для теста. Вы найдете своюMainActivity
в той, у которой нет описания после нее в скобках.
Если вы решили использовать Kotlin, вам может быть интересно, почему родительская папка называется Java . Это исторический артефакт, когда Android Studio была только Java. В будущих версиях это может быть исправлено, но не волнуйтесь, если вы хотите использовать Kotlin, все в порядке. Это просто имя папки для исходного кода.
- Откройте файл
MainActivity
, и вы увидите файл класса с именем MainActivity в редакторе кода. Это должно выглядеть так:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Под закрывающей фигурной скобкой вы можете добавить код расширения, который не является частью класса, но может использоваться классом. Вам понадобится расширение для чтения файла из ресурсов в виде растрового изображения. Это будет использоваться для загрузки изображения, которое вы скопировали в папку активов ранее.
- Добавьте этот код:
// extension function to get bitmap from assets
fun Context.assetsToBitmap(fileName: String): Bitmap?{
return try {
with(assets.open(fileName)){
BitmapFactory.decodeStream(this)
}
} catch (e: IOException) { null }
}
В этот момент Android Studio, вероятно, будет жаловаться и выделять часть кода красным цветом, например Context
, Bitmap
и IOException
:
Не волнуйся! Это потому, что вы еще не импортировали содержащие их библиотеки. Android Studio предлагает удобный ярлык.
- Наведите курсор на слово и нажмите ALT + Enter ( Option + Enter на Mac), и импорт будет сгенерирован для вас.
- Затем вы можете загрузить растровое изображение из ресурсов и поместить его в ImageView. Вернувшись в
onCreateFunction
MainActivity, добавьте этот код прямо подsetContentView
:
val img: ImageView = findViewById(R.id.imageToLabel)
// assets folder image file name with extension
val fileName = "flower1.jpg"
// get bitmap from assets folder
val bitmap: Bitmap? = assetsToBitmap(fileName)
bitmap?.apply {
img.setImageBitmap(this)
}
- Как и прежде, часть кода будет выделена красным. Поместите курсор на эту строку и используйте Alt + Enter / Option + Enter , чтобы автоматически добавить импорт.
- В файле
layout.xml
, который вы создали ранее, вы дали ImageView имя imageToLabel, поэтому первая строка создаст экземпляр объекта ImageView с именем img, используя эту информацию о макете. Он находит детали с помощьюfindViewById
, встроенной функции Android. Затем он использует имя файлаflower1.jpg
для загрузки изображения из папки ресурсов с помощью функцииassetsToBitmap
, которую вы создали на предыдущем шаге. Наконец, он использует абстрактный класс растрового изображения для загрузки растрового изображения в img. - В файле макета был TextView, который будет использоваться для отображения меток, выведенных для изображения. Получите объект кода для следующего. Сразу под предыдущим кодом добавьте следующий:
val txtOutput : TextView = findViewById(R.id.txtOutput)
Как и ранее, он находит информацию о файле макета для текстового представления по его имени (проверьте XML, где оно называется txtOutput
) и использует его для создания экземпляра объекта TextView с именем txtOutput.
Точно так же вы создадите объект кнопки для представления кнопки и создадите его экземпляр с содержимым файла макета.
В файле макета мы назвали кнопку btnTest
, поэтому мы можем создать ее экземпляр следующим образом:
val btn: Button = findViewById(R.id.btnTest)
Теперь у вас есть весь ваш код и элементы управления инициализированы, следующим (и последним) шагом будет их использование для получения вывода об изображении.
Прежде чем продолжить, убедитесь, что ваш код onCreate
выглядит так:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val img: ImageView = findViewById(R.id.imageToLabel)
// assets folder image file name with extension
val fileName = "flower1.jpg"
// get bitmap from assets folder
val bitmap: Bitmap? = assetsToBitmap(fileName)
bitmap?.apply {
img.setImageBitmap(this)
}
val txtOutput : TextView = findViewById(R.id.txtOutput)
val btn: Button = findViewById(R.id.btnTest)
}
Ни одно из ключевых слов не должно быть красного цвета, что указывает на то, что они еще не были импортированы. Если это так, вернитесь назад и выполните трюк ALT + Enter , чтобы сгенерировать импорт.
При использовании этикетировщика изображений ML Kit первым шагом обычно является создание объекта Options для настройки поведения. Вы преобразуете свое изображение в формат InputImage , который может распознать ML Kit. Затем вы создаете объект Labeler для выполнения логического вывода. Это даст вам асинхронный обратный вызов с результатами, которые вы затем сможете проанализировать.
Для только что созданной кнопки сделайте все это в событии onClickListener
. Вот полный код:
btn.setOnClickListener {
val labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS)
val image = InputImage.fromBitmap(bitmap!!, 0)
var outputText = ""
labeler.process(image)
.addOnSuccessListener { labels ->
// Task completed successfully
for (label in labels) {
val text = label.text
val confidence = label.confidence
outputText += "$text : $confidence\n"
}
txtOutput.text = outputText
}
.addOnFailureListener { e ->
// Task failed with an exception
}
}
- Когда пользователь впервые нажимает кнопку, код создает экземпляр метки, используя ImageLabeling.getClient, передавая ему ImageLabelerOptions. Это связано со свойством DEFAULT_OPTIONS, которое позволяет нам быстро приступить к работе.
- Затем из растрового изображения будет создано InputImage с использованием его метода fromBitmap. InputImage — это желаемый формат ML Kit для обработки изображений.
- Наконец, labeler обработает изображение и выдаст асинхронный обратный вызов либо в случае успеха, либо в случае неудачи. Если вывод успешен, обратный вызов будет включать список меток. Затем вы можете проанализировать этот список меток, чтобы прочитать текст метки и значение достоверности. Если это не удастся, он отправит вам исключение, которое вы можете использовать, чтобы сообщить пользователю.
Вот и все! Теперь вы можете запустить приложение либо на устройстве Android, либо в эмуляторе. Если вы никогда не делали этого раньше, вы можете узнать, как здесь: https://developer.android.com/studio/run/emulator
Вот приложение, работающее в эмуляторе. Сначала вы увидите изображение и кнопку, а метка будет пустой.
Нажмите на кнопку, и вы получите набор меток для изображения.
Здесь вы можете видеть, что составитель определил высокую вероятность того, что изображение содержит лепесток, цветок, растение и небо. Все они верны, и все они демонстрируют, что модель работает над синтаксическим анализом изображения.
Но пока не может определить, что это изображение маргаритки. Для этого вам понадобится пользовательская модель, обученная на определенных цветах, и вы увидите, как это сделать, в следующем лабораторном занятии.
На следующих шагах вы узнаете, как создать такое же приложение на iOS.
7. Создайте классификатор изображений на iOS — начните
Вы можете создать подобное приложение на iOS с помощью Xcode.
- Запустите Xcode и в меню файлов выберите New Project . Вы увидите этот диалог:
- Выберите приложение , как показано, и нажмите «Далее ». Вам будет предложено выбрать параметры для вашего проекта. Дайте ему имя и идентификатор организации, как показано. Убедитесь, что тип интерфейса — Storyboard , а язык — Swift , как показано.
- Если вы хотите выполнить развертывание на телефоне и настроить профиль разработчика, вы можете настроить параметр своей группы. Если нет, оставьте значение None , и вы сможете использовать симулятор iOS для запуска своего приложения.
- Нажмите « Далее » и выберите папку для хранения вашего проекта и его файлов. Запомните расположение этого проекта, оно понадобится вам на следующем шаге.
- Закройте Xcode на данный момент, потому что вы будете повторно открывать его, используя другой файл рабочей области после следующего шага.
8. Интегрируйте ML Kit с помощью Cocoapods
Поскольку ML Kit также работает на iOS, вы можете использовать его очень похожим образом для создания классификатора изображений. Для его интеграции вы будете использовать CocoaPods. Если у вас это еще не установлено, вы можете сделать это с помощью инструкций на https://cocoapods.org/
- Откройте каталог, в котором вы создали свой проект. Он должен содержать ваш файл .xcodeproj.
Здесь вы можете увидеть файл .xcodeproj, указывающий, что я нахожусь в правильном месте.
- В этой папке создайте новый файл с именем Podfile . Там нет расширения, это просто Podfile. В нем добавьте следующее:
platform :ios, '10.0' target 'ImageClassifierStep1' do pod 'GoogleMLKit/ImageLabeling' end
- Сохраните его и вернитесь к терминалу. В том же каталоге введите
pod install
. Cocoapods загрузит соответствующие библиотеки и зависимости и создаст новое рабочее пространство, объединяющее ваш проект с его внешними зависимостями.
Обратите внимание, что в конце вас попросят закрыть сеансы Xcode и с этого момента использовать файл рабочей области. Откройте этот файл, и Xcode запустится с исходным проектом и внешними зависимостями.
Теперь вы готовы перейти к следующему шагу и созданию пользовательского интерфейса.
9. Создайте пользовательский интерфейс iOS с помощью раскадровки
- Откройте файл
Main.storyboard
, и вы увидите макет пользовательского интерфейса с областью дизайна для телефона. - В правом верхнем углу экрана есть кнопка + , которую можно использовать для добавления элементов управления. Нажмите на нее, чтобы открыть палитру элементов управления.
- Оттуда перетащите ImageView , Button и Label на поверхность конструктора. Расположите их сверху вниз, как показано на рисунке:
- Дважды щелкните кнопку, чтобы изменить ее текст с Button на Classify .
- Перетащите маркеры управления вокруг метки, чтобы увеличить ее. (Скажем, такая же ширина, как у UIImageView, и вдвое больше высоты.)
- Не снимая выделения с метки, нажмите кнопку выбора в правом верхнем углу, чтобы отобразить палитру инспекторов.
- Сделав это, найдите параметр Lines и убедитесь, что он установлен на 0 . Это позволяет метке отображать динамическое количество строк.
Теперь вы готовы сделать следующий шаг — связать пользовательский интерфейс с кодом, используя выходы и действия.
10. Создавайте действия и торговые точки
При разработке iOS с использованием раскадровок вы обращаетесь к информации о макете для своих элементов управления с помощью выходов и определяете код, который будет выполняться, когда пользователь выполняет действие над элементом управления с помощью действий.
На следующем шаге вам нужно будет создать выходы для ImageView и Label. ImageView будет использоваться в коде для загрузки в него изображения. Метка будет упоминаться в коде, чтобы установить ее текст на основе вывода, полученного из комплекта ML.
- Закройте палитру инспекторов, щелкнув элемент управления в правом верхнем углу экрана, затем нажмите кнопку « Добавить редактор справа », которая находится сразу под ним.
- У вас будет запутанный макет экрана, где main.storyboard открывается дважды. Слева в навигаторе проекта выберите ViewController.swift , чтобы открылся код контроллера представления. Может показаться, что ваша область дизайна исчезла из редактора раскадровки слева, но не волнуйтесь, она все еще там!
- Чтобы вернуть его, щелкните View Controller в сцене View Controller. Постарайтесь, чтобы ваш пользовательский интерфейс выглядел так: раскадровка слева показывает ваш дизайн, а код для ViewController.swift — справа.
- Выберите UIImageView в рабочей области слева и, удерживая нажатой клавишу CONTROL, перетащите его в код справа, поместив чуть ниже ключевого слова
class
(в строке 11 на снимке экрана выше).
При перетаскивании вы увидите стрелку, а когда отпустите, появится всплывающее окно, подобное этому:
- Заполните поле « Имя » как «imageView» и нажмите « Подключиться ».
- Повторите этот процесс с меткой и дайте ей имя «lblOutput».
- Важно: для кнопки вы сделаете то же самое, но убедитесь, что вы установили тип соединения Action , а не Outlet !
- Дайте ему имя «doClassification» и нажмите « Подключиться ».
Когда вы закончите, ваш код должен выглядеть следующим образом: (Обратите внимание, что метка и представление изображения объявлены как IBOutlet (Выход построителя интерфейса), а кнопка — как IBAction (Действие построителя интерфейса).)
import UIKit
class ViewController: UIViewController {
@IBAction func doClassification(_ sender: Any) {
}
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var lblOutput: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
- Наконец, свяжите изображение с приложением, чтобы мы могли легко выполнить классификацию. Для этого перетащите файл из проводника в проводник слева от Xcode. Когда вы бросите его, вы получите всплывающее окно, подобное этому:
- Убедитесь, что флажок в разделе « Добавить к целевым объектам » установлен, как показано, затем нажмите « Готово » .
Файл будет связан с вашим приложением, и теперь вы сможете легко его классифицировать. Теперь вы готовы написать пользовательский интерфейс для классификации изображений!
11. Напишите код для классификации изображений
Теперь, когда все настроено, написать код для выполнения классификации изображений очень просто.
- Начните с закрытия конструктора раскадровки, щелкнув X в верхнем левом углу над областью конструктора. Это позволит вам сосредоточиться только на своем коде. Вы будете редактировать ViewController.swift для остальной части этой лабораторной работы.
- Импортируйте библиотеки MLKitVision и MLKit ImageLabeling, добавив этот код вверху, прямо под импортом UIKit:
import MLKitVision
import MLKitImageLabeling
- Затем в вашей функции
viewDidLoad
инициализируйте ImageView, используя файл, который мы вложили в приложение:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
imageView.image = UIImage(named:"flower1.jpg")
}
- Создайте вспомогательную функцию для получения меток для изображения сразу после
viewDidLoad()
:
func getLabels(with image: UIImage){
- Создайте VisionImage из изображения. ML Kit использует этот тип при выполнении классификации изображений. Итак, внутри функции getLabels добавьте этот код:
let visionImage = VisionImage(image: image)
visionImage.orientation = image.imageOrientation
- Затем создайте параметры для этикетировщика изображений. Он будет инициализирован с использованием этих опций. В этом случае вы просто установите базовую опцию
confidenceThreshold
. Это означает, что вы будете просить маркировщика возвращать метки только с достоверностью 0,4 или выше. Например, для нашего цветка такие классы, как «растение» или «лепесток», будут иметь высокую достоверность, а такие, как «баскетбол» или «автомобиль», — низкую.
let options = ImageLabelerOptions()
options.confidenceThreshold = 0.4
- Теперь создайте этикетировщик, используя эти параметры:
let labeler = ImageLabeler.imageLabeler(options: options)
- Когда у вас есть этикетировщик, вы можете его обработать. Это даст вам асинхронный обратный вызов с метками (в случае успеха) и ошибкой (в случае сбоя), которые вы затем сможете обработать в другой функции, которую мы создадим через мгновение.
labeler.process(visionImage) { labels, error in
self.processResult(from: labels, error: error)
}
Не беспокойтесь, если Xcode жалуется на отсутствие члена processResult
. Вы просто еще не реализовали это, и вы сделаете это дальше.
Для удобства, вот полная функция getLabels:
// This is called when the user presses the button
func getLabels(with image: UIImage){
// Get the image from the UI Image element and set its orientation
let visionImage = VisionImage(image: image)
visionImage.orientation = image.imageOrientation
// Create Image Labeler options, and set the threshold to 0.4
// so we will ignore all classes with a probability of 0.4 or less
let options = ImageLabelerOptions()
options.confidenceThreshold = 0.4
// Initialize the labeler with these options
let labeler = ImageLabeler.imageLabeler(options: options)
// And then process the image, with the callback going to self.processresult
labeler.process(visionImage) { labels, error in
self.processResult(from: labels, error: error)
}
}
Итак, теперь вам нужно реализовать функцию processResult
. Теперь это очень просто, учитывая, что у нас есть метки и возвращаемый нам объект ошибки. Метки должны быть преобразованы в тип ImageLabel из ML Kit.
Как только это будет сделано, вы можете просто перебрать набор меток, получить описание и значение достоверности и добавить их в labeltexts
var
Как только вы перебираете их все, вы просто устанавливаете lblOutput.text в это значение.
Вот полная функция:
// This gets called by the labeler's callback
func processResult(from labels: [ImageLabel]?, error: Error?){
// String to hold the labels
var labeltexts = ""
// Check that we have valid labels first
guard let labels = labels else{
return
}
// ...and if we do we can iterate through the set to get the description and confidence
for label in labels{
let labelText = label.text + " : " + label.confidence.description + "\n"
labeltexts += labelText
}
// And when we're done we can update the UI with the list of labels
lblOutput.text = labeltexts
}
Остается только вызывать getLabels
когда пользователь нажимает кнопку.
Когда вы создали действие, все было подключено за вас, поэтому вам просто нужно обновить IBAction
с именем doClassificaiton
, который вы создали ранее, для вызова getLabels
.
Вот код, чтобы просто вызвать его с содержимым imageView:
@IBAction func doClassification(_ sender: Any) {
getLabels(with: imageView.image!)
}
Теперь запустите свое приложение и попробуйте. Вы можете увидеть это в действии здесь:
Обратите внимание, что ваш макет может выглядеть по-разному в зависимости от вашего устройства.
Лаборатория кода не исследует различные типы макетов для каждого устройства, что само по себе является довольно сложной концепцией. Если вы не видите пользовательский интерфейс должным образом, вернитесь в редактор раскадровки, и внизу вы увидите раздел « Просмотр как: », где вы можете выбрать конкретное устройство. Выберите тот, который соответствует изображению или устройству, на котором вы тестируете, и отредактируйте пользовательский интерфейс в соответствии с ним.
По мере того, как вы углубляетесь в разработку для iOS, вы узнаете, как использовать ограничения, чтобы обеспечить согласованность вашего пользовательского интерфейса на всех телефонах, но это выходит за рамки данного лабораторного занятия.
12. Поздравляем!
Теперь вы реализовали приложение для Android и iOS, которое дает вам базовое компьютерное зрение с универсальной моделью. Вы уже сделали большую часть тяжелой работы.
В следующей лаборатории кода вы создадите пользовательскую модель, которая распознает различные типы цветов, и всего несколькими строками кода вы сможете реализовать пользовательскую модель в этом приложении, чтобы сделать его более полезным!