Бывает листаешь книгу или журнал, видишь красивое место или здание, но не знаешь, где оно и как называется. Тут пригодилось бы приложение, которое распознает его по фотографии.
С помощью машинного обучения создать такое приложение довольно просто. Об этом и пойдет речь в этой статье.
О распознавании достопримечательностей
Сервис распознавания достопримечательностей позволяет получить название достопримечательности, ее координаты (долготу и широту) и даже оценить достоверность исходного изображения. Уровень достоверности будет определен при загрузке изображения для распознавания. Чем больше достоверность, тем вероятнее, что достопримечательность на исходном изображении будет распознана. Все эти данные можно использовать, чтобы персонализировать приложение для пользователей.
При использовании функции распознавания достопримечательностей устройство вызывает облачный API, и в облаке запускается модель алгоритма обнаружения. При использовании сервиса устройство должно быть подключено к Интернету.
Подготовка
Настройка среды разработки
1. Create an app in AppGallery Connect
Подробнее см. в Кратком руководстве по Android.
2.Включите ML Kit
Нажмите здесь, чтобы узнать подробнее.
3.Загрузите файл agconnect-services.json, который автоматически создается после создания приложения. Скопируйте его в папку app проекта Android Studio.
4. Настройте адрес репозитория Maven для HMS Core SDK.
5.Интегрируйте SDK для распознавания достопримечательностей.
Настройте SDK в файле build.gradle в папке app.
// Import the landmark recognition SDK.
implementation 'com.huawei.hms:ml-computer-vision-cloud:2.0.5.304'
При необходимости добавьте конфигурацию плагина AppGallery Connect одним из следующих способов.
Способ 1. Добавьте следующий код в объявление в заголовке файла:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
Способ 2. Добавьте конфигурацию плагина в блок плагинов.
plugins {
id 'com.android.application'
id 'com.huawei.agconnect'
}
Разработка кода
1.Получите разрешение на использование камеры.
Обязательно настройте статическое разрешение.
<uses-permission android:name="android.permission.CAMERA" />
Также обязательно получите динамическое разрешение.
ActivityCompat.requestPermissions(
this, new String[]{Manifest.permission. CAMERA
}, 1);
2.Настройте ключ API. Сервис работает в облаке, то есть для настройки данных аутентификации в облаке для приложения требуется ключ API. Настроить ключ API нужно обязательно, иначе во время работы приложения возникнет ошибка.
// Set the API key to access the on-cloud services.
private void setApiKey() {
// Parse the agconnect-services.json file to obtain its information.
AGConnectServicesConfig config = AGConnectServicesConfig.fromContext(getApplication());
// Sets the API key.
MLApplication.getInstance().setApiKey(config.getString("client/api_key"));
}
3.Создайте анализатор достопримечательностей одним из следующих способов.
// Method 1: Use default parameter settings.
MLRemoteLandmarkAnalyzer analyzer = MLAnalyzerFactory.getInstance().getRemoteLandmarkAnalyzer();
// Method 2: Use customized parameter settings through the MLRemoteLandmarkAnalyzerSetting class.
/**
* Use custom parameter settings.
* setLargestNumOfReturns indicates the maximum number of recognition results.
* setPatternType indicates the analyzer mode.
* MLRemoteLandmarkAnalyzerSetting.STEADY_PATTERN: The value 1 indicates the stable mode.
* MLRemoteLandmarkAnalyzerSetting.NEWEST_PATTERN: The value 2 indicates the latest mode.
*/
private void initLandMarkAnalyzer() {
settings = new MLRemoteLandmarkAnalyzerSetting.Factory()
.setLargestNumOfReturns(1)
.setPatternType(MLRemoteLandmarkAnalyzerSetting.STEADY_PATTERN)
.create();
analyzer = MLAnalyzerFactory.getInstance().getRemoteLandmarkAnalyzer(settings);
}
4.Преобразуйте изображение, снятое на камеру или сохраненное на устройстве, в растровое изображение. У SDK для распознавания достопримечательностей нет такой функции, поэтому нужно сделать это в другом сервисе.
// Select an image.
private void selectLocalImage() {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, REQUEST_SELECT_IMAGE);
}
Включите сервис распознавания достопримечательностей в функции обратного вызова.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Image selection succeeded.
if (requestCode == REQUEST_SELECT_IMAGE && resultCode == RESULT_OK) {
if (data != null) {
// Obtain the image URI through getData(). imageUri = data.getData();
// Implement the BitmapUtils class by yourself. Obtain the bitmap of the image with its URI.
bitmap = BitmapUtils.loadFromPath(this, imageUri, getMaxWidthOfImage(), getMaxHeightOfImage());
}
// Start landmark recognition.
startAnalyzerImg(bitmap);
}
}
5.Запустите распознавание достопримечательностей после получения растрового изображения. Поскольку сервис работает в облаке, плохое соединение может замедлить передачу данных. Поэтому рекомендуется добавить маску к растровому изображению перед запуском распознавания.
// Start landmark recognition.
private void startAnalyzerImg(Bitmap bitmap) {
if (imageUri == null) {
return;
}
// Add a mask.
progressBar.setVisibility(View.VISIBLE);
img_analyzer_landmark.setImageBitmap(bitmap);
// Create an MLFrame object using android.graphics.Bitmap. JPG, JPEG, PNG, and BMP images are supported. It is recommended that the image size be greater than or equal to 640 x 640 px.
MLFrame mlFrame = new MLFrame.Creator().setBitmap(bitmap).create();
Task<List<MLRemoteLandmark>> task = analyzer.asyncAnalyseFrame(mlFrame);
task.addOnSuccessListener(new OnSuccessListener<List<MLRemoteLandmark>>() {
public void onSuccess(List<MLRemoteLandmark> landmarkResults) {
progressBar.setVisibility(View.GONE);
// Called upon recognition success.
Log.d("BitMapUtils", landmarkResults.get(0).getLandmark());
}
}).addOnFailureListener(new OnFailureListener() {
public void onFailure(Exception e) {
progressBar.setVisibility(View.GONE);
// Called upon recognition failure.
// Recognition failure.
try {
MLException mlException = (MLException) e;
// Obtain the result code. You can process the result code and set a different prompt for users for each result code.
int errorCode = mlException.getErrCode();
// Obtain the error message. You can quickly locate the fault based on the result code.
String errorMessage = mlException.getMessage();
// Record the code and message of the error in the log.
Log.d("BitMapUtils", "errorCode: " + errorCode + "; errorMessage: " + errorMessage);
} catch (Exception error) {
// Handle the conversion error.
}
}
});
}
Тестирование приложения
Ниже показана работа сервиса на примере башни «Восточная жемчужина» в Шанхае.
Примечания
1. Прежде чем распознать достопримечательность, настройте ключ API, чтобы настроить данные облачной аутентификации для приложения. В противном случае во время работы приложения возникнет ошибка.
2. Распознавание достопримечательностей выполняется в облаке, поэтому обработка может занять некоторое время. Перед распознаванием достопримечательностей рекомендуется добавить маску.
Комментарии (7)
gsaw
05.03.2022 22:04Какая то статья странная, для кружка очумелые ручки. По сути это про то, как "подключить HMS Core" зависимость в проекте, которая много чего умеет, но почему то только про Landmark recognition написано. Хотя бы пару слов про библиотеку обронили.
Jackson134 Автор
08.03.2022 05:48В интегрированном HMS Core ML Kit помимо распознавания достопримечательностей есть и другие возможности. Подробную информацию об этих возможностях можно посмотреть на официальном веб-сайте по ссылке https://developer.huawei.com/consumer/en/doc/development/hiai-Guides/service-introduction-0000001050040017#section119422313385?ha_source=hms1
Komandor_Yan
07.03.2022 11:19Так а откуда программа подхватывает "возможные варианты" достопримечательностей? Из своей базы берет или обращается к тому же Google Lens (который занимается тем же)?
Jackson134 Автор
08.03.2022 05:50Для обнаружения служба распознавания достопримечательностей вызывает облачные API на устройстве. Модель алгоритма обнаружения выполняется на стороне облака.
vtal007
Если это достопримечательность, то просто сфоткать и поиск по картинке в гугле/яндексе
nixtonixto
С помощью Google Lens — можно не фотографировать, а только навести объектив. Собственно, автор попытался изобрести Lens.
Jackson134 Автор
Вы, конечно, можете напрямую использовать Google Lens. Но у меня телефон Huawei, а на новых телефонах Huawei невозможно использовать GMS. Если интегрировать службы Google в приложение, то на новых телефонах Huawei его, вероятно, нельзя будет использовать. Эту проблему можно решить путем интеграции HMS, чтобы приложение нормально работало на телефонах Huawei.