Transformers documentation
Detecção de objetos zero-shot
Detecção de objetos zero-shot
Tradicionalmente, os modelos usados para detecção de objetos exigem conjuntos de dados de imagens rotulados para o treinamento e são limitados à detecção do conjunto de classes dos dados de treinamento.
A detecção de objetos zero-shot é uma tarefa de visão computacional para detectar objetos e suas classes em imagens, sem nenhum treinamento prévio ou conhecimento das classes. Os modelos de detecção de objetos zero-shot recebem uma imagem como entrada, bem como uma lista de classes candidatas, e produzem as caixas delimitadoras e os rótulos onde os objetos foram detectados.
O Hugging Face abriga muitos desses detectores de objetos zero shot com vocabulário aberto.
Neste guia, você aprenderá a usar esses modelos:
- para detectar objetos com base em prompts de texto
- para detecção de objetos em lote
- para detecção de objetos guiada por imagem
Antes de começar, verifique se você tem todas as bibliotecas necessárias instaladas:
pip install -q transformers
Pipeline de detecção de objetos zero-shot
A maneira mais simples de testar a inferência com modelos é usá-la em um pipeline(). Instancie um pipeline para detecção de objetos zero-shot a partir de um checkpoint no Hugging Face Hub:
>>> from transformers import pipeline
>>> # Use any checkpoint from the hf.co/models?pipeline_tag=zero-shot-object-detection
>>> checkpoint = "iSEE-Laboratory/llmdet_large"
>>> detector = pipeline(model=checkpoint, task="zero-shot-object-detection")Em seguida, escolha uma imagem em que você deseja detectar objetos. Aqui, usaremos a imagem da astronauta Eileen Collins, que faz parte do conjunto de dados Great Images da NASA.
>>> from transformers.image_utils import load_image
>>> url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/zero-sh-obj-detection_1.png"
>>> image = load_image(url)
>>> image
Passe a imagem e os rótulos dos objetos candidatos a serem procurados para o pipeline. Aqui, passamos a imagem diretamente; outras opções adequadas incluem um caminho local para uma imagem ou uma URL de imagem. Também passamos descrições em texto para todos os itens que queremos consultar na imagem.
>>> predictions = detector(
... image,
... candidate_labels=["human face", "rocket", "nasa badge", "star-spangled banner"],
... threshold=0.45,
... )
>>> predictions
[{'score': 0.8409242033958435,
'label': 'human face',
'box': {'xmin': 179, 'ymin': 74, 'xmax': 272, 'ymax': 179}},
{'score': 0.7380027770996094,
'label': 'rocket',
'box': {'xmin': 353, 'ymin': 0, 'xmax': 466, 'ymax': 284}},
{'score': 0.5850900411605835,
'label': 'star-spangled banner',
'box': {'xmin': 0, 'ymin': 0, 'xmax': 96, 'ymax': 511}},
{'score': 0.5697067975997925,
'label': 'human face',
'box': {'xmin': 18, 'ymin': 15, 'xmax': 366, 'ymax': 511}},
{'score': 0.47813931107521057,
'label': 'star-spangled banner',
'box': {'xmin': 353, 'ymin': 0, 'xmax': 459, 'ymax': 274}},
{'score': 0.46597740054130554,
'label': 'nasa badge',
'box': {'xmin': 353, 'ymin': 0, 'xmax': 462, 'ymax': 279}},
{'score': 0.4585932493209839,
'label': 'nasa badge',
'box': {'xmin': 132, 'ymin': 348, 'xmax': 208, 'ymax': 423}}]Vamos visualizar as previsões:
>>> from PIL import ImageDraw
>>> draw = ImageDraw.Draw(image)
>>> for prediction in predictions:
... box = prediction["box"]
... label = prediction["label"]
... score = prediction["score"]
... xmin, ymin, xmax, ymax = box.values()
... draw.rectangle((xmin, ymin, xmax, ymax), outline="red", width=1)
... draw.text((xmin, ymin), f"{label}: {round(score,2)}", fill="white")
>>> image
Detecção de objetos zero-shot com prompt de texto, feita manualmente
Agora que você viu como usar o pipeline de detecção de objetos zero-shot, vamos replicar o mesmo resultado manualmente.
Comece carregando o modelo e o processador associado de um checkpoint no Hugging Face Hub. Aqui, usaremos o mesmo checkpoint de antes:
>>> from transformers import AutoProcessor, AutoModelForZeroShotObjectDetection
>>> model = AutoModelForZeroShotObjectDetection.from_pretrained(checkpoint, device_map="auto")
>>> processor = AutoProcessor.from_pretrained(checkpoint)Vamos usar uma imagem diferente para variar.
>>> url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/zero-sh-obj-detection_3.png"
>>> image = load_image(url)
>>> image
Use o processor para preparar as entradas para o modelo.
>>> text_labels = ["hat", "book", "sunglasses", "camera"]
>>> inputs = processor(text=text_labels, images=image, return_tensors="pt").to(model.device)Passe as entradas pelo modelo, faça o pós-processamento e visualize os resultados. Como o processador de imagens redimensionou as imagens antes de enviá-las ao modelo, você precisa usar o método post_process_object_detection para garantir que as caixas delimitadoras previstas tenham as coordenadas corretas em relação à imagem original:
>>> import torch
>>> with torch.inference_mode():
... outputs = model(**inputs)
>>> results = processor.post_process_grounded_object_detection(
... outputs, threshold=0.50, target_sizes=[(image.height, image.width)], text_labels=text_labels,
... )[0]
>>> draw = ImageDraw.Draw(image)
>>> scores = results["scores"]
>>> text_labels = results["text_labels"]
>>> boxes = results["boxes"]
>>> for box, score, text_label in zip(boxes, scores, text_labels):
... xmin, ymin, xmax, ymax = box
... draw.rectangle((xmin, ymin, xmax, ymax), outline="red", width=1)
... draw.text((xmin, ymin), f"{text_label}: {round(score.item(),2)}", fill="white")
>>> image
Processamento em lote
Você pode passar vários conjuntos de imagens e consultas de texto para buscar objetos diferentes (ou os mesmos) em várias imagens. Vamos usar uma imagem de um astronauta e a imagem da praia juntos. Para processamento em lote, você deve passar as consultas de texto como uma lista aninhada para o processador e as imagens como listas de imagens PIL, tensors do PyTorch ou arrays NumPy.
>>> url1 = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/zero-sh-obj-detection_1.png"
>>> url2 = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/zero-sh-obj-detection_3.png"
>>> images = [load_image(url1), load_image(url2)]
>>> text_queries = [
... ["human face", "rocket", "nasa badge", "star-spangled banner"],
... ["hat", "book", "sunglasses", "camera", "can"],
... ]
>>> inputs = processor(text=text_queries, images=images, return_tensors="pt", padding=True)Anteriormente, para o pós-processamento, você passava o tamanho da imagem única como um tensor, mas também pode passar uma tupla ou, no caso de várias imagens, uma lista de tuplas. Vamos criar previsões para os dois exemplos e visualizar o segundo (image_idx = 1).
>>> with torch.no_grad():
>>> outputs = model(**inputs)
>>> target_sizes = [(image.height, image.width) for image in images]
>>> results = processor.post_process_grounded_object_detection(
... outputs, threshold=0.3, target_sizes=target_sizes, text_labels=text_labels,
... )Vamos visualizar os resultados:
>>> image_idx = 1
>>> draw = ImageDraw.Draw(images[image_idx])
>>> scores = results[image_idx]["scores"].tolist()
>>> text_labels = results[image_idx]["text_labels"]
>>> boxes = results[image_idx]["boxes"].tolist()
>>> for box, score, text_label in zip(boxes, scores, text_labels):
>>> xmin, ymin, xmax, ymax = box
>>> draw.rectangle((xmin, ymin, xmax, ymax), outline="red", width=1)
>>> draw.text((xmin, ymin), f"{text_label}: {round(score,2)}", fill="white")
>>> images[image_idx]
Detecção de objetos guiada por imagem
Além da detecção de objetos zero-shot com consultas de texto, modelos como OWL-ViT e OWLv2 oferecem detecção de objetos guiada por imagem. Isso significa que você pode usar uma consulta de imagem para encontrar objetos semelhantes na imagem de destino.
>>> from transformers import AutoProcessor, AutoModelForZeroShotObjectDetection
>>> checkpoint = "google/owlv2-base-patch16-ensemble"
>>> model = AutoModelForZeroShotObjectDetection.from_pretrained(checkpoint, device_map="auto")
>>> processor = AutoProcessor.from_pretrained(checkpoint)Diferentemente das consultas de texto, apenas uma única imagem de exemplo é permitida.
Vamos usar uma imagem com dois gatos em um sofá como imagem de referência e uma imagem de um único gato como consulta:
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
>>> image_target = Image.open(requests.get(url, stream=True).raw)
>>> query_url = "http://images.cocodataset.org/val2017/000000524280.jpg"
>>> query_image = Image.open(requests.get(query_url, stream=True).raw)Vamos dar uma olhada rápida nas imagens:
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots(1, 2)
>>> ax[0].imshow(image_target)
>>> ax[1].imshow(query_image)
>>> fig.show()
Na etapa de pré-processamento, em vez de consultas de texto, você agora precisa usar query_images:
>>> inputs = processor(images=image_target, query_images=query_image, return_tensors="pt")Para as previsões, em vez de passar as entradas para o modelo, passe-as para image_guided_detection(). Desenhe as previsões como antes, exceto que agora não há rótulos.
>>> with torch.no_grad():
... outputs = model.image_guided_detection(**inputs)
... target_sizes = torch.tensor([image_target.size[::-1]])
... results = processor.post_process_image_guided_detection(outputs=outputs, target_sizes=target_sizes)[0]
>>> draw = ImageDraw.Draw(image_target)
>>> scores = results["scores"].tolist()
>>> boxes = results["boxes"].tolist()
>>> for box, score in zip(boxes, scores):
... xmin, ymin, xmax, ymax = box
... draw.rectangle((xmin, ymin, xmax, ymax), outline="white", width=4)
>>> image_target