O Google Cloud Vision analisa imagens e diz o que há nelas: retorna rótulos descritivos, lê texto impresso e manuscrito (OCR), detecta faces, reconhece pontos de referência e logotipos famosos, e mais. O sgcWebSockets Enterprise inclui um cliente Vision gRPC tipado que se apoia sobre o TsgcGRPCClient, para que você possa enviar uma imagem e ler de volta suas anotações a partir do Delphi e do C++Builder sem nenhum runtime externo ou protobufs escritos à mão.
Como funciona
O Cloud Vision expõe um serviço gRPC ImageAnnotator. Uma requisição é um lote de uma ou mais imagens, cada uma pareada com a lista de recursos que você quer detectar, e a resposta é um lote correspondente de anotações. Toda a troca são mensagens Protocol Buffers encapsuladas sobre HTTP/2.
O sgcWebSockets já vem com uma pilha HTTP/2 completa, então o transporte é um TsgcHTTP2Client apontado para vision.googleapis.com:443 sobre TLS. O TsgcGRPCClient se apoia sobre ele e faz o enquadramento gRPC, os cabeçalhos, os timeouts e a análise de trailers. As classes de mensagem Vision em sgcGRPC_Google_Vision são auxiliares protobuf tipados: você preenche o objeto de requisição, chama ToBytes para serializá-lo, o envia com o cliente genérico e carrega os bytes da resposta de volta em um objeto de resposta tipado com LoadFromBytes.
A autenticação é o fluxo padrão de conta de serviço do Google. Um JWT autoassinado é trocado por um token bearer e enviado como metadado gRPC em cada chamada. Como o JWT é vinculado à audiência, o token tem como alvo o endpoint do Vision para que vision.googleapis.com o aceite.
Configurando os clientes
Crie o transporte HTTP/2, anexe o cliente gRPC a ele e diga ao canal para usar o tipo de conteúdo protobuf binário. O Vision fala application/grpc+proto.
uses
sgcHTTP2_Client, sgcGRPC_Types, sgcGRPC_Client,
sgcGRPC_Google_Vision;
var
HTTP2: TsgcHTTP2Client;
GRPC: TsgcGRPCClient;
begin
HTTP2 := TsgcHTTP2Client.Create(nil);
HTTP2.Host := 'vision.googleapis.com';
HTTP2.Port := 443;
HTTP2.TLS := True;
GRPC := TsgcGRPCClient.Create(nil);
GRPC.Client := HTTP2;
GRPC.ChannelOptions.ContentType := grpcProto;
GRPC.ChannelOptions.Compression := grpcNoCompression;
end;
Autenticação
O token bearer vem das suas credenciais de conta de serviço. Configure as opções JWT com os valores da chave JSON baixada, aponte a audiência para o endpoint do Vision e adicione o token resultante ao DefaultMetadata para que ele acompanhe cada chamada gRPC.
// configure the service-account JWT (values from the JSON key file)
CloudClient.GoogleCloudOptions.Authentication := gcaJWT;
CloudClient.GoogleCloudOptions.JWT.ClientEmail := ClientEmail;
CloudClient.GoogleCloudOptions.JWT.PrivateKeyId := PrivateKeyId;
CloudClient.GoogleCloudOptions.JWT.PrivateKey.Text := PrivateKey;
CloudClient.GoogleCloudOptions.JWT.ProjectId := ProjectId;
// the self-signed JWT is audience-bound to the Vision endpoint
CloudClient.GoogleCloudOptions.JWT.API_Endpoint :=
'https://vision.googleapis.com/';
// once the token is acquired, send it as gRPC metadata
GRPC.DefaultMetadata.Clear;
GRPC.DefaultMetadata.Add('authorization', 'Bearer ' + Token);
Anotando uma imagem
Para analisar uma imagem você monta um TsgcGRPCVisionBatchAnnotateImagesRequest, adiciona uma requisição de imagem, a aponta para a imagem (um URI do Google Cloud Storage aqui, mas você também pode enviar bytes brutos) e adiciona um ou mais recursos. Cada recurso tem um FeatureType e um MaxResults opcional. Serialize com ToBytes e chame o método BatchAnnotateImages do serviço ImageAnnotator.
var
oRequest: TsgcGRPCVisionBatchAnnotateImagesRequest;
oImgReq: TsgcGRPCVisionAnnotateImageRequest;
oFeature: TsgcGRPCVisionFeature;
oResponse: TsgcGRPCResponse;
begin
oRequest := TsgcGRPCVisionBatchAnnotateImagesRequest.Create;
try
oImgReq := oRequest.AddRequest;
oImgReq.Image.Source.GcsImageUri :=
'gs://cloud-samples-data/vision/demo-image.jpg';
oFeature := oImgReq.AddFeature;
oFeature.FeatureType := 4; // LABEL_DETECTION
oFeature.MaxResults := 10;
oResponse := GRPC.Call('google.cloud.vision.v1.ImageAnnotator',
'BatchAnnotateImages', oRequest.ToBytes);
finally
oRequest.Free;
end;
end;
Os valores de FeatureType seguem o enum da API Vision: 1 FACE_DETECTION, 2 LANDMARK_DETECTION, 3 LOGO_DETECTION, 4 LABEL_DETECTION, 5 TEXT_DETECTION, 6 DOCUMENT_TEXT_DETECTION, e os demais. Para executar várias detecções na mesma imagem em uma única viagem de ida e volta, adicione mais de um recurso.
Lendo as anotações
Os bytes da resposta carregam diretamente em uma resposta de lote tipada. Cada imagem no lote carrega listas separadas para anotações de rótulo, ponto de referência, logotipo e texto. Cada entrada é um TsgcGRPCVisionEntityAnnotation com uma Description e, para rótulos, uma pontuação de confiança Score.
var
oResponse: TsgcGRPCVisionBatchAnnotateImagesResponse;
oImgResp: TsgcGRPCVisionAnnotateImageResponse;
i, j: Integer;
begin
oResponse := TsgcGRPCVisionBatchAnnotateImagesResponse.Create;
try
oResponse.LoadFromBytes(aData);
for i := 0 to oResponse.ResponseCount - 1 do
begin
oImgResp := oResponse.Response(i);
for j := 0 to oImgResp.LabelAnnotationCount - 1 do
Memo1.Lines.Add('Label: ' + oImgResp.LabelAnnotation(j).Description +
' (score: ' + FloatToStr(oImgResp.LabelAnnotation(j).Score) + ')');
for j := 0 to oImgResp.TextAnnotationCount - 1 do
Memo1.Lines.Add('Text: ' + oImgResp.TextAnnotation(j).Description);
for j := 0 to oImgResp.LandmarkAnnotationCount - 1 do
Memo1.Lines.Add('Landmark: ' + oImgResp.LandmarkAnnotation(j).Description);
end;
finally
oResponse.Free;
end;
end;
Imagens do storage ou de bytes
A origem da imagem é flexível. Defina Image.Source.GcsImageUri para um objeto no Google Cloud Storage, ou Image.Source.ImageUri para uma URL HTTP(S) pública. Para anotar um arquivo local, leia-o em um TBytes e atribua-o a Image.Content, para que a imagem viaje inline na requisição. As mesmas classes de requisição e resposta lidam com todas as origens.
Síncrono ou assíncrono
O exemplo acima usa o Call bloqueante, que retorna um TsgcGRPCResponse com o StatusCode, os bytes brutos de Data e os trailers. Para manter a interface responsiva, use CallAsync e trate a resposta no evento OnGRPCResponse, onde você analisa aResponse.Data exatamente da mesma forma. Um status diferente de OK aparece através de OnGRPCError, e uma falha de transporte através de OnGRPCException.
Disponibilidade
O cliente Vision gRPC tipado faz parte da edição Enterprise do sgcWebSockets e roda em Windows, macOS, Linux, iOS e Android. Um exemplo pronto para executar está em Demos\21.GRPC\13.Vision, e a referência completa está na página do produto gRPC Client.
Dúvidas ou comentários? Entre em contato. Você receberá uma resposta das pessoas que escreveram o código.
