Telegram бот и использование Google Cloud Vision
Небольшая предыстория:
Мой бот вполне успешно работал пару месяцев с использованием распознавания IBM Watson, однако затем на хабре вышла статья про google cloud vision и оказалось, что Google распознает изображения лучше, чем IBM. В тот же день я зарегистрировался в консоли разработчика Google cloud platform и начал переписывать блок модерации котиков в своем боте.
Немного поискав, я нашел подходящий пример на C# на гитхабе GoogleCloudPlatform. Я поменял аутентификацию из примера и сделал ее из json файла с private key, который взял в разделе «сервисные аккаунты» консоли.
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, что дает неплохой прирост скорости работы.
private async Task> 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, и таким образом, определяю есть ли котик в переданной боту картинке:
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:
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
Источник
От Джона Уилера до наших дней: эволюция концепции бозонных звезд
Космический телескоп «Роман» займется поиском древних черных дыр по поглощаемым ими звездам
Можно ли разделить фотон пополам с точки зрения квантовой физики?
Призрачные отсветы минувшего
Объективная реальность существует лишь благодаря другим людям
Как миллионы лет эволюции сделали из стрекоз непревзойденных пилотов
Именная гитара «Flying Arrow» Керри Кинга от B.C. Rich
Темная энергия под вопросом: почему рушится главная модель Вселенной