Статьи

Распознавание изображений с помощью Google Vision API и Ionic

Распознавание изображений позволяет компьютерам распознавать изображения аналогично людям. В прошлом разработчикам приходилось использовать сложные методы и алгоритмы распознавания изображений, такие как распознавание образов . С выпуском 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

Сборка приложения

Теперь вы готовы к созданию приложения. Но сначала я бы хотел дать краткий обзор приложения, которое вы собираетесь создать. Приложение будет иметь одну страницу, которая содержит все элементы, необходимые для взаимодействия с 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, он больше не нуждается в преобразовании.

sourceTypeCamera.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 прочитайте официальную документацию, и я хотел бы услышать ваш опыт и мысли.