- PVSM.RU - https://www.pvsm.ru -

Telegram бот и использование Google Cloud Vision

Всем привет! Недавно я уже писал статью [1] про интеграцию своего бота с IBM Watson, а в этой статье рассмотрю интеграцию с Google Cloud Vision для распознавания котиков и более подробно опишу внутренности своего бота.

Небольшая предыстория:

Мой бот вполне успешно работал пару месяцев с использованием распознавания IBM Watson, однако затем на хабре вышла статья про google cloud vision [2] и оказалось, что Google распознает изображения лучше, чем IBM. В тот же день я зарегистрировался в консоли разработчика Google cloud platform и начал переписывать блок модерации котиков в своем боте.

Немного поискав, я нашел подходящий пример на C# на гитхабе GoogleCloudPlatform [3]. Я поменял аутентификацию из примера и сделал ее из json файла с private key, который взял в разделе «сервисные аккаунты» консоли.

код авторизации на c#

private VisionService service;
        private string _JsonPath = @"C:BOTSfcatsbotjson.json";       
        private VisionService CreateAuthorizedClient(string JsonPath)
        {
            GoogleCredential credential =
                GoogleCredential.FromStream(new FileStream(JsonPath, FileMode.Open));            
            // Inject the Cloud Vision scopes
            if (credential.IsCreateScopedRequired)
            {
                credential = credential.CreateScoped(new[]
                {
                    VisionService.Scope.CloudPlatform
                });
            }
            var res = new VisionService(new BaseClientService.Initializer
            {
                HttpClientInitializer = credential,
                GZipEnabled = false
            });
            return res;
        }

Далее я переделал модерацию изображений (label detection). В примере на гитхабе DetectLabels работает с файлом, а мне нужно было работать с ссылкой, которую я получал с серверов Telegram, чтобы не хранить у себя файлы изображений. Я сохраняю в базе только file_id, что дает неплохой прирост скорости работы.

код label detection

 private async Task<IList<AnnotateImageResponse>> DetectLabels(
            VisionService vision, string imageUrl)
        {
            // Convert image to Base64 encoded for JSON ASCII text based request   
            MemoryStream ms = new MemoryStream();
            using (var client = new HttpClient())
            {
                Stream imageBytes = await client.GetStreamAsync(imageUrl);
                imageBytes.CopyTo(ms);
            }
            byte[] imageArray = ms.ToArray();
            string imageContent = Convert.ToBase64String(imageArray);
            // Post label detection request to the Vision API
            // [START construct_request]
            var responses = vision.Images.Annotate(
                new BatchAnnotateImagesRequest()
                {
                    Requests = new[] {
                    new AnnotateImageRequest() {
                        Features = new []
                        { new Feature()
                            { Type =
                          "LABEL_DETECTION"}
                            },
                        Image = new Image() { Content = imageContent }
                    }
               }
                }).Execute();
            ms.Dispose();
            return responses.Responses;
        }

Затем я ищу в Responses есть ли label с описанием котика, с оценкой более 0.6, и таким образом, определяю есть ли котик в переданной боту картинке:

работа с labels

foreach (var response in responses.Responses)
{
  foreach (var label in response.LabelAnnotations)
  {
    double _score = label.Score == null ? 0 : Convert.ToDouble(label.Score.Value);
    var class = label.Description.Trim();
    if (class .Contains("kitten") || class .Contains("cat") ) && (_score > 0.60))
    {
      HasCatOrKittenClass = true;//moderation OK
    }
  }
}

Вот код работы с API Telegram для получения ссылки на изображение из file_id, я использовал библиотеку на C# telegram bot [4]:

telegram getFile

var file = await MainParams.TGBot.GetFileAsync(fileid);
var file_path = file.FilePath;
var urlImage = "https://api.telegram.org/file/bot" + MainParams.bot_token + "/" + file_path;

А когда я отправляю изображение пользователю с помощью sendPhoto, я просто передаю сохраненный file_id вторым параметром.

Таким образом, получается что когда пользователь присылает свое фото котика на модерацию (или использует для этого thecatapi.com), я сохраняю в базе только file_id и в дальнейшем использую его для получения ссылки на картинку на серверах Telegram и для отправки пользователям с помощью sendPhoto. А распознавание изображений с помощью Google cloud vision работает более точно, чем у IBM Watson

Автор: wildboar47

Источник [5]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/c-2/220315

Ссылки в тексте:

[1] статью: https://geektimes.ru/post/280044/

[2] статья про google cloud vision: https://habrahabr.ru/post/312714/

[3] гитхабе GoogleCloudPlatform: https://github.com/GoogleCloudPlatform/dotnet-docs-samples/tree/master/vision/labelDetection

[4] telegram bot: https://github.com/MrRoundRobin/telegram.bot

[5] Источник: https://geektimes.ru/post/283630/