# Detecção de objetos zero-shot

Tradicionalmente, os modelos usados para [detecção de objetos](object_detection) exigem conjuntos de dados de imagens rotulados para 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.

> [!NOTE]
> O Hugging Face abriga muitos desses [detectores de objetos zero shot com vocabulário aberto](https://huggingface.co/models?pipeline_tag=zero-shot-object-detection).

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:

```bash
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()](/docs/transformers/main/pt/main_classes/pipelines#transformers.pipeline). Instancie um pipeline para detecção de objetos zero-shot a partir de um [checkpoint no Hugging Face Hub](https://huggingface.co/models?pipeline_tag=zero-shot-object-detection):

```python
>>> 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](https://www.nasa.gov/multimedia/imagegallery/index.html).

```py
>>> 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.

```py
>>> 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:

```py
>>> 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](https://hf.co/iSEE-Laboratory/llmdet_large). Aqui, usaremos o mesmo checkpoint de antes:

```py
>>> 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.

```py
>>> 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.

```py
>>> 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:

```py
>>> 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, tensores do PyTorch ou arrays NumPy.

```py
>>> 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`).

```py
>>> 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:

```py
>>> 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](https://huggingface.co/collections/ariG23498/owlvit-689b0d0872a7634a6ea17ae7) e [OWLv2](https://huggingface.co/collections/ariG23498/owlv2-689b0d27bd7d96ba3c7f7530) 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.

```py
>>> 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 pegar uma imagem com dois gatos em um sofá como imagem de referência e uma imagem de um único gato como consulta:

```py
>>> 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:

```py
>>> 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`:

```py
>>> 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()](/docs/transformers/main/pt/model_doc/owlvit#transformers.OwlViTForObjectDetection.image_guided_detection). Desenhe as previsões como antes, exceto que agora não há rótulos.

```py
>>> 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
```

     

