Распознавание изображений позволяет компьютерам распознавать изображения аналогично людям. В прошлом разработчикам приходилось использовать сложные методы и алгоритмы распознавания изображений, такие как распознавание образов . С выпуском Google Cloud Vision API разработчики получили мощный набор инструментов, доступных от компании, с некоторыми из лучших доступных функций распознавания изображений.
В этом руководстве вы создадите приложение Ionic, которое позволит пользователям делать снимки, распознаваемые API Cloud Vision.
Начиная
Использование API включает загрузку файла JSON, содержащего требуемый тип обнаружения изображения и кодировку base64 изображения, в конечную точку API.
Вот пример файла JSON:
{ "requests":[ { "image":{ "content":"base64-encoded-image" }, "features":[ { "type":"LABEL_DETECTION", "maxResults":1 } ] } ] }
В этом примере вы должны заменить base64-encoded-image
реальным представлением строки в кодированном base64 изображении. Свойство features
— это то, где вы предоставляете массив объектов, содержащий тип обнаружения изображения, который вы хотите. LABEL_DETECTION
пытается классифицировать изображение, LABEL_DETECTION
ему метку или описание.
Как только вы получите ответ, он будет примерно таким:
{ "responses": [ { "labelAnnotations": [ { "mid": "/m/0bt9lr", "description": "dog", "score": 0.89208293 } ] } ] }
Поскольку вы указали LABEL_DETECTION
для функции и maxResults
1
, в массиве responses
вы получите один объект. В этом случае labelAnnotations
.
Помимо LABEL_DETECTION
, вы также можете использовать следующее:
-
FACE_DETECTION
: обнаруживает человеческие лица на фотографии, возвращая координаты, которые можно использовать для рисования вокруг обнаруженных лиц. -
LANDMARK_DETECTION
: обнаруживает такие достопримечательности, как Оперный театр в Сиднее или Стоунхендж в Уилтшире. -
LOGO_DETECTION
: обнаруживает различные логотипы компании. -
TEXT_DETECTION
: использует технологию оптического распознавания символов (OCR) для извлечения текста из изображений. -
SAFE_SEARCH_DETECTION
: классифицирует изображение на основе параметров безопасного поиска. Это классифицирует изображение какadult
,spoof
,medical
илиviolence
.
Регистрация в Cloud Vision API
На момент написания статьи Google Cloud Vision API находился в стадии бета-тестирования, что означает, что его можно попробовать бесплатно. Перейдите на веб-сайт Google Cloud Platform и нажмите кнопку « Попробовать бесплатно» . Это приведет вас на страницу с запросом информации о вашей компании и кредитной информации, но не волнуйтесь, Google не будет взимать с вас ничего до 300 долларов.
По завершении создайте новый проект в консоли Google , включите биллинг для своего проекта и включите API Cloud Vision . Я рекомендую вам пропустить обычный процесс и использовать опцию «API Key».
Сборка приложения
Теперь вы готовы к созданию приложения. Но сначала я бы хотел дать краткий обзор приложения, которое вы собираетесь создать. Приложение будет иметь одну страницу, которая содержит все элементы, необходимые для взаимодействия с API Cloud Vision. Он будет иметь раскрывающийся список для выбора типа обнаружения изображения, который требуется пользователю, кнопку для съемки изображения, элемент изображения для отображения снятого изображения и элемент заголовка для отображения описания изображения.
Вот как будет выглядеть финальное приложение:
Вы можете найти окончательный код проекта на GitHub .
Установка зависимостей
В вашем рабочем каталоге откройте новое окно терминала и установите Cordova и Ionic:
npm install -g cordova ionic
Создайте новый Ionic-проект, используя пустой шаблон:
ionic start ionic-vision blank
Добавьте платформы, которые вы хотите использовать. Я только собираюсь установить Android, но код должен работать и на iOS.
ionic platform add android
Вам необходимо установить несколько плагинов для взаимодействия с API-интерфейсами устройств, работы с камерой, файлов и загрузки файлов.
cordova plugin add cordova-plugin-camera cordova plugin add cordova-plugin-file cordova plugin add cordova-plugin-file-transfer
Установите ngCordova, используя bower :
bower install ngCordova
Библиотека ngCordova предоставляет оболочки AngularJS для установленных плагинов. Эти оболочки упрощают работу с плагинами внутри приложения Ionic.
Добавление контроллера
Откройте каталог www , создайте файл controllers / HomeController.js внутри каталога js и добавьте следующий код:
(function(){ angular.module('starter') .controller('HomeController', ['$scope', '$ionicModal', '$cordovaFile', '$cordovaFileTransfer', '$cordovaCamera', HomeController]); function HomeController($scope, $ionicModal, $cordovaFile, $cordovaFileTransfer, $cordovaCamera){ var me = this; me.current_image = 'img/koro-sensei.png'; me.image_description = ''; me.detection_type = 'LABEL_DETECTION'; me.detection_types = { LABEL_DETECTION: 'label', TEXT_DETECTION: 'text', LOGO_DETECTION: 'logo', LANDMARK_DETECTION: 'landmark' }; var api_key = 'your-google-api-key'; $scope.takePicture = function(){ var options = { destinationType: Camera.DestinationType.DATA_URL, sourceType: Camera.PictureSourceType.CAMERA, targetWidth: 500, targetHeight: 500, correctOrientation: true, cameraDirection: 0, encodingType: Camera.EncodingType.JPEG }; $cordovaCamera.getPicture(options).then(function(imagedata){ me.current_image = "data:image/jpeg;base64," + imagedata; me.image_description = ''; me.locale = ''; var vision_api_json = { "requests":[ { "image":{ "content": imagedata }, "features":[ { "type": me.detection_type, "maxResults": 1 } ] } ] }; var file_contents = JSON.stringify(vision_api_json); $cordovaFile.writeFile( cordova.file.applicationStorageDirectory, 'file.json', file_contents, true ).then(function(result){ var headers = { 'Content-Type': 'application/json' }; options.headers = headers; var server = 'https://vision.googleapis.com/v1/images:annotate?key=' + api_key; var filePath = cordova.file.applicationStorageDirectory + 'file.json'; $cordovaFileTransfer.upload(server, filePath, options, true) .then(function(result){ var res = JSON.parse(result.response); var key = me.detection_types[me.detection_type] + 'Annotations'; me.image_description = res.responses[0][key][0].description; }, function(err){ alert('An error occurred while uploading the file'); }); }, function(err){ alert('An error occurred while trying to write the file'); }); }, function(err){ alert('An error occurred getting the picture from the camera'); }); } } })();
Разбивка кода выше. Сначала вы создаете контроллер и импортируете необходимые библиотеки.
(function(){ angular.module('starter') .controller('HomeController', ['$scope', '$cordovaFile', '$cordovaFileTransfer', '$cordovaCamera', HomeController]); function HomeController($scope, $cordovaFile, $cordovaFileTransfer, $cordovaCamera){ ... }
Внутри контроллера установите данные по умолчанию, используемые представлением. Это включает в себя отображаемое изображение, пустое описание и тип обнаружения по умолчанию. LABEL_DETECTION
используется, поскольку он более обобщенный, чем другие.
var me = this; me.current_image = 'img/koro-sensei.png'; me.image_description = ''; me.detection_type = 'LABEL_DETECTION';
Ниже представлен объект, содержащий все типы обнаружения и ключ API от Google:
me.detection_types = { LABEL_DETECTION: 'label', TEXT_DETECTION: 'text', LOGO_DETECTION: 'logo', LANDMARK_DETECTION: 'landmark' }; var api_key = 'your-google-api-key';
Затем создайте метод, выполняемый при нажатии кнопки камеры.
$scope.takePicture = function(){ ... };
Внутри метода объявите параметры для плагина камеры, установив destinationType
в Camera.DestinationType.DATA_URL
. Это означает, что после выбора изображения функция обратного вызова будет иметь URI данных изображения. Поскольку этот URI данных уже закодирован в base64, он больше не нуждается в преобразовании.
sourceType
— Camera.PictureSourceType.CAMERA
поэтому в качестве источника используется изображение, полученное с камеры targetWidth
и targetHeight
устанавливают предпочтительные размеры этого изображения. correctOrientation
имеет значение true
поэтому оно автоматически меняет ориентацию изображения на портретное, а cameraDirection
равно 0
поэтому оно использует заднюю камеру. И, наконец, encodingType
— это Camera.EncodingType.JPEG
, позволяющий Camera.EncodingType.JPEG
добавить data:image/jpeg;base64,
к URI данных, чтобы вы могли отобразить изображение.
var options = { destinationType: Camera.DestinationType.DATA_URL, sourceType: Camera.PictureSourceType.CAMERA, targetWidth: 500, targetHeight: 500, correctOrientation: true, cameraDirection: 0, encodingType: Camera.EncodingType.JPEG };
Это открывает приложение камеры по умолчанию на устройстве, вызывая $cordovaCamera.getPicture
. Он использует options
в качестве аргумента, вызывая then
и предоставляя функции обратного вызова success и error. То же самое относится ко всем плагинам, которые вы будете использовать позже.
$cordovaCamera.getPicture(options).then(function(imagedata){ ... }, function(err){ alert('An error occurred getting the picture from the camera'); });
В обратном вызове успеха обновите источник изображения ( current_image
) и сбросьте описание в пустую строку.
me.current_image = "data:image/jpeg;base64," + imagedata; me.image_description = '';
me.detection_type
объект, используя URI данных из плагина камеры и тип обнаружения ( me.detection_type
), выбранный пользователем. Затем преобразуйте его в строку, чтобы вы могли использовать его в качестве содержимого для файла JSON, отправляемого в API.
var vision_api_json = { "requests":[ { "image":{ "content": imagedata }, "features":[ { "type": me.detection_type, "maxResults": 1 } ] } ] }; var file_contents = JSON.stringify(vision_api_json);
Используйте плагин Cordova File, чтобы записать file_contents
в файл file.json, хранящийся в корневом каталоге изолированной программной среды приложения. Третий аргумент метода writeFile
— это логическое значение, определяющее, следует ли создавать файл, если он еще не существует.
$cordovaFile.writeFile( cordova.file.applicationStorageDirectory, 'file.json', file_contents, true ).then(function(result){ ... }, function(err){ alert('An error occurred while writing to the file'); });
Когда содержимое записано в файл, объявите переменные, необходимые плагину передачи файлов для работы. Ниже приведена переменная headers
которая является заголовками http для запроса. Поскольку вы отправляете файл JSON, вы должны установить Content-Type
для application/json
. server
— это полный URL-адрес API для отправки запроса, а filePath
— полный путь к файлу JSON, который вы будете отправлять.
var headers = { 'Content-Type': 'application/json' }; options.headers = headers; var server = 'https://vision.googleapis.com/v1/images:annotate?key=' + api_key; var filePath = cordova.file.applicationStorageDirectory + 'file.json';
Вы отправляете файл на сервер, используя метод upload
плагина передачи файлов. Четвертый аргумент, предоставленный методу upload
— это логическое значение, определяющее, принимать ли сертификаты безопасности от всех хостов. Получив ответ, преобразуйте его в объект JavaScript, используя JSON.parse
. Создайте ключ, объединив значение текущего типа обнаружения и слово «Аннотации». Это позволяет сформировать строку labelAnnotations
если пользователь выбрал LABEL_DETECTION
в качестве типа обнаружения. Затем вы можете использовать эту строку для извлечения фактического описания изображения.
$cordovaFileTransfer.upload(server, filePath, options, true) .then(function(result){ var res = JSON.parse(result.response); var key = me.detection_types[me.detection_type] + 'Annotations'; me.image_description = res.responses[0][key][0].description; }, function(err){ alert('An error occured while uploading the file'); });
Добавление вида
Создайте файл templates / home.html и добавьте следующий код:
<ion-view title="IonicVision" ng-controller="HomeController as home_ctrl"> <header class="bar bar-header bar-stable"> <h1 class="title">Ionic Vision</h1> </header> <ion-content class="has-header padding"> <img src="{{ home_ctrl.current_image }}" class="picture"> <h3 class="text-center" ng-show="home_ctrl.image_description">{{ home_ctrl.image_description }}</h3> <label class="item item-input item-select"> <div class="input-label"> Detection Type </div> <select ng-model="home_ctrl.detection_type"> <option value="{{detection_type}}" ng-repeat="(detection_type, detection_type_value) in home_ctrl.detection_types">{{detection_type_value}}</option> </select> </label> <button class="button button-positive button-block" ng-click="takePicture()"> Take Picture </button> </ion-content> </ion-view>
Разбивка кода выше. Сначала он создает новый ion-view
и указывает используемый контроллер.
<ion-view title="IonicVision" ng-controller="HomeController as home_ctrl"> </ion-view>
Внутри ion-view
находится заголовок, а ion-content
— это элементы пользовательского интерфейса, которые вы видите под заголовком. Такие вещи, как изображение, описание изображения, список типов обнаружения и кнопка для съемки.
<header class="bar bar-header bar-stable"> <h1 class="title">Ionic Vision</h1> </header> <ion-content class="has-header padding"> <img src="{{ home_ctrl.current_image }}" class="picture"> <h3 class="text-center" ng-show="home_ctrl.image_description">{{ home_ctrl.image_description }}</h3> <label class="item item-input item-select"> <div class="input-label"> Detection Type </div> <select ng-model="home_ctrl.detection_type"> <option value="{{detection_type}}" ng-repeat="(detection_type, detection_type_value) in home_ctrl.detection_types">{{detection_type_value}}</option> </select> </label> <button class="button button-positive button-block" ng-click="takePicture()"> Take Picture </button> </ion-content>
стайлинг
Большая часть работы по оформлению выполняется Ionic, поэтому вам нужно всего лишь несколько объявлений стилей. Добавьте следующее в css / style.css :
.text-center { text-align: center; } .picture { max-width: 100%; max-height: 100%; }
Собираем все вместе
Откройте файл js / app.js , содержащий код для инициализации Ionic и ngCordova. Если вы использовали пустой начальный шаблон Ionic, большая часть кода уже заполнена. Все, что нужно, это указать использование ngCordova
и отредактировать содержимое метода config
чтобы он указывал на файл home.html .
angular.module('starter', ['ionic', 'ngCordova']) .run(function($ionicPlatform) { $ionicPlatform.ready(function() { if(window.cordova && window.cordova.plugins.Keyboard) { cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); cordova.plugins.Keyboard.disableScroll(true); } if(window.StatusBar) { StatusBar.styleDefault(); } }); }) .config(function($stateProvider, $urlRouterProvider) { $stateProvider .state('home', { url: '/home', templateUrl: 'templates/home.html' }); $urlRouterProvider.otherwise('/home'); });
Откройте файл index.html и укажите ссылку на файл ng-cordova.js после файла ionic.bundle.js . Ниже файла app.js , ссылка на файл HomeController.js .
Не забудьте указать starter
в качестве значения для ng-app
, а внутри body
добавьте ion-nav-view
чтобы он отображал представление home.html .
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> <title></title> <link href="lib/ionic/css/ionic.css" rel="stylesheet"> <link href="css/style.css" rel="stylesheet"> <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above <link href="css/ionic.app.css" rel="stylesheet"> --> <!-- ionic/angularjs js --> <script src="lib/ionic/js/ionic.bundle.js"></script> <script src="lib/ngCordova/dist/ng-cordova.js"></script> <!-- cordova script (this will be a 404 during development) --> <script src="cordova.js"></script> <!-- your app's js --> <script src="js/app.js"></script> <script src="js/controllers/HomeController.js"></script> </head> <body ng-app="starter"> <ion-nav-view></ion-nav-view> </body> </html>
Запуск приложения
Вы можете запустить приложение на своем устройстве или на эмуляторе, выполнив следующую команду:
ionic run android
Последние мысли
В этом руководстве вы создали приложение для распознавания изображений с помощью ionic и с помощью API Cloud Vision. Я рассмотрел использование различных типов обнаружения изображений, таких как метка, ориентир, логотип и обнаружение текста. Я не рассматривал обнаружение лиц или обнаружение безопасного поиска, но для обнаружения лиц вы можете использовать что-то вроде Fabric.js . Это преобразует изображение в объект холста и рисует круги на обнаруженных лицах.
Для получения дополнительной информации об API Cloud Vision прочитайте официальную документацию, и я хотел бы услышать ваш опыт и мысли.