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

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

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

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

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

    код авторизации на c#
    private VisionService service;
            private string _JsonPath = @"C:\BOTS\fcatsbot\json.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:

    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

    Комментарии 2

      +1
      А ссылку на бота можно?
        0
        поищите fcatsbot в сторе телеграма)

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое